Skip to content

Commit 077f7eb

Browse files
bors[bot]Kerollmops
andauthoredJan 23, 2021
Merge #85
85: Replace Vec remove by a retain_mut function in Container operations r=Kerollmops a=Kerollmops We introduce a `retain_mut` function that allows us to mutate the iterated element. There already were [a discussion about this `Vec::retain` parameter restriction](rust-lang/rust#25477). Using the `retain` algorithm is much better when multiple stores must be removed in one batch, same as in #83. Co-authored-by: Clément Renault <clement@meilisearch.com>
2 parents feedd3f + 543fa6c commit 077f7eb

File tree

2 files changed

+35
-29
lines changed

2 files changed

+35
-29
lines changed
 

‎src/bitmap/ops.rs

+13-29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign};
22

3-
use crate::RoaringBitmap;
3+
use crate::{retain_mut, RoaringBitmap};
44

55
impl RoaringBitmap {
66
/// Unions in-place with the specified other bitmap.
@@ -72,23 +72,15 @@ impl RoaringBitmap {
7272
/// assert_eq!(rb1, rb3);
7373
/// ```
7474
pub fn intersect_with(&mut self, other: &RoaringBitmap) {
75-
let mut index = 0;
76-
while index < self.containers.len() {
77-
let key = self.containers[index].key;
78-
match other.containers.binary_search_by_key(&key, |c| c.key) {
79-
Err(_) => {
80-
self.containers.remove(index);
81-
}
75+
retain_mut(&mut self.containers, |cont| {
76+
match other.containers.binary_search_by_key(&cont.key, |c| c.key) {
8277
Ok(loc) => {
83-
self.containers[index].intersect_with(&other.containers[loc]);
84-
if self.containers[index].len == 0 {
85-
self.containers.remove(index);
86-
} else {
87-
index += 1;
88-
}
78+
cont.intersect_with(&other.containers[loc]);
79+
cont.len != 0
8980
}
81+
Err(_) => false,
9082
}
91-
}
83+
})
9284
}
9385

9486
/// Removes all values in the specified other bitmap from self, in-place.
@@ -121,23 +113,15 @@ impl RoaringBitmap {
121113
/// assert_eq!(rb1, rb3);
122114
/// ```
123115
pub fn difference_with(&mut self, other: &RoaringBitmap) {
124-
let mut index = 0;
125-
while index < self.containers.len() {
126-
let key = self.containers[index].key;
127-
match other.containers.binary_search_by_key(&key, |c| c.key) {
116+
retain_mut(&mut self.containers, |cont| {
117+
match other.containers.binary_search_by_key(&cont.key, |c| c.key) {
128118
Ok(loc) => {
129-
self.containers[index].difference_with(&other.containers[loc]);
130-
if self.containers[index].len == 0 {
131-
self.containers.remove(index);
132-
} else {
133-
index += 1;
134-
}
135-
}
136-
_ => {
137-
index += 1;
119+
cont.difference_with(&other.containers[loc]);
120+
cont.len != 0
138121
}
122+
Err(_) => true,
139123
}
140-
}
124+
})
141125
}
142126

143127
/// Replaces this bitmap with one that is equivalent to `self XOR other`.

‎src/lib.rs

+22
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,25 @@ pub mod treemap;
2121

2222
pub use bitmap::RoaringBitmap;
2323
pub use treemap::RoaringTreemap;
24+
25+
fn retain_mut<T, F>(vec: &mut Vec<T>, mut f: F)
26+
where
27+
F: FnMut(&mut T) -> bool,
28+
{
29+
let len = vec.len();
30+
let mut del = 0;
31+
{
32+
let v = &mut **vec;
33+
34+
for i in 0..len {
35+
if !f(&mut v[i]) {
36+
del += 1;
37+
} else if del > 0 {
38+
v.swap(i - del, i);
39+
}
40+
}
41+
}
42+
if del > 0 {
43+
vec.truncate(len - del);
44+
}
45+
}

0 commit comments

Comments
 (0)