pub struct MutationBuffer { /* private fields */ }Expand description
Write buffer for batching mutations with size limits.
MutationBuffer provides a memory-bounded container for accumulating mutations
before applying them to a tree. This is useful for processing large datasets
that don’t fit in memory, allowing you to flush mutations in batches.
§Size Tracking
The buffer tracks the total byte size of accumulated mutations:
- For
Upsertmutations: key length + value length - For
Deletemutations: key length
When adding a mutation would exceed the configured maximum size, the add()
method returns Err(Error::BufferFull).
§Example
use prolly::{MutationBuffer, Mutation, Error};
let mut buffer = MutationBuffer::with_max_size(1024); // 1KB limit
// Add mutations until buffer is full
let mutation = Mutation::Upsert {
key: b"key".to_vec(),
val: b"value".to_vec(),
};
buffer.add(mutation).unwrap();
// Check buffer state
assert!(!buffer.is_empty());
assert_eq!(buffer.len(), 1);
// Drain mutations for processing
let mutations = buffer.drain();
assert!(buffer.is_empty());§Streaming Large Datasets
use prolly::{MutationBuffer, Mutation, Prolly, MemStore, Config};
let store = MemStore::new();
let prolly = Prolly::new(store, Config::default());
let mut tree = prolly.create();
let mut buffer = MutationBuffer::with_max_size(10 * 1024 * 1024); // 10MB
// Process large dataset in chunks
for i in 0..1000 {
let mutation = Mutation::Upsert {
key: format!("key{}", i).into_bytes(),
val: format!("value{}", i).into_bytes(),
};
if buffer.add(mutation).is_err() {
// Buffer full - flush to tree
let mutations = buffer.drain();
tree = prolly.batch(&tree, mutations).unwrap();
}
}
// Flush remaining mutations
if !buffer.is_empty() {
let mutations = buffer.drain();
tree = prolly.batch(&tree, mutations).unwrap();
}Implementations§
Source§impl MutationBuffer
impl MutationBuffer
Sourcepub fn with_max_size(max_size: usize) -> Self
pub fn with_max_size(max_size: usize) -> Self
Create a new MutationBuffer with a custom maximum size.
§Arguments
max_size- Maximum buffer size in bytes
§Returns
A new empty MutationBuffer with the specified size limit.
§Example
use prolly::MutationBuffer;
let buffer = MutationBuffer::with_max_size(1024 * 1024); // 1MB limit
assert!(buffer.is_empty());Sourcepub fn add(&mut self, mutation: Mutation) -> Result<(), Error>
pub fn add(&mut self, mutation: Mutation) -> Result<(), Error>
Add a mutation to the buffer.
The mutation’s size is calculated as:
Upsert: key length + value lengthDelete: key length
§Arguments
mutation- The mutation to add
§Returns
Ok(())- Mutation was added successfullyErr(Error::BufferFull)- Adding the mutation would exceed the buffer’s max size
§Example
use prolly::{MutationBuffer, Mutation, Error};
let mut buffer = MutationBuffer::with_max_size(5);
// This fits (1 + 1 = 2 bytes)
let result = buffer.add(Mutation::Upsert {
key: b"a".to_vec(),
val: b"1".to_vec(),
});
assert!(result.is_ok());
// This would exceed the limit (3 + 5 = 8 bytes, total would be 10 > 5)
let result = buffer.add(Mutation::Upsert {
key: b"key".to_vec(),
val: b"value".to_vec(),
});
assert!(matches!(result, Err(Error::BufferFull)));Sourcepub fn drain(&mut self) -> Vec<Mutation>
pub fn drain(&mut self) -> Vec<Mutation>
Drain all mutations from the buffer and reset its state.
Returns all accumulated mutations and resets the buffer to empty. The current size is reset to 0.
§Returns
A vector containing all mutations that were in the buffer.
§Example
use prolly::{MutationBuffer, Mutation};
let mut buffer = MutationBuffer::new();
buffer.add(Mutation::Upsert {
key: b"key".to_vec(),
val: b"value".to_vec(),
}).unwrap();
let mutations = buffer.drain();
assert_eq!(mutations.len(), 1);
assert!(buffer.is_empty());
assert_eq!(buffer.size(), 0);Sourcepub fn is_full(&self) -> bool
pub fn is_full(&self) -> bool
Check if the buffer is full.
Returns true if the current size equals or exceeds the maximum size.
Note that this doesn’t guarantee the next add() will fail, as it depends
on the size of the mutation being added.
§Returns
true if the buffer is at or over capacity, false otherwise.
§Example
use prolly::{MutationBuffer, Mutation};
let mut buffer = MutationBuffer::with_max_size(5);
assert!(!buffer.is_full());
buffer.add(Mutation::Upsert {
key: b"ab".to_vec(),
val: b"cde".to_vec(),
}).unwrap();
assert!(buffer.is_full()); // 2 + 3 = 5 bytesSourcepub fn size(&self) -> usize
pub fn size(&self) -> usize
Get the current size of the buffer in bytes.
§Returns
The total byte size of all mutations in the buffer.
§Example
use prolly::{MutationBuffer, Mutation};
let mut buffer = MutationBuffer::new();
assert_eq!(buffer.size(), 0);
buffer.add(Mutation::Upsert {
key: b"key".to_vec(), // 3 bytes
val: b"value".to_vec(), // 5 bytes
}).unwrap();
assert_eq!(buffer.size(), 8);Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Get the number of mutations in the buffer.
§Returns
The count of mutations currently in the buffer.
§Example
use prolly::{MutationBuffer, Mutation};
let mut buffer = MutationBuffer::new();
assert_eq!(buffer.len(), 0);
buffer.add(Mutation::Upsert {
key: b"key".to_vec(),
val: b"value".to_vec(),
}).unwrap();
assert_eq!(buffer.len(), 1);Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Check if the buffer is empty.
§Returns
true if the buffer contains no mutations, false otherwise.
§Example
use prolly::{MutationBuffer, Mutation};
let mut buffer = MutationBuffer::new();
assert!(buffer.is_empty());
buffer.add(Mutation::Upsert {
key: b"key".to_vec(),
val: b"value".to_vec(),
}).unwrap();
assert!(!buffer.is_empty());Sourcepub fn sort(&mut self)
pub fn sort(&mut self)
Sort mutations by key in lexicographic byte order.
Sorts mutations in place using lexicographic byte ordering, which is consistent with the tree’s key ordering. This prepares mutations for efficient batch processing.
The sort is stable, meaning mutations with the same key maintain their relative order. This is important for last-write-wins semantics when combined with deduplication.
§Example
use prolly::{MutationBuffer, Mutation};
let mut buffer = MutationBuffer::new();
buffer.add(Mutation::Upsert {
key: b"c".to_vec(),
val: b"3".to_vec(),
}).unwrap();
buffer.add(Mutation::Upsert {
key: b"a".to_vec(),
val: b"1".to_vec(),
}).unwrap();
buffer.add(Mutation::Upsert {
key: b"b".to_vec(),
val: b"2".to_vec(),
}).unwrap();
buffer.sort();
let mutations = buffer.drain();
assert_eq!(mutations[0].key(), b"a");
assert_eq!(mutations[1].key(), b"b");
assert_eq!(mutations[2].key(), b"c");Trait Implementations§
Auto Trait Implementations§
impl Freeze for MutationBuffer
impl RefUnwindSafe for MutationBuffer
impl Send for MutationBuffer
impl Sync for MutationBuffer
impl Unpin for MutationBuffer
impl UnsafeUnpin for MutationBuffer
impl UnwindSafe for MutationBuffer
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more