File tree Expand file tree Collapse file tree 3 files changed +46
-4
lines changed Expand file tree Collapse file tree 3 files changed +46
-4
lines changed Original file line number Diff line number Diff line change @@ -234,6 +234,32 @@ impl<T: Idx> DenseBitSet<T> {
234
234
self . clear_excess_bits ( ) ;
235
235
}
236
236
237
+ /// Checks whether any bit in the given range is a 1.
238
+ #[ inline]
239
+ pub fn contains_any ( & self , elems : impl RangeBounds < T > ) -> bool {
240
+ let Some ( ( start, end) ) = inclusive_start_end ( elems, self . domain_size ) else {
241
+ return false ;
242
+ } ;
243
+ let ( start_word_index, start_mask) = word_index_and_mask ( start) ;
244
+ let ( end_word_index, end_mask) = word_index_and_mask ( end) ;
245
+
246
+ if start_word_index == end_word_index {
247
+ self . words [ start_word_index] & ( end_mask | ( end_mask - start_mask) ) != 0
248
+ } else {
249
+ if self . words [ start_word_index] & !( start_mask - 1 ) != 0 {
250
+ return true ;
251
+ }
252
+
253
+ let remaining = start_word_index + 1 ..end_word_index;
254
+ if remaining. start <= remaining. end {
255
+ self . words [ remaining] . iter ( ) . any ( |& w| w != 0 )
256
+ || self . words [ end_word_index] & ( end_mask | ( end_mask - 1 ) ) != 0
257
+ } else {
258
+ false
259
+ }
260
+ }
261
+ }
262
+
237
263
/// Returns `true` if the set has changed.
238
264
#[ inline]
239
265
pub fn remove ( & mut self , elem : T ) -> bool {
Original file line number Diff line number Diff line change @@ -692,6 +692,25 @@ fn dense_last_set_before() {
692
692
}
693
693
}
694
694
695
+ #[ test]
696
+ fn dense_contains_any ( ) {
697
+ let mut set: DenseBitSet < usize > = DenseBitSet :: new_empty ( 300 ) ;
698
+ assert ! ( !set. contains_any( 0 ..300 ) ) ;
699
+ set. insert_range ( 10 ..20 ) ;
700
+ set. insert_range ( 60 ..70 ) ;
701
+ set. insert_range ( 150 ..=250 ) ;
702
+
703
+ assert ! ( set. contains_any( 0 ..30 ) ) ;
704
+ assert ! ( set. contains_any( 5 ..100 ) ) ;
705
+ assert ! ( set. contains_any( 250 ..255 ) ) ;
706
+
707
+ assert ! ( !set. contains_any( 20 ..59 ) ) ;
708
+ assert ! ( !set. contains_any( 256 ..290 ) ) ;
709
+
710
+ set. insert ( 22 ) ;
711
+ assert ! ( set. contains_any( 20 ..59 ) ) ;
712
+ }
713
+
695
714
#[ bench]
696
715
fn bench_insert ( b : & mut Bencher ) {
697
716
let mut bs = DenseBitSet :: new_filled ( 99999usize ) ;
Original file line number Diff line number Diff line change @@ -145,10 +145,7 @@ impl IsolatedAlloc {
145
145
if pinfo. domain_size ( ) < offset_pinfo + size_pinfo {
146
146
break ;
147
147
}
148
- // FIXME: is there a more efficient way to check whether the entire range is unset
149
- // in the bitset?
150
- let range_avail = !( offset_pinfo..offset_pinfo + size_pinfo) . any ( |i| pinfo. contains ( i) ) ;
151
- if range_avail {
148
+ if !pinfo. contains_any ( offset_pinfo..offset_pinfo + size_pinfo) {
152
149
pinfo. insert_range ( offset_pinfo..offset_pinfo + size_pinfo) ;
153
150
// SAFETY: We checked the available bytes after `idx` in the call
154
151
// to `domain_size` above and asserted there are at least `idx +
You can’t perform that action at this time.
0 commit comments