pub struct BitMap<const N: usize, S: State = Clean> { /* private fields */ }Expand description
A historical bitmap that maintains one actual bitmap plus diffs for history.
Uses a type-state pattern to track whether the bitmap is clean (no pending mutations) or dirty (has pending mutations).
Commit numbers must be strictly monotonically increasing and < u64::MAX.
Implementations§
Source§impl<const N: usize> BitMap<N>
impl<const N: usize> BitMap<N>
Sourcepub fn new_with_pruned_chunks(pruned_chunks: usize) -> Result<Self, Error>
pub fn new_with_pruned_chunks(pruned_chunks: usize) -> Result<Self, Error>
Create a new historical bitmap with the given number of pruned chunks.
Sourcepub fn into_dirty(self) -> DirtyBitMap<N>
pub fn into_dirty(self) -> DirtyBitMap<N>
Transition to dirty state to begin making mutations.
All mutations are applied to a diff layer and do not affect the current bitmap until commit.
§Examples
let bitmap: BitMap<4> = BitMap::new();
let mut dirty = bitmap.into_dirty();
dirty.push(true);
dirty.push(false);
let bitmap = dirty.commit(1).unwrap();
assert_eq!(bitmap.len(), 2);Sourcepub fn apply_batch<F>(self, commit_number: u64, f: F) -> Result<Self, Error>where
F: FnOnce(&mut DirtyBitMap<N>),
pub fn apply_batch<F>(self, commit_number: u64, f: F) -> Result<Self, Error>where
F: FnOnce(&mut DirtyBitMap<N>),
Execute a closure with a dirty bitmap and commit it at the given commit number.
§Errors
Returns Error::NonMonotonicCommit if the commit number is not greater than the previous commit.
Returns Error::ReservedCommitNumber if the commit number is u64::MAX.
§Examples
let mut bitmap: BitMap<4> = BitMap::new();
bitmap = bitmap.apply_batch(1, |dirty| {
dirty.push(true).push(false);
}).unwrap();
assert_eq!(bitmap.len(), 2);Sourcepub fn get_at_commit(&self, commit_number: u64) -> Option<Prunable<N>>
pub fn get_at_commit(&self, commit_number: u64) -> Option<Prunable<N>>
Get the bitmap state as it existed at a specific commit.
Returns None if the commit does not exist or if commit_number is u64::MAX
(which is reserved and cannot be used as a commit number).
This reconstructs the historical state by applying reverse diffs backward from the current state. Each commit’s reverse diff describes the state before that commit, so we “undo” commits one by one until we reach the target.
§Examples
let mut bitmap: BitMap<4> = BitMap::new();
bitmap = bitmap.apply_batch(1, |dirty| {
dirty.push(true);
dirty.push(false);
}).unwrap();
bitmap = bitmap.apply_batch(2, |dirty| {
dirty.set_bit(0, false);
dirty.push(true);
}).unwrap();
// Get state as it was at commit 1
let state_at_1 = bitmap.get_at_commit(1).unwrap();
assert_eq!(state_at_1.len(), 2);
assert!(state_at_1.get_bit(0));
assert!(!state_at_1.get_bit(1));
// Current state is different
assert_eq!(bitmap.len(), 3);
assert!(!bitmap.get_bit(0));Sourcepub fn commit_exists(&self, commit_number: u64) -> bool
pub fn commit_exists(&self, commit_number: u64) -> bool
Check if a commit exists.
Sourcepub fn commits(&self) -> impl Iterator<Item = u64> + '_
pub fn commits(&self) -> impl Iterator<Item = u64> + '_
Get an iterator over all commit numbers in ascending order.
Sourcepub fn latest_commit(&self) -> Option<u64>
pub fn latest_commit(&self) -> Option<u64>
Get the latest commit number, if any commits exist.
Sourcepub fn earliest_commit(&self) -> Option<u64>
pub fn earliest_commit(&self) -> Option<u64>
Get the earliest commit number, if any commits exist.
Sourcepub fn get_chunk_containing(&self, bit: u64) -> &[u8; N]
pub fn get_chunk_containing(&self, bit: u64) -> &[u8; N]
Get the chunk containing a bit in the current bitmap.
Sourcepub const fn pruned_chunks(&self) -> usize
pub const fn pruned_chunks(&self) -> usize
Number of pruned chunks in the current bitmap.
Sourcepub fn prune_commits_before(&mut self, commit_number: u64) -> usize
pub fn prune_commits_before(&mut self, commit_number: u64) -> usize
Remove all commits with numbers below the commit number.
Returns the number of commits removed.
Sourcepub fn clear_history(&mut self)
pub fn clear_history(&mut self)
Clear all historical commits.
Source§impl<const N: usize> BitMap<N, Dirty<N>>
impl<const N: usize> BitMap<N, Dirty<N>>
Sourcepub const fn is_empty(&self) -> bool
pub const fn is_empty(&self) -> bool
Returns true if the bitmap would be empty after committing.
Sourcepub const fn pruned_chunks(&self) -> usize
pub const fn pruned_chunks(&self) -> usize
Get the number of pruned chunks after committing.
Sourcepub fn get_bit(&self, bit: u64) -> bool
pub fn get_bit(&self, bit: u64) -> bool
Get a bit value with read-through semantics.
Returns the bit’s value as it would be after committing. Priority: appended bits > modified bits > original bitmap.
§Panics
Panics if the bit offset is out of bounds or if the bit has been pruned.
Sourcepub fn get_chunk(&self, bit: u64) -> [u8; N]
pub fn get_chunk(&self, bit: u64) -> [u8; N]
Get a chunk value with read-through semantics.
Reconstructs the chunk if it has modifications, otherwise returns from current.
§Panics
Panics if the bit offset is out of bounds or if the chunk has been pruned.
Sourcepub fn push_chunk(&mut self, chunk: &[u8; N]) -> &mut Self
pub fn push_chunk(&mut self, chunk: &[u8; N]) -> &mut Self
Push a full chunk to the end of the bitmap.
Sourcepub fn pop(&mut self) -> bool
pub fn pop(&mut self) -> bool
Pop the last bit from the bitmap.
Returns the value of the popped bit, accounting for any modifications.
§Panics
Panics if the bitmap is empty.
Sourcepub fn prune_to_bit(&mut self, bit: u64) -> &mut Self
pub fn prune_to_bit(&mut self, bit: u64) -> &mut Self
Prune chunks up to the chunk containing the given bit offset.
Note: bit can equal projected_len when pruning at a chunk boundary.
§Panics
Panics if bit is > the projected length.
Sourcepub fn commit(self, commit_number: u64) -> Result<CleanBitMap<N>, Error>
pub fn commit(self, commit_number: u64) -> Result<CleanBitMap<N>, Error>
Commit the changes and return a clean bitmap with a historical snapshot.
§Errors
Returns Error::NonMonotonicCommit if the commit number is not greater than the previous commit.
Returns Error::ReservedCommitNumber if the commit number is u64::MAX.
Sourcepub fn abort(self) -> CleanBitMap<N>
pub fn abort(self) -> CleanBitMap<N>
Abort the changes and return to clean state.
All pending mutations are discarded.