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> {
234234 self.clear_excess_bits();
235235 }
236236
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+
237263 /// Returns `true` if the set has changed.
238264 #[inline]
239265 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() {
692692 }
693693}
694694
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+
695714#[bench]
696715fn bench_insert(b: &mut Bencher) {
697716 let mut bs = DenseBitSet::new_filled(99999usize);
Original file line number Diff line number Diff line change @@ -145,10 +145,7 @@ impl IsolatedAlloc {
145145 if pinfo.domain_size() < offset_pinfo + size_pinfo {
146146 break;
147147 }
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) {
152149 pinfo.insert_range(offset_pinfo..offset_pinfo + size_pinfo);
153150 // SAFETY: We checked the available bytes after `idx` in the call
154151 // to `domain_size` above and asserted there are at least `idx +
You can’t perform that action at this time.
0 commit comments