mod builder; mod iterator; pub use builder::BlockBuilder; use bytes::{Buf, BufMut, Bytes}; pub use iterator::BlockIterator; pub(crate) const SIZEOF_U16: usize = std::mem::size_of::(); /// A block is the smallest unit of read and caching in LSM tree. It is a collection of sorted /// key-value pairs. pub struct Block { pub(crate) data: Vec, pub(crate) offsets: Vec, } impl Block { pub fn encode(&self) -> Bytes { let mut buf = self.data.clone(); let offsets_len = self.offsets.len(); for offset in &self.offsets { buf.put_u16(*offset); } // Adds number of elements at the end of the block buf.put_u16(offsets_len as u16); buf.into() } pub fn decode(data: &[u8]) -> Self { // get number of elements in the block let entry_offsets_len = (&data[data.len() - SIZEOF_U16..]).get_u16() as usize; let data_end = data.len() - SIZEOF_U16 - entry_offsets_len * SIZEOF_U16; let offsets_raw = &data[data_end..data.len() - SIZEOF_U16]; // get offset array let offsets = offsets_raw .chunks(SIZEOF_U16) .map(|mut x| x.get_u16()) .collect(); // retrieve data let data = data[0..data_end].to_vec(); Self { data, offsets } } }