@@ -40,9 +40,6 @@ struct Block {
40
40
41
41
impl Block {
42
42
/// Set a bit without updating `self.sub_blocks`.
43
- ///
44
- /// This panics if the bit was already set, because that indicates that the original positions
45
- /// list is invalid/had duplicates.
46
43
fn set ( & mut self , index : usize ) {
47
44
debug_assert ! ( index < BITS_PER_BLOCK ) ;
48
45
let chunk_idx = index / BITS_PER_SUB_BLOCK ;
@@ -52,11 +49,7 @@ impl Block {
52
49
self . bits [ chunk_idx] |= mask;
53
50
}
54
51
55
- /// The **total rank** of the block relative local index, and the index of the one
56
- /// bit that establishes that rank (aka "select") **if** it occurs within that same
57
- /// chunk, otherwise ['None']. The assumption is that if you would have to look back
58
- /// through previous chunks it would actually be cheaper to do a lookup in the original
59
- /// data structure that the bit vector was created from.
52
+ /// The **total rank** of the block relative local index.
60
53
fn rank ( & self , local_idx : usize ) -> usize {
61
54
let mut rank = self . rank as usize ;
62
55
let sub_block = local_idx / BITS_PER_SUB_BLOCK ;
@@ -65,11 +58,7 @@ impl Block {
65
58
let remainder = local_idx % BITS_PER_SUB_BLOCK ;
66
59
67
60
let last_chunk = local_idx / BITS_PER_SUB_BLOCK ;
68
- let masked = if remainder == 0 {
69
- 0
70
- } else {
71
- self . bits [ last_chunk] << ( BITS_PER_SUB_BLOCK - remainder)
72
- } ;
61
+ let masked = self . bits [ last_chunk] & !( SubblockBits :: MAX << remainder) ;
73
62
rank + masked. count_ones ( ) as usize
74
63
}
75
64
@@ -176,42 +165,52 @@ mod tests {
176
165
177
166
/// Creates a `BitRank` containing the integers in `iter` (which should be strictly
178
167
/// increasing).
179
- pub fn bitrank < I : IntoIterator < Item = usize > > ( capacity : usize , iter : I ) -> BitRank {
180
- let mut builder = BitRankBuilder :: with_capacity ( capacity) ;
181
- for position in iter {
182
- builder. push ( position) ;
168
+ pub fn bitrank < I > ( iter : I ) -> BitRank
169
+ where
170
+ I : IntoIterator < Item = usize > ,
171
+ I :: IntoIter : DoubleEndedIterator ,
172
+ {
173
+ let mut iter = iter. into_iter ( ) . rev ( ) ;
174
+ if let Some ( last) = iter. next ( ) {
175
+ let mut builder = BitRankBuilder :: with_capacity ( last + 1 ) ;
176
+ builder. push ( last) ;
177
+ for position in iter {
178
+ builder. push ( position) ;
179
+ }
180
+ builder. finish ( )
181
+ } else {
182
+ BitRank { blocks : vec ! [ ] }
183
183
}
184
- builder. finish ( )
185
184
}
186
185
187
186
#[ test]
188
187
fn test_rank_zero ( ) {
189
- let br = bitrank ( 1 , [ 0 ] ) ;
188
+ let br = bitrank ( [ 0 ] ) ;
190
189
assert_eq ! ( br. rank( 0 ) , 0 ) ;
191
190
assert_eq ! ( br. rank( 1 ) , 1 ) ;
192
191
}
193
192
194
193
#[ test]
195
194
fn test_empty ( ) {
196
- let br = bitrank ( 0 , [ ] ) ;
195
+ let br = bitrank ( [ ] ) ;
197
196
assert ! ( br. blocks. is_empty( ) ) ;
198
197
}
199
198
200
199
#[ test]
201
200
fn test_index_out_of_bounds ( ) {
202
- let br = bitrank ( BITS_PER_BLOCK , [ BITS_PER_BLOCK - 1 ] ) ;
201
+ let br = bitrank ( [ BITS_PER_BLOCK - 1 ] ) ;
203
202
assert_eq ! ( br. rank( BITS_PER_BLOCK ) , 1 ) ;
204
203
}
205
204
206
205
#[ test]
207
206
#[ should_panic]
208
207
fn test_duplicate_position ( ) {
209
- bitrank ( 91 , [ 64 , 66 , 68 , 68 , 90 ] ) ;
208
+ bitrank ( [ 64 , 66 , 68 , 68 , 90 ] ) ;
210
209
}
211
210
212
211
#[ test]
213
212
fn test_rank_exclusive ( ) {
214
- let br = bitrank ( 133 , 0 ..132 ) ;
213
+ let br = bitrank ( 0 ..132 ) ;
215
214
assert_eq ! ( br. blocks. len( ) , 1 ) ;
216
215
assert_eq ! ( br. rank( 64 ) , 64 ) ;
217
216
assert_eq ! ( br. rank( 132 ) , 132 ) ;
@@ -221,37 +220,37 @@ mod tests {
221
220
fn test_rank ( ) {
222
221
let mut positions: Vec < usize > = ( 0 ..132 ) . collect ( ) ;
223
222
positions. append ( & mut vec ! [ 138usize , 140 , 146 ] ) ;
224
- let br = bitrank ( 146 , positions) ;
223
+ let br = bitrank ( positions) ;
225
224
assert_eq ! ( br. rank( 135 ) , 132 ) ;
226
225
227
- let br2 = bitrank ( BITS_PER_BLOCK , 0 ..BITS_PER_BLOCK - 5 ) ;
226
+ let br2 = bitrank ( 0 ..BITS_PER_BLOCK - 5 ) ;
228
227
assert_eq ! ( br2. rank( 169 ) , 169 ) ;
229
228
230
- let br3 = bitrank ( BITS_PER_BLOCK + 6 , 0 ..BITS_PER_BLOCK + 5 ) ;
229
+ let br3 = bitrank ( 0 ..BITS_PER_BLOCK + 5 ) ;
231
230
assert_eq ! ( br3. rank( BITS_PER_BLOCK ) , BITS_PER_BLOCK ) ;
232
231
}
233
232
234
233
#[ test]
235
234
fn test_rank_idx ( ) {
236
235
let mut positions: Vec < usize > = ( 0 ..132 ) . collect ( ) ;
237
236
positions. append ( & mut vec ! [ 138usize , 140 , 146 ] ) ;
238
- let br = bitrank ( 147 , positions) ;
237
+ let br = bitrank ( positions) ;
239
238
assert_eq ! ( br. rank( 135 ) , 132 ) ;
240
239
241
240
let bits2: Vec < usize > = ( 0 ..BITS_PER_BLOCK - 5 ) . collect ( ) ;
242
- let br2 = bitrank ( BITS_PER_BLOCK , bits2) ;
241
+ let br2 = bitrank ( bits2) ;
243
242
assert_eq ! ( br2. rank( 169 ) , 169 ) ;
244
243
245
244
let bits3: Vec < usize > = ( 0 ..BITS_PER_BLOCK + 5 ) . collect ( ) ;
246
- let br3 = bitrank ( BITS_PER_BLOCK + 6 , bits3) ;
245
+ let br3 = bitrank ( bits3) ;
247
246
assert_eq ! ( br3. rank( BITS_PER_BLOCK ) , BITS_PER_BLOCK ) ;
248
247
249
248
let bits4: Vec < usize > = vec ! [ 1 , 1000 , 7777 , BITS_PER_BLOCK + 1 ] ;
250
- let br4 = bitrank ( BITS_PER_BLOCK + 1 , bits4) ;
249
+ let br4 = bitrank ( bits4) ;
251
250
assert_eq ! ( br4. rank( 8000 ) , 3 ) ;
252
251
253
252
let bits5: Vec < usize > = vec ! [ 1 , 1000 , 7777 , BITS_PER_BLOCK + 1 ] ;
254
- let br5 = bitrank ( BITS_PER_BLOCK + 1 , bits5) ;
253
+ let br5 = bitrank ( bits5) ;
255
254
assert_eq ! ( br5. rank( BITS_PER_BLOCK ) , 3 ) ;
256
255
}
257
256
@@ -267,7 +266,7 @@ mod tests {
267
266
// This isn't strictly necessary, given that the bit would just be toggled again, but it
268
267
// ensures that we are meeting the contract.
269
268
random_bits. dedup ( ) ;
270
- let br = bitrank ( 1_000_000 , random_bits. iter ( ) . copied ( ) ) ;
269
+ let br = bitrank ( random_bits. iter ( ) . copied ( ) ) ;
271
270
let mut rank = 0 ;
272
271
for i in 0 ..random_bits. capacity ( ) {
273
272
assert_eq ! ( br. rank( i) , rank) ;
@@ -282,7 +281,7 @@ mod tests {
282
281
#[ test]
283
282
fn test_rank_out_of_bounds ( ) {
284
283
for i in 1 ..30 {
285
- let br = bitrank ( BITS_PER_BLOCK * i , [ BITS_PER_BLOCK * i - 1 ] ) ;
284
+ let br = bitrank ( [ BITS_PER_BLOCK * i - 1 ] ) ;
286
285
assert_eq ! ( br. max_rank( ) , 1 ) ;
287
286
assert_eq ! ( br. rank( BITS_PER_BLOCK * i - 1 ) , 0 ) ;
288
287
for j in 0 ..10 {
@@ -293,10 +292,7 @@ mod tests {
293
292
294
293
#[ test]
295
294
fn test_large_gap ( ) {
296
- let br = bitrank (
297
- BITS_PER_BLOCK * 16 ,
298
- ( 3 ..4 ) . chain ( BITS_PER_BLOCK * 15 ..BITS_PER_BLOCK * 15 + 17 ) ,
299
- ) ;
295
+ let br = bitrank ( ( 3 ..4 ) . chain ( BITS_PER_BLOCK * 15 ..BITS_PER_BLOCK * 15 + 17 ) ) ;
300
296
for i in 1 ..15 {
301
297
assert_eq ! ( br. rank( BITS_PER_BLOCK * i) , 1 ) ;
302
298
}
0 commit comments