commonware_utils/bitmap/historical/mod.rs
1//! A historical wrapper around [crate::bitmap::Prunable] that maintains snapshots via diff-based batching.
2//!
3//! The Historical bitmap maintains one full [crate::bitmap::Prunable] bitmap (the current/head state).
4//! All historical states and batch mutations are represented as diffs, not full bitmap clones.
5//!
6//! # Examples
7//!
8//! ## Basic Batching
9//!
10//! ```
11//! # use commonware_utils::bitmap::historical::BitMap;
12//! let mut bitmap: BitMap<4> = BitMap::new();
13//!
14//! // Create and commit a batch
15//! bitmap.with_batch(1, |batch| {
16//! batch.push(true);
17//! batch.push(false);
18//! }).unwrap();
19//!
20//! assert_eq!(bitmap.len(), 2);
21//! assert!(bitmap.get_bit(0));
22//! assert!(!bitmap.get_bit(1));
23//! ```
24//!
25//! ## Read-Through Semantics
26//!
27//! ```
28//! # use commonware_utils::bitmap::historical::BitMap;
29//! let mut bitmap: BitMap<4> = BitMap::new();
30//! bitmap.with_batch(1, |batch| { batch.push(false); }).unwrap();
31//!
32//! // Before modification
33//! assert!(!bitmap.get_bit(0));
34//!
35//! {
36//! let mut batch = bitmap.start_batch();
37//! batch.set_bit(0, true);
38//!
39//! // Read through batch sees the modification
40//! assert!(batch.get_bit(0));
41//!
42//! batch.commit(2).unwrap();
43//! }
44//!
45//! // After commit, modification is in current
46//! assert!(bitmap.get_bit(0));
47//! ```
48//!
49//! ## Abort on Drop
50//!
51//! ```
52//! # use commonware_utils::bitmap::historical::BitMap;
53//! # let mut bitmap: BitMap<4> = BitMap::new();
54//! # bitmap.with_batch(1, |batch| { batch.push(true); }).unwrap();
55//! let len_before = bitmap.len();
56//!
57//! {
58//! let mut batch = bitmap.start_batch();
59//! batch.push(true);
60//! batch.push(false);
61//! // Drop without commit = automatic abort
62//! }
63//!
64//! assert_eq!(bitmap.len(), len_before); // Unchanged
65//! ```
66//!
67//! ## Commit History Management
68//!
69//! ```
70//! # use commonware_utils::bitmap::historical::BitMap;
71//! # let mut bitmap: BitMap<4> = BitMap::new();
72//! for i in 1..=5 {
73//! bitmap.with_batch(i, |batch| {
74//! batch.push(true);
75//! }).unwrap();
76//! }
77//!
78//! assert_eq!(bitmap.commits().count(), 5);
79//!
80//! // Prune old commits
81//! bitmap.prune_commits_before(3);
82//! assert_eq!(bitmap.commits().count(), 3);
83//! ```
84
85mod batch;
86pub use batch::BatchGuard;
87mod bitmap;
88pub use bitmap::BitMap;
89mod error;
90pub use error::Error;
91
92#[cfg(test)]
93mod tests;