Skip to content
This repository has been archived by the owner on Apr 15, 2023. It is now read-only.

Commit

Permalink
Changed to use supplied buffers to reduce allocations
Browse files Browse the repository at this point in the history
  • Loading branch information
chotchki committed Sep 12, 2021
1 parent c65cef8 commit 53cda6d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 27 deletions.
26 changes: 25 additions & 1 deletion src/engine/io/page_formats/page_offset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use crate::{
constants::{PAGES_PER_FILE, PAGE_SIZE},
engine::io::ConstEncodedSize,
};
use bytes::{Buf, BufMut};
use std::{
convert::TryFrom,
fmt,
mem::size_of,
num::TryFromIntError,
Expand All @@ -14,6 +16,26 @@ use thiserror::Error;
pub struct PageOffset(pub usize);

impl PageOffset {
pub fn serialize(&self, buffer: &mut impl BufMut) {
//TODO switch this and other serialize calls to usize based once my pull request is accepted
//https://github.com/tokio-rs/bytes/pull/511
buffer.put_uint_le(self.0 as u64, size_of::<usize>());
}

pub fn parse(buffer: &mut impl Buf) -> Result<Self, PageOffsetError> {
if buffer.remaining() < size_of::<usize>() {
return Err(PageOffsetError::BufferTooShort(
size_of::<usize>(),
buffer.remaining(),
));
}

let value = buffer.get_uint_le(size_of::<usize>());
let page = usize::try_from(value)?;

Ok(PageOffset(page))
}

/// This will calculate a page offset based on the max file count and the offset from the first
/// non-zero page in a file.
///
Expand Down Expand Up @@ -101,8 +123,10 @@ impl Mul for PageOffset {
}
}

#[derive(Debug, Error)]
#[derive(Debug, Error, PartialEq)]
pub enum PageOffsetError {
#[error("Not enough space to parse usize need {0} got {1}")]
BufferTooShort(usize, usize),
#[error(transparent)]
TryFromIntError(#[from] TryFromIntError),
}
Expand Down
38 changes: 14 additions & 24 deletions src/engine/io/row_formats/item_pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//!
//! We will be treating this a little different since our size will be based on usize
use crate::engine::io::page_formats::PageOffset;
use crate::engine::io::page_formats::{PageOffset, PageOffsetError};
use crate::engine::io::ConstEncodedSize;

use super::super::page_formats::{UInt12, UInt12Error};
Expand All @@ -25,28 +25,15 @@ impl ItemPointer {
ItemPointer { page, count }
}

pub fn serialize(&self) -> Bytes {
let mut buffer = BytesMut::with_capacity(size_of::<ItemPointer>());

buffer.put_slice(&self.page.0.to_le_bytes());
UInt12::serialize_packed(&mut buffer, &[self.count]);

buffer.freeze()
pub fn serialize(&self, buffer: &mut impl BufMut) {
self.page.serialize(buffer);
UInt12::serialize_packed(buffer, &[self.count]);
}

pub fn parse(buffer: &mut impl Buf) -> Result<Self, ItemPointerError> {
if buffer.remaining() < size_of::<usize>() {
return Err(ItemPointerError::BufferTooShort(
size_of::<usize>(),
buffer.remaining(),
));
}

let value = buffer.get_uint_le(size_of::<usize>());
let page = usize::try_from(value)?;

let po = PageOffset::parse(buffer)?;
let items = UInt12::parse_packed(buffer, 1)?;
Ok(ItemPointer::new(PageOffset(page), items[0]))
Ok(ItemPointer::new(po, items[0]))
}
}

Expand All @@ -66,8 +53,8 @@ impl ConstEncodedSize for ItemPointer {

#[derive(Debug, Error, PartialEq)]
pub enum ItemPointerError {
#[error("Not enough space to parse usize need {0} got {1}")]
BufferTooShort(usize, usize),
#[error(transparent)]
PageOffsetError(#[from] PageOffsetError),
#[error(transparent)]
TryFromIntError(#[from] TryFromIntError),
#[error(transparent)]
Expand All @@ -84,8 +71,9 @@ mod tests {
fn test_item_pointer_roundtrip() -> Result<(), Box<dyn std::error::Error>> {
let test = ItemPointer::new(PageOffset(1), UInt12::new(1).unwrap());

let mut test_serial = test.clone().serialize();
let test_reparse = ItemPointer::parse(&mut test_serial)?;
let mut buffer = BytesMut::new();
test.serialize(&mut buffer);
let test_reparse = ItemPointer::parse(&mut buffer.freeze())?;

assert_eq!(test, test_reparse);
Ok(())
Expand All @@ -96,7 +84,9 @@ mod tests {
let parse = ItemPointer::parse(&mut Bytes::new());

assert_eq!(
Err(ItemPointerError::BufferTooShort(size_of::<usize>(), 0)),
Err(ItemPointerError::PageOffsetError(
PageOffsetError::BufferTooShort(size_of::<usize>(), 0)
)),
parse
);

Expand Down
3 changes: 1 addition & 2 deletions src/engine/io/row_formats/row_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ impl RowData {
pub fn serialize(&self, buffer: &mut impl BufMut) {
buffer.put_u64_le(self.min.get_u64());
buffer.put_u64_le(self.max.unwrap_or_else(|| TransactionId::new(0)).get_u64());

buffer.put(self.item_pointer.serialize());
self.item_pointer.serialize(buffer);

//If there is null we add it to the flags and write a nullmask
let mut mask = InfoMask::empty();
Expand Down

0 comments on commit 53cda6d

Please sign in to comment.