Files
mini_lsm/mini-lsm/src/block/builder.rs
Alex Chi a03cb765ff feat(docs): finish part 1
Signed-off-by: Alex Chi <iskyzh@gmail.com>
2022-12-24 00:17:48 -05:00

62 lines
1.6 KiB
Rust

use bytes::BufMut;
use super::{Block, SIZEOF_U16};
/// Builds a block.
pub struct BlockBuilder {
/// Offsets of each key-value entries.
offsets: Vec<u16>,
/// All key-value pairs in the block.
data: Vec<u8>,
/// The expected block size.
block_size: usize,
}
impl BlockBuilder {
/// Creates a new block builder.
pub fn new(block_size: usize) -> Self {
Self {
offsets: Vec::new(),
data: Vec::new(),
block_size,
}
}
fn estimated_size(&self) -> usize {
self.offsets.len() * SIZEOF_U16 + self.data.len() + SIZEOF_U16
}
/// Adds a key-value pair to the block. Returns false when the block is full.
#[must_use]
pub fn add(&mut self, key: &[u8], value: &[u8]) -> bool {
assert!(!key.is_empty(), "key must not be empty");
if self.estimated_size() + key.len() + value.len() + SIZEOF_U16 * 3 > self.block_size
&& !self.is_empty()
{
return false;
}
self.offsets.push(self.data.len() as u16);
self.data.put_u16(key.len() as u16);
self.data.put(key);
self.data.put_u16(value.len() as u16);
self.data.put(value);
true
}
/// Check if there is no key-value pair in the block.
pub fn is_empty(&self) -> bool {
self.offsets.is_empty()
}
/// Finalize the block.
pub fn build(self) -> Block {
if self.is_empty() {
panic!("block should not be empty");
}
Block {
data: self.data,
offsets: self.offsets,
}
}
}