Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add remove_front and remove_back method #253

Merged
merged 55 commits into from
Jul 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
dcc5eeb
Feat remove first
shimatar0 May 7, 2023
2009f6e
Fix process
shimatar0 May 7, 2023
389da10
Fix remove first function
shimatar0 May 7, 2023
758bb6d
Fix bit switching process of remove_first
shimatar0 May 8, 2023
db3df9e
Feat remove last
shimatar0 May 8, 2023
e8e9be6
Fix container remove target
shimatar0 May 8, 2023
6a3ffb5
Fix where counts are subtracted and add test
shimatar0 May 8, 2023
43a88e9
Add handle of cases where the target to be deleted is larger than the…
shimatar0 May 9, 2023
e92df34
Fix to use rposition for remove_last
shimatar0 May 9, 2023
85a8f02
Add test
shimatar0 May 9, 2023
ede6cde
Add test to delete 0 elements
shimatar0 May 10, 2023
33b540c
Remove unnecessary if statement
shimatar0 May 10, 2023
f7601db
Add all bit clear
shimatar0 May 10, 2023
1cd29e3
Change conditional expression
shimatar0 May 10, 2023
7f02d44
Remove hard to follow variables
shimatar0 May 10, 2023
ad19557
Change the part that loops unnecessary
shimatar0 May 10, 2023
acf4ecd
Bump Rust version to 1.65.0
Kerollmops Jul 9, 2023
b9b3246
Update git2 for security reasons
Kerollmops Jul 9, 2023
203012f
Change the workflow branche from master to main
Kerollmops Jul 9, 2023
81f1f2a
Fix clippy
Kerollmops Jul 9, 2023
9f0d4d0
Remove bors from the repo
Kerollmops Jul 9, 2023
25251c9
Merge pull request #256 from RoaringBitmap/bump-rust-version-to-1.60.0
Kerollmops Jul 9, 2023
5618314
Deserialize run containers and convert them into bitmap/array
Kerollmops Jul 7, 2023
8f23ccf
Add a test for the run containers
Kerollmops Jul 7, 2023
95664bd
Update README badge
Kerollmops Jul 9, 2023
6aabe69
Merge pull request #255 from RoaringBitmap/deserialize-run-containers
Kerollmops Jul 10, 2023
4b2384b
Feat remove first
shimatar0 May 7, 2023
0a2be31
Fix process
shimatar0 May 7, 2023
cca8f22
Fix remove first function
shimatar0 May 7, 2023
da12781
Fix bit switching process of remove_first
shimatar0 May 8, 2023
88880f8
Feat remove last
shimatar0 May 8, 2023
9b200fb
Fix container remove target
shimatar0 May 8, 2023
6666418
Fix where counts are subtracted and add test
shimatar0 May 8, 2023
ca65479
Add handle of cases where the target to be deleted is larger than the…
shimatar0 May 9, 2023
e6442ae
Fix to use rposition for remove_last
shimatar0 May 9, 2023
4339221
Add test
shimatar0 May 9, 2023
216bb8b
Add test to delete 0 elements
shimatar0 May 10, 2023
7247532
Remove unnecessary if statement
shimatar0 May 10, 2023
8640495
Add all bit clear
shimatar0 May 10, 2023
7e3ef24
Change conditional expression
shimatar0 May 10, 2023
948d588
Remove hard to follow variables
shimatar0 May 10, 2023
3abe4d5
Change the part that loops unnecessary
shimatar0 May 10, 2023
99e36b3
Merge branch 'remove-first-last' of https://github.com/shimatar0/roar…
shimatar0 Jul 10, 2023
5c7cb3b
fix test
shimatar0 Jul 10, 2023
b7c5b5a
fixe to use u64 instead of usize
shimatar0 Jul 10, 2023
f4080d9
Rename remove_first to remove_front and remove_last to remove_back
shimatar0 Jul 10, 2023
e690f2a
Fix incorrect judgment condition.
shimatar0 Jul 13, 2023
5761b1c
Fix use the Vec::drain method
shimatar0 Jul 13, 2023
44c5a19
Fix the panics and removed unnecessary comments.
shimatar0 Jul 13, 2023
6b54277
Fix to delete all cases when "n" exceeds the container size
shimatar0 Jul 13, 2023
521f5a7
Remove unwanted clone
shimatar0 Jul 13, 2023
d0e7322
Fix unwanted clone
shimatar0 Jul 13, 2023
deaa66f
Add clear method to avoid new allocations
shimatar0 Jul 13, 2023
f7a18aa
Fix clippy warnings
shimatar0 Jul 13, 2023
d63dd69
Refactor to clearly define the method to clear the bit
shimatar0 Jul 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
- trying
pull_request:
branches:
- master
- main

name: Continuous integration

Expand All @@ -18,7 +18,7 @@ jobs:
- stable
- beta
- nightly
- 1.56.1
- 1.65.0
env:
RUSTFLAGS: "-C target-cpu=native -C opt-level=3"
ROARINGRS_BENCH_OFFLINE: "true"
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ serde = { version = "1.0.139", optional = true }
simd = []

[dev-dependencies]
proptest = "1.0.0"
proptest = "1.2.0"
serde_json = "1.0.85"
bincode = "1.3.3"

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you shall be dual licensed as above, without any
additional terms or conditions.

[github-actions-badge]: https://img.shields.io/github/workflow/status/RoaringBitmap/roaring-rs/Continuous%20integration.svg?style=flat-square
[github-actions-badge]:
https://github.com/RoaringBitmap/roaring-rs/actions/workflows/test.yml/badge.svg
[github-actions]: https://github.com/RoaringBitmap/roaring-rs/actions
[release-badge]: https://img.shields.io/github/release/RoaringBitmap/roaring-rs.svg?style=flat-square
[cargo]: https://crates.io/crates/roaring
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ roaring = { path = ".." }

[dev-dependencies]
once_cell = "1.9"
git2 = { version = "0.13", default-features = false, features = ["https", "vendored-openssl"] }
git2 = { version = "0.17", default-features = false, features = ["https", "vendored-openssl"] }
zip = { version = "0.5", default-features = false, features = ["deflate"] }
indicatif = "0.16"
criterion = { version = "0.3", features = ["html_reports"] }
Expand Down
3 changes: 0 additions & 3 deletions bors.toml

This file was deleted.

2 changes: 1 addition & 1 deletion src/bitmap/arbitrary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ mod test {
fn containers(n: usize)
(keys in ArrayStore::sampled(..=n, ..=n),
stores in vec(Store::arbitrary(), n)) -> RoaringBitmap {
let containers = keys.into_iter().zip(stores.into_iter()).map(|(key, store)| {
let containers = keys.into_iter().zip(stores).map(|(key, store)| {
let mut container = Container { key, store };
container.ensure_correct_store();
container
Expand Down
32 changes: 31 additions & 1 deletion src/bitmap/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::ops::{
use super::store::{self, Store};
use super::util;

const ARRAY_LIMIT: u64 = 4096;
pub const ARRAY_LIMIT: u64 = 4096;

#[derive(PartialEq, Clone)]
pub struct Container {
Expand Down Expand Up @@ -94,6 +94,36 @@ impl Container {
result
}

pub fn remove_front(&mut self, n: u64) {
match &self.store {
Store::Bitmap(bits) => {
if bits.len() - n <= ARRAY_LIMIT {
let mut replace_array = Vec::with_capacity((bits.len() - n) as usize);
replace_array.extend(bits.iter().skip(n as usize));
self.store = Store::Array(store::ArrayStore::from_vec_unchecked(replace_array));
} else {
self.store.remove_front(n)
}
}
Store::Array(_) => self.store.remove_front(n),
};
}

pub fn remove_back(&mut self, n: u64) {
match &self.store {
Store::Bitmap(bits) => {
if bits.len() - n <= ARRAY_LIMIT {
let mut replace_array = Vec::with_capacity((bits.len() - n) as usize);
replace_array.extend(bits.iter().take((bits.len() - n) as usize));
self.store = Store::Array(store::ArrayStore::from_vec_unchecked(replace_array));
} else {
self.store.remove_back(n)
}
}
Store::Array(_) => self.store.remove_back(n),
};
}

pub fn contains(&self, index: u16) -> bool {
self.store.contains(index)
}
Expand Down
195 changes: 195 additions & 0 deletions src/bitmap/inherent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,76 @@ impl RoaringBitmap {

None
}

/// Removes the specified number of elements from the top.
///
/// # Examples
///
/// ```rust
/// use roaring::RoaringBitmap;
///
/// let mut rb = RoaringBitmap::from_iter([1, 5, 7, 9]);
/// rb.remove_front(2);
/// assert_eq!(rb, RoaringBitmap::from_iter([7, 9]));
///
/// let mut rb = RoaringBitmap::from_iter([1, 3, 7, 9]);
/// rb.remove_front(2);
/// assert_eq!(rb, RoaringBitmap::from_iter([7, 9]));
pub fn remove_front(&mut self, mut n: u64) {
// remove containers up to the front of the target
let position = self.containers.iter().position(|container| {
let container_len = container.len();
if container_len <= n {
n -= container_len;
false
} else {
true
}
});
let position = position.unwrap_or(self.containers.len());
if position > 0 {
self.containers.drain(..position);
}
// remove data in containers if there are still targets for deletion
if n > 0 && !self.containers.is_empty() {
// container immediately before should have been deleted, so the target is 0 index
self.containers[0].remove_front(n);
}
}

/// Removes the specified number of elements from the tail.
///
/// # Examples
///
/// ```rust
/// use roaring::RoaringBitmap;
///
/// let mut rb = RoaringBitmap::from_iter([1, 5, 7, 9]);
/// rb.remove_back(2);
/// assert_eq!(rb, RoaringBitmap::from_iter([1, 5]));
/// rb.remove_back(1);
/// assert_eq!(rb, RoaringBitmap::from_iter([1]));
pub fn remove_back(&mut self, mut n: u64) {
// remove containers up to the back of the target
let position = self.containers.iter().rposition(|container| {
let container_len = container.len();
if container_len <= n {
n -= container_len;
false
} else {
true
}
});
// It is checked at the beginning of the function, so it is usually never an Err
if let Some(position) = position {
self.containers.drain(position + 1..);
if n > 0 && !self.containers.is_empty() {
self.containers[position].remove_back(n);
}
} else {
self.containers.clear();
}
}
}

impl Default for RoaringBitmap {
Expand Down Expand Up @@ -728,4 +798,129 @@ mod tests {
assert_eq!(bitmap.containers.len(), 1);
assert_eq!(bitmap.containers[0].key, 1);
}

#[test]
fn remove_front_for_vec() {
let mut bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]);
bitmap.remove_front(3);
assert_eq!(bitmap.len(), 3);
assert_eq!(bitmap, RoaringBitmap::from_iter([7, 9, 11]));

bitmap = RoaringBitmap::from_iter([1, 2, 5, 7, 9, 11]);
bitmap.remove_front(3);
assert_eq!(bitmap.len(), 3);
assert_eq!(bitmap, RoaringBitmap::from_iter([7, 9, 11]));

bitmap = RoaringBitmap::from_iter([1, 3]);
bitmap.remove_front(2);
assert_eq!(bitmap.len(), 0);

bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]);
bitmap.remove_front(0);
assert_eq!(bitmap.len(), 6);
assert_eq!(bitmap, RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]));

bitmap = RoaringBitmap::new();
bitmap.insert_range(0..(1_u32 << 16) + 5);
bitmap.remove_front(65537);
assert_eq!(bitmap.len(), 4);
assert_eq!(bitmap, RoaringBitmap::from_iter([65537, 65538, 65539, 65540]));

bitmap = RoaringBitmap::from_iter([1, 2, 5, 7, 9, 11]);
bitmap.remove_front(7);
assert_eq!(bitmap, RoaringBitmap::default());
}

#[test]
fn remove_front_for_bit() {
let mut bitmap = RoaringBitmap::new();
bitmap.insert_range(0..4098);
bitmap.remove_front(4095);
assert_eq!(bitmap.len(), 3);
// removed bit to vec
assert_eq!(bitmap, RoaringBitmap::from_iter([4095, 4096, 4097]));

bitmap = RoaringBitmap::new();
bitmap.insert_range(0..6000);
bitmap.remove_front(999);
assert_eq!(bitmap.len(), 5001);

bitmap = RoaringBitmap::new();
bitmap.insert_range(0..8000);
bitmap.remove_front(10);
assert_eq!(bitmap.len(), 7990);

bitmap = RoaringBitmap::new();
bitmap.insert_range(0..200000);
bitmap.remove_front(2000);
assert_eq!(bitmap.len(), 198000);
assert_eq!(bitmap, RoaringBitmap::from_iter(2000..200000));

bitmap = RoaringBitmap::new();
bitmap.insert_range(0..2);
bitmap.insert_range(4..7);
bitmap.insert_range(1000..6000);
bitmap.remove_front(30);
assert_eq!(bitmap.len(), 4975);

bitmap = RoaringBitmap::new();
bitmap.insert_range(0..65535);
bitmap.remove_front(0);
assert_eq!(bitmap.len(), 65535);
}

#[test]
fn remove_back_for_bit() {
let mut bitmap = RoaringBitmap::new();
bitmap.insert_range(0..5000);
bitmap.remove_back(1000);
assert_eq!(bitmap.len(), 4000);

bitmap = RoaringBitmap::new();
bitmap.insert_range(0..6000);
bitmap.remove_back(1000);
assert_eq!(bitmap.len(), 5000);

bitmap = RoaringBitmap::new();
bitmap.insert_range(0..200000);
bitmap.remove_back(196000);
assert_eq!(bitmap.len(), 4000);

bitmap = RoaringBitmap::new();
bitmap.insert_range(0..200000);
bitmap.remove_back(2000);
assert_eq!(bitmap.len(), 198000);
assert_eq!(bitmap, RoaringBitmap::from_iter(0..198000));

bitmap = RoaringBitmap::new();
bitmap.insert_range(0..65535);
bitmap.remove_back(0);
assert_eq!(bitmap.len(), 65535);
}

#[test]
fn remove_back_for_vec() {
let mut bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]);
bitmap.remove_back(2);
assert_eq!(bitmap, RoaringBitmap::from_iter([1, 2, 3, 7]));

bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]);
bitmap.remove_back(6);
assert_eq!(bitmap.len(), 0);

bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]);
bitmap.remove_back(0);
assert_eq!(bitmap.len(), 6);
assert_eq!(bitmap, RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]));

bitmap = RoaringBitmap::new();
bitmap.insert_range(0..(1_u32 << 16) + 5);
bitmap.remove_back(65537);
assert_eq!(bitmap.len(), 4);
assert_eq!(bitmap, RoaringBitmap::from_iter([0, 1, 2, 3]));

let mut bitmap = RoaringBitmap::from_iter([1, 2, 3]);
bitmap.remove_back(4);
assert_eq!(bitmap, RoaringBitmap::default());
}
}
2 changes: 1 addition & 1 deletion src/bitmap/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl IntoIterator for RoaringBitmap {

impl<const N: usize> From<[u32; N]> for RoaringBitmap {
fn from(arr: [u32; N]) -> Self {
RoaringBitmap::from_iter(arr.into_iter())
RoaringBitmap::from_iter(arr)
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/bitmap/multiops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ fn try_multi_and_owned<E>(
let mut start = start.into_iter();

if let Some(mut lhs) = start.next() {
for rhs in start.into_iter().map(Ok).chain(iter) {
for rhs in start.map(Ok).chain(iter) {
if lhs.is_empty() {
return Ok(lhs);
}
Expand All @@ -151,7 +151,7 @@ fn try_multi_and_ref<'a, E>(
let mut start = start.into_iter();

if let Some(mut lhs) = start.next().cloned() {
for rhs in start.into_iter().map(Ok).chain(iter) {
for rhs in start.map(Ok).chain(iter) {
if lhs.is_empty() {
return Ok(lhs);
}
Expand Down Expand Up @@ -225,7 +225,7 @@ fn try_multi_or_owned<E>(
return Ok(RoaringBitmap::new());
};

for bitmap in start.into_iter().map(Ok).chain(iter) {
for bitmap in start.map(Ok).chain(iter) {
merge_container_owned(&mut containers, bitmap?.containers, BitOrAssign::bitor_assign);
}

Expand Down Expand Up @@ -323,7 +323,7 @@ fn try_multi_or_ref<'a, E: 'a>(
};

// Phase 2: Operate on the remaining containers
for bitmap in start.into_iter().map(Ok).chain(iter) {
for bitmap in start.map(Ok).chain(iter) {
merge_container_ref(&mut containers, &bitmap?.containers, |a, b| *a |= b);
}

Expand Down
2 changes: 2 additions & 0 deletions src/bitmap/proptests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ mod test {
fn the_empty_set_is_the_identity_for_union(a in RoaringBitmap::arbitrary()) {
prop_assert_eq!(&(&a | &empty_set()), &a);

#[allow(clippy::redundant_clone)]
{ // op_assign_ref
let mut x = a.clone();
x |= &empty_set();
Expand All @@ -419,6 +420,7 @@ mod test {
fn the_empty_set_is_the_identity_for_symmetric_difference(a in RoaringBitmap::arbitrary()) {
prop_assert_eq!(&(&a ^ &empty_set()), &a);

#[allow(clippy::redundant_clone)]
{ // op_assign_ref
let mut x = a.clone();
x ^= &empty_set();
Expand Down
Loading