Skip to content

Commit

Permalink
quicklog(serialize): modify Serialize impl for DSTs
Browse files Browse the repository at this point in the history
  • Loading branch information
thog92 committed Mar 7, 2024
1 parent ce0da33 commit 4c8cdc5
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 46 deletions.
28 changes: 17 additions & 11 deletions quicklog/benches/logger_benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,36 @@ struct Nested {

impl Serialize for BigStruct {
fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> Store<'buf> {
let (mut _head, mut tail) = write_buf.split_at_mut(0);
for i in 0..100 {
(_head, tail) = tail.split_at_mut(4);
let (chunk, _) = write_buf.split_at_mut(self.buffer_size_required());

let elm_size = std::mem::size_of::<i32>();
let (vec_chunk, str_chunk) = chunk.split_at_mut(self.vec.len() * elm_size);
let (mut _head, mut _tail) = vec_chunk.split_at_mut(0);
for i in 0..self.vec.len() {
(_head, _tail) = _tail.split_at_mut(elm_size);
_head.copy_from_slice(&self.vec[i].to_le_bytes())
}

tail.copy_from_slice(self.some.as_bytes());
_ = self.some.encode(str_chunk);

Store::new(Self::decode, write_buf)
Store::new(Self::decode, chunk)
}

fn decode(buf: &[u8]) -> (String, &[u8]) {
let (mut _head, mut tail) = buf.split_at(0);
let mut vec = vec![];
for _ in 0..100 {
(_head, tail) = tail.split_at(4);
vec.push(i32::from_le_bytes(_head.try_into().unwrap()));
let mut arr = [0; 100];
let elm_size = std::mem::size_of::<i32>();
for i in &mut arr {
(_head, tail) = tail.split_at(elm_size);
*i = i32::from_le_bytes(_head.try_into().unwrap());
}
let (s, rest) = <&str as Serialize>::decode(tail);
(format!("vec: {:?}, str: {}", vec, s), rest)

(format!("vec: {:?}, str: {}", arr, s), rest)
}

fn buffer_size_required(&self) -> usize {
std::mem::size_of::<i32>() * 100 + self.some.len()
std::mem::size_of::<i32>() * 100 + self.some.buffer_size_required()
}
}

Expand Down
44 changes: 26 additions & 18 deletions quicklog/src/serialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ pub trait Serialize {
/// Function pointer which decodes a byte buffer back into `String` representation
pub type DecodeFn = fn(&[u8]) -> (String, &[u8]);

/// Number of bytes it takes to store the size of a type.
pub const SIZE_LENGTH: usize = std::mem::size_of::<usize>();

/// Contains the decode function required to decode `buffer` back into a `String`
/// representation.
#[derive(Clone)]
Expand Down Expand Up @@ -76,36 +79,42 @@ gen_serialize!(usize);

impl Serialize for &str {
fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> Store<'buf> {
assert!(self.len() == write_buf.len());
write_buf.copy_from_slice(self.as_bytes());
Store::new(Self::decode, write_buf)
let str_len = self.len();
let (chunk, _) = write_buf.split_at_mut(str_len + SIZE_LENGTH);
let (len_chunk, str_chunk) = chunk.split_at_mut(SIZE_LENGTH);

len_chunk.copy_from_slice(&str_len.to_le_bytes());
str_chunk.copy_from_slice(self.as_bytes());

Store::new(Self::decode, chunk)
}

fn decode(read_buf: &[u8]) -> (String, &[u8]) {
let x = from_utf8(read_buf).unwrap();
(x.to_string(), &[])
let (len_chunk, chunk) = read_buf.split_at(SIZE_LENGTH);
let str_len = usize::from_le_bytes(len_chunk.try_into().unwrap());

let (str_chunk, rest) = chunk.split_at(str_len);
let s = from_utf8(str_chunk).unwrap();

(s.to_string(), rest)
}

fn buffer_size_required(&self) -> usize {
self.len()
SIZE_LENGTH + self.len()
}
}

/// Eager evaluation into a String for debug structs
pub fn encode_debug<T: std::fmt::Debug>(val: T, write_buf: &mut [u8]) -> Store {
let val_string = format!("{:?}", val);
// TODO: change back to strict equality when Serialize implemented, to use
// `buffer_size_required`
assert!(val_string.len() <= write_buf.len());
let str_len = val_string.len();

fn decode(read_buf: &[u8]) -> (String, &[u8]) {
let x = from_utf8(read_buf).unwrap();
(x.to_string(), &[])
}
let (chunk, _) = write_buf.split_at_mut(str_len + SIZE_LENGTH);
let (len_chunk, str_chunk) = chunk.split_at_mut(SIZE_LENGTH);
len_chunk.copy_from_slice(&str_len.to_le_bytes());
str_chunk.copy_from_slice(val_string.as_bytes());

let (chunk, _) = write_buf.split_at_mut(val_string.len());
chunk.copy_from_slice(val_string.as_bytes());
Store::new(decode, chunk)
Store::new(<&str as Serialize>::decode, chunk)
}

#[cfg(test)]
Expand Down Expand Up @@ -162,8 +171,7 @@ mod tests {
fn serialize_str() {
let mut buf = [0; 128];
let s = "hello world";
let (s_chunk, _) = buf.split_at_mut(s.buffer_size_required());
let store = s.encode(s_chunk);
let store = s.encode(&mut buf);

assert_eq!(s, format!("{}", store).as_str())
}
Expand Down
38 changes: 21 additions & 17 deletions quicklog/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,17 +106,15 @@ pub(crate) struct SerializeStruct {

impl Serialize for SerializeStruct {
fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> Store<'buf> {
write_buf.copy_from_slice(self.symbol.as_bytes());
Store::new(Self::decode, write_buf)
self.symbol.as_str().encode(write_buf)
}

fn decode(read_buf: &[u8]) -> (String, &[u8]) {
let x = std::str::from_utf8(read_buf).unwrap();
(x.to_string(), &[])
<&str as Serialize>::decode(read_buf)
}

fn buffer_size_required(&self) -> usize {
self.symbol.len()
self.symbol.as_str().buffer_size_required()
}
}

Expand All @@ -128,30 +126,36 @@ pub(crate) struct BigStruct {

impl Serialize for BigStruct {
fn encode<'buf>(&self, write_buf: &'buf mut [u8]) -> Store<'buf> {
let (mut _head, mut tail) = write_buf.split_at_mut(0);
for i in 0..100 {
(_head, tail) = tail.split_at_mut(4);
let (chunk, _) = write_buf.split_at_mut(self.buffer_size_required());

let elm_size = std::mem::size_of::<i32>();
let (vec_chunk, str_chunk) = chunk.split_at_mut(self.vec.len() * elm_size);
let (mut _head, mut _tail) = vec_chunk.split_at_mut(0);
for i in 0..self.vec.len() {
(_head, _tail) = _tail.split_at_mut(elm_size);
_head.copy_from_slice(&self.vec[i].to_le_bytes())
}

tail.copy_from_slice(self.some.as_bytes());
_ = self.some.encode(str_chunk);

Store::new(Self::decode, write_buf)
Store::new(Self::decode, chunk)
}

fn decode(buf: &[u8]) -> (String, &[u8]) {
let (mut _head, mut tail) = buf.split_at(0);
let mut vec = vec![];
for _ in 0..100 {
(_head, tail) = tail.split_at(4);
vec.push(i32::from_le_bytes(_head.try_into().unwrap()));
let mut arr = [0; 100];
let elm_size = std::mem::size_of::<i32>();
for i in 0..100 {
(_head, tail) = tail.split_at(elm_size);
arr[i] = i32::from_le_bytes(_head.try_into().unwrap());
}
let s = std::str::from_utf8(tail).unwrap();
(format!("vec: {:?}, str: {}", vec, s), &[])
let (s, rest) = <&str as Serialize>::decode(tail);

(format!("vec: {:?}, str: {}", arr, s), rest)
}

fn buffer_size_required(&self) -> usize {
std::mem::size_of::<i32>() * 100 + self.some.len()
std::mem::size_of::<i32>() * 100 + self.some.buffer_size_required()
}
}

Expand Down

0 comments on commit 4c8cdc5

Please sign in to comment.