1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! A historical wrapper around [crate::bitmap::Prunable] that maintains snapshots via diffs.
//!
//! The Historical bitmap maintains one full [crate::bitmap::Prunable] bitmap (the current/head state).
//! All historical states are represented as diffs, not full bitmap clones.
//!
//! Uses a type-state pattern to track whether the bitmap is clean (no pending mutations) or
//! dirty (has pending mutations). This provides compile-time guarantees about when mutations
//! are allowed.
//!
//! # Examples
//!
//! ## Usage
//!
//! ```
//! # use commonware_utils::bitmap::historical::BitMap;
//! let bitmap: BitMap<4> = BitMap::new();
//!
//! // Transition to dirty state to make mutations
//! let mut dirty = bitmap.into_dirty();
//! dirty.push(true);
//! dirty.push(false);
//!
//! // Commit changes and return to clean state
//! let bitmap = dirty.commit(1).unwrap();
//!
//! assert_eq!(bitmap.len(), 2);
//! assert!(bitmap.get_bit(0));
//! assert!(!bitmap.get_bit(1));
//! ```
//!
//! ## Usage with closure
//!
//! ```
//! # use commonware_utils::bitmap::historical::BitMap;
//! let mut bitmap: BitMap<4> = BitMap::new();
//!
//! bitmap = bitmap.apply_batch(1, |dirty| {
//! dirty.push(true);
//! dirty.push(false);
//! }).unwrap();
//!
//! assert_eq!(bitmap.len(), 2);
//! assert!(bitmap.get_bit(0));
//! assert!(!bitmap.get_bit(1));
//! ```
//!
//! ## Read-Through Semantics
//!
//! ```
//! # use commonware_utils::bitmap::historical::BitMap;
//! let mut bitmap: BitMap<4> = BitMap::new();
//! bitmap = bitmap.apply_batch(1, |dirty| { dirty.push(false); }).unwrap();
//!
//! // Before modification
//! assert!(!bitmap.get_bit(0));
//!
//! let mut dirty = bitmap.into_dirty();
//! dirty.set_bit(0, true);
//!
//! // Read through dirty state sees the modification
//! assert!(dirty.get_bit(0));
//!
//! let bitmap = dirty.commit(2).unwrap();
//!
//! // After commit, modification is in current
//! assert!(bitmap.get_bit(0));
//! ```
//!
//! ## Abort Mutations
//!
//! ```
//! # use commonware_utils::bitmap::historical::BitMap;
//! let mut bitmap: BitMap<4> = BitMap::new();
//! bitmap = bitmap.apply_batch(1, |dirty| { dirty.push(true); }).unwrap();
//! let len_before = bitmap.len();
//!
//! // Make changes in dirty state
//! let mut dirty = bitmap.into_dirty();
//! dirty.push(true);
//! dirty.push(false);
//!
//! // Abort to discard changes and return to clean state
//! let bitmap = dirty.abort();
//!
//! assert_eq!(bitmap.len(), len_before); // Unchanged
//! ```
//!
//! ## Commit History Management
//!
//! ```
//! # use commonware_utils::bitmap::historical::BitMap;
//! let mut bitmap: BitMap<4> = BitMap::new();
//! for i in 1..=5 {
//! bitmap = bitmap.apply_batch(i, |dirty| {
//! dirty.push(true);
//! }).unwrap();
//! }
//!
//! assert_eq!(bitmap.commits().count(), 5);
//!
//! // Prune old commits
//! bitmap.prune_commits_before(3);
//! assert_eq!(bitmap.commits().count(), 3);
//! ```
pub use ;
pub use Error;