@@ -37,12 +37,14 @@ pub struct Bitmap<H: CHasher> {
3737 /// The bitmap itself, in chunks of size DIGEST_SIZE bytes. The number of valid bits in the last
3838 /// chunk is given by `self.next_bit`. Within each byte, lowest order bits are treated as coming
3939 /// before higher order bits in the bit ordering.
40+ ///
41+ /// Invariant: The last chunk in the bitmap always has room for at least one more bit.
4042 bitmap : Vec < u8 > ,
4143
4244 /// The position within the last chunk of the bitmap where the next bit is to be appended.
4345 ///
4446 /// Invariant: This value is always in the range [0, DIGEST_SIZE * 8).
45- next_bit : usize ,
47+ next_bit : u64 ,
4648
4749 /// A Merkle tree with each leaf representing DIGEST_SIZE*8 bits of the bitmap.
4850 ///
@@ -61,7 +63,11 @@ impl<H: CHasher> Default for Bitmap<H> {
6163}
6264
6365impl < H : CHasher > Bitmap < H > {
64- const CHUNK_SIZE : usize = H :: Digest :: SIZE ;
66+ /// The size of a chunk in bytes.
67+ pub const CHUNK_SIZE : usize = H :: Digest :: SIZE ;
68+
69+ /// The size of a chunk in bits.
70+ const CHUNK_SIZE_BITS : u64 = Self :: CHUNK_SIZE as u64 * 8 ;
6571
6672 /// Return a new empty bitmap.
6773 pub fn new ( ) -> Self {
@@ -79,14 +85,13 @@ impl<H: CHasher> Bitmap<H> {
7985
8086 /// Return the number of bits currently stored in the bitmap, irrespective of any pruning.
8187 pub fn bit_count ( & self ) -> u64 {
82- ( ( self . pruned_bytes ( ) + self . bitmap . len ( ) ) * 8 - Self :: CHUNK_SIZE * 8 + self . next_bit )
83- as u64
88+ ( self . pruned_bytes ( ) + self . bitmap . len ( ) ) as u64 * 8 - Self :: CHUNK_SIZE_BITS + self . next_bit
8489 }
8590
8691 /// Prune the bitmap to the most recent chunk boundary that contains the referenced bit. Panics
8792 /// if the referenced bit has been pruned or is greater than the number of bits in the bitmap.
8893 pub fn prune_to_bit ( & mut self , bit_offset : u64 ) {
89- let chunk_pos = bit_offset as usize / 8 / Self :: CHUNK_SIZE ;
94+ let chunk_pos = Self :: chunk_pos ( bit_offset ) ;
9095 let mut byte_offset = chunk_pos * Self :: CHUNK_SIZE ;
9196 let pruned_bytes = self . pruned_bytes ( ) ;
9297 assert ! ( byte_offset >= pruned_bytes, "bit pruned" ) ;
@@ -110,7 +115,7 @@ impl<H: CHasher> Bitmap<H> {
110115 /// Returns the bitmap chunk containing the specified bit as a digest. Panics if the bit doesn't
111116 /// exist or has been pruned.
112117 fn get_chunk ( & self , bit_offset : u64 ) -> H :: Digest {
113- let mut byte_offset = bit_offset as usize / 8 / Self :: CHUNK_SIZE * Self :: CHUNK_SIZE ;
118+ let mut byte_offset = Self :: chunk_pos ( bit_offset ) * Self :: CHUNK_SIZE ;
114119 let pruned_bytes = self . pruned_bytes ( ) ;
115120 assert ! ( byte_offset >= pruned_bytes, "bit pruned" ) ;
116121 byte_offset -= pruned_bytes;
@@ -145,26 +150,26 @@ impl<H: CHasher> Bitmap<H> {
145150 "cannot add byte when not byte aligned"
146151 ) ;
147152
148- let chunk_byte = self . next_bit / 8 ;
153+ let chunk_byte = ( self . next_bit / 8 ) as usize ;
149154 self . last_chunk_mut ( ) [ chunk_byte] = byte;
150155 self . next_bit += 8 ;
151- assert ! ( self . next_bit <= Self :: CHUNK_SIZE * 8 ) ;
156+ assert ! ( self . next_bit <= Self :: CHUNK_SIZE_BITS ) ;
152157
153- if self . next_bit == Self :: CHUNK_SIZE * 8 {
158+ if self . next_bit == Self :: CHUNK_SIZE_BITS {
154159 self . commit_last_chunk ( hasher) ;
155160 }
156161 }
157162
158163 /// Add a single bit to the bitmap.
159164 pub fn append ( & mut self , hasher : & mut H , bit : bool ) {
160165 if bit {
161- let chunk_byte = self . next_bit / 8 ;
162- self . last_chunk_mut ( ) [ chunk_byte] |= Self :: chunk_byte_bit_mask ( self . next_bit as u64 ) ;
166+ let chunk_byte = ( self . next_bit / 8 ) as usize ;
167+ self . last_chunk_mut ( ) [ chunk_byte] |= Self :: chunk_byte_bit_mask ( self . next_bit ) ;
163168 }
164169 self . next_bit += 1 ;
165- assert ! ( self . next_bit <= Self :: CHUNK_SIZE * 8 ) ;
170+ assert ! ( self . next_bit <= Self :: CHUNK_SIZE_BITS ) ;
166171
167- if self . next_bit == Self :: CHUNK_SIZE * 8 {
172+ if self . next_bit == Self :: CHUNK_SIZE_BITS {
168173 self . commit_last_chunk ( hasher) ;
169174 }
170175 }
@@ -179,21 +184,25 @@ impl<H: CHasher> Bitmap<H> {
179184 #[ allow( dead_code) ] // Remove when we start using this outside the test module.
180185 #[ inline]
181186 pub ( crate ) fn chunk_byte_offset ( bit_offset : u64 ) -> usize {
182- ( bit_offset as usize / 8 ) % Self :: CHUNK_SIZE
187+ ( bit_offset / 8 ) as usize % Self :: CHUNK_SIZE
183188 }
184189
185190 /// Convert a bit offset into the position of the Merkle tree leaf it belongs to.
186191 #[ inline]
187192 pub ( crate ) fn leaf_pos ( bit_offset : u64 ) -> u64 {
188- let leaf_num = bit_offset / 8 / Self :: CHUNK_SIZE as u64 ;
189- leaf_num_to_pos ( leaf_num)
193+ leaf_num_to_pos ( Self :: chunk_pos ( bit_offset) as u64 )
194+ }
195+
196+ // Convert a bit offset into the position of the chunk it belongs to.
197+ #[ inline]
198+ fn chunk_pos ( bit_offset : u64 ) -> usize {
199+ ( bit_offset / 8 ) as usize / Self :: CHUNK_SIZE
190200 }
191201
192202 /// Get the value of a bit. Panics if the bit doesn't exist or has been pruned.
193203 pub fn get_bit ( & self , bit_offset : u64 ) -> bool {
194204 assert ! ( bit_offset < self . bit_count( ) , "out of bounds" ) ;
195- let chunk_pos = bit_offset / 8 / Self :: CHUNK_SIZE as u64 ;
196- if chunk_pos < self . mmr . oldest_retained_pos {
205+ if Self :: chunk_pos ( bit_offset) < self . mmr . oldest_retained_pos as usize {
197206 panic ! ( "bit pruned" ) ;
198207 }
199208 let byte_offset = bit_offset as usize / 8 - self . pruned_bytes ( ) ;
@@ -203,8 +212,7 @@ impl<H: CHasher> Bitmap<H> {
203212 /// Set the value of the referenced bit. Panics if the bit doesn't exist or has been pruned.
204213 pub fn set_bit ( & mut self , hasher : & mut H , bit_offset : u64 , bit : bool ) {
205214 assert ! ( bit_offset < self . bit_count( ) , "out of bounds" ) ;
206- let chunk_pos = bit_offset / 8 / Self :: CHUNK_SIZE as u64 ;
207- if chunk_pos < self . mmr . oldest_retained_pos {
215+ if Self :: chunk_pos ( bit_offset) < self . mmr . oldest_retained_pos as usize {
208216 panic ! ( "bit pruned" ) ;
209217 }
210218
0 commit comments