@@ -6,7 +6,7 @@ use super::{Block, SIZEOF_U16};
|
||||
pub struct BlockBuilder {
|
||||
/// Offsets of each key-value entries.
|
||||
offsets: Vec<u16>,
|
||||
/// All key-value pairs in the block.
|
||||
/// All serialized key-value pairs in the block.
|
||||
data: Vec<u8>,
|
||||
/// The expected block size.
|
||||
block_size: usize,
|
||||
@@ -23,29 +23,33 @@ impl BlockBuilder {
|
||||
}
|
||||
|
||||
fn estimated_size(&self) -> usize {
|
||||
self.offsets.len() * SIZEOF_U16 + self.data.len() + SIZEOF_U16
|
||||
SIZEOF_U16 /* number of key-value pairs in the block */ + self.offsets.len() * SIZEOF_U16 /* offsets */ + self.data.len()
|
||||
/* key-value pairs */
|
||||
}
|
||||
|
||||
/// 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");
|
||||
// The overhead here is `key_len` + `val_len` + `offset`, each is of type `u16`
|
||||
if self.estimated_size() + key.len() + value.len() + SIZEOF_U16 * 3 > self.block_size
|
||||
if self.estimated_size() + key.len() + value.len() + SIZEOF_U16 * 3 /* key_len, value_len and offset */ > self.block_size
|
||||
&& !self.is_empty()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// The offsets should be updated at first, to maintain the correct offset
|
||||
// Add the offset of the data into the offset array.
|
||||
self.offsets.push(self.data.len() as u16);
|
||||
// Encode key length.
|
||||
self.data.put_u16(key.len() as u16);
|
||||
// Encode key content.
|
||||
self.data.put(key);
|
||||
// Encode value length.
|
||||
self.data.put_u16(value.len() as u16);
|
||||
// Encode value content.
|
||||
self.data.put(value);
|
||||
true
|
||||
}
|
||||
|
||||
/// Check if there is no key-value pair in the block.
|
||||
/// Check if there are no key-value pairs in the block.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.offsets.is_empty()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user