roaring-0.10.2/.cargo_vcs_info.json0000644000000001360000000000100125550ustar { "git": { "sha1": "4f8c798f69c71c88625aebb1042b5552849c7f42" }, "path_in_vcs": "" }roaring-0.10.2/.editorconfig000064400000000000000000000002111046102023000140140ustar 00000000000000[*.rs] end_of_line = lf trim_trailing_whitespace = true insert_final_newline = true charset = utf-8 indent_style = space indent_size = 4 roaring-0.10.2/.github/workflows/test.yml000064400000000000000000000054121046102023000164460ustar 00000000000000on: push: branches: - staging - trying pull_request: branches: - main name: Continuous integration jobs: ci: runs-on: ubuntu-latest strategy: matrix: rust: - stable - beta - nightly - 1.65.0 env: RUSTFLAGS: "-C target-cpu=native -C opt-level=3" ROARINGRS_BENCH_OFFLINE: "true" steps: - name: Checkout roaring-rs uses: actions/checkout@v2 - name: Checkout benchmark datasets uses: actions/checkout@v2 with: repository: "RoaringBitmap/real-roaring-datasets" path: "benchmarks/real-roaring-datasets" - name: Initialize rust toolchain uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: ${{ matrix.rust }} override: true components: rustfmt, clippy - name: Fetch uses: actions-rs/cargo@v1 with: command: fetch - name: Fetch benchmarks uses: actions-rs/cargo@v1 with: command: fetch args: --manifest-path benchmarks/Cargo.toml - name: Build uses: actions-rs/cargo@v1 with: command: build args: --all-targets - name: Build benchmarks uses: actions-rs/cargo@v1 with: command: build args: --manifest-path benchmarks/Cargo.toml --all-targets - name: Check uses: actions-rs/cargo@v1 with: command: clippy args: --all-targets -- -D warnings - name: Check benchmarks uses: actions-rs/cargo@v1 with: command: clippy args: --manifest-path benchmarks/Cargo.toml --all-targets -- -D warnings - name: Check formatting uses: actions-rs/cargo@v1 with: command: fmt args: -- --check - name: Check benchmark formatting uses: actions-rs/cargo@v1 with: command: fmt args: --manifest-path benchmarks/Cargo.toml -- --check - name: Test uses: actions-rs/cargo@v1 with: command: test args: --features serde - name: Test benchmarks uses: actions-rs/cargo@v1 with: command: test args: --manifest-path benchmarks/Cargo.toml --benches - name: SIMD test if: matrix.rust == 'nightly' uses: actions-rs/cargo@v1 with: toolchain: nightly command: test args: --features "simd" - name: SIMD test benchmarks if: matrix.rust == 'nightly' uses: actions-rs/cargo@v1 with: toolchain: nightly command: test args: --manifest-path benchmarks/Cargo.toml --features "simd" --benches roaring-0.10.2/.gitignore000064400000000000000000000000521046102023000133320ustar 00000000000000/target /Cargo.lock /proptest-regressions roaring-0.10.2/Cargo.toml0000644000000025430000000000100105570ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.65.0" name = "roaring" version = "0.10.2" authors = [ "Wim Looman ", "Kerollmops ", ] description = "https://roaringbitmap.org: A better compressed bitset - pure Rust implementation" documentation = "https://docs.rs/roaring" readme = "README.md" keywords = [ "roaring", "data-structure", "bitmap", ] categories = ["data-structures"] license = "MIT OR Apache-2.0" repository = "https://github.com/RoaringBitmap/roaring-rs" [profile.test] opt-level = 2 [dependencies.bytemuck] version = "1.7.3" [dependencies.byteorder] version = "1.4.3" [dependencies.retain_mut] version = "=0.1.7" [dependencies.serde] version = "1.0.139" optional = true [dev-dependencies.bincode] version = "1.3.3" [dev-dependencies.proptest] version = "1.2.0" [dev-dependencies.serde_json] version = "1.0.85" [features] simd = [] roaring-0.10.2/Cargo.toml.orig000064400000000000000000000013701046102023000142350ustar 00000000000000[package] name = "roaring" version = "0.10.2" rust-version = "1.65.0" authors = ["Wim Looman ", "Kerollmops "] description = "https://roaringbitmap.org: A better compressed bitset - pure Rust implementation" documentation = "https://docs.rs/roaring" repository = "https://github.com/RoaringBitmap/roaring-rs" readme = "README.md" keywords = ["roaring", "data-structure", "bitmap"] categories = ["data-structures"] edition = "2021" license = "MIT OR Apache-2.0" [dependencies] bytemuck = "1.7.3" byteorder = "1.4.3" retain_mut = "=0.1.7" serde = { version = "1.0.139", optional = true } [features] simd = [] [dev-dependencies] proptest = "1.2.0" serde_json = "1.0.85" bincode = "1.3.3" [profile.test] opt-level = 2 roaring-0.10.2/LICENSE-APACHE000064400000000000000000000251371046102023000133010ustar 00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. roaring-0.10.2/LICENSE-MIT000064400000000000000000000020721046102023000130020ustar 00000000000000MIT License Copyright (c) 2016 The roaring-rs developers. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. roaring-0.10.2/README.md000064400000000000000000000060731046102023000126320ustar 00000000000000# RoaringBitmap [![github-actions-badge][]][github-actions] [![release-badge][]][cargo] [![docs-badge][]][docs] [![rust-version-badge][]][rust-version] This is a [Rust][] port of the [Roaring bitmap][] data structure, initially defined as a [Java library][roaring-java] and described in [_Better bitmap performance with Roaring bitmaps_][roaring-paper]. ## Rust version policy This crate only supports the current stable version of Rust, patch releases may use new features at any time. ## Developing This project uses [Clippy][], [rustfmt][], and denies warnings in CI builds. Available via `rustup component add clippy rustfmt`. To ensure your changes will be accepted please check them with: ``` cargo fmt -- --check cargo fmt --manifest-path benchmarks/Cargo.toml -- --check cargo clippy --all-targets -- -D warnings ``` In addition, ensure all tests are passing with `cargo test` ### Benchmarking It is recommended to run the `cargo bench` command inside of the `benchmarks` directory. This directory contains a library that is dedicated to benchmarking the Roaring library by using a set of [real-world datasets][]. It is also advised to run the benchmarks on a bare-metal machine, running them on the base branch and then on the contribution PR branch to better see the changes. Those benchmarks are designed on top of the Criterion library, you can read more about it [on the user guide][]. ## License Licensed under either of * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT) at your option. ### Contribution 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://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 [docs-badge]: https://img.shields.io/badge/API-docs-blue.svg?style=flat-square [docs]: https://docs.rs/roaring [rust-version-badge]: https://img.shields.io/badge/rust-latest%20stable-blue.svg?style=flat-square [rust-version]: https://github.com/RoaringBitmap/roaring-rs#rust-version-policy [Rust]: https://www.rust-lang.org/ [Roaring bitmap]: https://roaringbitmap.org/ [roaring-java]: https://github.com/lemire/RoaringBitmap [roaring-paper]: https://arxiv.org/pdf/1402.6407v4 [Clippy]: https://github.com/rust-lang/rust-clippy [rustfmt]: https://github.com/rust-lang/rustfmt [real-world datasets]: https://github.com/RoaringBitmap/real-roaring-datasets [on the user guide]: https://bheisler.github.io/criterion.rs/book/user_guide/user_guide.html ## Experimental features The `simd` feature is in active development. It has not been tested. If you would like to build with `simd` note that `std::simd` is only available in Rust nightly. roaring-0.10.2/rustfmt.toml000064400000000000000000000000351046102023000137440ustar 00000000000000use_small_heuristics = "max" roaring-0.10.2/src/bitmap/arbitrary.rs000064400000000000000000000131561046102023000157630ustar 00000000000000#[cfg(test)] mod test { use crate::bitmap::container::Container; use crate::bitmap::store::{ArrayStore, BitmapStore, Store}; use crate::RoaringBitmap; use proptest::bits::{BitSetLike, BitSetStrategy, SampledBitSetStrategy}; use proptest::collection::{vec, SizeRange}; use proptest::prelude::*; use std::fmt::{Debug, Formatter}; impl Debug for BitmapStore { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { if self.len() < 16 { write!(f, "BitmapStore<{:?}>", self.iter().collect::>()) } else { write!( f, "BitmapStore<{:?} values between {:?} and {:?}>", self.len(), self.min().unwrap(), self.max().unwrap() ) } } } impl BitSetLike for BitmapStore { fn new_bitset(max: usize) -> Self { assert!(max <= BitmapStore::MAX + 1); BitmapStore::new() } fn len(&self) -> usize { BitmapStore::MAX + 1 } fn test(&self, bit: usize) -> bool { assert!(bit <= BitmapStore::MAX); self.contains(bit as u16) } fn set(&mut self, bit: usize) { assert!(bit <= BitmapStore::MAX); self.insert(bit as u16); } fn clear(&mut self, bit: usize) { assert!(bit <= BitmapStore::MAX); self.remove(bit as u16); } fn count(&self) -> usize { self.len() as usize } } impl BitmapStore { const MAX: usize = u16::MAX as usize; pub fn universe() -> Self { BitmapStore::try_from(1 + u16::MAX as u64, Box::new([u64::MAX; 1024])).unwrap() } pub fn between(min: u16, max: u16) -> BitSetStrategy { BitSetStrategy::new(min as usize, max as usize) } pub fn masked(mask: Self) -> BitSetStrategy { BitSetStrategy::masked(mask) } pub fn sampled( size: impl Into, bits: impl Into, ) -> SampledBitSetStrategy { SampledBitSetStrategy::new(size.into(), bits.into()) } pub fn arbitrary() -> SampledBitSetStrategy { Self::sampled(..=u16::MAX as usize, ..=u16::MAX as usize) } } impl Debug for ArrayStore { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { if self.len() < 16 { write!(f, "ArrayStore<{:?}>", self.as_slice()) } else { write!( f, "ArrayStore<{:?} values between {:?} and {:?}>", self.len(), self.min().unwrap(), self.max().unwrap() ) } } } impl BitSetLike for ArrayStore { fn new_bitset(max: usize) -> Self { assert!(max <= ArrayStore::MAX + 1); ArrayStore::new() } fn len(&self) -> usize { ArrayStore::MAX + 1 } fn test(&self, bit: usize) -> bool { assert!(bit <= ArrayStore::MAX); self.contains(bit as u16) } fn set(&mut self, bit: usize) { assert!(bit <= ArrayStore::MAX); self.insert(bit as u16); } fn clear(&mut self, bit: usize) { assert!(bit <= ArrayStore::MAX); self.remove(bit as u16); } fn count(&self) -> usize { self.len() as usize } } impl ArrayStore { const MAX: usize = u16::MAX as usize; pub fn between(min: u16, max: u16) -> BitSetStrategy { BitSetStrategy::new(min as usize, max as usize) } pub fn masked(mask: ArrayStore) -> BitSetStrategy { BitSetStrategy::masked(mask) } pub fn sampled( size: impl Into, bits: impl Into, ) -> SampledBitSetStrategy { SampledBitSetStrategy::new(size.into(), bits.into()) } pub fn arbitrary() -> SampledBitSetStrategy { Self::sampled(..=4096_usize, ..=u16::MAX as usize) } } impl Debug for Store { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { Store::Array(a) => write!(f, "Store({:?})", a), Store::Bitmap(b) => write!(f, "Store({:?})", b), } } } impl Store { fn arbitrary() -> impl Strategy { prop_oneof![ ArrayStore::sampled(1..=4096, ..=u16::MAX as usize).prop_map(Store::Array), BitmapStore::sampled(4097..u16::MAX as usize, ..=u16::MAX as usize) .prop_map(Store::Bitmap), ] } } prop_compose! { fn containers(n: usize) (keys in ArrayStore::sampled(..=n, ..=n), stores in vec(Store::arbitrary(), n)) -> RoaringBitmap { let containers = keys.into_iter().zip(stores).map(|(key, store)| { let mut container = Container { key, store }; container.ensure_correct_store(); container }).collect::>(); RoaringBitmap { containers } } } impl RoaringBitmap { prop_compose! { pub fn arbitrary()(bitmap in (0usize..=16).prop_flat_map(containers)) -> RoaringBitmap { bitmap } } } } roaring-0.10.2/src/bitmap/cmp.rs000064400000000000000000000077701046102023000145500ustar 00000000000000use std::borrow::Borrow; use std::cmp::Ordering; use std::iter::Peekable; use super::container::Container; use crate::RoaringBitmap; impl RoaringBitmap { /// Returns true if the set has no elements in common with other. This is equivalent to /// checking for an empty intersection. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb1 = RoaringBitmap::new(); /// let mut rb2 = RoaringBitmap::new(); /// /// rb1.insert(1); /// /// assert_eq!(rb1.is_disjoint(&rb2), true); /// /// rb2.insert(1); /// /// assert_eq!(rb1.is_disjoint(&rb2), false); /// /// ``` pub fn is_disjoint(&self, other: &Self) -> bool { Pairs::new(&self.containers, &other.containers) .filter_map(|(c1, c2)| c1.zip(c2)) .all(|(c1, c2)| c1.is_disjoint(c2)) } /// Returns `true` if this set is a subset of `other`. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb1 = RoaringBitmap::new(); /// let mut rb2 = RoaringBitmap::new(); /// /// rb1.insert(1); /// /// assert_eq!(rb1.is_subset(&rb2), false); /// /// rb2.insert(1); /// /// assert_eq!(rb1.is_subset(&rb2), true); /// /// rb1.insert(2); /// /// assert_eq!(rb1.is_subset(&rb2), false); /// ``` pub fn is_subset(&self, other: &Self) -> bool { for pair in Pairs::new(&self.containers, &other.containers) { match pair { (None, _) => (), (_, None) => return false, (Some(c1), Some(c2)) => { if !c1.is_subset(c2) { return false; } } } } true } /// Returns `true` if this set is a superset of `other`. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb1 = RoaringBitmap::new(); /// let mut rb2 = RoaringBitmap::new(); /// /// rb1.insert(1); /// /// assert_eq!(rb2.is_superset(&rb1), false); /// /// rb2.insert(1); /// /// assert_eq!(rb2.is_superset(&rb1), true); /// /// rb1.insert(2); /// /// assert_eq!(rb2.is_superset(&rb1), false); /// ``` pub fn is_superset(&self, other: &Self) -> bool { other.is_subset(self) } } /// An helping Iterator over pairs of containers. /// /// Returns the smallest container according to its key /// or both if the key is the same. It is useful when you need /// to iterate over two containers to do operations on them. pub struct Pairs where I: Iterator, J: Iterator, L: Borrow, R: Borrow, { left: Peekable, right: Peekable, } impl Pairs where I: Iterator, J: Iterator, L: Borrow, R: Borrow, { pub fn new(left: A, right: B) -> Pairs where A: IntoIterator, B: IntoIterator, { Pairs { left: left.into_iter().peekable(), right: right.into_iter().peekable() } } } impl Iterator for Pairs where I: Iterator, J: Iterator, L: Borrow, R: Borrow, { type Item = (Option, Option); fn next(&mut self) -> Option { match (self.left.peek(), self.right.peek()) { (None, None) => None, (Some(_), None) => Some((self.left.next(), None)), (None, Some(_)) => Some((None, self.right.next())), (Some(c1), Some(c2)) => match c1.borrow().key.cmp(&c2.borrow().key) { Ordering::Equal => Some((self.left.next(), self.right.next())), Ordering::Less => Some((self.left.next(), None)), Ordering::Greater => Some((None, self.right.next())), }, } } } roaring-0.10.2/src/bitmap/container.rs000064400000000000000000000207031046102023000157420ustar 00000000000000use std::fmt; use std::ops::{ BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, RangeInclusive, Sub, SubAssign, }; use super::store::{self, Store}; use super::util; pub const ARRAY_LIMIT: u64 = 4096; #[derive(PartialEq, Clone)] pub struct Container { pub key: u16, pub store: Store, } pub struct Iter<'a> { pub key: u16, inner: store::Iter<'a>, } impl Container { pub fn new(key: u16) -> Container { Container { key, store: Store::new() } } pub fn full(key: u16) -> Container { Container { key, store: Store::full() } } } impl Container { pub fn len(&self) -> u64 { self.store.len() } pub fn insert(&mut self, index: u16) -> bool { if self.store.insert(index) { self.ensure_correct_store(); true } else { false } } pub fn insert_range(&mut self, range: RangeInclusive) -> u64 { // If inserting the range will make this a bitmap by itself, do it now if range.len() as u64 > ARRAY_LIMIT { if let Store::Array(arr) = &self.store { self.store = Store::Bitmap(arr.to_bitmap_store()); } } let inserted = self.store.insert_range(range); self.ensure_correct_store(); inserted } /// Pushes `index` at the end of the container only if `index` is the new max. /// /// Returns whether the `index` was effectively pushed. pub fn push(&mut self, index: u16) -> bool { if self.store.push(index) { self.ensure_correct_store(); true } else { false } } /// /// Pushes `index` at the end of the container. /// It is up to the caller to have validated index > self.max() /// /// # Panics /// /// If debug_assertions enabled and index is > self.max() pub(crate) fn push_unchecked(&mut self, index: u16) { self.store.push_unchecked(index); self.ensure_correct_store(); } pub fn remove(&mut self, index: u16) -> bool { if self.store.remove(index) { self.ensure_correct_store(); true } else { false } } pub fn remove_range(&mut self, range: RangeInclusive) -> u64 { let result = self.store.remove_range(range); self.ensure_correct_store(); result } pub fn remove_smallest(&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_smallest(n) } } Store::Array(_) => self.store.remove_smallest(n), }; } pub fn remove_biggest(&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_biggest(n) } } Store::Array(_) => self.store.remove_biggest(n), }; } pub fn contains(&self, index: u16) -> bool { self.store.contains(index) } pub fn contains_range(&self, range: RangeInclusive) -> bool { self.store.contains_range(range) } pub fn is_full(&self) -> bool { self.store.is_full() } pub fn is_disjoint(&self, other: &Self) -> bool { self.store.is_disjoint(&other.store) } pub fn is_subset(&self, other: &Self) -> bool { self.len() <= other.len() && self.store.is_subset(&other.store) } pub fn intersection_len(&self, other: &Self) -> u64 { self.store.intersection_len(&other.store) } pub fn min(&self) -> Option { self.store.min() } pub fn max(&self) -> Option { self.store.max() } pub fn rank(&self, index: u16) -> u64 { self.store.rank(index) } pub(crate) fn ensure_correct_store(&mut self) { match &self.store { Store::Bitmap(ref bits) => { if bits.len() <= ARRAY_LIMIT { self.store = Store::Array(bits.to_array_store()) } } Store::Array(ref vec) => { if vec.len() > ARRAY_LIMIT { self.store = Store::Bitmap(vec.to_bitmap_store()) } } }; } } impl BitOr<&Container> for &Container { type Output = Container; fn bitor(self, rhs: &Container) -> Container { let store = BitOr::bitor(&self.store, &rhs.store); let mut container = Container { key: self.key, store }; container.ensure_correct_store(); container } } impl BitOrAssign for Container { fn bitor_assign(&mut self, rhs: Container) { BitOrAssign::bitor_assign(&mut self.store, rhs.store); self.ensure_correct_store(); } } impl BitOrAssign<&Container> for Container { fn bitor_assign(&mut self, rhs: &Container) { BitOrAssign::bitor_assign(&mut self.store, &rhs.store); self.ensure_correct_store(); } } impl BitAnd<&Container> for &Container { type Output = Container; fn bitand(self, rhs: &Container) -> Container { let store = BitAnd::bitand(&self.store, &rhs.store); let mut container = Container { key: self.key, store }; container.ensure_correct_store(); container } } impl BitAndAssign for Container { fn bitand_assign(&mut self, rhs: Container) { BitAndAssign::bitand_assign(&mut self.store, rhs.store); self.ensure_correct_store(); } } impl BitAndAssign<&Container> for Container { fn bitand_assign(&mut self, rhs: &Container) { BitAndAssign::bitand_assign(&mut self.store, &rhs.store); self.ensure_correct_store(); } } impl Sub<&Container> for &Container { type Output = Container; fn sub(self, rhs: &Container) -> Container { let store = Sub::sub(&self.store, &rhs.store); let mut container = Container { key: self.key, store }; container.ensure_correct_store(); container } } impl SubAssign<&Container> for Container { fn sub_assign(&mut self, rhs: &Container) { SubAssign::sub_assign(&mut self.store, &rhs.store); self.ensure_correct_store(); } } impl BitXor<&Container> for &Container { type Output = Container; fn bitxor(self, rhs: &Container) -> Container { let store = BitXor::bitxor(&self.store, &rhs.store); let mut container = Container { key: self.key, store }; container.ensure_correct_store(); container } } impl BitXorAssign for Container { fn bitxor_assign(&mut self, rhs: Container) { BitXorAssign::bitxor_assign(&mut self.store, rhs.store); self.ensure_correct_store(); } } impl BitXorAssign<&Container> for Container { fn bitxor_assign(&mut self, rhs: &Container) { BitXorAssign::bitxor_assign(&mut self.store, &rhs.store); self.ensure_correct_store(); } } impl<'a> IntoIterator for &'a Container { type Item = u32; type IntoIter = Iter<'a>; fn into_iter(self) -> Iter<'a> { let store: &Store = &self.store; Iter { key: self.key, inner: store.into_iter() } } } impl IntoIterator for Container { type Item = u32; type IntoIter = Iter<'static>; fn into_iter(self) -> Iter<'static> { Iter { key: self.key, inner: self.store.into_iter() } } } impl<'a> Iterator for Iter<'a> { type Item = u32; fn next(&mut self) -> Option { self.inner.next().map(|i| util::join(self.key, i)) } } impl DoubleEndedIterator for Iter<'_> { fn next_back(&mut self) -> Option { self.inner.next_back().map(|i| util::join(self.key, i)) } } impl fmt::Debug for Container { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { format!("Container<{:?} @ {:?}>", self.len(), self.key).fmt(formatter) } } roaring-0.10.2/src/bitmap/fmt.rs000064400000000000000000000007671046102023000145560ustar 00000000000000use std::fmt; use crate::RoaringBitmap; impl fmt::Debug for RoaringBitmap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.len() < 16 { write!(f, "RoaringBitmap<{:?}>", self.iter().collect::>()) } else { write!( f, "RoaringBitmap<{:?} values between {:?} and {:?}>", self.len(), self.min().unwrap(), self.max().unwrap() ) } } } roaring-0.10.2/src/bitmap/inherent.rs000064400000000000000000000707231046102023000156030ustar 00000000000000use std::cmp::Ordering; use std::ops::RangeBounds; use crate::RoaringBitmap; use super::container::Container; use super::util; impl RoaringBitmap { /// Creates an empty `RoaringBitmap`. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// let rb = RoaringBitmap::new(); /// ``` pub fn new() -> RoaringBitmap { RoaringBitmap { containers: Vec::new() } } /// Creates a full `RoaringBitmap`. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// let rb = RoaringBitmap::full(); /// ``` pub fn full() -> RoaringBitmap { RoaringBitmap { containers: (0..=u16::MAX).map(Container::full).collect() } } /// Adds a value to the set. /// /// Returns whether the value was absent from the set. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// assert_eq!(rb.insert(3), true); /// assert_eq!(rb.insert(3), false); /// assert_eq!(rb.contains(3), true); /// ``` pub fn insert(&mut self, value: u32) -> bool { let (key, index) = util::split(value); let container = match self.containers.binary_search_by_key(&key, |c| c.key) { Ok(loc) => &mut self.containers[loc], Err(loc) => { self.containers.insert(loc, Container::new(key)); &mut self.containers[loc] } }; container.insert(index) } /// Search for the specific container by the given key. /// Create a new container if not exist. /// /// Return the index of the target container. fn find_container_by_key(&mut self, key: u16) -> usize { match self.containers.binary_search_by_key(&key, |c| c.key) { Ok(loc) => loc, Err(loc) => { self.containers.insert(loc, Container::new(key)); loc } } } /// Inserts a range of values. /// Returns the number of inserted values. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// rb.insert_range(2..4); /// assert!(rb.contains(2)); /// assert!(rb.contains(3)); /// assert!(!rb.contains(4)); /// ``` pub fn insert_range(&mut self, range: R) -> u64 where R: RangeBounds, { let (start, end) = match util::convert_range_to_inclusive(range) { Some(range) => (*range.start(), *range.end()), None => return 0, }; let (start_container_key, start_index) = util::split(start); let (end_container_key, end_index) = util::split(end); // Find the container index for start_container_key let first_index = self.find_container_by_key(start_container_key); // If the end range value is in the same container, just call into // the one container. if start_container_key == end_container_key { return self.containers[first_index].insert_range(start_index..=end_index); } // For the first container, insert start_index..=u16::MAX, with // subsequent containers inserting 0..MAX. // // The last container (end_container_key) is handled explicitly outside // the loop. let mut low = start_index; let mut inserted = 0; for i in start_container_key..end_container_key { let index = self.find_container_by_key(i); // Insert the range subset for this container inserted += self.containers[index].insert_range(low..=u16::MAX); // After the first container, always fill the containers. low = 0; } // Handle the last container let last_index = self.find_container_by_key(end_container_key); inserted += self.containers[last_index].insert_range(0..=end_index); inserted } /// Pushes `value` in the bitmap only if it is greater than the current maximum value. /// /// Returns whether the value was inserted. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// assert!(rb.push(1)); /// assert!(rb.push(3)); /// assert_eq!(rb.push(3), false); /// assert!(rb.push(5)); /// /// assert_eq!(rb.iter().collect::>(), vec![1, 3, 5]); /// ``` pub fn push(&mut self, value: u32) -> bool { let (key, index) = util::split(value); match self.containers.last_mut() { Some(container) if container.key == key => container.push(index), Some(container) if container.key > key => false, _otherwise => { let mut container = Container::new(key); container.push(index); self.containers.push(container); true } } } /// /// Pushes `value` at the end of the bitmap. /// It is up to the caller to have validated index > self.max() /// /// # Panics /// /// If debug_assertions enabled and index is > self.max() pub(crate) fn push_unchecked(&mut self, value: u32) { let (key, index) = util::split(value); match self.containers.last_mut() { Some(container) if container.key == key => container.push_unchecked(index), Some(container) if cfg!(debug_assertions) && container.key > key => { panic!("last container key > key of value") } _otherwise => { let mut container = Container::new(key); container.push_unchecked(index); self.containers.push(container); } } } /// Removes a value from the set. Returns `true` if the value was present in the set. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// rb.insert(3); /// assert_eq!(rb.remove(3), true); /// assert_eq!(rb.remove(3), false); /// assert_eq!(rb.contains(3), false); /// ``` pub fn remove(&mut self, value: u32) -> bool { let (key, index) = util::split(value); match self.containers.binary_search_by_key(&key, |c| c.key) { Ok(loc) => { if self.containers[loc].remove(index) { if self.containers[loc].len() == 0 { self.containers.remove(loc); } true } else { false } } _ => false, } } /// Removes a range of values. /// Returns the number of removed values. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// rb.insert(2); /// rb.insert(3); /// assert_eq!(rb.remove_range(2..4), 2); /// ``` pub fn remove_range(&mut self, range: R) -> u64 where R: RangeBounds, { let (start, end) = match util::convert_range_to_inclusive(range) { Some(range) => (*range.start(), *range.end()), None => return 0, }; let (start_container_key, start_index) = util::split(start); let (end_container_key, end_index) = util::split(end); let mut index = 0; let mut removed = 0; while index < self.containers.len() { let key = self.containers[index].key; if key >= start_container_key && key <= end_container_key { let a = if key == start_container_key { start_index } else { 0 }; let b = if key == end_container_key { end_index } else { u16::MAX }; removed += self.containers[index].remove_range(a..=b); if self.containers[index].len() == 0 { self.containers.remove(index); continue; } } index += 1; } removed } /// Returns `true` if this set contains the specified integer. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// rb.insert(1); /// assert_eq!(rb.contains(0), false); /// assert_eq!(rb.contains(1), true); /// assert_eq!(rb.contains(100), false); /// ``` pub fn contains(&self, value: u32) -> bool { let (key, index) = util::split(value); match self.containers.binary_search_by_key(&key, |c| c.key) { Ok(loc) => self.containers[loc].contains(index), Err(_) => false, } } /// Returns `true` if all values in the range are present in this set. /// /// # Examples /// /// ``` /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// // An empty range is always contained /// assert!(rb.contains_range(7..7)); /// /// rb.insert_range(1..0xFFF); /// assert!(rb.contains_range(1..0xFFF)); /// assert!(rb.contains_range(2..0xFFF)); /// // 0 is not contained /// assert!(!rb.contains_range(0..2)); /// // 0xFFF is not contained /// assert!(!rb.contains_range(1..=0xFFF)); /// ``` pub fn contains_range(&self, range: R) -> bool where R: RangeBounds, { let (start, end) = match util::convert_range_to_inclusive(range) { Some(range) => (*range.start(), *range.end()), // Empty ranges are always contained None => return true, }; let (start_high, start_low) = util::split(start); let (end_high, end_low) = util::split(end); debug_assert!(start_high <= end_high); let containers = match self.containers.binary_search_by_key(&start_high, |container| container.key) { Ok(i) => &self.containers[i..], Err(_) => return false, }; if start_high == end_high { return containers[0].contains_range(start_low..=end_low); } let high_span = usize::from(end_high - start_high); // If this contains everything in the range, there should be a container for every item in the span // and the container that many items away should be the high key let containers = match containers.get(high_span) { Some(c) if c.key == end_high => &containers[..=high_span], _ => return false, }; match containers { [first, rest @ .., last] => { first.contains_range(start_low..=u16::MAX) && rest.iter().all(|container| container.is_full()) && last.contains_range(0..=end_low) } _ => unreachable!("already validated containers has at least 2 items"), } } /// Returns the number of elements in this set which are in the passed range. /// /// # Examples /// /// ``` /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// rb.insert_range(0x10000..0x40000); /// rb.insert(0x50001); /// rb.insert(0x50005); /// rb.insert(u32::MAX); /// /// assert_eq!(rb.range_cardinality(0..0x10000), 0); /// assert_eq!(rb.range_cardinality(0x10000..0x40000), 0x30000); /// assert_eq!(rb.range_cardinality(0x50000..0x60000), 2); /// assert_eq!(rb.range_cardinality(0x10000..0x10000), 0); /// assert_eq!(rb.range_cardinality(0x50000..=u32::MAX), 3); /// ``` pub fn range_cardinality(&self, range: R) -> u64 where R: RangeBounds, { let (start, end) = match util::convert_range_to_inclusive(range) { Some(range) => (*range.start(), *range.end()), // Empty ranges have 0 bits set in them None => return 0, }; let (start_key, start_low) = util::split(start); let (end_key, end_low) = util::split(end); let mut cardinality = 0; let i = match self.containers.binary_search_by_key(&start_key, |c| c.key) { Ok(i) => { let container = &self.containers[i]; if start_key == end_key { cardinality += container.rank(end_low) } else { cardinality += container.len(); } if start_low != 0 { cardinality -= container.rank(start_low - 1); } i + 1 } Err(i) => i, }; for container in &self.containers[i..] { match container.key.cmp(&end_key) { Ordering::Less => cardinality += container.len(), Ordering::Equal => { cardinality += container.rank(end_low); break; } Ordering::Greater => { break; } } } cardinality } /// Clears all integers in this set. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// rb.insert(1); /// assert_eq!(rb.contains(1), true); /// rb.clear(); /// assert_eq!(rb.contains(1), false); /// ``` pub fn clear(&mut self) { self.containers.clear(); } /// Returns `true` if there are no integers in this set. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// assert_eq!(rb.is_empty(), true); /// /// rb.insert(3); /// assert_eq!(rb.is_empty(), false); /// ``` pub fn is_empty(&self) -> bool { self.containers.is_empty() } /// Returns `true` if there are every possible integers in this set. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::full(); /// assert!(!rb.is_empty()); /// assert!(rb.is_full()); /// ``` pub fn is_full(&self) -> bool { self.containers.len() == (u16::MAX as usize + 1) && self.containers.iter().all(Container::is_full) } /// Returns the number of distinct integers added to the set. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// assert_eq!(rb.len(), 0); /// /// rb.insert(3); /// assert_eq!(rb.len(), 1); /// /// rb.insert(3); /// rb.insert(4); /// assert_eq!(rb.len(), 2); /// ``` pub fn len(&self) -> u64 { self.containers.iter().map(|container| container.len()).sum() } /// Returns the minimum value in the set (if the set is non-empty). /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// assert_eq!(rb.min(), None); /// /// rb.insert(3); /// rb.insert(4); /// assert_eq!(rb.min(), Some(3)); /// ``` pub fn min(&self) -> Option { self.containers.first().and_then(|tail| tail.min().map(|min| util::join(tail.key, min))) } /// Returns the maximum value in the set (if the set is non-empty). /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// assert_eq!(rb.max(), None); /// /// rb.insert(3); /// rb.insert(4); /// assert_eq!(rb.max(), Some(4)); /// ``` pub fn max(&self) -> Option { self.containers.last().and_then(|tail| tail.max().map(|max| util::join(tail.key, max))) } /// Returns the number of integers that are <= value. rank(u32::MAX) == len() /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// assert_eq!(rb.rank(0), 0); /// /// rb.insert(3); /// rb.insert(4); /// assert_eq!(rb.rank(3), 1); /// assert_eq!(rb.rank(10), 2) /// ``` pub fn rank(&self, value: u32) -> u64 { // if len becomes cached for RoaringBitmap: return len if len > value let (key, index) = util::split(value); match self.containers.binary_search_by_key(&key, |c| c.key) { Ok(i) => { // For optimal locality of reference: // * container[i] should be a cache hit after binary search, rank it first // * sum in reverse to avoid cache misses near i unsafe { self.containers.get_unchecked(i) }.rank(index) + self.containers[..i].iter().rev().map(|c| c.len()).sum::() } Err(i) => self.containers[..i].iter().map(|c| c.len()).sum(), } } /// Returns the `n`th integer in the set or `None` if `n >= len()` /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// assert_eq!(rb.select(0), None); /// /// rb.append(vec![0, 10, 100]); /// /// assert_eq!(rb.select(0), Some(0)); /// assert_eq!(rb.select(1), Some(10)); /// assert_eq!(rb.select(2), Some(100)); /// assert_eq!(rb.select(3), None); /// ``` pub fn select(&self, n: u32) -> Option { let mut n = n as u64; for container in &self.containers { let len = container.len(); if len > n { return container .store .select(n as u16) .map(|index| util::join(container.key, index)); } n -= len; } None } /// Removes the `n` smallests values from this bitmap. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::from_iter([1, 5, 7, 9]); /// rb.remove_smallest(2); /// assert_eq!(rb, RoaringBitmap::from_iter([7, 9])); /// /// let mut rb = RoaringBitmap::from_iter([1, 3, 7, 9]); /// rb.remove_smallest(2); /// assert_eq!(rb, RoaringBitmap::from_iter([7, 9])); pub fn remove_smallest(&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_smallest(n); } } /// Removes the `n` biggests values from this bitmap. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::from_iter([1, 5, 7, 9]); /// rb.remove_biggest(2); /// assert_eq!(rb, RoaringBitmap::from_iter([1, 5])); /// rb.remove_biggest(1); /// assert_eq!(rb, RoaringBitmap::from_iter([1])); pub fn remove_biggest(&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_biggest(n); } } else { self.containers.clear(); } } } impl Default for RoaringBitmap { fn default() -> RoaringBitmap { RoaringBitmap::new() } } impl Clone for RoaringBitmap { fn clone(&self) -> Self { RoaringBitmap { containers: self.containers.clone() } } fn clone_from(&mut self, other: &Self) { self.containers.clone_from(&other.containers); } } #[cfg(test)] mod tests { use proptest::collection::vec; use proptest::prelude::*; use super::*; proptest! { #[test] fn insert_range( lo in 0u32..=65535, hi in 65536u32..=131071, checks in vec(0u32..=262143, 1000) ){ let r = lo..hi; let mut b = RoaringBitmap::new(); let inserted = b.insert_range(r.clone()); if r.end > r.start { assert_eq!(inserted, r.end as u64 - r.start as u64); } else { assert_eq!(inserted, 0); } // Assert all values in the range are present for i in r.clone() { assert!(b.contains(i), "does not contain {}", i); } // Run the check values looking for any false positives for i in checks { let bitmap_has = b.contains(i); let range_has = r.contains(&i); assert_eq!( bitmap_has, range_has, "value {} in bitmap={} and range={}", i, bitmap_has, range_has ); } } } #[test] fn test_insert_remove_range_same_container() { let mut b = RoaringBitmap::new(); let inserted = b.insert_range(1..5); assert_eq!(inserted, 4); for i in 1..5 { assert!(b.contains(i)); } let removed = b.remove_range(2..10); assert_eq!(removed, 3); assert!(b.contains(1)); for i in 2..5 { assert!(!b.contains(i)); } } #[test] fn test_insert_remove_range_pre_populated() { let mut b = RoaringBitmap::new(); let inserted = b.insert_range(1..20_000); assert_eq!(inserted, 19_999); let removed = b.remove_range(10_000..21_000); assert_eq!(removed, 10_000); let inserted = b.insert_range(1..20_000); assert_eq!(inserted, 10_000); } #[test] fn test_insert_max_u32() { let mut b = RoaringBitmap::new(); let inserted = b.insert(u32::MAX); // We are allowed to add u32::MAX assert!(inserted); } #[test] fn test_insert_remove_across_container() { let mut b = RoaringBitmap::new(); let inserted = b.insert_range(u16::MAX as u32..=u16::MAX as u32 + 1); assert_eq!(inserted, 2); assert_eq!(b.containers.len(), 2); let removed = b.remove_range(u16::MAX as u32 + 1..=u16::MAX as u32 + 1); assert_eq!(removed, 1); assert_eq!(b.containers.len(), 1); } #[test] fn test_insert_remove_single_element() { let mut b = RoaringBitmap::new(); let inserted = b.insert_range(u16::MAX as u32 + 1..=u16::MAX as u32 + 1); assert_eq!(inserted, 1); assert_eq!(b.containers[0].len(), 1); assert_eq!(b.containers.len(), 1); let removed = b.remove_range(u16::MAX as u32 + 1..=u16::MAX as u32 + 1); assert_eq!(removed, 1); assert_eq!(b.containers.len(), 0); } #[test] fn test_insert_remove_range_multi_container() { let mut bitmap = RoaringBitmap::new(); assert_eq!(bitmap.insert_range(0..((1_u32 << 16) + 1)), (1_u64 << 16) + 1); assert_eq!(bitmap.containers.len(), 2); assert_eq!(bitmap.containers[0].key, 0); assert_eq!(bitmap.containers[1].key, 1); assert_eq!(bitmap.insert_range(0..((1_u32 << 16) + 1)), 0); assert!(bitmap.insert((1_u32 << 16) * 4)); assert_eq!(bitmap.containers.len(), 3); assert_eq!(bitmap.containers[2].key, 4); assert_eq!(bitmap.remove_range(((1_u32 << 16) * 3)..=((1_u32 << 16) * 4)), 1); assert_eq!(bitmap.containers.len(), 2); } #[test] fn insert_range_single() { let mut bitmap = RoaringBitmap::new(); assert_eq!(bitmap.insert_range((1_u32 << 16)..(2_u32 << 16)), 1_u64 << 16); assert_eq!(bitmap.containers.len(), 1); assert_eq!(bitmap.containers[0].key, 1); } #[test] fn remove_smallest_for_vec() { let mut bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]); bitmap.remove_smallest(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_smallest(3); assert_eq!(bitmap.len(), 3); assert_eq!(bitmap, RoaringBitmap::from_iter([7, 9, 11])); bitmap = RoaringBitmap::from_iter([1, 3]); bitmap.remove_smallest(2); assert_eq!(bitmap.len(), 0); bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]); bitmap.remove_smallest(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_smallest(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_smallest(7); assert_eq!(bitmap, RoaringBitmap::default()); } #[test] fn remove_smallest_for_bit() { let mut bitmap = RoaringBitmap::new(); bitmap.insert_range(0..4098); bitmap.remove_smallest(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_smallest(999); assert_eq!(bitmap.len(), 5001); bitmap = RoaringBitmap::new(); bitmap.insert_range(0..8000); bitmap.remove_smallest(10); assert_eq!(bitmap.len(), 7990); bitmap = RoaringBitmap::new(); bitmap.insert_range(0..200000); bitmap.remove_smallest(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_smallest(30); assert_eq!(bitmap.len(), 4975); bitmap = RoaringBitmap::new(); bitmap.insert_range(0..65535); bitmap.remove_smallest(0); assert_eq!(bitmap.len(), 65535); } #[test] fn remove_biggest_for_bit() { let mut bitmap = RoaringBitmap::new(); bitmap.insert_range(0..5000); bitmap.remove_biggest(1000); assert_eq!(bitmap.len(), 4000); bitmap = RoaringBitmap::new(); bitmap.insert_range(0..6000); bitmap.remove_biggest(1000); assert_eq!(bitmap.len(), 5000); bitmap = RoaringBitmap::new(); bitmap.insert_range(0..200000); bitmap.remove_biggest(196000); assert_eq!(bitmap.len(), 4000); bitmap = RoaringBitmap::new(); bitmap.insert_range(0..200000); bitmap.remove_biggest(2000); assert_eq!(bitmap.len(), 198000); assert_eq!(bitmap, RoaringBitmap::from_iter(0..198000)); bitmap = RoaringBitmap::new(); bitmap.insert_range(0..65535); bitmap.remove_biggest(0); assert_eq!(bitmap.len(), 65535); } #[test] fn remove_biggest_for_vec() { let mut bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]); bitmap.remove_biggest(2); assert_eq!(bitmap, RoaringBitmap::from_iter([1, 2, 3, 7])); bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]); bitmap.remove_biggest(6); assert_eq!(bitmap.len(), 0); bitmap = RoaringBitmap::from_iter([1, 2, 3, 7, 9, 11]); bitmap.remove_biggest(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_biggest(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_biggest(4); assert_eq!(bitmap, RoaringBitmap::default()); } } roaring-0.10.2/src/bitmap/iter.rs000064400000000000000000000162251046102023000147270ustar 00000000000000use std::iter::{self, FromIterator}; use std::{slice, vec}; use super::container::Container; use crate::{NonSortedIntegers, RoaringBitmap}; /// An iterator for `RoaringBitmap`. pub struct Iter<'a> { inner: iter::Flatten>, size_hint: u64, } /// An iterator for `RoaringBitmap`. pub struct IntoIter { inner: iter::Flatten>, size_hint: u64, } impl Iter<'_> { fn new(containers: &[Container]) -> Iter { let size_hint = containers.iter().map(|c| c.len()).sum(); Iter { inner: containers.iter().flatten(), size_hint } } } impl IntoIter { fn new(containers: Vec) -> IntoIter { let size_hint = containers.iter().map(|c| c.len()).sum(); IntoIter { inner: containers.into_iter().flatten(), size_hint } } } impl Iterator for Iter<'_> { type Item = u32; fn next(&mut self) -> Option { self.size_hint = self.size_hint.saturating_sub(1); self.inner.next() } fn size_hint(&self) -> (usize, Option) { if self.size_hint < usize::MAX as u64 { (self.size_hint as usize, Some(self.size_hint as usize)) } else { (usize::MAX, None) } } } impl DoubleEndedIterator for Iter<'_> { fn next_back(&mut self) -> Option { self.size_hint = self.size_hint.saturating_sub(1); self.inner.next_back() } } #[cfg(target_pointer_width = "64")] impl ExactSizeIterator for Iter<'_> { fn len(&self) -> usize { self.size_hint as usize } } impl Iterator for IntoIter { type Item = u32; fn next(&mut self) -> Option { self.size_hint = self.size_hint.saturating_sub(1); self.inner.next() } fn size_hint(&self) -> (usize, Option) { if self.size_hint < usize::MAX as u64 { (self.size_hint as usize, Some(self.size_hint as usize)) } else { (usize::MAX, None) } } } impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option { self.size_hint = self.size_hint.saturating_sub(1); self.inner.next_back() } } #[cfg(target_pointer_width = "64")] impl ExactSizeIterator for IntoIter { fn len(&self) -> usize { self.size_hint as usize } } impl RoaringBitmap { /// Iterator over each value stored in the RoaringBitmap, guarantees values are ordered by value. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// use std::iter::FromIterator; /// /// let bitmap = (1..3).collect::(); /// let mut iter = bitmap.iter(); /// /// assert_eq!(iter.next(), Some(1)); /// assert_eq!(iter.next(), Some(2)); /// assert_eq!(iter.next(), None); /// ``` pub fn iter(&self) -> Iter { Iter::new(&self.containers) } } impl<'a> IntoIterator for &'a RoaringBitmap { type Item = u32; type IntoIter = Iter<'a>; fn into_iter(self) -> Iter<'a> { self.iter() } } impl IntoIterator for RoaringBitmap { type Item = u32; type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { IntoIter::new(self.containers) } } impl From<[u32; N]> for RoaringBitmap { fn from(arr: [u32; N]) -> Self { RoaringBitmap::from_iter(arr) } } impl FromIterator for RoaringBitmap { fn from_iter>(iterator: I) -> RoaringBitmap { let mut rb = RoaringBitmap::new(); rb.extend(iterator); rb } } impl<'a> FromIterator<&'a u32> for RoaringBitmap { fn from_iter>(iterator: I) -> RoaringBitmap { let mut rb = RoaringBitmap::new(); rb.extend(iterator); rb } } impl Extend for RoaringBitmap { fn extend>(&mut self, iterator: I) { for value in iterator { self.insert(value); } } } impl<'a> Extend<&'a u32> for RoaringBitmap { fn extend>(&mut self, iterator: I) { for value in iterator { self.insert(*value); } } } impl RoaringBitmap { /// Create the set from a sorted iterator. Values must be sorted and deduplicated. /// /// The values of the iterator must be ordered and strictly greater than the greatest value /// in the set. If a value in the iterator doesn't satisfy this requirement, it is not added /// and the append operation is stopped. /// /// Returns `Ok` with the requested `RoaringBitmap`, `Err` with the number of elements /// that were correctly appended before failure. /// /// # Example: Create a set from an ordered list of integers. /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::from_sorted_iter(0..10).unwrap(); /// /// assert!(rb.iter().eq(0..10)); /// ``` /// /// # Example: Try to create a set from a non-ordered list of integers. /// /// ```rust /// use roaring::RoaringBitmap; /// /// let integers = 0..10u32; /// let error = RoaringBitmap::from_sorted_iter(integers.rev()).unwrap_err(); /// /// assert_eq!(error.valid_until(), 1); /// ``` pub fn from_sorted_iter>( iterator: I, ) -> Result { let mut rb = RoaringBitmap::new(); rb.append(iterator).map(|_| rb) } /// Extend the set with a sorted iterator. /// /// The values of the iterator must be ordered and strictly greater than the greatest value /// in the set. If a value in the iterator doesn't satisfy this requirement, it is not added /// and the append operation is stopped. /// /// Returns `Ok` with the number of elements appended to the set, `Err` with /// the number of elements we effectively appended before an error occurred. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// assert_eq!(rb.append(0..10), Ok(10)); /// /// assert!(rb.iter().eq(0..10)); /// ``` pub fn append>( &mut self, iterator: I, ) -> Result { // Name shadowed to prevent accidentally referencing the param let mut iterator = iterator.into_iter(); let mut prev = match (iterator.next(), self.max()) { (None, _) => return Ok(0), (Some(first), Some(max)) if first <= max => { return Err(NonSortedIntegers { valid_until: 0 }) } (Some(first), _) => first, }; // It is now guaranteed that so long as the values of the iterator are // monotonically increasing they must also be the greatest in the set. self.push_unchecked(prev); let mut count = 1; for value in iterator { if value <= prev { return Err(NonSortedIntegers { valid_until: count }); } else { self.push_unchecked(value); prev = value; count += 1; } } Ok(count) } } roaring-0.10.2/src/bitmap/mod.rs000064400000000000000000000015041046102023000145350ustar 00000000000000mod arbitrary; mod container; mod fmt; mod multiops; mod proptests; mod store; mod util; // Order of these modules matters as it determines the `impl` blocks order in // the docs mod cmp; mod inherent; mod iter; mod ops; #[cfg(feature = "serde")] mod serde; mod serialization; use self::cmp::Pairs; pub use self::iter::IntoIter; pub use self::iter::Iter; /// A compressed bitmap using the [Roaring bitmap compression scheme](https://roaringbitmap.org/). /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// /// // insert all primes less than 10 /// rb.insert(2); /// rb.insert(3); /// rb.insert(5); /// rb.insert(7); /// println!("total bits set to true: {}", rb.len()); /// ``` #[derive(PartialEq)] pub struct RoaringBitmap { containers: Vec, } roaring-0.10.2/src/bitmap/multiops.rs000064400000000000000000000325121046102023000156350ustar 00000000000000use std::{ borrow::Cow, cmp::Reverse, convert::Infallible, mem, ops::{BitOrAssign, BitXorAssign}, }; use retain_mut::RetainMut; use crate::{MultiOps, RoaringBitmap}; use super::{container::Container, store::Store}; /// When collecting bitmaps for optimizing the computation. If we don't know how many // elements are in the iterator we collect 10 elements. const BASE_COLLECT: usize = 10; /// If an iterator contain 50 elements or less we collect everything because it'll be so /// much faster without impacting the memory usage too much (in most cases). const MAX_COLLECT: usize = 50; impl MultiOps for I where I: IntoIterator, { type Output = RoaringBitmap; fn union(self) -> Self::Output { try_multi_or_owned(self.into_iter().map(Ok::<_, Infallible>)).unwrap() } fn intersection(self) -> Self::Output { try_multi_and_owned(self.into_iter().map(Ok::<_, Infallible>)).unwrap() } fn difference(self) -> Self::Output { try_multi_sub_owned(self.into_iter().map(Ok::<_, Infallible>)).unwrap() } fn symmetric_difference(self) -> Self::Output { try_multi_xor_owned(self.into_iter().map(Ok::<_, Infallible>)).unwrap() } } impl MultiOps> for I where I: IntoIterator>, { type Output = Result; fn union(self) -> Self::Output { try_multi_or_owned(self) } fn intersection(self) -> Self::Output { try_multi_and_owned(self) } fn difference(self) -> Self::Output { try_multi_sub_owned(self) } fn symmetric_difference(self) -> Self::Output { try_multi_xor_owned(self) } } impl<'a, I> MultiOps<&'a RoaringBitmap> for I where I: IntoIterator, { type Output = RoaringBitmap; fn union(self) -> Self::Output { try_multi_or_ref(self.into_iter().map(Ok::<_, Infallible>)).unwrap() } fn intersection(self) -> Self::Output { try_multi_and_ref(self.into_iter().map(Ok::<_, Infallible>)).unwrap() } fn difference(self) -> Self::Output { try_multi_sub_ref(self.into_iter().map(Ok::<_, Infallible>)).unwrap() } fn symmetric_difference(self) -> Self::Output { try_multi_xor_ref(self.into_iter().map(Ok::<_, Infallible>)).unwrap() } } impl<'a, I, E: 'a> MultiOps> for I where I: IntoIterator>, { type Output = Result; fn union(self) -> Self::Output { try_multi_or_ref(self) } fn intersection(self) -> Self::Output { try_multi_and_ref(self) } fn difference(self) -> Self::Output { try_multi_sub_ref(self) } fn symmetric_difference(self) -> Self::Output { try_multi_xor_ref(self) } } #[inline] fn try_multi_and_owned( bitmaps: impl IntoIterator>, ) -> Result { let mut iter = bitmaps.into_iter(); // We're going to take a bunch of elements at the start of the iterator and sort // them to reduce the size of our bitmap faster. let mut start = collect_starting_elements(iter.by_ref())?; start.sort_unstable_by_key(|bitmap| bitmap.containers.len()); let mut start = start.into_iter(); if let Some(mut lhs) = start.next() { for rhs in start.map(Ok).chain(iter) { if lhs.is_empty() { return Ok(lhs); } lhs &= rhs?; } Ok(lhs) } else { Ok(RoaringBitmap::new()) } } #[inline] fn try_multi_and_ref<'a, E>( bitmaps: impl IntoIterator>, ) -> Result { let mut iter = bitmaps.into_iter(); // We're going to take a bunch of elements at the start of the iterator and sort // them to reduce the size of our bitmap faster. let mut start = collect_starting_elements(iter.by_ref())?; start.sort_unstable_by_key(|bitmap| bitmap.containers.len()); let mut start = start.into_iter(); if let Some(mut lhs) = start.next().cloned() { for rhs in start.map(Ok).chain(iter) { if lhs.is_empty() { return Ok(lhs); } lhs &= rhs?; } Ok(lhs) } else { Ok(RoaringBitmap::new()) } } #[inline] fn try_multi_sub_owned( bitmaps: impl IntoIterator>, ) -> Result { let mut iter = bitmaps.into_iter(); match iter.next().transpose()? { Some(mut lhs) => { for rhs in iter { if lhs.is_empty() { return Ok(lhs); } lhs -= rhs?; } Ok(lhs) } None => Ok(RoaringBitmap::default()), } } #[inline] fn try_multi_sub_ref<'a, E>( bitmaps: impl IntoIterator>, ) -> Result { let mut iter = bitmaps.into_iter(); match iter.next().transpose()?.cloned() { Some(mut lhs) => { for rhs in iter { if lhs.is_empty() { return Ok(lhs); } lhs -= rhs?; } Ok(lhs) } None => Ok(RoaringBitmap::default()), } } #[inline] fn try_multi_or_owned( bitmaps: impl IntoIterator>, ) -> Result { let mut iter = bitmaps.into_iter(); // We're going to take a bunch of elements at the start of the iterator and // move the biggest one first to grow faster. let mut start = collect_starting_elements(iter.by_ref())?; start.sort_unstable_by_key(|bitmap| Reverse(bitmap.containers.len())); let start_size = start.len(); let mut start = start.into_iter(); let mut containers = if let Some(c) = start.next() { if c.is_empty() { // everything must be empty if the max is empty start.by_ref().nth(start_size); } c.containers } else { return Ok(RoaringBitmap::new()); }; for bitmap in start.map(Ok).chain(iter) { merge_container_owned(&mut containers, bitmap?.containers, BitOrAssign::bitor_assign); } RetainMut::retain_mut(&mut containers, |container| { if container.len() > 0 { container.ensure_correct_store(); true } else { false } }); Ok(RoaringBitmap { containers }) } #[inline] fn try_multi_xor_owned( bitmaps: impl IntoIterator>, ) -> Result { let mut iter = bitmaps.into_iter(); let mut containers = match iter.next().transpose()? { None => Vec::new(), Some(v) => v.containers, }; for bitmap in iter { merge_container_owned(&mut containers, bitmap?.containers, BitXorAssign::bitxor_assign); } RetainMut::retain_mut(&mut containers, |container| { if container.len() > 0 { container.ensure_correct_store(); true } else { false } }); Ok(RoaringBitmap { containers }) } fn merge_container_owned( lhs: &mut Vec, rhs: Vec, op: impl Fn(&mut Store, Store), ) { for mut rhs in rhs { match lhs.binary_search_by_key(&rhs.key, |c| c.key) { Err(loc) => lhs.insert(loc, rhs), Ok(loc) => { let lhs = &mut lhs[loc]; match (&lhs.store, &rhs.store) { (Store::Array(..), Store::Array(..)) => lhs.store = lhs.store.to_bitmap(), (Store::Array(..), Store::Bitmap(..)) => mem::swap(lhs, &mut rhs), _ => (), }; op(&mut lhs.store, rhs.store); } } } } #[inline] fn try_multi_or_ref<'a, E: 'a>( bitmaps: impl IntoIterator>, ) -> Result { // This algorithm operates on bitmaps. It must deal with arrays for which there are not (yet) // any others with the same key. // // 1. Eager cloning would create useless intermediate values that might become bitmaps // 2. Eager promoting forces disjoint containers to converted back to arrays at the end // // This strategy uses COW to lazily promote arrays to bitmaps as they are operated on. // More memory efficient, negligible wall time difference benchmarks // Phase 1. Borrow all the containers from the first element. let mut iter = bitmaps.into_iter(); let mut start = collect_starting_elements(iter.by_ref())?; let start_size = start.len(); start.sort_unstable_by_key(|bitmap| Reverse(bitmap.containers.len())); let mut start = start.into_iter(); let mut containers = match start.next() { Some(c) => { let c: Vec> = c.containers.iter().map(Cow::Borrowed).collect(); if c.is_empty() { // everything must be empty if the max is empty start.by_ref().nth(start_size); } c } None => { return Ok(RoaringBitmap::new()); } }; // Phase 2: Operate on the remaining containers for bitmap in start.map(Ok).chain(iter) { merge_container_ref(&mut containers, &bitmap?.containers, |a, b| *a |= b); } // Phase 3: Clean up let containers: Vec<_> = containers .into_iter() .filter(|container| container.len() > 0) .map(|c| { // Any borrowed bitmaps or arrays left over get cloned here let mut container = c.into_owned(); container.ensure_correct_store(); container }) .collect(); Ok(RoaringBitmap { containers }) } #[inline] fn try_multi_xor_ref<'a, E: 'a>( bitmaps: impl IntoIterator>, ) -> Result { // // This algorithm operates on bitmaps. It must deal with arrays for which there are not (yet) // any others with the same key. // // 1. Eager cloning would create useless intermediate values that might become bitmaps // 2. Eager promoting forces disjoint containers to converted back to arrays at the end // // This strategy uses COW to lazily promote arrays to bitmaps as they are operated on. // More memory efficient, negligible wall time difference benchmarks // Phase 1. Borrow all the containers from the first element. let mut iter = bitmaps.into_iter(); let mut containers: Vec> = match iter.next().transpose()? { None => Vec::new(), Some(v) => v.containers.iter().map(Cow::Borrowed).collect(), }; // Phase 2: Operate on the remaining containers for bitmap in iter { merge_container_ref(&mut containers, &bitmap?.containers, |a, b| *a ^= b); } // Phase 3: Clean up let containers: Vec<_> = containers .into_iter() .filter(|container| container.len() > 0) .map(|c| { // Any borrowed bitmaps or arrays left over get cloned here let mut container = c.into_owned(); container.ensure_correct_store(); container }) .collect(); Ok(RoaringBitmap { containers }) } fn merge_container_ref<'a>( containers: &mut Vec>, rhs: &'a [Container], op: impl Fn(&mut Store, &Store), ) { for rhs in rhs { match containers.binary_search_by_key(&rhs.key, |c| c.key) { Err(loc) => { // A container not currently in containers. Borrow it. containers.insert(loc, Cow::Borrowed(rhs)) } Ok(loc) => { // A container that is in containers. Operate on it. let lhs = &mut containers[loc]; match (&lhs.store, &rhs.store) { (Store::Array(..), Store::Array(..)) => { // We had borrowed an array. Without cloning it, create a new bitmap // Add all the elements to the new bitmap let mut store = lhs.store.to_bitmap(); op(&mut store, &rhs.store); *lhs = Cow::Owned(Container { key: lhs.key, store }); } (Store::Array(..), Store::Bitmap(..)) => { // We had borrowed an array. Copy the rhs bitmap, add lhs to it let mut store = rhs.store.clone(); op(&mut store, &lhs.store); *lhs = Cow::Owned(Container { key: lhs.key, store }); } (Store::Bitmap(..), _) => { // This might be a owned or borrowed bitmap. // If it was borrowed it will clone-on-write op(&mut lhs.to_mut().store, &rhs.store); } }; } } } } #[inline] fn collect_starting_elements(iter: I) -> Result, Er> where I: IntoIterator>, { let iter = iter.into_iter(); let mut to_collect = iter.size_hint().1.unwrap_or(BASE_COLLECT); if to_collect > MAX_COLLECT { to_collect = BASE_COLLECT; } let mut ret = Vec::with_capacity(to_collect); for el in iter.take(to_collect) { ret.push(el?); } Ok(ret) } roaring-0.10.2/src/bitmap/ops.rs000064400000000000000000000470001046102023000145600ustar 00000000000000use std::mem; use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; use retain_mut::RetainMut; use crate::bitmap::container::Container; use crate::bitmap::Pairs; use crate::RoaringBitmap; impl RoaringBitmap { /// Computes the len of the intersection with the specified other bitmap without creating a /// new bitmap. /// /// This is faster and more space efficient when you're only interested in the cardinality of /// the intersection. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let rb1: RoaringBitmap = (1..4).collect(); /// let rb2: RoaringBitmap = (3..5).collect(); /// /// /// assert_eq!(rb1.intersection_len(&rb2), (rb1 & rb2).len()); /// ``` pub fn intersection_len(&self, other: &RoaringBitmap) -> u64 { Pairs::new(&self.containers, &other.containers) .map(|pair| match pair { (Some(..), None) => 0, (None, Some(..)) => 0, (Some(lhs), Some(rhs)) => lhs.intersection_len(rhs), (None, None) => 0, }) .sum() } /// Computes the len of the union with the specified other bitmap without creating a new bitmap. /// /// This is faster and more space efficient when you're only interested in the cardinality of /// the union. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let rb1: RoaringBitmap = (1..4).collect(); /// let rb2: RoaringBitmap = (3..5).collect(); /// /// /// assert_eq!(rb1.union_len(&rb2), (rb1 | rb2).len()); /// ``` pub fn union_len(&self, other: &RoaringBitmap) -> u64 { self.len().wrapping_add(other.len()).wrapping_sub(self.intersection_len(other)) } /// Computes the len of the difference with the specified other bitmap without creating a new /// bitmap. /// /// This is faster and more space efficient when you're only interested in the cardinality of /// the difference. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let rb1: RoaringBitmap = (1..4).collect(); /// let rb2: RoaringBitmap = (3..5).collect(); /// /// /// assert_eq!(rb1.difference_len(&rb2), (rb1 - rb2).len()); /// ``` pub fn difference_len(&self, other: &RoaringBitmap) -> u64 { self.len() - self.intersection_len(other) } /// Computes the len of the symmetric difference with the specified other bitmap without /// creating a new bitmap. /// /// This is faster and more space efficient when you're only interested in the cardinality of /// the symmetric difference. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let rb1: RoaringBitmap = (1..4).collect(); /// let rb2: RoaringBitmap = (3..5).collect(); /// /// /// assert_eq!(rb1.symmetric_difference_len(&rb2), (rb1 ^ rb2).len()); /// ``` pub fn symmetric_difference_len(&self, other: &RoaringBitmap) -> u64 { let intersection_len = self.intersection_len(other); self.len() .wrapping_add(other.len()) .wrapping_sub(intersection_len) .wrapping_sub(intersection_len) } } impl BitOr for RoaringBitmap { type Output = RoaringBitmap; /// An `union` between two sets. fn bitor(mut self, rhs: RoaringBitmap) -> RoaringBitmap { BitOrAssign::bitor_assign(&mut self, rhs); self } } impl BitOr<&RoaringBitmap> for RoaringBitmap { type Output = RoaringBitmap; /// An `union` between two sets. fn bitor(mut self, rhs: &RoaringBitmap) -> RoaringBitmap { BitOrAssign::bitor_assign(&mut self, rhs); self } } impl BitOr for &RoaringBitmap { type Output = RoaringBitmap; /// An `union` between two sets. fn bitor(self, rhs: RoaringBitmap) -> RoaringBitmap { BitOr::bitor(rhs, self) } } impl BitOr<&RoaringBitmap> for &RoaringBitmap { type Output = RoaringBitmap; /// An `union` between two sets. fn bitor(self, rhs: &RoaringBitmap) -> RoaringBitmap { let mut containers = Vec::new(); for pair in Pairs::new(&self.containers, &rhs.containers) { match pair { (Some(lhs), None) => containers.push(lhs.clone()), (None, Some(rhs)) => containers.push(rhs.clone()), (Some(lhs), Some(rhs)) => containers.push(BitOr::bitor(lhs, rhs)), (None, None) => break, } } RoaringBitmap { containers } } } impl BitOrAssign for RoaringBitmap { /// An `union` between two sets. fn bitor_assign(&mut self, mut rhs: RoaringBitmap) { // We make sure that we apply the union operation on the biggest map. if self.len() < rhs.len() { mem::swap(self, &mut rhs); } for container in rhs.containers { let key = container.key; match self.containers.binary_search_by_key(&key, |c| c.key) { Err(loc) => self.containers.insert(loc, container), Ok(loc) => BitOrAssign::bitor_assign(&mut self.containers[loc], container), } } } } impl BitOrAssign<&RoaringBitmap> for RoaringBitmap { /// An `union` between two sets. fn bitor_assign(&mut self, rhs: &RoaringBitmap) { for container in &rhs.containers { let key = container.key; match self.containers.binary_search_by_key(&key, |c| c.key) { Err(loc) => self.containers.insert(loc, container.clone()), Ok(loc) => BitOrAssign::bitor_assign(&mut self.containers[loc], container), } } } } impl BitAnd for RoaringBitmap { type Output = RoaringBitmap; /// An `intersection` between two sets. fn bitand(mut self, rhs: RoaringBitmap) -> RoaringBitmap { BitAndAssign::bitand_assign(&mut self, rhs); self } } impl BitAnd<&RoaringBitmap> for RoaringBitmap { type Output = RoaringBitmap; /// An `intersection` between two sets. fn bitand(mut self, rhs: &RoaringBitmap) -> RoaringBitmap { BitAndAssign::bitand_assign(&mut self, rhs); self } } impl BitAnd for &RoaringBitmap { type Output = RoaringBitmap; /// An `intersection` between two sets. fn bitand(self, rhs: RoaringBitmap) -> RoaringBitmap { BitAnd::bitand(rhs, self) } } impl BitAnd<&RoaringBitmap> for &RoaringBitmap { type Output = RoaringBitmap; /// An `intersection` between two sets. fn bitand(self, rhs: &RoaringBitmap) -> RoaringBitmap { let mut containers = Vec::new(); for pair in Pairs::new(&self.containers, &rhs.containers) { if let (Some(lhs), Some(rhs)) = pair { let container = BitAnd::bitand(lhs, rhs); if container.len() != 0 { containers.push(container); } } } RoaringBitmap { containers } } } impl BitAndAssign for RoaringBitmap { /// An `intersection` between two sets. fn bitand_assign(&mut self, mut rhs: RoaringBitmap) { // We make sure that we apply the intersection operation on the smallest map. if rhs.containers.len() < self.containers.len() { mem::swap(self, &mut rhs); } RetainMut::retain_mut(&mut self.containers, |cont| { let key = cont.key; match rhs.containers.binary_search_by_key(&key, |c| c.key) { Ok(loc) => { let rhs_cont = &mut rhs.containers[loc]; let rhs_cont = mem::replace(rhs_cont, Container::new(rhs_cont.key)); BitAndAssign::bitand_assign(cont, rhs_cont); cont.len() != 0 } Err(_) => false, } }) } } impl BitAndAssign<&RoaringBitmap> for RoaringBitmap { /// An `intersection` between two sets. fn bitand_assign(&mut self, rhs: &RoaringBitmap) { RetainMut::retain_mut(&mut self.containers, |cont| { let key = cont.key; match rhs.containers.binary_search_by_key(&key, |c| c.key) { Ok(loc) => { BitAndAssign::bitand_assign(cont, &rhs.containers[loc]); cont.len() != 0 } Err(_) => false, } }) } } impl Sub for RoaringBitmap { type Output = RoaringBitmap; /// A `difference` between two sets. fn sub(mut self, rhs: RoaringBitmap) -> RoaringBitmap { SubAssign::sub_assign(&mut self, &rhs); self } } impl Sub<&RoaringBitmap> for RoaringBitmap { type Output = RoaringBitmap; /// A `difference` between two sets. fn sub(mut self, rhs: &RoaringBitmap) -> RoaringBitmap { SubAssign::sub_assign(&mut self, rhs); self } } impl Sub for &RoaringBitmap { type Output = RoaringBitmap; /// A `difference` between two sets. fn sub(self, rhs: RoaringBitmap) -> RoaringBitmap { Sub::sub(self, &rhs) } } impl Sub<&RoaringBitmap> for &RoaringBitmap { type Output = RoaringBitmap; /// A `difference` between two sets. fn sub(self, rhs: &RoaringBitmap) -> RoaringBitmap { let mut containers = Vec::new(); for pair in Pairs::new(&self.containers, &rhs.containers) { match pair { (Some(lhs), None) => containers.push(lhs.clone()), (None, Some(_)) => (), (Some(lhs), Some(rhs)) => { let container = Sub::sub(lhs, rhs); if container.len() != 0 { containers.push(container); } } (None, None) => break, } } RoaringBitmap { containers } } } impl SubAssign for RoaringBitmap { /// A `difference` between two sets. fn sub_assign(&mut self, rhs: RoaringBitmap) { SubAssign::sub_assign(self, &rhs) } } impl SubAssign<&RoaringBitmap> for RoaringBitmap { /// A `difference` between two sets. fn sub_assign(&mut self, rhs: &RoaringBitmap) { RetainMut::retain_mut(&mut self.containers, |cont| { match rhs.containers.binary_search_by_key(&cont.key, |c| c.key) { Ok(loc) => { SubAssign::sub_assign(cont, &rhs.containers[loc]); cont.len() != 0 } Err(_) => true, } }) } } impl BitXor for RoaringBitmap { type Output = RoaringBitmap; /// A `symmetric difference` between two sets. fn bitxor(mut self, rhs: RoaringBitmap) -> RoaringBitmap { BitXorAssign::bitxor_assign(&mut self, rhs); self } } impl BitXor<&RoaringBitmap> for RoaringBitmap { type Output = RoaringBitmap; /// A `symmetric difference` between two sets. fn bitxor(mut self, rhs: &RoaringBitmap) -> RoaringBitmap { BitXorAssign::bitxor_assign(&mut self, rhs); self } } impl BitXor for &RoaringBitmap { type Output = RoaringBitmap; /// A `symmetric difference` between two sets. fn bitxor(self, rhs: RoaringBitmap) -> RoaringBitmap { BitXor::bitxor(rhs, self) } } impl BitXor<&RoaringBitmap> for &RoaringBitmap { type Output = RoaringBitmap; /// A `symmetric difference` between two sets. fn bitxor(self, rhs: &RoaringBitmap) -> RoaringBitmap { let mut containers = Vec::new(); for pair in Pairs::new(&self.containers, &rhs.containers) { match pair { (Some(lhs), None) => containers.push(lhs.clone()), (None, Some(rhs)) => containers.push(rhs.clone()), (Some(lhs), Some(rhs)) => { let container = BitXor::bitxor(lhs, rhs); if container.len() != 0 { containers.push(container); } } (None, None) => break, } } RoaringBitmap { containers } } } impl BitXorAssign for RoaringBitmap { /// A `symmetric difference` between two sets. fn bitxor_assign(&mut self, rhs: RoaringBitmap) { for pair in Pairs::new(mem::take(&mut self.containers), rhs.containers) { match pair { (Some(mut lhs), Some(rhs)) => { BitXorAssign::bitxor_assign(&mut lhs, rhs); if lhs.len() != 0 { self.containers.push(lhs); } } (Some(lhs), None) => self.containers.push(lhs), (None, Some(rhs)) => self.containers.push(rhs), (None, None) => break, } } } } impl BitXorAssign<&RoaringBitmap> for RoaringBitmap { /// A `symmetric difference` between two sets. fn bitxor_assign(&mut self, rhs: &RoaringBitmap) { for pair in Pairs::new(mem::take(&mut self.containers), &rhs.containers) { match pair { (Some(mut lhs), Some(rhs)) => { BitXorAssign::bitxor_assign(&mut lhs, rhs); if lhs.len() != 0 { self.containers.push(lhs); } } (Some(lhs), None) => self.containers.push(lhs), (None, Some(rhs)) => self.containers.push(rhs.clone()), (None, None) => break, } } } } #[cfg(test)] mod test { use crate::{MultiOps, RoaringBitmap}; use proptest::prelude::*; use std::convert::Infallible; // fast count tests proptest! { #[test] fn union_len_eq_len_of_materialized_union( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary() ) { prop_assert_eq!(a.union_len(&b), (a | b).len()); } #[test] fn intersection_len_eq_len_of_materialized_intersection( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary() ) { prop_assert_eq!(a.intersection_len(&b), (a & b).len()); } #[test] fn difference_len_eq_len_of_materialized_difference( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary() ) { prop_assert_eq!(a.difference_len(&b), (a - b).len()); } #[test] fn symmetric_difference_len_eq_len_of_materialized_symmetric_difference( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary() ) { prop_assert_eq!(a.symmetric_difference_len(&b), (a ^ b).len()); } #[test] fn all_union_give_the_same_result( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary(), c in RoaringBitmap::arbitrary() ) { let mut ref_assign = a.clone(); ref_assign |= &b; ref_assign |= &c; let mut own_assign = a.clone(); own_assign |= b.clone(); own_assign |= c.clone(); let ref_inline = &a | &b | &c; let own_inline = a.clone() | b.clone() | c.clone(); let ref_multiop = [&a, &b, &c].union(); let own_multiop = [a.clone(), b.clone(), c.clone()].union(); let ref_multiop_try = [&a, &b, &c].map(Ok::<_, Infallible>).union().unwrap(); let own_multiop_try = [a, b, c].map(Ok::<_, Infallible>).union().unwrap(); for roar in &[ own_assign, ref_inline, own_inline, ref_multiop, own_multiop, ref_multiop_try, own_multiop_try, ] { prop_assert_eq!(&ref_assign, roar); } } #[test] fn all_intersection_give_the_same_result( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary(), c in RoaringBitmap::arbitrary() ) { let mut ref_assign = a.clone(); ref_assign &= &b; ref_assign &= &c; let mut own_assign = a.clone(); own_assign &= b.clone(); own_assign &= c.clone(); let ref_inline = &a & &b & &c; let own_inline = a.clone() & b.clone() & c.clone(); let ref_multiop = [&a, &b, &c].intersection(); let own_multiop = [a.clone(), b.clone(), c.clone()].intersection(); let ref_multiop_try = [&a, &b, &c].map(Ok::<_, Infallible>).intersection().unwrap(); let own_multiop_try = [a, b, c].map(Ok::<_, Infallible>).intersection().unwrap(); for roar in &[ own_assign, ref_inline, own_inline, ref_multiop, own_multiop, ref_multiop_try, own_multiop_try, ] { prop_assert_eq!(&ref_assign, roar); } } #[test] fn all_difference_give_the_same_result( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary(), c in RoaringBitmap::arbitrary() ) { let mut ref_assign = a.clone(); ref_assign -= &b; ref_assign -= &c; let mut own_assign = a.clone(); own_assign -= b.clone(); own_assign -= c.clone(); let ref_inline = &a - &b - &c; let own_inline = a.clone() - b.clone() - c.clone(); let ref_multiop = [&a, &b, &c].difference(); let own_multiop = [a.clone(), b.clone(), c.clone()].difference(); let ref_multiop_try = [&a, &b, &c].map(Ok::<_, Infallible>).difference().unwrap(); let own_multiop_try = [a, b, c].map(Ok::<_, Infallible>).difference().unwrap(); for roar in &[ own_assign, ref_inline, own_inline, ref_multiop, own_multiop, ref_multiop_try, own_multiop_try, ] { prop_assert_eq!(&ref_assign, roar); } } #[test] fn all_symmetric_difference_give_the_same_result( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary(), c in RoaringBitmap::arbitrary() ) { let mut ref_assign = a.clone(); ref_assign ^= &b; ref_assign ^= &c; let mut own_assign = a.clone(); own_assign ^= b.clone(); own_assign ^= c.clone(); let ref_inline = &a ^ &b ^ &c; let own_inline = a.clone() ^ b.clone() ^ c.clone(); let ref_multiop = [&a, &b, &c].symmetric_difference(); let own_multiop = [a.clone(), b.clone(), c.clone()].symmetric_difference(); let ref_multiop_try = [&a, &b, &c] .map(Ok::<_, Infallible>) .symmetric_difference() .unwrap(); let own_multiop_try = [a, b, c] .map(Ok::<_, Infallible>) .symmetric_difference() .unwrap(); for roar in &[ own_assign, ref_inline, own_inline, ref_multiop, own_multiop, ref_multiop_try, own_multiop_try, ] { prop_assert_eq!(&ref_assign, roar); } } } } roaring-0.10.2/src/bitmap/proptests.rs000064400000000000000000000655041046102023000160330ustar 00000000000000#[cfg(test)] #[allow(clippy::eq_op)] // Allow equal expressions as operands mod test { use crate::RoaringBitmap; use proptest::prelude::*; // // Tests algebraic set properties in terms of RoaringBitmaps. // Follows wikipedia article regarding ordering and heading // // https://en.wikipedia.org/wiki/Algebra_of_sets // // Notes: // // * Although a universe set exists, we leave properties involving it it out of these tests. // It would be ~512 MiB and operations on it would be relatively slow // // * Likewise, there is no compliment operator // // // // // The fundamental properties of set algebra // ========================================= // // Commutative property: // -------------------- proptest! { #[test] fn unions_are_commutative( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary() ) { prop_assert_eq!(&a | &b, &b | &a); { // op_assign_ref let mut x = a.clone(); let mut y = b.clone(); x |= &b; y |= &a; prop_assert_eq!(x, y); } { // op_assign_own let mut x = a.clone(); let mut y = b.clone(); x |= b; y |= a; prop_assert_eq!(x, y); } } #[test] fn intersections_are_commutative( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary() ) { prop_assert_eq!(&a & &b, &b & &a); { // op_assign_ref let mut x = a.clone(); let mut y = b.clone(); x &= &b; y &= &a; prop_assert_eq!(x, y); } { // op_assign_own let mut x = a.clone(); let mut y = b.clone(); x &= b; y &= a; prop_assert_eq!(x, y); } } #[test] fn symmetric_differences_are_commutative( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary() ) { prop_assert_eq!(&a ^ &b, &b ^ &a); { // op_assign_ref let mut x = a.clone(); let mut y = b.clone(); x ^= &b; y ^= &a; prop_assert_eq!(x, y); } { // op_assign_own let mut x = a.clone(); let mut y = b.clone(); x ^= b; y ^= a; prop_assert_eq!(x, y); } } } // // Associative property: // --------------------- proptest! { #[test] fn unions_are_associative( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary(), c in RoaringBitmap::arbitrary() ) { prop_assert_eq!( &a | ( &b | &c ), ( &a | &b ) | &c ); { // op_assign_ref let mut x = b.clone(); x |= &c; x |= &a; let mut y = a.clone(); y |= &b; y |= &c; prop_assert_eq!(x, y); } { // op_assign_own let mut x = b.clone(); x |= c.clone(); x |= a.clone(); let mut y = a; y |= b; y |= c; prop_assert_eq!(x, y); } } #[test] fn intersections_are_associative( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary(), c in RoaringBitmap::arbitrary() ) { prop_assert_eq!( &a & ( &b & &c ), ( &a & &b ) & &c ); { // op_assign_ref let mut x = b.clone(); x &= &c; x &= &a; let mut y = a.clone(); y &= &b; y &= &c; prop_assert_eq!(x, y); } { // op_assign_own let mut x = b.clone(); x &= c.clone(); x &= a.clone(); let mut y = a; y &= b; y &= c; prop_assert_eq!(x, y); } } #[test] fn symmetric_differences_are_associative( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary(), c in RoaringBitmap::arbitrary() ) { prop_assert_eq!( &a ^ ( &b ^ &c ), ( &a ^ &b ) ^ &c ); { // op_assign_ref let mut x = b.clone(); x ^= &c; x ^= &a; let mut y = a.clone(); y ^= &b; y ^= &c; prop_assert_eq!(x, y); } { // op_assign_own let mut x = b.clone(); x ^= c.clone(); x ^= a.clone(); let mut y = a; y ^= b; y ^= c; prop_assert_eq!(x, y); } } } // // Distributive property: // --------------------- proptest! { #[test] fn union_distributes_over_intersection( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary(), c in RoaringBitmap::arbitrary() ) { prop_assert_eq!( &a | ( &b & &c), ( &a | &b ) & ( &a | &c ) ); { // op_assign_ref let mut x = b.clone(); x &= &c; x |= &a; let y = { let mut ab = a.clone(); ab |= &b; let mut ac = a.clone(); ac |= &c; ab &= ∾ ab }; prop_assert_eq!(x, y); } { // op_assign_own let mut x = b.clone(); x &= c.clone(); x |= a.clone(); let y = { let mut ab = a.clone(); ab |= b; let mut ac = a; ac |= c; // moves the owned ac on the rhs ab &= ac; ab }; prop_assert_eq!(x, y); } } #[test] fn intersection_distributes_over_union( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary(), c in RoaringBitmap::arbitrary() ) { prop_assert_eq!( &a & ( &b | &c), ( &a & &b ) | ( &a & &c ) ); { // op_assign_ref let mut x = b.clone(); x |= &c; x &= &a; let y = { let mut ab = a.clone(); ab &= &b; let mut ac = a.clone(); ac &= &c; ab |= ∾ ab }; prop_assert_eq!(x, y); } { // op_assign_own let mut x = b.clone(); x |= c.clone(); x &= a.clone(); let y = { let mut ab = a.clone(); ab &= b; let mut ac = a; ac &= c; // moves the owned ac on the rhs ab |= ac; ab }; prop_assert_eq!(x, y); } } #[test] fn intersection_distributes_over_symmetric_difference( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary(), c in RoaringBitmap::arbitrary() ) { prop_assert_eq!( &a & ( &b ^ &c), ( &a & &b ) ^ ( &a & &c ) ); { // op_assign_ref let mut x = b.clone(); x ^= &c; x &= &a; let y = { let mut ab = a.clone(); ab &= &b; let mut ac = a.clone(); ac &= &c; ab ^= ∾ ab }; prop_assert_eq!(x, y); } { // op_assign_own let mut x = b.clone(); x ^= c.clone(); x &= a.clone(); let y = { let mut ab = a.clone(); ab &= b; let mut ac = a; ac &= c; // moves the owned ac on the rhs ab ^= ac; ab }; prop_assert_eq!(x, y); } } } // Identity: // -------- proptest! { #[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(); prop_assert_eq!(x, a.clone()); } { // op_assign_own let mut x = a.clone(); // empty_set() returns an owned empty set x |= empty_set(); prop_assert_eq!(x, a); } } #[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(); prop_assert_eq!(x, a.clone()); } { // op_assign_own let mut x = a.clone(); // empty_set() returns an owned empty set x ^= empty_set(); prop_assert_eq!(x, a); } } } // Some additional laws for unions and intersections // ================================================= // // PROPOSITION 3: For any subsets A and B of a universe set U, the following identities hold: // // Idempotent laws // --------------- proptest! { #[test] fn unions_are_idempotent(a in RoaringBitmap::arbitrary()) { prop_assert_eq!(&(&a | &a), &a); { // op_assign_ref let mut x = a.clone(); x |= &a; prop_assert_eq!(x, a.clone()); } { // op_assign_own let mut x = a.clone(); x |= a.clone(); prop_assert_eq!(x, a); } } #[test] fn intersections_are_idempotent(a in RoaringBitmap::arbitrary()) { prop_assert_eq!(&(&a & &a), &a); { // op_assign_ref let mut x = a.clone(); x &= &a; prop_assert_eq!(x, a.clone()); } { // op_assign_own let mut x = a.clone(); x &= a.clone(); prop_assert_eq!(x, a); } } } // // Domination laws // --------------- proptest! { #[test] fn empty_set_domination(a in RoaringBitmap::arbitrary()) { prop_assert_eq!(&a & &empty_set(), empty_set()); { // op_assign_ref let mut x = a.clone(); x &= &empty_set(); prop_assert_eq!(x, empty_set()); } { // op_assign_own let mut x = a; x &= empty_set(); prop_assert_eq!(x, empty_set()); } } } // The algebra of inclusion // ======================== // PROPOSITION 6: If A, B and C are sets then the following hold: // // Note that for inclusion we do not also assert for the assignment operators // Inclusion is the property under test, not the set operation proptest! { #[test] fn reflexivity(a in RoaringBitmap::arbitrary()) { prop_assert!(a.is_subset(&a)); } #[test] fn antisymmetry(a in RoaringBitmap::arbitrary()) { let mut b = a.clone(); prop_assert_eq!(&a, &b); prop_assert!(a.is_subset(&b) && b.is_subset(&a)); // Flip one bit let mut c = RoaringBitmap::new(); c.insert(0); b ^= c; prop_assert_ne!(&a, &b); prop_assert!(!(a.is_subset(&b) && b.is_subset(&a))); } #[test] fn transitivity( a in RoaringBitmap::arbitrary(), mut b in RoaringBitmap::arbitrary(), mut c in RoaringBitmap::arbitrary() ) { b |= &a; c |= &b; // If prop_assert!(a.is_subset(&b)); prop_assert!(b.is_subset(&c)); // Then prop_assert!(a.is_subset(&c)); } } // PROPOSITION 7: If A, B and C are subsets of a set S then the following hold: proptest! { #[test] fn existence_of_joins(a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary()) { prop_assert!(a.is_subset(&(&a | &b))); } #[test] fn existence_of_meets(a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary()) { prop_assert!(&(&a & &b).is_subset(&a)); } } // PROPOSITION 8: For any two sets A and B, the following are equivalent: proptest! { #[test] fn inclusion_can_be_characterized_by_union_or_inersection( b in RoaringBitmap::arbitrary(), c in RoaringBitmap::arbitrary() ) { let a = &b - &c; prop_assert!(a.is_subset(&b)); prop_assert_eq!(&(&a & &b), &a); prop_assert_eq!(&(&a | &b), &b); prop_assert_eq!(&(&a - &b), &empty_set()); } } // The algebra of relative complements // =================================== // // PROPOSITION 9: For any universe U and subsets A, B, and C of U, // the following identities hold: // Note: I dont have good names for these identities. If somebody could give them good names // and split each triplet of ref-ref, owned-ref, and owned-owned into a separate test: // I will happily buy them a very large but finite number of beers. proptest! { #[test] fn relative_compliments( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary(), c in RoaringBitmap::arbitrary() ) { let u = &a | &b | &c; prop_assert_eq!( &c - (&a & &b), (&c - &a) | (&c - &b) ); { // op assign ref let mut a_and_b = a.clone(); a_and_b &= &b; let mut c_sub_a = c.clone(); c_sub_a -= &a; let mut c_sub_b = c.clone(); c_sub_b -= &b; let mut x = c.clone(); x -= &a_and_b; let mut y = c_sub_a; y |= &c_sub_b; prop_assert_eq!(x, y); } { // op assign own let mut a_and_b = a.clone(); a_and_b &= b.clone(); let mut c_sub_a = c.clone(); c_sub_a -= a.clone(); let mut c_sub_b = c.clone(); c_sub_b -= b.clone(); let mut x = c.clone(); x -= a_and_b; let mut y = c_sub_a; y |= c_sub_b; prop_assert_eq!(x, y); } prop_assert_eq!( &c - (&a | &b), (&c - &a) & (&c - &b) ); { // op assign ref let mut a_or_b = a.clone(); a_or_b |= &b; let mut c_sub_a = c.clone(); c_sub_a -= &a; let mut c_sub_b = c.clone(); c_sub_b -= &b; let mut x = c.clone(); x -= &a_or_b; let mut y = c_sub_a; y &= &c_sub_b; prop_assert_eq!(x, y); } { // op assign own let mut a_or_b = a.clone(); a_or_b |= b.clone(); let mut c_sub_a = c.clone(); c_sub_a -= a.clone(); let mut c_sub_b = c.clone(); c_sub_b -= b.clone(); let mut x = c.clone(); x -= a_or_b; let mut y = c_sub_a; y &= c_sub_b; prop_assert_eq!(x, y); } prop_assert_eq!( &c - (&b - &a), (&a & &c) | (&c - &b) ); { // op assign ref let mut b_sub_a = b.clone(); b_sub_a -= &b; let mut a_and_c = c.clone(); a_and_c &= &c; let mut c_sub_b = c.clone(); c_sub_b -= &b; let mut x = c.clone(); x -= &b_sub_a; let mut y = a_and_c; y |= &c_sub_b; prop_assert_eq!(x, y); } { // op assign own let mut b_sub_a = b.clone(); b_sub_a -= b.clone(); let mut a_and_c = c.clone(); a_and_c &= c.clone(); let mut c_sub_b = c.clone(); c_sub_b -= b.clone(); let mut x = c.clone(); x -= b_sub_a; let mut y = a_and_c; y |= c_sub_b; prop_assert_eq!(x, y); } { let x = (&b - &a) & &c; let y = (&b & &c) - &a; let z = &b & (&c - &a); prop_assert_eq!(&x, &y); prop_assert_eq!(&y, &z); prop_assert_eq!(&z, &x); } { // op assign ref let mut b_sub_a = b.clone(); b_sub_a -= &a; let mut b_and_c = b.clone(); b_and_c &= &c; let mut c_sub_a = c.clone(); c_sub_a -= &a; let mut x = b_sub_a; x &= &c; let mut y = b_and_c; y -= &a; let mut z = c_sub_a; z &= &b; prop_assert_eq!(&x, &y); prop_assert_eq!(&y, &z); prop_assert_eq!(&z, &x); } { // op assign own let mut b_sub_a = b.clone(); b_sub_a -= a.clone(); let mut b_and_c = b.clone(); b_and_c &= c.clone(); let mut c_sub_a = c.clone(); c_sub_a -= a.clone(); let mut x = b_sub_a; x &= c.clone(); let mut y = b_and_c; y -= a.clone(); let mut z = c_sub_a; z &= b.clone(); prop_assert_eq!(&x, &y); prop_assert_eq!(&y, &z); prop_assert_eq!(&z, &x); } prop_assert_eq!( (&b - &a) | &c, (&b | &c) - (&a - &c) ); { // op assign ref let mut b_sub_a = b.clone(); b_sub_a -= &a; let mut b_or_c = b.clone(); b_or_c |= &c; let mut a_sub_c = a.clone(); a_sub_c -= &c; let mut x = b_sub_a; x |= &c; let mut y = b_or_c; y -= &a_sub_c; prop_assert_eq!(x, y); } { // op assign own let mut b_sub_a = b.clone(); b_sub_a -= a.clone(); let mut b_or_c = b.clone(); b_or_c |= c.clone(); let mut a_sub_c = a.clone(); a_sub_c -= c.clone(); let mut x = b_sub_a; x |= c.clone(); let mut y = b_or_c; y -= a_sub_c; prop_assert_eq!(x, y); } prop_assert_eq!( (&b - &a) - &c, &b - (&a | &c) ); { // op assign ref let mut b_sub_a = b.clone(); b_sub_a -= &a; let mut a_or_c = a.clone(); a_or_c |= &c; let mut x = b_sub_a; x -= &c; let mut y = b.clone(); y -= &a_or_c; prop_assert_eq!(x, y); } { // op assign ref let mut b_sub_a = b.clone(); b_sub_a -= a.clone(); let mut a_or_c = a.clone(); a_or_c |= c.clone(); let mut x = b_sub_a; x -= c; let mut y = b; y -= a_or_c; prop_assert_eq!(x, y); } prop_assert_eq!( &a - &a, empty_set() ); { // op assign ref let mut x = a.clone(); x -= &a; prop_assert_eq!(x, empty_set()); } { // op assign own let mut x = a.clone(); x -= a.clone(); prop_assert_eq!(x, empty_set()); } prop_assert_eq!( empty_set() - &a, empty_set() ); { // op assign ref let mut x = empty_set(); x -= &a; prop_assert_eq!(x, empty_set()); } { // op assign own let mut x = empty_set(); x -= a.clone(); prop_assert_eq!(x, empty_set()); } prop_assert_eq!( &a - &u, empty_set() ); { // op assign ref let mut x = a.clone(); x -= &u; prop_assert_eq!(x, empty_set()); } { // op assign own let mut x = a; x -= u; prop_assert_eq!(x, empty_set()); } } } // Additional properties of symmetric differences // ============================================== // proptest! { #[test] fn symmetric_difference_triangle_inequality( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary(), c in RoaringBitmap::arbitrary() ) { prop_assert_eq!( &((&a ^ &b) ^ (&b ^ &c)), &(&a ^ &c) ); { // op assign ref let mut a_xor_b = a.clone(); a_xor_b ^= &b; let mut b_xor_c = b.clone(); b_xor_c ^= &c; let mut a_xor_c = a.clone(); a_xor_c ^= &c; let mut tri = a_xor_b; tri ^= &b_xor_c; prop_assert_eq!(tri, a_xor_c); } { // op assign own let mut a_xor_b = a.clone(); a_xor_b ^= b.clone(); let mut b_xor_c = b; b_xor_c ^= c.clone(); let mut a_xor_c = a; a_xor_c ^= c; let mut tri = a_xor_b; tri ^= b_xor_c; prop_assert_eq!(tri, a_xor_c); } } #[test] fn symmetric_difference_empty_set_neutral( a in RoaringBitmap::arbitrary() ) { prop_assert_eq!( &(&a ^ &empty_set()), &a ); { // op assign ref let mut x = a.clone(); x ^= &empty_set(); prop_assert_eq!(&x, &a); } { // op assign own let mut x = a.clone(); x ^= empty_set(); prop_assert_eq!(x, a); } } #[test] fn symmetric_difference_inverse_of_itself( a in RoaringBitmap::arbitrary() ) { prop_assert_eq!( &(&a ^ &a), &empty_set() ); { // op assign ref let mut x = a.clone(); x ^= &a; prop_assert_eq!(&x, &empty_set()); } { // op assign own let mut x = a.clone(); x ^= a; prop_assert_eq!(x, empty_set()); } } #[test] fn symmetric_difference_relative_compliments( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary() ) { prop_assert_eq!( &(&a ^ &b), &(&(&a - &b) | &(&b - &a)) ); { // op assign ref let mut x = a.clone(); x ^= &b; let mut a_sub_b = a.clone(); a_sub_b -= &b; let mut b_sub_a = b.clone(); b_sub_a -= &a; let mut y = a_sub_b; y |= &b_sub_a; prop_assert_eq!(x, y); } { // op assign own let mut x = a.clone(); x ^= b.clone(); let mut a_sub_b = a.clone(); a_sub_b -= b.clone(); let mut b_sub_a = b.clone(); b_sub_a -= a.clone(); let mut y = a_sub_b; y |= b_sub_a; prop_assert_eq!(x, y); } prop_assert_eq!( &(&a ^ &b), &(&(&a | &b) - &(&a & &b)) ); { // op assign ref let mut x = a.clone(); x ^= &b; let mut a_or_b = a.clone(); a_or_b |= &b; let mut a_and_b = a.clone(); a_and_b &= &b; let mut y = a_or_b; y -= &a_and_b; prop_assert_eq!(x, y); } { // op assign own let mut x = a.clone(); x ^= b.clone(); let mut a_or_b = a.clone(); a_or_b |= b.clone(); let mut a_and_b = a; a_and_b &= b; let mut y = a_or_b; y -= a_and_b; prop_assert_eq!(x, y); } } } fn empty_set() -> RoaringBitmap { RoaringBitmap::new() } } roaring-0.10.2/src/bitmap/serde.rs000064400000000000000000000045541046102023000150700ustar 00000000000000use serde::de::SeqAccess; use serde::de::Visitor; use serde::Deserialize; use serde::Deserializer; use serde::Serialize; use crate::RoaringBitmap; impl<'de> Deserialize<'de> for RoaringBitmap { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { struct BitmapVisitor; impl<'de> Visitor<'de> for BitmapVisitor { type Value = RoaringBitmap; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("roaring bitmap") } fn visit_bytes(self, bytes: &[u8]) -> Result where E: serde::de::Error, { RoaringBitmap::deserialize_from(bytes).map_err(serde::de::Error::custom) } // in some case bytes will be serialized as a sequence thus we need to accept both // even if it means non optimal performance fn visit_seq(self, mut seq: A) -> Result where A: SeqAccess<'de>, { let mut bytes: Vec = Vec::new(); while let Some(el) = seq.next_element()? { bytes.push(el); } RoaringBitmap::deserialize_from(&*bytes).map_err(serde::de::Error::custom) } } deserializer.deserialize_bytes(BitmapVisitor) } } impl Serialize for RoaringBitmap { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { let mut buf = Vec::new(); self.serialize_into(&mut buf).map_err(serde::ser::Error::custom)?; serializer.serialize_bytes(&buf) } } #[cfg(test)] mod test { use crate::RoaringBitmap; use proptest::prelude::*; proptest! { #[test] fn test_serde_json( bitmap in RoaringBitmap::arbitrary(), ) { let json = serde_json::to_vec(&bitmap).unwrap(); prop_assert_eq!(bitmap, serde_json::from_slice(&json).unwrap()); } #[test] fn test_bincode( bitmap in RoaringBitmap::arbitrary(), ) { let buffer = bincode::serialize(&bitmap).unwrap(); prop_assert_eq!(bitmap, bincode::deserialize(&buffer).unwrap()); } } } roaring-0.10.2/src/bitmap/serialization.rs000064400000000000000000000234701046102023000166410ustar 00000000000000use bytemuck::cast_slice_mut; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use std::convert::{Infallible, TryFrom}; use std::error::Error; use std::io; use std::ops::RangeInclusive; use crate::bitmap::container::{Container, ARRAY_LIMIT}; use crate::bitmap::store::{ArrayStore, BitmapStore, Store, BITMAP_LENGTH}; use crate::RoaringBitmap; const SERIAL_COOKIE_NO_RUNCONTAINER: u32 = 12346; const SERIAL_COOKIE: u16 = 12347; const NO_OFFSET_THRESHOLD: usize = 4; // Sizes of header structures const DESCRIPTION_BYTES: usize = 4; const OFFSET_BYTES: usize = 4; impl RoaringBitmap { /// Return the size in bytes of the serialized output. /// This is compatible with the official C/C++, Java and Go implementations. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let rb1: RoaringBitmap = (1..4).collect(); /// let mut bytes = Vec::with_capacity(rb1.serialized_size()); /// rb1.serialize_into(&mut bytes).unwrap(); /// let rb2 = RoaringBitmap::deserialize_from(&bytes[..]).unwrap(); /// /// assert_eq!(rb1, rb2); /// ``` pub fn serialized_size(&self) -> usize { let container_sizes: usize = self .containers .iter() .map(|container| match container.store { Store::Array(ref values) => 8 + values.len() as usize * 2, Store::Bitmap(..) => 8 + 8 * 1024, }) .sum(); // header + container sizes 8 + container_sizes } /// Serialize this bitmap into [the standard Roaring on-disk format][format]. /// This is compatible with the official C/C++, Java and Go implementations. /// /// [format]: https://github.com/RoaringBitmap/RoaringFormatSpec /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let rb1: RoaringBitmap = (1..4).collect(); /// let mut bytes = vec![]; /// rb1.serialize_into(&mut bytes).unwrap(); /// let rb2 = RoaringBitmap::deserialize_from(&bytes[..]).unwrap(); /// /// assert_eq!(rb1, rb2); /// ``` pub fn serialize_into(&self, mut writer: W) -> io::Result<()> { writer.write_u32::(SERIAL_COOKIE_NO_RUNCONTAINER)?; writer.write_u32::(self.containers.len() as u32)?; for container in &self.containers { writer.write_u16::(container.key)?; writer.write_u16::((container.len() - 1) as u16)?; } let mut offset = 8 + 8 * self.containers.len() as u32; for container in &self.containers { writer.write_u32::(offset)?; match container.store { Store::Array(ref values) => { offset += values.len() as u32 * 2; } Store::Bitmap(..) => { offset += 8 * 1024; } } } for container in &self.containers { match container.store { Store::Array(ref values) => { for &value in values.iter() { writer.write_u16::(value)?; } } Store::Bitmap(ref bits) => { for &value in bits.as_array() { writer.write_u64::(value)?; } } } } Ok(()) } /// Deserialize a bitmap into memory from [the standard Roaring on-disk /// format][format]. This is compatible with the official C/C++, Java and /// Go implementations. This method checks that all of the internal values /// are valid. If deserializing from a trusted source consider /// [RoaringBitmap::deserialize_unchecked_from] /// /// [format]: https://github.com/RoaringBitmap/RoaringFormatSpec /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let rb1: RoaringBitmap = (1..4).collect(); /// let mut bytes = vec![]; /// rb1.serialize_into(&mut bytes).unwrap(); /// let rb2 = RoaringBitmap::deserialize_from(&bytes[..]).unwrap(); /// /// assert_eq!(rb1, rb2); /// ``` pub fn deserialize_from(reader: R) -> io::Result { RoaringBitmap::deserialize_from_impl(reader, ArrayStore::try_from, BitmapStore::try_from) } /// Deserialize a bitmap into memory from [the standard Roaring on-disk /// format][format]. This is compatible with the official C/C++, Java and /// Go implementations. This method is memory safe but will not check if /// the data is a valid bitmap. /// /// [format]: https://github.com/RoaringBitmap/RoaringFormatSpec /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let rb1: RoaringBitmap = (1..4).collect(); /// let mut bytes = vec![]; /// rb1.serialize_into(&mut bytes).unwrap(); /// let rb2 = RoaringBitmap::deserialize_unchecked_from(&bytes[..]).unwrap(); /// /// assert_eq!(rb1, rb2); /// ``` pub fn deserialize_unchecked_from(reader: R) -> io::Result { RoaringBitmap::deserialize_from_impl::( reader, |values| Ok(ArrayStore::from_vec_unchecked(values)), |len, values| Ok(BitmapStore::from_unchecked(len, values)), ) } fn deserialize_from_impl( mut reader: R, a: A, b: B, ) -> io::Result where R: io::Read, A: Fn(Vec) -> Result, AErr: Error + Send + Sync + 'static, B: Fn(u64, Box<[u64; 1024]>) -> Result, BErr: Error + Send + Sync + 'static, { // First read the cookie to determine which version of the format we are reading let (size, has_offsets, has_run_containers) = { let cookie = reader.read_u32::()?; if cookie == SERIAL_COOKIE_NO_RUNCONTAINER { (reader.read_u32::()? as usize, true, false) } else if (cookie as u16) == SERIAL_COOKIE { let size = ((cookie >> 16) + 1) as usize; (size, size >= NO_OFFSET_THRESHOLD, true) } else { return Err(io::Error::new(io::ErrorKind::Other, "unknown cookie value")); } }; // Read the run container bitmap if necessary let run_container_bitmap = if has_run_containers { let mut bitmap = vec![0u8; (size + 7) / 8]; reader.read_exact(&mut bitmap)?; Some(bitmap) } else { None }; if size > u16::MAX as usize + 1 { return Err(io::Error::new(io::ErrorKind::Other, "size is greater than supported")); } // Read the container descriptions let mut description_bytes = vec![0u8; size * DESCRIPTION_BYTES]; reader.read_exact(&mut description_bytes)?; let mut description_bytes = &description_bytes[..]; if has_offsets { let mut offsets = vec![0u8; size * OFFSET_BYTES]; reader.read_exact(&mut offsets)?; drop(offsets); // Not useful when deserializing into memory } let mut containers = Vec::with_capacity(size); // Read each container for i in 0..size { let key = description_bytes.read_u16::()?; let cardinality = u64::from(description_bytes.read_u16::()?) + 1; // If the run container bitmap is present, check if this container is a run container let is_run_container = run_container_bitmap.as_ref().map_or(false, |bm| bm[i / 8] & (1 << (i % 8)) != 0); let store = if is_run_container { let runs = reader.read_u16::()?; let mut intervals = vec![[0, 0]; runs as usize]; reader.read_exact(cast_slice_mut(&mut intervals))?; intervals.iter_mut().for_each(|[s, len]| { *s = u16::from_le(*s); *len = u16::from_le(*len); }); let cardinality = intervals.iter().map(|[_, len]| *len as usize).sum(); let mut store = Store::with_capacity(cardinality); intervals.into_iter().for_each(|[s, len]| { store.insert_range(RangeInclusive::new(s, s + len)); }); store } else if cardinality <= ARRAY_LIMIT { let mut values = vec![0; cardinality as usize]; reader.read_exact(cast_slice_mut(&mut values))?; values.iter_mut().for_each(|n| *n = u16::from_le(*n)); let array = a(values).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; Store::Array(array) } else { let mut values = Box::new([0; BITMAP_LENGTH]); reader.read_exact(cast_slice_mut(&mut values[..]))?; values.iter_mut().for_each(|n| *n = u64::from_le(*n)); let bitmap = b(cardinality, values) .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; Store::Bitmap(bitmap) }; containers.push(Container { key, store }); } Ok(RoaringBitmap { containers }) } } #[cfg(test)] mod test { use crate::RoaringBitmap; use proptest::prelude::*; proptest! { #[test] fn test_serialization( bitmap in RoaringBitmap::arbitrary(), ) { let mut buffer = Vec::new(); bitmap.serialize_into(&mut buffer).unwrap(); prop_assert_eq!(bitmap, RoaringBitmap::deserialize_from(buffer.as_slice()).unwrap()); } } } roaring-0.10.2/src/bitmap/store/array_store/mod.rs000064400000000000000000000434321046102023000202310ustar 00000000000000mod scalar; mod vector; mod visitor; use crate::bitmap::store::array_store::visitor::{CardinalityCounter, VecWriter}; use std::cmp::Ordering; use std::cmp::Ordering::*; use std::convert::{TryFrom, TryInto}; use std::fmt::{Display, Formatter}; use std::ops::{BitAnd, BitAndAssign, BitOr, BitXor, RangeInclusive, Sub, SubAssign}; use super::bitmap_store::{bit, key, BitmapStore, BITMAP_LENGTH}; #[derive(Clone, Eq, PartialEq)] pub struct ArrayStore { vec: Vec, } impl ArrayStore { pub fn new() -> ArrayStore { ArrayStore { vec: vec![] } } pub fn with_capacity(capacity: usize) -> ArrayStore { ArrayStore { vec: Vec::with_capacity(capacity) } } /// /// Create a new SortedU16Vec from a given vec /// It is up to the caller to ensure the vec is sorted and deduplicated /// Favor `try_from` / `try_into` for cases in which these invariants should be checked /// /// # Panics /// /// When debug_assertions are enabled and the above invariants are not met #[inline] pub fn from_vec_unchecked(vec: Vec) -> ArrayStore { if cfg!(debug_assertions) { vec.try_into().unwrap() } else { ArrayStore { vec } } } pub fn insert(&mut self, index: u16) -> bool { self.vec.binary_search(&index).map_err(|loc| self.vec.insert(loc, index)).is_err() } pub fn insert_range(&mut self, range: RangeInclusive) -> u64 { let start = *range.start(); let end = *range.end(); // Figure out the starting/ending position in the vec. let pos_start = self.vec.binary_search(&start).unwrap_or_else(|x| x); let pos_end = pos_start + match self.vec[pos_start..].binary_search(&end) { Ok(x) => x + 1, Err(x) => x, }; // Overwrite the range in the middle - there's no need to take // into account any existing elements between start and end, as // they're all being added to the set. let dropped = self.vec.splice(pos_start..pos_end, start..=end); end as u64 - start as u64 + 1 - dropped.len() as u64 } pub fn push(&mut self, index: u16) -> bool { if self.max().map_or(true, |max| max < index) { self.vec.push(index); true } else { false } } /// /// Pushes `index` at the end of the store. /// It is up to the caller to have validated index > self.max() /// /// # Panics /// /// If debug_assertions enabled and index is > self.max() pub(crate) fn push_unchecked(&mut self, index: u16) { if cfg!(debug_assertions) { if let Some(max) = self.max() { assert!(index > max, "store max >= index") } } self.vec.push(index); } pub fn remove(&mut self, index: u16) -> bool { self.vec.binary_search(&index).map(|loc| self.vec.remove(loc)).is_ok() } pub fn remove_range(&mut self, range: RangeInclusive) -> u64 { let start = *range.start(); let end = *range.end(); // Figure out the starting/ending position in the vec. let pos_start = self.vec.binary_search(&start).unwrap_or_else(|x| x); let pos_end = pos_start + match self.vec[pos_start..].binary_search(&end) { Ok(x) => x + 1, Err(x) => x, }; self.vec.drain(pos_start..pos_end); (pos_end - pos_start) as u64 } pub fn remove_smallest(&mut self, n: u64) { self.vec.rotate_left(n as usize); self.vec.truncate(self.vec.len() - n as usize); } pub fn remove_biggest(&mut self, n: u64) { self.vec.truncate(self.vec.len() - n as usize); } pub fn contains(&self, index: u16) -> bool { self.vec.binary_search(&index).is_ok() } pub fn contains_range(&self, range: RangeInclusive) -> bool { let start = *range.start(); let end = *range.end(); let range_count = usize::from(end - start) + 1; if self.vec.len() < range_count { return false; } let start_i = match self.vec.binary_search(&start) { Ok(i) => i, Err(_) => return false, }; // If there are `range_count` items, last item in the next range_count should be the // expected end value, because this vec is sorted and has no duplicates self.vec.get(start_i + range_count - 1) == Some(&end) } pub fn is_disjoint(&self, other: &Self) -> bool { let (mut i1, mut i2) = (self.vec.iter(), other.vec.iter()); let (mut value1, mut value2) = (i1.next(), i2.next()); loop { match value1.and_then(|v1| value2.map(|v2| v1.cmp(v2))) { None => return true, Some(Equal) => return false, Some(Less) => value1 = i1.next(), Some(Greater) => value2 = i2.next(), } } } pub fn is_subset(&self, other: &Self) -> bool { let (mut i1, mut i2) = (self.iter(), other.iter()); let (mut value1, mut value2) = (i1.next(), i2.next()); loop { match (value1, value2) { (None, _) => return true, (Some(..), None) => return false, (Some(v1), Some(v2)) => match v1.cmp(v2) { Equal => { value1 = i1.next(); value2 = i2.next(); } Less => return false, Greater => value2 = i2.next(), }, } } } pub fn intersection_len(&self, other: &Self) -> u64 { let mut visitor = CardinalityCounter::new(); #[cfg(feature = "simd")] vector::and(self.as_slice(), other.as_slice(), &mut visitor); #[cfg(not(feature = "simd"))] scalar::and(self.as_slice(), other.as_slice(), &mut visitor); visitor.into_inner() } pub fn to_bitmap_store(&self) -> BitmapStore { let mut bits = Box::new([0; BITMAP_LENGTH]); let len = self.len(); for &index in self.iter() { bits[key(index)] |= 1 << bit(index); } BitmapStore::from_unchecked(len, bits) } pub fn len(&self) -> u64 { self.vec.len() as u64 } pub fn min(&self) -> Option { self.vec.first().copied() } pub fn max(&self) -> Option { self.vec.last().copied() } pub fn rank(&self, index: u16) -> u64 { match self.vec.binary_search(&index) { Ok(i) => i as u64 + 1, Err(i) => i as u64, } } pub fn select(&self, n: u16) -> Option { self.vec.get(n as usize).cloned() } pub fn iter(&self) -> std::slice::Iter { self.vec.iter() } pub fn into_iter(self) -> std::vec::IntoIter { self.vec.into_iter() } pub fn as_slice(&self) -> &[u16] { &self.vec } /// Retains only the elements specified by the predicate. pub fn retain(&mut self, mut f: impl FnMut(u16) -> bool) { // Idea to avoid branching from "Engineering Fast Indexes for Big Data // Applications" talk by Daniel Lemire // (https://youtu.be/1QMgGxiCFWE?t=1242). let slice = self.vec.as_mut_slice(); let mut pos = 0; for i in 0..slice.len() { let val = slice[i]; // We want to do `slice[pos] = val` but we don't need the bounds check. // SAFETY: pos is always at most i because `f(val) as usize` is at most 1. unsafe { *slice.get_unchecked_mut(pos) = val } pos += f(val) as usize; } self.vec.truncate(pos); } } impl Default for ArrayStore { fn default() -> Self { ArrayStore::new() } } #[derive(Debug)] pub struct Error { index: usize, kind: ErrorKind, } #[derive(Debug)] pub enum ErrorKind { Duplicate, OutOfOrder, } impl Display for Error { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self.kind { ErrorKind::Duplicate => { write!(f, "Duplicate element found at index: {}", self.index) } ErrorKind::OutOfOrder => { write!(f, "An element was out of order at index: {}", self.index) } } } } impl std::error::Error for Error {} impl TryFrom> for ArrayStore { type Error = Error; fn try_from(value: Vec) -> Result { let mut iter = value.iter().enumerate(); if let Some((_, mut prev)) = iter.next() { for (i, cur) in iter { match cur.cmp(prev) { Ordering::Less => return Err(Error { index: i, kind: ErrorKind::OutOfOrder }), Ordering::Equal => return Err(Error { index: i, kind: ErrorKind::Duplicate }), Ordering::Greater => (), } prev = cur; } } Ok(ArrayStore { vec: value }) } } impl BitOr for &ArrayStore { type Output = ArrayStore; fn bitor(self, rhs: Self) -> Self::Output { #[allow(clippy::suspicious_arithmetic_impl)] let capacity = self.vec.len() + rhs.vec.len(); let mut visitor = VecWriter::new(capacity); #[cfg(feature = "simd")] vector::or(self.as_slice(), rhs.as_slice(), &mut visitor); #[cfg(not(feature = "simd"))] scalar::or(self.as_slice(), rhs.as_slice(), &mut visitor); ArrayStore::from_vec_unchecked(visitor.into_inner()) } } impl BitAnd for &ArrayStore { type Output = ArrayStore; fn bitand(self, rhs: Self) -> Self::Output { let mut visitor = VecWriter::new(self.vec.len().min(rhs.vec.len())); #[cfg(feature = "simd")] vector::and(self.as_slice(), rhs.as_slice(), &mut visitor); #[cfg(not(feature = "simd"))] scalar::and(self.as_slice(), rhs.as_slice(), &mut visitor); ArrayStore::from_vec_unchecked(visitor.into_inner()) } } impl BitAndAssign<&Self> for ArrayStore { #[allow(clippy::suspicious_op_assign_impl)] fn bitand_assign(&mut self, rhs: &Self) { #[cfg(feature = "simd")] { let mut visitor = VecWriter::new(self.vec.len().min(rhs.vec.len())); vector::and(self.as_slice(), rhs.as_slice(), &mut visitor); self.vec = visitor.into_inner() } #[cfg(not(feature = "simd"))] { let mut i = 0; self.retain(|x| { i += rhs.iter().skip(i).position(|y| *y >= x).unwrap_or(rhs.vec.len()); rhs.vec.get(i).map_or(false, |y| x == *y) }); } } } impl BitAndAssign<&BitmapStore> for ArrayStore { fn bitand_assign(&mut self, rhs: &BitmapStore) { self.retain(|x| rhs.contains(x)); } } impl Sub for &ArrayStore { type Output = ArrayStore; fn sub(self, rhs: Self) -> Self::Output { let mut visitor = VecWriter::new(self.vec.len()); #[cfg(feature = "simd")] vector::sub(self.as_slice(), rhs.as_slice(), &mut visitor); #[cfg(not(feature = "simd"))] scalar::sub(self.as_slice(), rhs.as_slice(), &mut visitor); ArrayStore::from_vec_unchecked(visitor.into_inner()) } } impl SubAssign<&Self> for ArrayStore { #[allow(clippy::suspicious_op_assign_impl)] fn sub_assign(&mut self, rhs: &Self) { #[cfg(feature = "simd")] { let mut visitor = VecWriter::new(self.vec.len().min(rhs.vec.len())); vector::sub(self.as_slice(), rhs.as_slice(), &mut visitor); self.vec = visitor.into_inner() } #[cfg(not(feature = "simd"))] { let mut i = 0; self.retain(|x| { i += rhs.iter().skip(i).position(|y| *y >= x).unwrap_or(rhs.vec.len()); rhs.vec.get(i).map_or(true, |y| x != *y) }); } } } impl SubAssign<&BitmapStore> for ArrayStore { fn sub_assign(&mut self, rhs: &BitmapStore) { self.retain(|x| !rhs.contains(x)); } } impl BitXor for &ArrayStore { type Output = ArrayStore; fn bitxor(self, rhs: Self) -> Self::Output { #[allow(clippy::suspicious_arithmetic_impl)] let capacity = self.vec.len() + rhs.vec.len(); let mut visitor = VecWriter::new(capacity); #[cfg(feature = "simd")] vector::xor(self.as_slice(), rhs.as_slice(), &mut visitor); #[cfg(not(feature = "simd"))] scalar::xor(self.as_slice(), rhs.as_slice(), &mut visitor); ArrayStore::from_vec_unchecked(visitor.into_inner()) } } #[cfg(test)] mod tests { use super::*; use crate::bitmap::store::Store; fn into_vec(s: Store) -> Vec { match s { Store::Array(vec) => vec.vec, Store::Bitmap(bits) => bits.to_array_store().vec, } } fn into_bitmap_store(s: Store) -> Store { match s { Store::Array(vec) => Store::Bitmap(vec.to_bitmap_store()), Store::Bitmap(..) => s, } } #[test] #[allow(clippy::reversed_empty_ranges)] fn test_array_insert_invalid_range() { let mut store = Store::Array(ArrayStore::from_vec_unchecked(vec![1, 2, 8, 9])); // Insert a range with start > end. let new = store.insert_range(6..=1); assert_eq!(new, 0); assert_eq!(into_vec(store), vec![1, 2, 8, 9]); } #[test] fn test_array_insert_range() { let mut store = Store::Array(ArrayStore::from_vec_unchecked(vec![1, 2, 8, 9])); let new = store.insert_range(4..=5); assert_eq!(new, 2); assert_eq!(into_vec(store), vec![1, 2, 4, 5, 8, 9]); } #[test] fn test_array_insert_range_left_overlap() { let mut store = Store::Array(ArrayStore::from_vec_unchecked(vec![1, 2, 8, 9])); let new = store.insert_range(2..=5); assert_eq!(new, 3); assert_eq!(into_vec(store), vec![1, 2, 3, 4, 5, 8, 9]); } #[test] fn test_array_insert_range_right_overlap() { let mut store = Store::Array(ArrayStore::from_vec_unchecked(vec![1, 2, 8, 9])); let new = store.insert_range(4..=8); assert_eq!(new, 4); assert_eq!(into_vec(store), vec![1, 2, 4, 5, 6, 7, 8, 9]); } #[test] fn test_array_contains_range() { let store = Store::Array(ArrayStore::from_vec_unchecked(vec![])); assert!(!store.contains_range(0..=0)); assert!(!store.contains_range(0..=1)); assert!(!store.contains_range(1..=u16::MAX)); let store = Store::Array(ArrayStore::from_vec_unchecked(vec![0, 1, 2, 3, 4, 5, 100])); assert!(store.contains_range(0..=0)); assert!(store.contains_range(0..=5)); assert!(!store.contains_range(0..=6)); assert!(store.contains_range(100..=100)); } #[test] fn test_array_insert_range_full_overlap() { let mut store = Store::Array(ArrayStore::from_vec_unchecked(vec![1, 2, 8, 9])); let new = store.insert_range(1..=9); assert_eq!(new, 5); assert_eq!(into_vec(store), vec![1, 2, 3, 4, 5, 6, 7, 8, 9]); } #[test] #[allow(clippy::reversed_empty_ranges)] fn test_bitmap_insert_invalid_range() { let store = Store::Array(ArrayStore::from_vec_unchecked(vec![1, 2, 8, 9])); let mut store = into_bitmap_store(store); // Insert a range with start > end. let new = store.insert_range(6..=1); assert_eq!(new, 0); assert_eq!(into_vec(store), vec![1, 2, 8, 9]); } #[test] fn test_bitmap_insert_same_key_overlap() { let store = Store::Array(ArrayStore::from_vec_unchecked(vec![1, 2, 3, 62, 63])); let mut store = into_bitmap_store(store); let new = store.insert_range(1..=62); assert_eq!(new, 58); assert_eq!(into_vec(store), (1..64).collect::>()); } #[test] fn test_bitmap_insert_range() { let store = Store::Array(ArrayStore::from_vec_unchecked(vec![1, 2, 130])); let mut store = into_bitmap_store(store); let new = store.insert_range(4..=128); assert_eq!(new, 125); let mut want = vec![1, 2]; want.extend(4..129); want.extend([130]); assert_eq!(into_vec(store), want); } #[test] fn test_bitmap_insert_range_left_overlap() { let store = Store::Array(ArrayStore::from_vec_unchecked(vec![1, 2, 130])); let mut store = into_bitmap_store(store); let new = store.insert_range(1..=128); assert_eq!(new, 126); let mut want = Vec::new(); want.extend(1..129); want.extend([130]); assert_eq!(into_vec(store), want); } #[test] fn test_bitmap_insert_range_right_overlap() { let store = Store::Array(ArrayStore::from_vec_unchecked(vec![1, 2, 130])); let mut store = into_bitmap_store(store); let new = store.insert_range(4..=132); assert_eq!(new, 128); let mut want = vec![1, 2]; want.extend(4..133); assert_eq!(into_vec(store), want); } #[test] fn test_bitmap_insert_range_full_overlap() { let store = Store::Array(ArrayStore::from_vec_unchecked(vec![1, 2, 130])); let mut store = into_bitmap_store(store); let new = store.insert_range(1..=134); assert_eq!(new, 131); let mut want = Vec::new(); want.extend(1..135); assert_eq!(into_vec(store), want); } #[test] fn test_bitmap_remove_smallest() { let mut store = Store::Array(ArrayStore::from_vec_unchecked(vec![1, 2, 130, 500])); store.remove_smallest(3); assert_eq!(into_vec(store), vec![500]); } #[test] fn test_bitmap_remove_biggest() { let mut store = Store::Array(ArrayStore::from_vec_unchecked(vec![1, 2, 130, 500])); store.remove_biggest(2); assert_eq!(into_vec(store), vec![1, 2]); } } roaring-0.10.2/src/bitmap/store/array_store/scalar.rs000064400000000000000000000055241046102023000207170ustar 00000000000000//! Scalar arithmetic binary set operations on `ArrayStore`'s inner types use crate::bitmap::store::array_store::visitor::BinaryOperationVisitor; use std::cmp::Ordering::*; #[inline] pub fn or(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) { // Traverse both arrays let mut i = 0; let mut j = 0; while i < lhs.len() && j < rhs.len() { let a = unsafe { lhs.get_unchecked(i) }; let b = unsafe { rhs.get_unchecked(j) }; match a.cmp(b) { Less => { visitor.visit_scalar(*a); i += 1; } Greater => { visitor.visit_scalar(*b); j += 1; } Equal => { visitor.visit_scalar(*a); i += 1; j += 1; } } } // Store remaining elements of the arrays visitor.visit_slice(&lhs[i..]); visitor.visit_slice(&rhs[j..]); } #[inline] pub fn and(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) { // Traverse both arrays let mut i = 0; let mut j = 0; while i < lhs.len() && j < rhs.len() { let a = unsafe { lhs.get_unchecked(i) }; let b = unsafe { rhs.get_unchecked(j) }; match a.cmp(b) { Less => i += 1, Greater => j += 1, Equal => { visitor.visit_scalar(*a); i += 1; j += 1; } } } } #[inline] pub fn sub(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) { // Traverse both arrays let mut i = 0; let mut j = 0; while i < lhs.len() && j < rhs.len() { let a = unsafe { lhs.get_unchecked(i) }; let b = unsafe { rhs.get_unchecked(j) }; match a.cmp(b) { Less => { visitor.visit_scalar(*a); i += 1; } Greater => j += 1, Equal => { i += 1; j += 1; } } } // Store remaining elements of the left array visitor.visit_slice(&lhs[i..]); } #[inline] pub fn xor(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) { // Traverse both arrays let mut i = 0; let mut j = 0; while i < lhs.len() && j < rhs.len() { let a = unsafe { lhs.get_unchecked(i) }; let b = unsafe { rhs.get_unchecked(j) }; match a.cmp(b) { Less => { visitor.visit_scalar(*a); i += 1; } Greater => { visitor.visit_scalar(*b); j += 1; } Equal => { i += 1; j += 1; } } } // Store remaining elements of the arrays visitor.visit_slice(&lhs[i..]); visitor.visit_slice(&rhs[j..]); } roaring-0.10.2/src/bitmap/store/array_store/vector.rs000064400000000000000000000775501046102023000207640ustar 00000000000000//! Ported from CRoaring and arXiv:1709.07821 //! Lemire et al, Roaring Bitmaps: Implementation of an Optimized Software Library //! //! Prior work: Schlegel et al., Fast Sorted-Set Intersection using SIMD Instructions //! //! Rust port notes: //! The x86 PCMPESTRM instruction has been replaced with a simple vector or-shift //! While several more instructions, this is what is available through LLVM intrinsics //! and is portable. #![cfg(feature = "simd")] use super::scalar; use core::simd::{ mask16x8, simd_swizzle, u16x8, LaneCount, Mask, Simd, SimdElement, SimdPartialEq, SimdPartialOrd, SupportedLaneCount, ToBitMask, }; // a one-pass SSE union algorithm pub fn or(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) { // De-duplicates `slice` in place // Returns the end index of the deduplicated slice. // elements after the return value are not guaranteed to be unique or in order #[inline] fn dedup(slice: &mut [u16]) -> usize { let mut pos: usize = 1; for i in 1..slice.len() { if slice[i] != slice[i - 1] { slice[pos] = slice[i]; pos += 1; } } pos } #[inline] fn handle_vector(old: u16x8, new: u16x8, f: impl FnOnce(u16x8, u8)) { let tmp: u16x8 = Shr1::swizzle2(new, old); let mask = 255 - tmp.simd_eq(new).to_bitmask(); f(new, mask); } if (lhs.len() < 8) || (rhs.len() < 8) { scalar::or(lhs, rhs, visitor); return; } let len1: usize = lhs.len() / 8; let len2: usize = rhs.len() / 8; let v_a: u16x8 = load(lhs); let v_b: u16x8 = load(rhs); let [mut v_min, mut v_max] = simd_merge_u16(v_a, v_b); let mut i = 1; let mut j = 1; handle_vector(Simd::splat(u16::MAX), v_min, |v, m| visitor.visit_vector(v, m)); let mut v_prev: u16x8 = v_min; if (i < len1) && (j < len2) { let mut v: u16x8; let mut cur_a: u16 = lhs[8 * i]; let mut cur_b: u16 = rhs[8 * j]; loop { if cur_a <= cur_b { v = load(&lhs[8 * i..]); i += 1; if i < len1 { cur_a = lhs[8 * i]; } else { break; } } else { v = load(&rhs[8 * j..]); j += 1; if j < len2 { cur_b = rhs[8 * j]; } else { break; } } [v_min, v_max] = simd_merge_u16(v, v_max); handle_vector(v_prev, v_min, |v, m| visitor.visit_vector(v, m)); v_prev = v_min; } [v_min, v_max] = simd_merge_u16(v, v_max); handle_vector(v_prev, v_min, |v, m| visitor.visit_vector(v, m)); v_prev = v_min; } debug_assert!(i == len1 || j == len2); // we finish the rest off using a scalar algorithm // could be improved? // // copy the small end on a tmp buffer let mut buffer: [u16; 16] = [0; 16]; let mut rem = 0; handle_vector(v_prev, v_max, |v, m| { store(swizzle_to_front(v, m), buffer.as_mut_slice()); rem = m.count_ones() as usize; }); let (tail_a, tail_b, tail_len) = if i == len1 { (&lhs[8 * i..], &rhs[8 * j..], lhs.len() - 8 * len1) } else { (&rhs[8 * j..], &lhs[8 * i..], rhs.len() - 8 * len2) }; buffer[rem..rem + tail_len].copy_from_slice(tail_a); rem += tail_len; if rem == 0 { visitor.visit_slice(tail_b) } else { buffer[..rem as usize].sort_unstable(); rem = dedup(&mut buffer[..rem]); scalar::or(&buffer[..rem], tail_b, visitor); } } pub fn and(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) { let st_a = (lhs.len() / u16x8::LANES) * u16x8::LANES; let st_b = (rhs.len() / u16x8::LANES) * u16x8::LANES; let mut i: usize = 0; let mut j: usize = 0; if (i < st_a) && (j < st_b) { let mut v_a: u16x8 = load(&lhs[i..]); let mut v_b: u16x8 = load(&rhs[j..]); loop { let mask = matrix_cmp_u16(v_a, v_b).to_bitmask(); visitor.visit_vector(v_a, mask); let a_max: u16 = lhs[i + u16x8::LANES - 1]; let b_max: u16 = rhs[j + u16x8::LANES - 1]; if a_max <= b_max { i += u16x8::LANES; if i == st_a { break; } v_a = load(&lhs[i..]); } if b_max <= a_max { j += u16x8::LANES; if j == st_b { break; } v_b = load(&rhs[j..]); } } } // intersect the tail using scalar intersection scalar::and(&lhs[i..], &rhs[j..], visitor); } // a one-pass SSE xor algorithm pub fn xor(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) { /// De-duplicates `slice` in place, removing _both_ duplicates /// Returns the end index of the xor-ed slice. /// elements after the return value are not guaranteed to be unique or in order #[inline] fn xor_slice(slice: &mut [u16]) -> usize { let mut pos: usize = 1; for i in 1..slice.len() { if slice[i] != slice[i - 1] { slice[pos] = slice[i]; pos += 1; } else { pos -= 1; // it is identical to previous, delete it } } pos } // write vector new, while omitting repeated values assuming that previously // written vector was "old" #[inline] fn handle_vector(old: u16x8, new: u16x8, f: impl FnOnce(u16x8, u8)) { let tmp1: u16x8 = Shr2::swizzle2(new, old); let tmp2: u16x8 = Shr1::swizzle2(new, old); let eq_l: mask16x8 = tmp2.simd_eq(tmp1); let eq_r: mask16x8 = tmp2.simd_eq(new); let eq_l_or_r: mask16x8 = eq_l | eq_r; let mask: u8 = eq_l_or_r.to_bitmask(); f(tmp2, 255 - mask); } if (lhs.len() < 8) || (rhs.len() < 8) { scalar::xor(lhs, rhs, visitor); return; } let len1: usize = lhs.len() / 8; let len2: usize = rhs.len() / 8; let v_a: u16x8 = load(lhs); let v_b: u16x8 = load(rhs); let [mut v_min, mut v_max] = simd_merge_u16(v_a, v_b); let mut i = 1; let mut j = 1; handle_vector(Simd::splat(u16::MAX), v_min, |v, m| visitor.visit_vector(v, m)); let mut v_prev: u16x8 = v_min; if (i < len1) && (j < len2) { let mut v: u16x8; let mut cur_a: u16 = lhs[8 * i]; let mut cur_b: u16 = rhs[8 * j]; loop { if cur_a <= cur_b { v = load(&lhs[8 * i..]); i += 1; if i < len1 { cur_a = lhs[8 * i]; } else { break; } } else { v = load(&rhs[8 * j..]); j += 1; if j < len2 { cur_b = rhs[8 * j]; } else { break; } } [v_min, v_max] = simd_merge_u16(v, v_max); handle_vector(v_prev, v_min, |v, m| visitor.visit_vector(v, m)); v_prev = v_min; } [v_min, v_max] = simd_merge_u16(v, v_max); handle_vector(v_prev, v_min, |v, m| visitor.visit_vector(v, m)); v_prev = v_min; } debug_assert!(i == len1 || j == len2); // we finish the rest off using a scalar algorithm // could be improved? // conditionally stores the last value of laststore as well as all but the // last value of vecMax, let mut buffer: [u16; 17] = [0; 17]; // remaining size let mut rem = 0; handle_vector(v_prev, v_max, |v, m| { store(swizzle_to_front(v, m), buffer.as_mut_slice()); rem = m.count_ones() as usize; }); let arr_max = v_max.as_array(); let vec7 = arr_max[7]; let vec6 = arr_max[6]; if vec6 != vec7 { buffer[rem] = vec7; rem += 1; } let (tail_a, tail_b, tail_len) = if i == len1 { (&lhs[8 * i..], &rhs[8 * j..], lhs.len() - 8 * len1) } else { (&rhs[8 * j..], &lhs[8 * i..], rhs.len() - 8 * len2) }; buffer[rem..rem + tail_len].copy_from_slice(tail_a); rem += tail_len; if rem == 0 { visitor.visit_slice(tail_b) } else { buffer[..rem as usize].sort_unstable(); rem = xor_slice(&mut buffer[..rem]); scalar::xor(&buffer[..rem], tail_b, visitor); } } pub fn sub(lhs: &[u16], rhs: &[u16], visitor: &mut impl BinaryOperationVisitor) { // we handle the degenerate cases if lhs.is_empty() { return; } else if rhs.is_empty() { visitor.visit_slice(lhs); return; } let st_a = (lhs.len() / u16x8::LANES) * u16x8::LANES; let st_b = (rhs.len() / u16x8::LANES) * u16x8::LANES; let mut i = 0; let mut j = 0; if (i < st_a) && (j < st_b) { let mut v_a: u16x8 = load(&lhs[i..]); let mut v_b: u16x8 = load(&rhs[j..]); // we have a running mask which indicates which values from a have been // spotted in b, these don't get written out. let mut runningmask_a_found_in_b: u8 = 0; loop { // a_found_in_b will contain a mask indicate for each entry in A // whether it is seen in B let a_found_in_b: u8 = matrix_cmp_u16(v_a, v_b).to_bitmask(); runningmask_a_found_in_b |= a_found_in_b; // we always compare the last values of A and B let a_max: u16 = lhs[i + u16x8::LANES - 1]; let b_max: u16 = rhs[j + u16x8::LANES - 1]; if a_max <= b_max { // Ok. In this code path, we are ready to write our v_a // because there is no need to read more from B, they will // all be large values. let bitmask_belongs_to_difference = runningmask_a_found_in_b ^ 0xFF; visitor.visit_vector(v_a, bitmask_belongs_to_difference); i += u16x8::LANES; if i == st_a { break; } runningmask_a_found_in_b = 0; v_a = load(&lhs[i..]); } if b_max <= a_max { // in this code path, the current v_b has become useless j += u16x8::LANES; if j == st_b { break; } v_b = load(&rhs[j..]); } } debug_assert!(i == st_a || j == st_b); // End of main vectorized loop // At this point either i_a == st_a, which is the end of the vectorized processing, // or i_b == st_b and we are not done processing the vector... // so we need to finish it off. if i < st_a { let mut buffer: [u16; 8] = [0; 8]; // buffer to do a masked load buffer[..rhs.len() - j].copy_from_slice(&rhs[j..]); v_b = Simd::from_array(buffer); let a_found_in_b: u8 = matrix_cmp_u16(v_a, v_b).to_bitmask(); runningmask_a_found_in_b |= a_found_in_b; let bitmask_belongs_to_difference: u8 = runningmask_a_found_in_b ^ 0xFF; visitor.visit_vector(v_a, bitmask_belongs_to_difference); i += u16x8::LANES; } } // do the tail using scalar code scalar::sub(&lhs[i..], &rhs[j..], visitor); } /// compute the min for each lane in `a` and `b` #[inline] fn lanes_min_u16( lhs: Simd, rhs: Simd, ) -> Simd where LaneCount: SupportedLaneCount, { lhs.simd_le(rhs).select(lhs, rhs) } /// compute the max for each lane in `a` and `b` #[inline] fn lanes_max_u16( lhs: Simd, rhs: Simd, ) -> Simd where LaneCount: SupportedLaneCount, { lhs.simd_gt(rhs).select(lhs, rhs) } #[inline] pub fn load(src: &[U]) -> Simd where U: SimdElement + PartialOrd, LaneCount: SupportedLaneCount, { debug_assert!(src.len() >= LANES); unsafe { load_unchecked(src) } } /// write `v` to slice `out` without checking bounds /// /// ### Safety /// - The caller must ensure `LANES` does not exceed the allocation for `out` #[inline] pub unsafe fn load_unchecked(src: &[U]) -> Simd where U: SimdElement + PartialOrd, LaneCount: SupportedLaneCount, { unsafe { std::ptr::read_unaligned(src as *const _ as *const Simd) } } /// write `v` to slice `out` #[inline] pub fn store(v: Simd, out: &mut [U]) where U: SimdElement + PartialOrd, LaneCount: SupportedLaneCount, { debug_assert!(out.len() >= LANES); unsafe { store_unchecked(v, out); } } /// write `v` to slice `out` without checking bounds /// /// ### Safety /// - The caller must ensure `LANES` does not exceed the allocation for `out` #[inline] unsafe fn store_unchecked(v: Simd, out: &mut [U]) where U: SimdElement + PartialOrd, LaneCount: SupportedLaneCount, { unsafe { std::ptr::write_unaligned(out as *mut _ as *mut Simd, v) } } /// Compare all lanes in `a` to all lanes in `b` /// /// Returns result mask will be set if any lane at `a[i]` is in any lane of `b` /// /// ### Example /// ```ignore /// let a = Simd::from_array([1, 2, 3, 4, 32, 33, 34, 35]); /// let b = Simd::from_array([2, 4, 6, 8, 10, 12, 14, 16]); /// let result = matrix_cmp_u16(a, b); /// assert_eq!(result, Mask::from_array([false, true, false, true, false, false, false, false])); /// ``` #[inline] // It would be nice to implement this for all supported lane counts // However, we currently only support u16x8 so it's not really necessary fn matrix_cmp_u16(a: Simd, b: Simd) -> Mask { a.simd_eq(b) | a.simd_eq(b.rotate_lanes_left::<1>()) | a.simd_eq(b.rotate_lanes_left::<2>()) | a.simd_eq(b.rotate_lanes_left::<3>()) | a.simd_eq(b.rotate_lanes_left::<4>()) | a.simd_eq(b.rotate_lanes_left::<5>()) | a.simd_eq(b.rotate_lanes_left::<6>()) | a.simd_eq(b.rotate_lanes_left::<7>()) } use crate::bitmap::store::array_store::visitor::BinaryOperationVisitor; use core::simd::{Swizzle2, Which, Which::First as A, Which::Second as B}; /// Append to vectors to an imaginary 16 lane vector, shift the lanes right by 1, then /// truncate to the low order 8 lanes pub struct Shr1; impl Swizzle2<8, 8> for Shr1 { const INDEX: [Which; 8] = [B(7), A(0), A(1), A(2), A(3), A(4), A(5), A(6)]; } /// Append to vectors to an imaginary 16 lane vector, shift the lanes right by 2, then /// truncate to the low order 8 lanes pub struct Shr2; impl Swizzle2<8, 8> for Shr2 { const INDEX: [Which; 8] = [B(6), B(7), A(0), A(1), A(2), A(3), A(4), A(5)]; } /// Assuming that a and b are sorted, returns an array of the sorted output. /// Developed originally for merge sort using SIMD instructions. /// Standard merge. See, e.g., Inoue and Taura, SIMD- and Cache-Friendly /// Algorithm for Sorting an Array of Structures #[inline] fn simd_merge_u16(a: Simd, b: Simd) -> [Simd; 2] { let mut tmp: Simd = lanes_min_u16(a, b); let mut max: Simd = lanes_max_u16(a, b); tmp = tmp.rotate_lanes_left::<1>(); let mut min: Simd = lanes_min_u16(tmp, max); for _ in 0..6 { max = lanes_max_u16(tmp, max); tmp = min.rotate_lanes_left::<1>(); min = lanes_min_u16(tmp, max); } max = lanes_max_u16(tmp, max); min = min.rotate_lanes_left::<1>(); [min, max] } /// Move the values in `val` with the corresponding index in `bitmask` /// set to the front of the return vector, preserving their order. /// /// This had to be implemented as a jump table to be portable, /// as LLVM swizzle intrinsic only supports swizzle by a const /// value. https://github.com/rust-lang/portable-simd/issues/11 /// /// The values in the return vector after index bitmask.count_ones() is unspecified. /// /// The masks can be constructed with the following snippet /// ```ignore /// for n in 0usize..256 { /// let mut x = n; /// let mut arr = [0; 8]; /// let mut i = 0; /// while x > 0 { /// let lsb = x.trailing_zeros(); /// arr[i] = lsb; /// x ^= 1 << lsb; /// i += 1; /// } /// } /// ``` pub fn swizzle_to_front(val: u16x8, bitmask: u8) -> u16x8 { match bitmask { 0x00 => simd_swizzle!(val, [0, 0, 0, 0, 0, 0, 0, 0]), 0x01 => simd_swizzle!(val, [0, 0, 0, 0, 0, 0, 0, 0]), 0x02 => simd_swizzle!(val, [1, 0, 0, 0, 0, 0, 0, 0]), 0x03 => simd_swizzle!(val, [0, 1, 0, 0, 0, 0, 0, 0]), 0x04 => simd_swizzle!(val, [2, 0, 0, 0, 0, 0, 0, 0]), 0x05 => simd_swizzle!(val, [0, 2, 0, 0, 0, 0, 0, 0]), 0x06 => simd_swizzle!(val, [1, 2, 0, 0, 0, 0, 0, 0]), 0x07 => simd_swizzle!(val, [0, 1, 2, 0, 0, 0, 0, 0]), 0x08 => simd_swizzle!(val, [3, 0, 0, 0, 0, 0, 0, 0]), 0x09 => simd_swizzle!(val, [0, 3, 0, 0, 0, 0, 0, 0]), 0x0A => simd_swizzle!(val, [1, 3, 0, 0, 0, 0, 0, 0]), 0x0B => simd_swizzle!(val, [0, 1, 3, 0, 0, 0, 0, 0]), 0x0C => simd_swizzle!(val, [2, 3, 0, 0, 0, 0, 0, 0]), 0x0D => simd_swizzle!(val, [0, 2, 3, 0, 0, 0, 0, 0]), 0x0E => simd_swizzle!(val, [1, 2, 3, 0, 0, 0, 0, 0]), 0x0F => simd_swizzle!(val, [0, 1, 2, 3, 0, 0, 0, 0]), 0x10 => simd_swizzle!(val, [4, 0, 0, 0, 0, 0, 0, 0]), 0x11 => simd_swizzle!(val, [0, 4, 0, 0, 0, 0, 0, 0]), 0x12 => simd_swizzle!(val, [1, 4, 0, 0, 0, 0, 0, 0]), 0x13 => simd_swizzle!(val, [0, 1, 4, 0, 0, 0, 0, 0]), 0x14 => simd_swizzle!(val, [2, 4, 0, 0, 0, 0, 0, 0]), 0x15 => simd_swizzle!(val, [0, 2, 4, 0, 0, 0, 0, 0]), 0x16 => simd_swizzle!(val, [1, 2, 4, 0, 0, 0, 0, 0]), 0x17 => simd_swizzle!(val, [0, 1, 2, 4, 0, 0, 0, 0]), 0x18 => simd_swizzle!(val, [3, 4, 0, 0, 0, 0, 0, 0]), 0x19 => simd_swizzle!(val, [0, 3, 4, 0, 0, 0, 0, 0]), 0x1A => simd_swizzle!(val, [1, 3, 4, 0, 0, 0, 0, 0]), 0x1B => simd_swizzle!(val, [0, 1, 3, 4, 0, 0, 0, 0]), 0x1C => simd_swizzle!(val, [2, 3, 4, 0, 0, 0, 0, 0]), 0x1D => simd_swizzle!(val, [0, 2, 3, 4, 0, 0, 0, 0]), 0x1E => simd_swizzle!(val, [1, 2, 3, 4, 0, 0, 0, 0]), 0x1F => simd_swizzle!(val, [0, 1, 2, 3, 4, 0, 0, 0]), 0x20 => simd_swizzle!(val, [5, 0, 0, 0, 0, 0, 0, 0]), 0x21 => simd_swizzle!(val, [0, 5, 0, 0, 0, 0, 0, 0]), 0x22 => simd_swizzle!(val, [1, 5, 0, 0, 0, 0, 0, 0]), 0x23 => simd_swizzle!(val, [0, 1, 5, 0, 0, 0, 0, 0]), 0x24 => simd_swizzle!(val, [2, 5, 0, 0, 0, 0, 0, 0]), 0x25 => simd_swizzle!(val, [0, 2, 5, 0, 0, 0, 0, 0]), 0x26 => simd_swizzle!(val, [1, 2, 5, 0, 0, 0, 0, 0]), 0x27 => simd_swizzle!(val, [0, 1, 2, 5, 0, 0, 0, 0]), 0x28 => simd_swizzle!(val, [3, 5, 0, 0, 0, 0, 0, 0]), 0x29 => simd_swizzle!(val, [0, 3, 5, 0, 0, 0, 0, 0]), 0x2A => simd_swizzle!(val, [1, 3, 5, 0, 0, 0, 0, 0]), 0x2B => simd_swizzle!(val, [0, 1, 3, 5, 0, 0, 0, 0]), 0x2C => simd_swizzle!(val, [2, 3, 5, 0, 0, 0, 0, 0]), 0x2D => simd_swizzle!(val, [0, 2, 3, 5, 0, 0, 0, 0]), 0x2E => simd_swizzle!(val, [1, 2, 3, 5, 0, 0, 0, 0]), 0x2F => simd_swizzle!(val, [0, 1, 2, 3, 5, 0, 0, 0]), 0x30 => simd_swizzle!(val, [4, 5, 0, 0, 0, 0, 0, 0]), 0x31 => simd_swizzle!(val, [0, 4, 5, 0, 0, 0, 0, 0]), 0x32 => simd_swizzle!(val, [1, 4, 5, 0, 0, 0, 0, 0]), 0x33 => simd_swizzle!(val, [0, 1, 4, 5, 0, 0, 0, 0]), 0x34 => simd_swizzle!(val, [2, 4, 5, 0, 0, 0, 0, 0]), 0x35 => simd_swizzle!(val, [0, 2, 4, 5, 0, 0, 0, 0]), 0x36 => simd_swizzle!(val, [1, 2, 4, 5, 0, 0, 0, 0]), 0x37 => simd_swizzle!(val, [0, 1, 2, 4, 5, 0, 0, 0]), 0x38 => simd_swizzle!(val, [3, 4, 5, 0, 0, 0, 0, 0]), 0x39 => simd_swizzle!(val, [0, 3, 4, 5, 0, 0, 0, 0]), 0x3A => simd_swizzle!(val, [1, 3, 4, 5, 0, 0, 0, 0]), 0x3B => simd_swizzle!(val, [0, 1, 3, 4, 5, 0, 0, 0]), 0x3C => simd_swizzle!(val, [2, 3, 4, 5, 0, 0, 0, 0]), 0x3D => simd_swizzle!(val, [0, 2, 3, 4, 5, 0, 0, 0]), 0x3E => simd_swizzle!(val, [1, 2, 3, 4, 5, 0, 0, 0]), 0x3F => simd_swizzle!(val, [0, 1, 2, 3, 4, 5, 0, 0]), 0x40 => simd_swizzle!(val, [6, 0, 0, 0, 0, 0, 0, 0]), 0x41 => simd_swizzle!(val, [0, 6, 0, 0, 0, 0, 0, 0]), 0x42 => simd_swizzle!(val, [1, 6, 0, 0, 0, 0, 0, 0]), 0x43 => simd_swizzle!(val, [0, 1, 6, 0, 0, 0, 0, 0]), 0x44 => simd_swizzle!(val, [2, 6, 0, 0, 0, 0, 0, 0]), 0x45 => simd_swizzle!(val, [0, 2, 6, 0, 0, 0, 0, 0]), 0x46 => simd_swizzle!(val, [1, 2, 6, 0, 0, 0, 0, 0]), 0x47 => simd_swizzle!(val, [0, 1, 2, 6, 0, 0, 0, 0]), 0x48 => simd_swizzle!(val, [3, 6, 0, 0, 0, 0, 0, 0]), 0x49 => simd_swizzle!(val, [0, 3, 6, 0, 0, 0, 0, 0]), 0x4A => simd_swizzle!(val, [1, 3, 6, 0, 0, 0, 0, 0]), 0x4B => simd_swizzle!(val, [0, 1, 3, 6, 0, 0, 0, 0]), 0x4C => simd_swizzle!(val, [2, 3, 6, 0, 0, 0, 0, 0]), 0x4D => simd_swizzle!(val, [0, 2, 3, 6, 0, 0, 0, 0]), 0x4E => simd_swizzle!(val, [1, 2, 3, 6, 0, 0, 0, 0]), 0x4F => simd_swizzle!(val, [0, 1, 2, 3, 6, 0, 0, 0]), 0x50 => simd_swizzle!(val, [4, 6, 0, 0, 0, 0, 0, 0]), 0x51 => simd_swizzle!(val, [0, 4, 6, 0, 0, 0, 0, 0]), 0x52 => simd_swizzle!(val, [1, 4, 6, 0, 0, 0, 0, 0]), 0x53 => simd_swizzle!(val, [0, 1, 4, 6, 0, 0, 0, 0]), 0x54 => simd_swizzle!(val, [2, 4, 6, 0, 0, 0, 0, 0]), 0x55 => simd_swizzle!(val, [0, 2, 4, 6, 0, 0, 0, 0]), 0x56 => simd_swizzle!(val, [1, 2, 4, 6, 0, 0, 0, 0]), 0x57 => simd_swizzle!(val, [0, 1, 2, 4, 6, 0, 0, 0]), 0x58 => simd_swizzle!(val, [3, 4, 6, 0, 0, 0, 0, 0]), 0x59 => simd_swizzle!(val, [0, 3, 4, 6, 0, 0, 0, 0]), 0x5A => simd_swizzle!(val, [1, 3, 4, 6, 0, 0, 0, 0]), 0x5B => simd_swizzle!(val, [0, 1, 3, 4, 6, 0, 0, 0]), 0x5C => simd_swizzle!(val, [2, 3, 4, 6, 0, 0, 0, 0]), 0x5D => simd_swizzle!(val, [0, 2, 3, 4, 6, 0, 0, 0]), 0x5E => simd_swizzle!(val, [1, 2, 3, 4, 6, 0, 0, 0]), 0x5F => simd_swizzle!(val, [0, 1, 2, 3, 4, 6, 0, 0]), 0x60 => simd_swizzle!(val, [5, 6, 0, 0, 0, 0, 0, 0]), 0x61 => simd_swizzle!(val, [0, 5, 6, 0, 0, 0, 0, 0]), 0x62 => simd_swizzle!(val, [1, 5, 6, 0, 0, 0, 0, 0]), 0x63 => simd_swizzle!(val, [0, 1, 5, 6, 0, 0, 0, 0]), 0x64 => simd_swizzle!(val, [2, 5, 6, 0, 0, 0, 0, 0]), 0x65 => simd_swizzle!(val, [0, 2, 5, 6, 0, 0, 0, 0]), 0x66 => simd_swizzle!(val, [1, 2, 5, 6, 0, 0, 0, 0]), 0x67 => simd_swizzle!(val, [0, 1, 2, 5, 6, 0, 0, 0]), 0x68 => simd_swizzle!(val, [3, 5, 6, 0, 0, 0, 0, 0]), 0x69 => simd_swizzle!(val, [0, 3, 5, 6, 0, 0, 0, 0]), 0x6A => simd_swizzle!(val, [1, 3, 5, 6, 0, 0, 0, 0]), 0x6B => simd_swizzle!(val, [0, 1, 3, 5, 6, 0, 0, 0]), 0x6C => simd_swizzle!(val, [2, 3, 5, 6, 0, 0, 0, 0]), 0x6D => simd_swizzle!(val, [0, 2, 3, 5, 6, 0, 0, 0]), 0x6E => simd_swizzle!(val, [1, 2, 3, 5, 6, 0, 0, 0]), 0x6F => simd_swizzle!(val, [0, 1, 2, 3, 5, 6, 0, 0]), 0x70 => simd_swizzle!(val, [4, 5, 6, 0, 0, 0, 0, 0]), 0x71 => simd_swizzle!(val, [0, 4, 5, 6, 0, 0, 0, 0]), 0x72 => simd_swizzle!(val, [1, 4, 5, 6, 0, 0, 0, 0]), 0x73 => simd_swizzle!(val, [0, 1, 4, 5, 6, 0, 0, 0]), 0x74 => simd_swizzle!(val, [2, 4, 5, 6, 0, 0, 0, 0]), 0x75 => simd_swizzle!(val, [0, 2, 4, 5, 6, 0, 0, 0]), 0x76 => simd_swizzle!(val, [1, 2, 4, 5, 6, 0, 0, 0]), 0x77 => simd_swizzle!(val, [0, 1, 2, 4, 5, 6, 0, 0]), 0x78 => simd_swizzle!(val, [3, 4, 5, 6, 0, 0, 0, 0]), 0x79 => simd_swizzle!(val, [0, 3, 4, 5, 6, 0, 0, 0]), 0x7A => simd_swizzle!(val, [1, 3, 4, 5, 6, 0, 0, 0]), 0x7B => simd_swizzle!(val, [0, 1, 3, 4, 5, 6, 0, 0]), 0x7C => simd_swizzle!(val, [2, 3, 4, 5, 6, 0, 0, 0]), 0x7D => simd_swizzle!(val, [0, 2, 3, 4, 5, 6, 0, 0]), 0x7E => simd_swizzle!(val, [1, 2, 3, 4, 5, 6, 0, 0]), 0x7F => simd_swizzle!(val, [0, 1, 2, 3, 4, 5, 6, 0]), 0x80 => simd_swizzle!(val, [7, 0, 0, 0, 0, 0, 0, 0]), 0x81 => simd_swizzle!(val, [0, 7, 0, 0, 0, 0, 0, 0]), 0x82 => simd_swizzle!(val, [1, 7, 0, 0, 0, 0, 0, 0]), 0x83 => simd_swizzle!(val, [0, 1, 7, 0, 0, 0, 0, 0]), 0x84 => simd_swizzle!(val, [2, 7, 0, 0, 0, 0, 0, 0]), 0x85 => simd_swizzle!(val, [0, 2, 7, 0, 0, 0, 0, 0]), 0x86 => simd_swizzle!(val, [1, 2, 7, 0, 0, 0, 0, 0]), 0x87 => simd_swizzle!(val, [0, 1, 2, 7, 0, 0, 0, 0]), 0x88 => simd_swizzle!(val, [3, 7, 0, 0, 0, 0, 0, 0]), 0x89 => simd_swizzle!(val, [0, 3, 7, 0, 0, 0, 0, 0]), 0x8A => simd_swizzle!(val, [1, 3, 7, 0, 0, 0, 0, 0]), 0x8B => simd_swizzle!(val, [0, 1, 3, 7, 0, 0, 0, 0]), 0x8C => simd_swizzle!(val, [2, 3, 7, 0, 0, 0, 0, 0]), 0x8D => simd_swizzle!(val, [0, 2, 3, 7, 0, 0, 0, 0]), 0x8E => simd_swizzle!(val, [1, 2, 3, 7, 0, 0, 0, 0]), 0x8F => simd_swizzle!(val, [0, 1, 2, 3, 7, 0, 0, 0]), 0x90 => simd_swizzle!(val, [4, 7, 0, 0, 0, 0, 0, 0]), 0x91 => simd_swizzle!(val, [0, 4, 7, 0, 0, 0, 0, 0]), 0x92 => simd_swizzle!(val, [1, 4, 7, 0, 0, 0, 0, 0]), 0x93 => simd_swizzle!(val, [0, 1, 4, 7, 0, 0, 0, 0]), 0x94 => simd_swizzle!(val, [2, 4, 7, 0, 0, 0, 0, 0]), 0x95 => simd_swizzle!(val, [0, 2, 4, 7, 0, 0, 0, 0]), 0x96 => simd_swizzle!(val, [1, 2, 4, 7, 0, 0, 0, 0]), 0x97 => simd_swizzle!(val, [0, 1, 2, 4, 7, 0, 0, 0]), 0x98 => simd_swizzle!(val, [3, 4, 7, 0, 0, 0, 0, 0]), 0x99 => simd_swizzle!(val, [0, 3, 4, 7, 0, 0, 0, 0]), 0x9A => simd_swizzle!(val, [1, 3, 4, 7, 0, 0, 0, 0]), 0x9B => simd_swizzle!(val, [0, 1, 3, 4, 7, 0, 0, 0]), 0x9C => simd_swizzle!(val, [2, 3, 4, 7, 0, 0, 0, 0]), 0x9D => simd_swizzle!(val, [0, 2, 3, 4, 7, 0, 0, 0]), 0x9E => simd_swizzle!(val, [1, 2, 3, 4, 7, 0, 0, 0]), 0x9F => simd_swizzle!(val, [0, 1, 2, 3, 4, 7, 0, 0]), 0xA0 => simd_swizzle!(val, [5, 7, 0, 0, 0, 0, 0, 0]), 0xA1 => simd_swizzle!(val, [0, 5, 7, 0, 0, 0, 0, 0]), 0xA2 => simd_swizzle!(val, [1, 5, 7, 0, 0, 0, 0, 0]), 0xA3 => simd_swizzle!(val, [0, 1, 5, 7, 0, 0, 0, 0]), 0xA4 => simd_swizzle!(val, [2, 5, 7, 0, 0, 0, 0, 0]), 0xA5 => simd_swizzle!(val, [0, 2, 5, 7, 0, 0, 0, 0]), 0xA6 => simd_swizzle!(val, [1, 2, 5, 7, 0, 0, 0, 0]), 0xA7 => simd_swizzle!(val, [0, 1, 2, 5, 7, 0, 0, 0]), 0xA8 => simd_swizzle!(val, [3, 5, 7, 0, 0, 0, 0, 0]), 0xA9 => simd_swizzle!(val, [0, 3, 5, 7, 0, 0, 0, 0]), 0xAA => simd_swizzle!(val, [1, 3, 5, 7, 0, 0, 0, 0]), 0xAB => simd_swizzle!(val, [0, 1, 3, 5, 7, 0, 0, 0]), 0xAC => simd_swizzle!(val, [2, 3, 5, 7, 0, 0, 0, 0]), 0xAD => simd_swizzle!(val, [0, 2, 3, 5, 7, 0, 0, 0]), 0xAE => simd_swizzle!(val, [1, 2, 3, 5, 7, 0, 0, 0]), 0xAF => simd_swizzle!(val, [0, 1, 2, 3, 5, 7, 0, 0]), 0xB0 => simd_swizzle!(val, [4, 5, 7, 0, 0, 0, 0, 0]), 0xB1 => simd_swizzle!(val, [0, 4, 5, 7, 0, 0, 0, 0]), 0xB2 => simd_swizzle!(val, [1, 4, 5, 7, 0, 0, 0, 0]), 0xB3 => simd_swizzle!(val, [0, 1, 4, 5, 7, 0, 0, 0]), 0xB4 => simd_swizzle!(val, [2, 4, 5, 7, 0, 0, 0, 0]), 0xB5 => simd_swizzle!(val, [0, 2, 4, 5, 7, 0, 0, 0]), 0xB6 => simd_swizzle!(val, [1, 2, 4, 5, 7, 0, 0, 0]), 0xB7 => simd_swizzle!(val, [0, 1, 2, 4, 5, 7, 0, 0]), 0xB8 => simd_swizzle!(val, [3, 4, 5, 7, 0, 0, 0, 0]), 0xB9 => simd_swizzle!(val, [0, 3, 4, 5, 7, 0, 0, 0]), 0xBA => simd_swizzle!(val, [1, 3, 4, 5, 7, 0, 0, 0]), 0xBB => simd_swizzle!(val, [0, 1, 3, 4, 5, 7, 0, 0]), 0xBC => simd_swizzle!(val, [2, 3, 4, 5, 7, 0, 0, 0]), 0xBD => simd_swizzle!(val, [0, 2, 3, 4, 5, 7, 0, 0]), 0xBE => simd_swizzle!(val, [1, 2, 3, 4, 5, 7, 0, 0]), 0xBF => simd_swizzle!(val, [0, 1, 2, 3, 4, 5, 7, 0]), 0xC0 => simd_swizzle!(val, [6, 7, 0, 0, 0, 0, 0, 0]), 0xC1 => simd_swizzle!(val, [0, 6, 7, 0, 0, 0, 0, 0]), 0xC2 => simd_swizzle!(val, [1, 6, 7, 0, 0, 0, 0, 0]), 0xC3 => simd_swizzle!(val, [0, 1, 6, 7, 0, 0, 0, 0]), 0xC4 => simd_swizzle!(val, [2, 6, 7, 0, 0, 0, 0, 0]), 0xC5 => simd_swizzle!(val, [0, 2, 6, 7, 0, 0, 0, 0]), 0xC6 => simd_swizzle!(val, [1, 2, 6, 7, 0, 0, 0, 0]), 0xC7 => simd_swizzle!(val, [0, 1, 2, 6, 7, 0, 0, 0]), 0xC8 => simd_swizzle!(val, [3, 6, 7, 0, 0, 0, 0, 0]), 0xC9 => simd_swizzle!(val, [0, 3, 6, 7, 0, 0, 0, 0]), 0xCA => simd_swizzle!(val, [1, 3, 6, 7, 0, 0, 0, 0]), 0xCB => simd_swizzle!(val, [0, 1, 3, 6, 7, 0, 0, 0]), 0xCC => simd_swizzle!(val, [2, 3, 6, 7, 0, 0, 0, 0]), 0xCD => simd_swizzle!(val, [0, 2, 3, 6, 7, 0, 0, 0]), 0xCE => simd_swizzle!(val, [1, 2, 3, 6, 7, 0, 0, 0]), 0xCF => simd_swizzle!(val, [0, 1, 2, 3, 6, 7, 0, 0]), 0xD0 => simd_swizzle!(val, [4, 6, 7, 0, 0, 0, 0, 0]), 0xD1 => simd_swizzle!(val, [0, 4, 6, 7, 0, 0, 0, 0]), 0xD2 => simd_swizzle!(val, [1, 4, 6, 7, 0, 0, 0, 0]), 0xD3 => simd_swizzle!(val, [0, 1, 4, 6, 7, 0, 0, 0]), 0xD4 => simd_swizzle!(val, [2, 4, 6, 7, 0, 0, 0, 0]), 0xD5 => simd_swizzle!(val, [0, 2, 4, 6, 7, 0, 0, 0]), 0xD6 => simd_swizzle!(val, [1, 2, 4, 6, 7, 0, 0, 0]), 0xD7 => simd_swizzle!(val, [0, 1, 2, 4, 6, 7, 0, 0]), 0xD8 => simd_swizzle!(val, [3, 4, 6, 7, 0, 0, 0, 0]), 0xD9 => simd_swizzle!(val, [0, 3, 4, 6, 7, 0, 0, 0]), 0xDA => simd_swizzle!(val, [1, 3, 4, 6, 7, 0, 0, 0]), 0xDB => simd_swizzle!(val, [0, 1, 3, 4, 6, 7, 0, 0]), 0xDC => simd_swizzle!(val, [2, 3, 4, 6, 7, 0, 0, 0]), 0xDD => simd_swizzle!(val, [0, 2, 3, 4, 6, 7, 0, 0]), 0xDE => simd_swizzle!(val, [1, 2, 3, 4, 6, 7, 0, 0]), 0xDF => simd_swizzle!(val, [0, 1, 2, 3, 4, 6, 7, 0]), 0xE0 => simd_swizzle!(val, [5, 6, 7, 0, 0, 0, 0, 0]), 0xE1 => simd_swizzle!(val, [0, 5, 6, 7, 0, 0, 0, 0]), 0xE2 => simd_swizzle!(val, [1, 5, 6, 7, 0, 0, 0, 0]), 0xE3 => simd_swizzle!(val, [0, 1, 5, 6, 7, 0, 0, 0]), 0xE4 => simd_swizzle!(val, [2, 5, 6, 7, 0, 0, 0, 0]), 0xE5 => simd_swizzle!(val, [0, 2, 5, 6, 7, 0, 0, 0]), 0xE6 => simd_swizzle!(val, [1, 2, 5, 6, 7, 0, 0, 0]), 0xE7 => simd_swizzle!(val, [0, 1, 2, 5, 6, 7, 0, 0]), 0xE8 => simd_swizzle!(val, [3, 5, 6, 7, 0, 0, 0, 0]), 0xE9 => simd_swizzle!(val, [0, 3, 5, 6, 7, 0, 0, 0]), 0xEA => simd_swizzle!(val, [1, 3, 5, 6, 7, 0, 0, 0]), 0xEB => simd_swizzle!(val, [0, 1, 3, 5, 6, 7, 0, 0]), 0xEC => simd_swizzle!(val, [2, 3, 5, 6, 7, 0, 0, 0]), 0xED => simd_swizzle!(val, [0, 2, 3, 5, 6, 7, 0, 0]), 0xEE => simd_swizzle!(val, [1, 2, 3, 5, 6, 7, 0, 0]), 0xEF => simd_swizzle!(val, [0, 1, 2, 3, 5, 6, 7, 0]), 0xF0 => simd_swizzle!(val, [4, 5, 6, 7, 0, 0, 0, 0]), 0xF1 => simd_swizzle!(val, [0, 4, 5, 6, 7, 0, 0, 0]), 0xF2 => simd_swizzle!(val, [1, 4, 5, 6, 7, 0, 0, 0]), 0xF3 => simd_swizzle!(val, [0, 1, 4, 5, 6, 7, 0, 0]), 0xF4 => simd_swizzle!(val, [2, 4, 5, 6, 7, 0, 0, 0]), 0xF5 => simd_swizzle!(val, [0, 2, 4, 5, 6, 7, 0, 0]), 0xF6 => simd_swizzle!(val, [1, 2, 4, 5, 6, 7, 0, 0]), 0xF7 => simd_swizzle!(val, [0, 1, 2, 4, 5, 6, 7, 0]), 0xF8 => simd_swizzle!(val, [3, 4, 5, 6, 7, 0, 0, 0]), 0xF9 => simd_swizzle!(val, [0, 3, 4, 5, 6, 7, 0, 0]), 0xFA => simd_swizzle!(val, [1, 3, 4, 5, 6, 7, 0, 0]), 0xFB => simd_swizzle!(val, [0, 1, 3, 4, 5, 6, 7, 0]), 0xFC => simd_swizzle!(val, [2, 3, 4, 5, 6, 7, 0, 0]), 0xFD => simd_swizzle!(val, [0, 2, 3, 4, 5, 6, 7, 0]), 0xFE => simd_swizzle!(val, [1, 2, 3, 4, 5, 6, 7, 0]), 0xFF => simd_swizzle!(val, [0, 1, 2, 3, 4, 5, 6, 7]), } } roaring-0.10.2/src/bitmap/store/array_store/visitor.rs000064400000000000000000000056361046102023000211550ustar 00000000000000#[cfg(feature = "simd")] use crate::bitmap::store::array_store::vector::swizzle_to_front; /// This visitor pattern allows multiple different algorithms to be written over the same data /// For example: vectorized algorithms can pass a visitor off to a scalar algorithm to finish off /// a tail that is not a multiple of the vector width. /// /// Perhaps more importantly: it separates the set algorithms from the operations performed on /// their results. Future work can utilize the exiting algorithms to trivially implement /// computing the cardinality of an operation without materializng a new bitmap. pub trait BinaryOperationVisitor { #[cfg(feature = "simd")] fn visit_vector(&mut self, value: core::simd::u16x8, mask: u8); fn visit_scalar(&mut self, value: u16); fn visit_slice(&mut self, values: &[u16]); } /// A simple visitor that stores the computation result to a Vec /// accessible by calling `into_inner()` pub struct VecWriter { vec: Vec, } impl VecWriter { pub fn new(capacity: usize) -> VecWriter { let vec = Vec::with_capacity(capacity); VecWriter { vec } } pub fn into_inner(self) -> Vec { // Consider shrinking the vec here. // Exacty len could be too aggressive. Len rounded up to next power of 2? // Related, but not exact issue: https://github.com/RoaringBitmap/roaring-rs/issues/136 self.vec } } impl BinaryOperationVisitor for VecWriter { #[cfg(feature = "simd")] fn visit_vector(&mut self, value: core::simd::u16x8, mask: u8) { let result = swizzle_to_front(value, mask); // This idiom is better than subslicing result, as it compiles down to an unaligned vector // store instr. // A more straightforward, but unsafe way would be ptr::write_unaligned and Vec::set_len // Writing a vector at once is why the vectorized algorithms do not operate in place // first write the entire vector self.vec.extend_from_slice(&result.as_array()[..]); // next truncate the masked out values self.vec.truncate(self.vec.len() - (result.lanes() - mask.count_ones() as usize)); } fn visit_scalar(&mut self, value: u16) { self.vec.push(value) } fn visit_slice(&mut self, values: &[u16]) { self.vec.extend_from_slice(values); } } pub struct CardinalityCounter { count: usize, } impl CardinalityCounter { pub fn new() -> CardinalityCounter { CardinalityCounter { count: 0 } } pub fn into_inner(self) -> u64 { self.count as u64 } } impl BinaryOperationVisitor for CardinalityCounter { #[cfg(feature = "simd")] fn visit_vector(&mut self, _value: core::simd::u16x8, mask: u8) { self.count += mask.count_ones() as usize; } fn visit_scalar(&mut self, _value: u16) { self.count += 1; } fn visit_slice(&mut self, values: &[u16]) { self.count += values.len(); } } roaring-0.10.2/src/bitmap/store/bitmap_store.rs000064400000000000000000000436261046102023000176150ustar 00000000000000use std::borrow::Borrow; use std::cmp::Ordering; use std::fmt::{Display, Formatter}; use std::ops::{BitAndAssign, BitOrAssign, BitXorAssign, RangeInclusive, SubAssign}; use super::ArrayStore; pub const BITMAP_LENGTH: usize = 1024; #[derive(Clone, Eq, PartialEq)] pub struct BitmapStore { len: u64, bits: Box<[u64; BITMAP_LENGTH]>, } impl BitmapStore { pub fn new() -> BitmapStore { BitmapStore { len: 0, bits: Box::new([0; BITMAP_LENGTH]) } } pub fn full() -> BitmapStore { BitmapStore { len: (BITMAP_LENGTH as u64) * 64, bits: Box::new([u64::MAX; BITMAP_LENGTH]) } } pub fn try_from(len: u64, bits: Box<[u64; BITMAP_LENGTH]>) -> Result { let actual_len = bits.iter().map(|v| v.count_ones() as u64).sum(); if len != actual_len { Err(Error { kind: ErrorKind::Cardinality { expected: len, actual: actual_len } }) } else { Ok(BitmapStore { len, bits }) } } /// /// Create a new BitmapStore from a given len and bits array /// It is up to the caller to ensure len == cardinality of bits /// Favor `try_from` for cases in which this invariants should be checked /// /// # Panics /// /// When debug_assertions are enabled and the above invariant is not met pub fn from_unchecked(len: u64, bits: Box<[u64; BITMAP_LENGTH]>) -> BitmapStore { if cfg!(debug_assertions) { BitmapStore::try_from(len, bits).unwrap() } else { BitmapStore { len, bits } } } pub fn insert(&mut self, index: u16) -> bool { let (key, bit) = (key(index), bit(index)); let old_w = self.bits[key]; let new_w = old_w | 1 << bit; let inserted = (old_w ^ new_w) >> bit; // 1 or 0 self.bits[key] = new_w; self.len += inserted; inserted != 0 } pub fn insert_range(&mut self, range: RangeInclusive) -> u64 { let start = *range.start(); let end = *range.end(); let (start_key, start_bit) = (key(start), bit(start)); let (end_key, end_bit) = (key(end), bit(end)); // MSB > start_bit > end_bit > LSB if start_key == end_key { // Set the end_bit -> LSB to 1 let mut mask = if end_bit == 63 { u64::MAX } else { (1 << (end_bit + 1)) - 1 }; // Set MSB -> start_bit to 1 mask &= !((1 << start_bit) - 1); let existed = (self.bits[start_key] & mask).count_ones(); self.bits[start_key] |= mask; let inserted = u64::from(end - start + 1) - u64::from(existed); self.len += inserted; return inserted; } // Mask off the left-most bits (MSB -> start_bit) let mask = !((1 << start_bit) - 1); // Keep track of the number of bits that were already set to // return how many new bits were set later let mut existed = (self.bits[start_key] & mask).count_ones(); self.bits[start_key] |= mask; // Set the full blocks, tracking the number of set bits for i in (start_key + 1)..end_key { existed += self.bits[i].count_ones(); self.bits[i] = u64::MAX; } // Set the end bits in the last chunk (MSB -> end_bit) let mask = if end_bit == 63 { u64::MAX } else { (1 << (end_bit + 1)) - 1 }; existed += (self.bits[end_key] & mask).count_ones(); self.bits[end_key] |= mask; let inserted = end as u64 - start as u64 + 1 - existed as u64; self.len += inserted; inserted } pub fn push(&mut self, index: u16) -> bool { if self.max().map_or(true, |max| max < index) { self.insert(index); true } else { false } } /// /// Pushes `index` at the end of the store. /// It is up to the caller to have validated index > self.max() /// /// # Panics /// /// If debug_assertions enabled and index is > self.max() pub(crate) fn push_unchecked(&mut self, index: u16) { if cfg!(debug_assertions) { if let Some(max) = self.max() { assert!(index > max, "store max >= index") } } self.insert(index); } pub fn remove(&mut self, index: u16) -> bool { let (key, bit) = (key(index), bit(index)); let old_w = self.bits[key]; let new_w = old_w & !(1 << bit); let removed = (old_w ^ new_w) >> bit; // 0 or 1 self.bits[key] = new_w; self.len -= removed; removed != 0 } pub fn remove_range(&mut self, range: RangeInclusive) -> u64 { let start = *range.start(); let end = *range.end(); let (start_key, start_bit) = (key(start), bit(start)); let (end_key, end_bit) = (key(end), bit(end)); if start_key == end_key { let mask = (u64::MAX << start_bit) & (u64::MAX >> (63 - end_bit)); let removed = (self.bits[start_key] & mask).count_ones(); self.bits[start_key] &= !mask; let removed = u64::from(removed); self.len -= removed; return removed; } let mut removed = 0; // start key bits removed += (self.bits[start_key] & (u64::MAX << start_bit)).count_ones(); self.bits[start_key] &= !(u64::MAX << start_bit); // counts bits in between for word in &self.bits[start_key + 1..end_key] { removed += word.count_ones(); // When popcnt is available zeroing in this loop is faster, // but we opt to perform reasonably on most cpus by zeroing after. // By doing that the compiler uses simd to count ones. } // do zeroing outside the loop for word in &mut self.bits[start_key + 1..end_key] { *word = 0; } // end key bits removed += (self.bits[end_key] & (u64::MAX >> (63 - end_bit))).count_ones(); self.bits[end_key] &= !(u64::MAX >> (63 - end_bit)); let removed = u64::from(removed); self.len -= removed; removed } pub fn contains(&self, index: u16) -> bool { self.bits[key(index)] & (1 << bit(index)) != 0 } pub fn contains_range(&self, range: RangeInclusive) -> bool { let start = *range.start(); let end = *range.end(); if self.len() < u64::from(end - start) + 1 { return false; } let (start_i, start_bit) = (key(start), bit(start)); let (end_i, end_bit) = (key(end), bit(end)); // Create a mask to exclude the first `start_bit` bits // e.g. if we start at bit index 1, this will create a mask which includes all but the bit // at index 0. let start_mask = !((1 << start_bit) - 1); // We want to create a mask which includes the end_bit, so we create a mask of // `end_bit + 1` bits. `end_bit` will be between [0, 63], so we create a mask including // between [1, 64] bits. For example, if the last bit is the 0th bit, we make a mask with // only the 0th bit set (one bit). let end_mask = (!0) >> (64 - (end_bit + 1)); match &self.bits[start_i..=end_i] { [] => unreachable!(), &[word] => word & (start_mask & end_mask) == (start_mask & end_mask), &[first, ref rest @ .., last] => { (first & start_mask) == start_mask && rest.iter().all(|&word| word == !0) && (last & end_mask) == end_mask } } } pub fn is_disjoint(&self, other: &BitmapStore) -> bool { self.bits.iter().zip(other.bits.iter()).all(|(&i1, &i2)| (i1 & i2) == 0) } pub fn is_subset(&self, other: &Self) -> bool { self.bits.iter().zip(other.bits.iter()).all(|(&i1, &i2)| (i1 & i2) == i1) } pub fn to_array_store(&self) -> ArrayStore { let mut vec = Vec::with_capacity(self.len as usize); for (index, mut bit) in self.bits.iter().cloned().enumerate() { while bit != 0 { vec.push((u64::trailing_zeros(bit) + (64 * index as u32)) as u16); bit &= bit - 1; } } ArrayStore::from_vec_unchecked(vec) } pub fn len(&self) -> u64 { self.len } pub fn min(&self) -> Option { self.bits .iter() .enumerate() .find(|&(_, &bit)| bit != 0) .map(|(index, bit)| (index * 64 + (bit.trailing_zeros() as usize)) as u16) } pub fn max(&self) -> Option { self.bits .iter() .enumerate() .rev() .find(|&(_, &bit)| bit != 0) .map(|(index, bit)| (index * 64 + (63 - bit.leading_zeros() as usize)) as u16) } pub fn rank(&self, index: u16) -> u64 { let (key, bit) = (key(index), bit(index)); self.bits[..key].iter().map(|v| v.count_ones() as u64).sum::() + (self.bits[key] << (63 - bit)).count_ones() as u64 } pub fn select(&self, n: u16) -> Option { let mut n = n as u64; for (key, value) in self.bits.iter().cloned().enumerate() { let len = value.count_ones() as u64; if n < len { let index = select(value, n); return Some((64 * key as u64 + index) as u16); } n -= len; } None } pub fn intersection_len_bitmap(&self, other: &BitmapStore) -> u64 { self.bits.iter().zip(other.bits.iter()).map(|(&a, &b)| (a & b).count_ones() as u64).sum() } pub fn intersection_len_array(&self, other: &ArrayStore) -> u64 { other .iter() .map(|&index| { let (key, bit) = (key(index), bit(index)); let old_w = self.bits[key]; let new_w = old_w & (1 << bit); new_w >> bit }) .sum::() } pub fn iter(&self) -> BitmapIter<&[u64; BITMAP_LENGTH]> { BitmapIter::new(&self.bits) } pub fn into_iter(self) -> BitmapIter> { BitmapIter::new(self.bits) } pub fn as_array(&self) -> &[u64; BITMAP_LENGTH] { &self.bits } pub fn clear(&mut self) { self.bits.fill(0); self.len = 0; } /// Set N bits that are currently 1 bit from the lower bit to 0. pub fn remove_smallest(&mut self, mut clear_bits: u64) { if self.len() < clear_bits { self.clear(); return; } self.len -= clear_bits; for word in self.bits.iter_mut() { let count = word.count_ones() as u64; if clear_bits < count { for _ in 0..clear_bits { *word = *word & (*word - 1); } return; } *word = 0; clear_bits -= count; if clear_bits == 0 { return; } } } /// Set N bits that are currently 1 bit from the lower bit to 0. pub fn remove_biggest(&mut self, mut clear_bits: u64) { if self.len() < clear_bits { self.clear(); return; } self.len -= clear_bits; for word in self.bits.iter_mut().rev() { let count = word.count_ones() as u64; if clear_bits < count { for _ in 0..clear_bits { *word &= !(1 << (63 - word.leading_zeros())); } return; } *word = 0; clear_bits -= count; if clear_bits == 0 { return; } } } } // this can be done in 3 instructions on x86-64 with bmi2 with: tzcnt(pdep(1 << rank, value)) // if n > value.count_ones() this method returns 0 fn select(mut value: u64, n: u64) -> u64 { // reset n of the least significant bits for _ in 0..n { value &= value - 1; } value.trailing_zeros() as u64 } impl Default for BitmapStore { fn default() -> Self { BitmapStore::new() } } #[derive(Debug)] pub struct Error { kind: ErrorKind, } #[derive(Debug)] pub enum ErrorKind { Cardinality { expected: u64, actual: u64 }, } impl Display for Error { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self.kind { ErrorKind::Cardinality { expected, actual } => { write!(f, "Expected cardinality was {} but was {}", expected, actual) } } } } impl std::error::Error for Error {} pub struct BitmapIter> { key: usize, value: u64, key_back: usize, value_back: u64, bits: B, } impl> BitmapIter { fn new(bits: B) -> BitmapIter { BitmapIter { key: 0, value: bits.borrow()[0], key_back: BITMAP_LENGTH - 1, value_back: bits.borrow()[BITMAP_LENGTH - 1], bits, } } } impl> Iterator for BitmapIter { type Item = u16; fn next(&mut self) -> Option { loop { if self.value == 0 { self.key += 1; let cmp = self.key.cmp(&self.key_back); // Match arms can be reordered, this ordering is perf sensitive self.value = if cmp == Ordering::Less { unsafe { *self.bits.borrow().get_unchecked(self.key) } } else if cmp == Ordering::Equal { self.value_back } else { return None; }; continue; } let index = self.value.trailing_zeros() as usize; self.value &= self.value - 1; return Some((64 * self.key + index) as u16); } } } impl> DoubleEndedIterator for BitmapIter { fn next_back(&mut self) -> Option { loop { let value = if self.key_back <= self.key { &mut self.value } else { &mut self.value_back }; if *value == 0 { if self.key_back <= self.key { return None; } self.key_back -= 1; self.value_back = unsafe { *self.bits.borrow().get_unchecked(self.key_back) }; continue; } let index_from_left = value.leading_zeros() as usize; let index = 63 - index_from_left; *value &= !(1 << index); return Some((64 * self.key_back + index) as u16); } } } #[inline] pub fn key(index: u16) -> usize { index as usize / 64 } #[inline] pub fn bit(index: u16) -> usize { index as usize % 64 } #[inline] fn op_bitmaps(bits1: &mut BitmapStore, bits2: &BitmapStore, op: impl Fn(&mut u64, u64)) { bits1.len = 0; for (index1, &index2) in bits1.bits.iter_mut().zip(bits2.bits.iter()) { op(index1, index2); bits1.len += index1.count_ones() as u64; } } impl BitOrAssign<&Self> for BitmapStore { fn bitor_assign(&mut self, rhs: &Self) { op_bitmaps(self, rhs, BitOrAssign::bitor_assign); } } impl BitOrAssign<&ArrayStore> for BitmapStore { fn bitor_assign(&mut self, rhs: &ArrayStore) { for &index in rhs.iter() { let (key, bit) = (key(index), bit(index)); let old_w = self.bits[key]; let new_w = old_w | 1 << bit; self.len += (old_w ^ new_w) >> bit; self.bits[key] = new_w; } } } impl BitAndAssign<&Self> for BitmapStore { fn bitand_assign(&mut self, rhs: &Self) { op_bitmaps(self, rhs, BitAndAssign::bitand_assign); } } impl SubAssign<&Self> for BitmapStore { #[allow(clippy::suspicious_op_assign_impl)] fn sub_assign(&mut self, rhs: &Self) { op_bitmaps(self, rhs, |l, r| *l &= !r); } } impl SubAssign<&ArrayStore> for BitmapStore { #[allow(clippy::suspicious_op_assign_impl)] fn sub_assign(&mut self, rhs: &ArrayStore) { for &index in rhs.iter() { let (key, bit) = (key(index), bit(index)); let old_w = self.bits[key]; let new_w = old_w & !(1 << bit); self.len -= (old_w ^ new_w) >> bit; self.bits[key] = new_w; } } } impl BitXorAssign<&Self> for BitmapStore { fn bitxor_assign(&mut self, rhs: &Self) { op_bitmaps(self, rhs, BitXorAssign::bitxor_assign); } } impl BitXorAssign<&ArrayStore> for BitmapStore { fn bitxor_assign(&mut self, rhs: &ArrayStore) { let mut len = self.len as i64; for &index in rhs.iter() { let (key, bit) = (key(index), bit(index)); let old_w = self.bits[key]; let new_w = old_w ^ 1 << bit; len += 1 - 2 * (((1 << bit) & old_w) >> bit) as i64; // +1 or -1 self.bits[key] = new_w; } self.len = len as u64; } } #[cfg(test)] mod tests { use super::*; #[test] fn test_bitmap_remove_smallest() { let mut store = BitmapStore::new(); let range = RangeInclusive::new(1, 3); store.insert_range(range); let range_second = RangeInclusive::new(5, 65535); // store.bits[0] = 0b1111111111111111111111111111111111111111111111111111111111101110 store.insert_range(range_second); store.remove_smallest(2); assert_eq!( store.bits[0], 0b1111111111111111111111111111111111111111111111111111111111101000 ); } #[test] fn test_bitmap_remove_biggest() { let mut store = BitmapStore::new(); let range = RangeInclusive::new(1, 3); store.insert_range(range); let range_second = RangeInclusive::new(5, 65535); // store.bits[1023] = 0b1111111111111111111111111111111111111111111111111111111111111111 store.insert_range(range_second); store.remove_biggest(2); assert_eq!( store.bits[1023], 0b11111111111111111111111111111111111111111111111111111111111111 ); } } roaring-0.10.2/src/bitmap/store/mod.rs000064400000000000000000000360121046102023000156730ustar 00000000000000mod array_store; mod bitmap_store; use std::mem; use std::ops::{ BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, RangeInclusive, Sub, SubAssign, }; use std::{slice, vec}; pub use self::bitmap_store::BITMAP_LENGTH; use self::Store::{Array, Bitmap}; pub use self::array_store::ArrayStore; pub use self::bitmap_store::{BitmapIter, BitmapStore}; use crate::bitmap::container::ARRAY_LIMIT; #[derive(Clone)] pub enum Store { Array(ArrayStore), Bitmap(BitmapStore), } pub enum Iter<'a> { Array(slice::Iter<'a, u16>), Vec(vec::IntoIter), BitmapBorrowed(BitmapIter<&'a [u64; BITMAP_LENGTH]>), BitmapOwned(BitmapIter>), } impl Store { pub fn new() -> Store { Store::Array(ArrayStore::new()) } pub fn with_capacity(capacity: usize) -> Store { if capacity <= ARRAY_LIMIT as usize { Store::Array(ArrayStore::with_capacity(capacity)) } else { Store::Bitmap(BitmapStore::new()) } } pub fn full() -> Store { Store::Bitmap(BitmapStore::full()) } pub fn insert(&mut self, index: u16) -> bool { match self { Array(vec) => vec.insert(index), Bitmap(bits) => bits.insert(index), } } pub fn insert_range(&mut self, range: RangeInclusive) -> u64 { // A Range is defined as being of size 0 if start >= end. if range.is_empty() { return 0; } match self { Array(vec) => vec.insert_range(range), Bitmap(bits) => bits.insert_range(range), } } /// Push `index` at the end of the store only if `index` is the new max. /// /// Returns whether `index` was effectively pushed. pub fn push(&mut self, index: u16) -> bool { match self { Array(vec) => vec.push(index), Bitmap(bits) => bits.push(index), } } /// /// Pushes `index` at the end of the store. /// It is up to the caller to have validated index > self.max() /// /// # Panics /// /// If debug_assertions enabled and index is > self.max() pub(crate) fn push_unchecked(&mut self, index: u16) { match self { Array(vec) => vec.push_unchecked(index), Bitmap(bits) => bits.push_unchecked(index), } } pub fn remove(&mut self, index: u16) -> bool { match self { Array(vec) => vec.remove(index), Bitmap(bits) => bits.remove(index), } } pub fn remove_range(&mut self, range: RangeInclusive) -> u64 { if range.is_empty() { return 0; } match self { Array(vec) => vec.remove_range(range), Bitmap(bits) => bits.remove_range(range), } } pub fn remove_smallest(&mut self, index: u64) { match self { Array(vec) => vec.remove_smallest(index), Bitmap(bits) => bits.remove_smallest(index), } } pub fn remove_biggest(&mut self, index: u64) { match self { Array(vec) => vec.remove_biggest(index), Bitmap(bits) => bits.remove_biggest(index), } } pub fn contains(&self, index: u16) -> bool { match self { Array(vec) => vec.contains(index), Bitmap(bits) => bits.contains(index), } } pub fn contains_range(&self, range: RangeInclusive) -> bool { match self { Array(vec) => vec.contains_range(range), Bitmap(bits) => bits.contains_range(range), } } pub fn is_full(&self) -> bool { self.len() == (1 << 16) } pub fn is_disjoint(&self, other: &Self) -> bool { match (self, other) { (Array(vec1), Array(vec2)) => vec1.is_disjoint(vec2), (Bitmap(bits1), Bitmap(bits2)) => bits1.is_disjoint(bits2), (Array(vec), Bitmap(bits)) | (Bitmap(bits), Array(vec)) => { vec.iter().all(|&i| !bits.contains(i)) } } } pub fn is_subset(&self, other: &Self) -> bool { match (self, other) { (Array(vec1), Array(vec2)) => vec1.is_subset(vec2), (Bitmap(bits1), Bitmap(bits2)) => bits1.is_subset(bits2), (Array(vec), Bitmap(bits)) => vec.iter().all(|&i| bits.contains(i)), (Bitmap(..), &Array(..)) => false, } } pub fn intersection_len(&self, other: &Self) -> u64 { match (self, other) { (Array(vec1), Array(vec2)) => vec1.intersection_len(vec2), (Bitmap(bits1), Bitmap(bits2)) => bits1.intersection_len_bitmap(bits2), (Array(vec), Bitmap(bits)) => bits.intersection_len_array(vec), (Bitmap(bits), Array(vec)) => bits.intersection_len_array(vec), } } pub fn len(&self) -> u64 { match self { Array(vec) => vec.len(), Bitmap(bits) => bits.len(), } } pub fn min(&self) -> Option { match self { Array(vec) => vec.min(), Bitmap(bits) => bits.min(), } } pub fn max(&self) -> Option { match self { Array(vec) => vec.max(), Bitmap(bits) => bits.max(), } } pub fn rank(&self, index: u16) -> u64 { match self { Array(vec) => vec.rank(index), Bitmap(bits) => bits.rank(index), } } pub fn select(&self, n: u16) -> Option { match self { Array(vec) => vec.select(n), Bitmap(bits) => bits.select(n), } } pub(crate) fn to_bitmap(&self) -> Store { match self { Array(arr) => Bitmap(arr.to_bitmap_store()), Bitmap(_) => self.clone(), } } } impl Default for Store { fn default() -> Self { Store::new() } } impl BitOr<&Store> for &Store { type Output = Store; fn bitor(self, rhs: &Store) -> Store { match (self, rhs) { (Array(vec1), Array(vec2)) => Array(BitOr::bitor(vec1, vec2)), (&Bitmap(..), &Array(..)) => { let mut lhs = self.clone(); BitOrAssign::bitor_assign(&mut lhs, rhs); lhs } (&Bitmap(..), &Bitmap(..)) => { let mut lhs = self.clone(); BitOrAssign::bitor_assign(&mut lhs, rhs); lhs } (&Array(..), &Bitmap(..)) => { let mut rhs = rhs.clone(); BitOrAssign::bitor_assign(&mut rhs, self); rhs } } } } impl BitOrAssign for Store { fn bitor_assign(&mut self, mut rhs: Store) { match (self, &mut rhs) { (&mut Array(ref mut vec1), &mut Array(ref vec2)) => { *vec1 = BitOr::bitor(&*vec1, vec2); } (&mut Bitmap(ref mut bits1), &mut Array(ref vec2)) => { BitOrAssign::bitor_assign(bits1, vec2); } (&mut Bitmap(ref mut bits1), &mut Bitmap(ref bits2)) => { BitOrAssign::bitor_assign(bits1, bits2); } (this @ &mut Array(..), &mut Bitmap(..)) => { mem::swap(this, &mut rhs); BitOrAssign::bitor_assign(this, rhs); } } } } impl BitOrAssign<&Store> for Store { fn bitor_assign(&mut self, rhs: &Store) { match (self, rhs) { (&mut Array(ref mut vec1), Array(vec2)) => { let this = mem::take(vec1); *vec1 = BitOr::bitor(&this, vec2); } (&mut Bitmap(ref mut bits1), Array(vec2)) => { BitOrAssign::bitor_assign(bits1, vec2); } (&mut Bitmap(ref mut bits1), Bitmap(bits2)) => { BitOrAssign::bitor_assign(bits1, bits2); } (this @ &mut Array(..), Bitmap(bits2)) => { let mut lhs: Store = Bitmap(bits2.clone()); BitOrAssign::bitor_assign(&mut lhs, &*this); *this = lhs; } } } } impl BitAnd<&Store> for &Store { type Output = Store; fn bitand(self, rhs: &Store) -> Store { match (self, rhs) { (Array(vec1), Array(vec2)) => Array(BitAnd::bitand(vec1, vec2)), (&Bitmap(..), &Array(..)) => { let mut rhs = rhs.clone(); BitAndAssign::bitand_assign(&mut rhs, self); rhs } _ => { let mut lhs = self.clone(); BitAndAssign::bitand_assign(&mut lhs, rhs); lhs } } } } impl BitAndAssign for Store { #[allow(clippy::suspicious_op_assign_impl)] fn bitand_assign(&mut self, mut rhs: Store) { match (self, &mut rhs) { (&mut Array(ref mut vec1), &mut Array(ref mut vec2)) => { if vec2.len() < vec1.len() { mem::swap(vec1, vec2); } BitAndAssign::bitand_assign(vec1, &*vec2); } (&mut Bitmap(ref mut bits1), &mut Bitmap(ref bits2)) => { BitAndAssign::bitand_assign(bits1, bits2); } (&mut Array(ref mut vec1), &mut Bitmap(ref bits2)) => { BitAndAssign::bitand_assign(vec1, bits2); } (this @ &mut Bitmap(..), &mut Array(..)) => { mem::swap(this, &mut rhs); BitAndAssign::bitand_assign(this, rhs); } } } } impl BitAndAssign<&Store> for Store { #[allow(clippy::suspicious_op_assign_impl)] fn bitand_assign(&mut self, rhs: &Store) { match (self, rhs) { (&mut Array(ref mut vec1), Array(vec2)) => { let (mut lhs, rhs) = if vec2.len() < vec1.len() { (vec2.clone(), &*vec1) } else { (mem::take(vec1), vec2) }; BitAndAssign::bitand_assign(&mut lhs, rhs); *vec1 = lhs; } (&mut Bitmap(ref mut bits1), Bitmap(bits2)) => { BitAndAssign::bitand_assign(bits1, bits2); } (&mut Array(ref mut vec1), Bitmap(bits2)) => { BitAndAssign::bitand_assign(vec1, bits2); } (this @ &mut Bitmap(..), &Array(..)) => { let mut new = rhs.clone(); BitAndAssign::bitand_assign(&mut new, &*this); *this = new; } } } } impl Sub<&Store> for &Store { type Output = Store; fn sub(self, rhs: &Store) -> Store { match (self, rhs) { (Array(vec1), Array(vec2)) => Array(Sub::sub(vec1, vec2)), _ => { let mut lhs = self.clone(); SubAssign::sub_assign(&mut lhs, rhs); lhs } } } } impl SubAssign<&Store> for Store { fn sub_assign(&mut self, rhs: &Store) { match (self, rhs) { (&mut Array(ref mut vec1), Array(vec2)) => { SubAssign::sub_assign(vec1, vec2); } (&mut Bitmap(ref mut bits1), Array(vec2)) => { SubAssign::sub_assign(bits1, vec2); } (&mut Bitmap(ref mut bits1), Bitmap(bits2)) => { SubAssign::sub_assign(bits1, bits2); } (&mut Array(ref mut vec1), Bitmap(bits2)) => { SubAssign::sub_assign(vec1, bits2); } } } } impl BitXor<&Store> for &Store { type Output = Store; fn bitxor(self, rhs: &Store) -> Store { match (self, rhs) { (Array(vec1), Array(vec2)) => Array(BitXor::bitxor(vec1, vec2)), (&Array(..), &Bitmap(..)) => { let mut lhs = rhs.clone(); BitXorAssign::bitxor_assign(&mut lhs, self); lhs } _ => { let mut lhs = self.clone(); BitXorAssign::bitxor_assign(&mut lhs, rhs); lhs } } } } impl BitXorAssign for Store { fn bitxor_assign(&mut self, mut rhs: Store) { match (self, &mut rhs) { (&mut Array(ref mut vec1), &mut Array(ref vec2)) => { *vec1 = BitXor::bitxor(&*vec1, vec2); } (&mut Bitmap(ref mut bits1), &mut Array(ref vec2)) => { BitXorAssign::bitxor_assign(bits1, vec2); } (&mut Bitmap(ref mut bits1), &mut Bitmap(ref bits2)) => { BitXorAssign::bitxor_assign(bits1, bits2); } (this @ &mut Array(..), &mut Bitmap(..)) => { mem::swap(this, &mut rhs); BitXorAssign::bitxor_assign(this, rhs); } } } } impl BitXorAssign<&Store> for Store { fn bitxor_assign(&mut self, rhs: &Store) { match (self, rhs) { (&mut Array(ref mut vec1), Array(vec2)) => { let this = mem::take(vec1); *vec1 = BitXor::bitxor(&this, vec2); } (&mut Bitmap(ref mut bits1), Array(vec2)) => { BitXorAssign::bitxor_assign(bits1, vec2); } (&mut Bitmap(ref mut bits1), Bitmap(bits2)) => { BitXorAssign::bitxor_assign(bits1, bits2); } (this @ &mut Array(..), Bitmap(bits2)) => { let mut lhs: Store = Bitmap(bits2.clone()); BitXorAssign::bitxor_assign(&mut lhs, &*this); *this = lhs; } } } } impl<'a> IntoIterator for &'a Store { type Item = u16; type IntoIter = Iter<'a>; fn into_iter(self) -> Iter<'a> { match self { Array(vec) => Iter::Array(vec.iter()), Bitmap(bits) => Iter::BitmapBorrowed(bits.iter()), } } } impl IntoIterator for Store { type Item = u16; type IntoIter = Iter<'static>; fn into_iter(self) -> Iter<'static> { match self { Array(vec) => Iter::Vec(vec.into_iter()), Bitmap(bits) => Iter::BitmapOwned(bits.into_iter()), } } } impl PartialEq for Store { fn eq(&self, other: &Self) -> bool { match (self, other) { (Array(vec1), Array(vec2)) => vec1 == vec2, (Bitmap(bits1), Bitmap(bits2)) => { bits1.len() == bits2.len() && bits1.iter().zip(bits2.iter()).all(|(i1, i2)| i1 == i2) } _ => false, } } } impl<'a> Iterator for Iter<'a> { type Item = u16; fn next(&mut self) -> Option { match self { Iter::Array(inner) => inner.next().cloned(), Iter::Vec(inner) => inner.next(), Iter::BitmapBorrowed(inner) => inner.next(), Iter::BitmapOwned(inner) => inner.next(), } } } impl DoubleEndedIterator for Iter<'_> { fn next_back(&mut self) -> Option { match self { Iter::Array(inner) => inner.next_back().cloned(), Iter::Vec(inner) => inner.next_back(), Iter::BitmapBorrowed(inner) => inner.next_back(), Iter::BitmapOwned(inner) => inner.next_back(), } } } roaring-0.10.2/src/bitmap/util.rs000064400000000000000000000065471046102023000147470ustar 00000000000000use std::ops::{Bound, RangeBounds, RangeInclusive}; /// Returns the container key and the index /// in this container for a given integer. #[inline] pub fn split(value: u32) -> (u16, u16) { ((value >> 16) as u16, value as u16) } /// Returns the original integer from the container /// key and the index of it in the container. #[inline] pub fn join(high: u16, low: u16) -> u32 { (u32::from(high) << 16) + u32::from(low) } /// Convert a `RangeBounds` object to `RangeInclusive`, pub fn convert_range_to_inclusive(range: R) -> Option> where R: RangeBounds, { let start: u32 = match range.start_bound() { Bound::Included(&i) => i, Bound::Excluded(&i) => i.checked_add(1)?, Bound::Unbounded => 0, }; let end: u32 = match range.end_bound() { Bound::Included(&i) => i, Bound::Excluded(&i) => i.checked_sub(1)?, Bound::Unbounded => u32::MAX, }; if end < start { return None; } Some(start..=end) } #[cfg(test)] mod test { use super::{convert_range_to_inclusive, join, split}; use std::ops::Bound; #[test] fn test_split_u32() { assert_eq!((0x0000u16, 0x0000u16), split(0x0000_0000u32)); assert_eq!((0x0000u16, 0x0001u16), split(0x0000_0001u32)); assert_eq!((0x0000u16, 0xFFFEu16), split(0x0000_FFFEu32)); assert_eq!((0x0000u16, 0xFFFFu16), split(0x0000_FFFFu32)); assert_eq!((0x0001u16, 0x0000u16), split(0x0001_0000u32)); assert_eq!((0x0001u16, 0x0001u16), split(0x0001_0001u32)); assert_eq!((0xFFFFu16, 0xFFFEu16), split(0xFFFF_FFFEu32)); assert_eq!((0xFFFFu16, 0xFFFFu16), split(0xFFFF_FFFFu32)); } #[test] fn test_join_u32() { assert_eq!(0x0000_0000u32, join(0x0000u16, 0x0000u16)); assert_eq!(0x0000_0001u32, join(0x0000u16, 0x0001u16)); assert_eq!(0x0000_FFFEu32, join(0x0000u16, 0xFFFEu16)); assert_eq!(0x0000_FFFFu32, join(0x0000u16, 0xFFFFu16)); assert_eq!(0x0001_0000u32, join(0x0001u16, 0x0000u16)); assert_eq!(0x0001_0001u32, join(0x0001u16, 0x0001u16)); assert_eq!(0xFFFF_FFFEu32, join(0xFFFFu16, 0xFFFEu16)); assert_eq!(0xFFFF_FFFFu32, join(0xFFFFu16, 0xFFFFu16)); } #[test] #[allow(clippy::reversed_empty_ranges)] fn test_convert_range_to_inclusive() { assert_eq!(Some(1..=5), convert_range_to_inclusive(1..6)); assert_eq!(Some(1..=u32::MAX), convert_range_to_inclusive(1..)); assert_eq!(Some(0..=u32::MAX), convert_range_to_inclusive(..)); assert_eq!(Some(16..=16), convert_range_to_inclusive(16..=16)); assert_eq!( Some(11..=19), convert_range_to_inclusive((Bound::Excluded(10), Bound::Excluded(20))) ); assert_eq!(None, convert_range_to_inclusive(0..0)); assert_eq!(None, convert_range_to_inclusive(5..5)); assert_eq!(None, convert_range_to_inclusive(1..0)); assert_eq!(None, convert_range_to_inclusive(10..5)); assert_eq!( None, convert_range_to_inclusive((Bound::Excluded(u32::MAX), Bound::Included(u32::MAX))) ); assert_eq!( None, convert_range_to_inclusive((Bound::Excluded(u32::MAX), Bound::Included(u32::MAX))) ); assert_eq!(None, convert_range_to_inclusive((Bound::Excluded(0), Bound::Included(0)))); } } roaring-0.10.2/src/lib.rs000064400000000000000000000053451046102023000132570ustar 00000000000000//! This is a [Rust][] port of the [Roaring bitmap][] data structure, initially //! defined as a [Java library][roaring-java] and described in [_Better bitmap //! performance with Roaring bitmaps_][roaring-paper]. //! //! [Rust]: https://www.rust-lang.org/ //! [Roaring bitmap]: https://roaringbitmap.org/ //! [roaring-java]: https://github.com/lemire/RoaringBitmap //! [roaring-paper]: https://arxiv.org/pdf/1402.6407v4 #![cfg_attr(feature = "simd", feature(portable_simd))] #![warn(missing_docs)] #![warn(unsafe_op_in_unsafe_fn)] #![warn(variant_size_differences)] #![allow(unknown_lints)] // For clippy extern crate byteorder; use std::error::Error; use std::fmt; /// A compressed bitmap using the [Roaring bitmap compression scheme](https://roaringbitmap.org/). pub mod bitmap; /// A compressed bitmap with u64 values. Implemented as a `BTreeMap` of `RoaringBitmap`s. pub mod treemap; pub use bitmap::RoaringBitmap; pub use treemap::RoaringTreemap; /// An error type that is returned when an iterator isn't sorted. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct NonSortedIntegers { valid_until: u64, } impl NonSortedIntegers { /// Returns the number of elements that were pub fn valid_until(&self) -> u64 { self.valid_until } } impl fmt::Display for NonSortedIntegers { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "integers are ordered up to the {}th element", self.valid_until()) } } impl Error for NonSortedIntegers {} /// A [`Iterator::collect`] blanket implementation that provides extra methods for [`RoaringBitmap`] /// and [`RoaringTreemap`]. /// /// When merging multiple bitmap with the same operation it's usually faster to call the /// method in this trait than to write your own for loop and merging the bitmaps yourself. /// /// # Examples /// ``` /// use roaring::{MultiOps, RoaringBitmap}; /// /// let bitmaps = [ /// RoaringBitmap::from_iter(0..10), /// RoaringBitmap::from_iter(10..20), /// RoaringBitmap::from_iter(20..30), /// ]; /// /// // Stop doing this /// let naive = bitmaps.clone().into_iter().reduce(|a, b| a | b).unwrap_or_default(); /// /// // And start doing this instead, it will be much faster! /// let iter = bitmaps.union(); /// /// assert_eq!(naive, iter); /// ``` pub trait MultiOps: IntoIterator { /// The type of output from operations. type Output; /// The `union` between all elements. fn union(self) -> Self::Output; /// The `intersection` between all elements. fn intersection(self) -> Self::Output; /// The `difference` between all elements. fn difference(self) -> Self::Output; /// The `symmetric difference` between all elements. fn symmetric_difference(self) -> Self::Output; } roaring-0.10.2/src/treemap/arbitrary.rs000064400000000000000000000012521046102023000161360ustar 00000000000000#[cfg(test)] mod test { use crate::{RoaringBitmap, RoaringTreemap}; use proptest::collection::btree_map; use proptest::prelude::*; impl RoaringTreemap { prop_compose! { pub fn arbitrary()(map in btree_map(0u32..=16, RoaringBitmap::arbitrary(), 0usize..=16)) -> RoaringTreemap { // we’re NEVER supposed to start with a treemap containing empty bitmaps // Since we can’t configure this in arbitrary we’re simply going to ignore the generated empty bitmaps let map = map.into_iter().filter(|(_, v)| !v.is_empty()).collect(); RoaringTreemap { map } } } } } roaring-0.10.2/src/treemap/cmp.rs000064400000000000000000000073321046102023000147230ustar 00000000000000use std::collections::btree_map; use std::iter::Peekable; use crate::RoaringBitmap; use crate::RoaringTreemap; pub(crate) struct Pairs<'a>( Peekable>, Peekable>, ); impl RoaringTreemap { pub(crate) fn pairs<'a>(&'a self, other: &'a RoaringTreemap) -> Pairs<'a> { Pairs(self.map.iter().peekable(), other.map.iter().peekable()) } /// Returns true if the set has no elements in common with other. This is equivalent to /// checking for an empty intersection. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb1 = RoaringTreemap::new(); /// let mut rb2 = RoaringTreemap::new(); /// /// rb1.insert(1); /// /// assert_eq!(rb1.is_disjoint(&rb2), true); /// /// rb2.insert(1); /// /// assert_eq!(rb1.is_disjoint(&rb2), false); /// /// ``` pub fn is_disjoint(&self, other: &Self) -> bool { self.pairs(other) .filter(|&(c1, c2)| c1.is_some() && c2.is_some()) .all(|(c1, c2)| c1.unwrap().is_disjoint(c2.unwrap())) } /// Returns `true` if this set is a subset of `other`. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb1 = RoaringTreemap::new(); /// let mut rb2 = RoaringTreemap::new(); /// /// rb1.insert(1); /// /// assert_eq!(rb1.is_subset(&rb2), false); /// /// rb2.insert(1); /// /// assert_eq!(rb1.is_subset(&rb2), true); /// /// rb1.insert(2); /// /// assert_eq!(rb1.is_subset(&rb2), false); /// ``` pub fn is_subset(&self, other: &Self) -> bool { for pair in self.pairs(other) { match pair { (None, _) => (), (_, None) => { return false; } (Some(c1), Some(c2)) => { if !c1.is_subset(c2) { return false; } } } } true } /// Returns `true` if this set is a superset of `other`. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb1 = RoaringTreemap::new(); /// let mut rb2 = RoaringTreemap::new(); /// /// rb1.insert(1); /// /// assert_eq!(rb2.is_superset(&rb1), false); /// /// rb2.insert(1); /// /// assert_eq!(rb2.is_superset(&rb1), true); /// /// rb1.insert(2); /// /// assert_eq!(rb2.is_superset(&rb1), false); /// ``` pub fn is_superset(&self, other: &Self) -> bool { other.is_subset(self) } } impl<'a> Iterator for Pairs<'a> { type Item = (Option<&'a RoaringBitmap>, Option<&'a RoaringBitmap>); fn next(&mut self) -> Option { enum Which { Left, Right, Both, None, } let which = match (self.0.peek(), self.1.peek()) { (None, None) => Which::None, (Some(_), None) => Which::Left, (None, Some(_)) => Which::Right, (Some(c1), Some(c2)) => match (c1.0, c2.0) { (key1, key2) if key1 == key2 => Which::Both, (key1, key2) if key1 < key2 => Which::Left, (key1, key2) if key1 > key2 => Which::Right, (_, _) => unreachable!(), }, }; match which { Which::Left => Some((self.0.next().map(|e| e.1), None)), Which::Right => Some((None, self.1.next().map(|e| e.1))), Which::Both => Some((self.0.next().map(|e| e.1), self.1.next().map(|e| e.1))), Which::None => None, } } } roaring-0.10.2/src/treemap/fmt.rs000064400000000000000000000007731046102023000147340ustar 00000000000000use std::fmt; use crate::RoaringTreemap; impl fmt::Debug for RoaringTreemap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.len() < 16 { write!(f, "RoaringTreemap<{:?}>", self.iter().collect::>()) } else { write!( f, "RoaringTreemap<{:?} values between {:?} and {:?}>", self.len(), self.min().unwrap(), self.max().unwrap() ) } } } roaring-0.10.2/src/treemap/inherent.rs000064400000000000000000000305171046102023000157610ustar 00000000000000use std::collections::btree_map::{BTreeMap, Entry}; use std::iter; use std::ops::RangeBounds; use crate::RoaringBitmap; use crate::RoaringTreemap; use super::util; impl RoaringTreemap { /// Creates an empty `RoaringTreemap`. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// let rb = RoaringTreemap::new(); /// ``` pub fn new() -> RoaringTreemap { RoaringTreemap { map: BTreeMap::new() } } /// Creates a full `RoaringTreemap`. /// /// # Examples /// /// ```rust,ignore /// use roaring::RoaringTreemap; /// let rb = RoaringTreemap::full(); /// ``` pub fn full() -> RoaringTreemap { RoaringTreemap { map: (0..=u32::MAX).zip(iter::repeat(RoaringBitmap::full())).collect() } } /// Adds a value to the set. Returns `true` if the value was not already present in the set. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// assert_eq!(rb.insert(3), true); /// assert_eq!(rb.insert(3), false); /// assert_eq!(rb.contains(3), true); /// ``` pub fn insert(&mut self, value: u64) -> bool { let (hi, lo) = util::split(value); self.map.entry(hi).or_insert_with(RoaringBitmap::new).insert(lo) } /// Inserts a range of values. /// /// Returns the number of inserted values. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// rb.insert_range(2..4); /// assert!(rb.contains(2)); /// assert!(rb.contains(3)); /// assert!(!rb.contains(4)); /// ``` pub fn insert_range>(&mut self, range: R) -> u64 { let (start, end) = match util::convert_range_to_inclusive(range) { Some(range) => (*range.start(), *range.end()), None => return 0, }; let (start_hi, start_lo) = util::split(start); let (end_hi, end_lo) = util::split(end); let mut counter = 0u64; // Split the input range by the leading 32 bits for hi in start_hi..=end_hi { let entry = self.map.entry(hi); // Calculate the sub-range from the lower 32 bits counter += if hi == end_hi && hi == start_hi { entry.or_insert_with(RoaringBitmap::new).insert_range(start_lo..=end_lo) } else if hi == start_hi { entry.or_insert_with(RoaringBitmap::new).insert_range(start_lo..=u32::MAX) } else if hi == end_hi { entry.or_insert_with(RoaringBitmap::new).insert_range(0..=end_lo) } else { // We insert a full bitmap if it doesn't already exist and return the size of it. // But if the bitmap already exists at this spot we replace it with a full bitmap // and specify that we didn't inserted the integers from the previous bitmap. let full_bitmap = RoaringBitmap::full(); match entry { Entry::Vacant(entry) => entry.insert(full_bitmap).len(), Entry::Occupied(mut entry) => { full_bitmap.len() - entry.insert(full_bitmap).len() } } }; } counter } /// Pushes `value` in the treemap only if it is greater than the current maximum value. /// /// Returns whether the value was inserted. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// assert!(rb.push(1)); /// assert!(rb.push(3)); /// assert_eq!(rb.push(3), false); /// assert!(rb.push(5)); /// /// assert_eq!(rb.iter().collect::>(), vec![1, 3, 5]); /// ``` pub fn push(&mut self, value: u64) -> bool { let (hi, lo) = util::split(value); self.map.entry(hi).or_insert_with(RoaringBitmap::new).push(lo) } /// Pushes `value` in the treemap only if it is greater than the current maximum value. /// It is up to the caller to have validated index > self.max() /// /// # Panics /// /// If debug_assertions enabled and index is > self.max() pub(crate) fn push_unchecked(&mut self, value: u64) { let (hi, lo) = util::split(value); // BTreeMap last_mut not stabilized see https://github.com/rust-lang/rust/issues/62924 match self.map.iter_mut().next_back() { Some((&key, bitmap)) if key == hi => bitmap.push_unchecked(lo), Some((&key, _)) if cfg!(debug_assertions) && key > hi => { panic!("last bitmap key > key of value") } _otherwise => { // The tree is empty let mut rb = RoaringBitmap::new(); rb.push_unchecked(lo); self.map.insert(hi, rb); } } } /// Removes a value from the set. Returns `true` if the value was present in the set. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// rb.insert(3); /// assert_eq!(rb.remove(3), true); /// assert_eq!(rb.remove(3), false); /// assert_eq!(rb.contains(3), false); /// ``` pub fn remove(&mut self, value: u64) -> bool { let (hi, lo) = util::split(value); match self.map.entry(hi) { Entry::Vacant(_) => false, Entry::Occupied(mut ent) => { if ent.get_mut().remove(lo) { if ent.get().is_empty() { ent.remove(); } true } else { false } } } } /// Removes a range of values. /// Returns the number of removed values. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// rb.insert(2); /// rb.insert(3); /// assert_eq!(rb.remove_range(2..4), 2); /// ``` pub fn remove_range(&mut self, range: R) -> u64 where R: RangeBounds, { let (start, end) = match util::convert_range_to_inclusive(range) { Some(range) => (*range.start(), *range.end()), None => return 0, }; let (start_container_key, start_index) = util::split(start); let (end_container_key, end_index) = util::split(end); let mut keys_to_remove = Vec::new(); let mut removed = 0; for (&key, rb) in &mut self.map { if key >= start_container_key && key <= end_container_key { let a = if key == start_container_key { start_index } else { 0 }; let b = if key == end_container_key { end_index } else { u32::MAX }; removed += rb.remove_range(a..=b); if rb.is_empty() { keys_to_remove.push(key); } } } for key in keys_to_remove { self.map.remove(&key); } removed } /// Returns `true` if this set contains the specified integer. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// rb.insert(1); /// assert_eq!(rb.contains(0), false); /// assert_eq!(rb.contains(1), true); /// assert_eq!(rb.contains(100), false); /// ``` pub fn contains(&self, value: u64) -> bool { let (hi, lo) = util::split(value); match self.map.get(&hi) { None => false, Some(r) => r.contains(lo), } } /// Clears all integers in this set. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// rb.insert(1); /// assert_eq!(rb.contains(1), true); /// rb.clear(); /// assert_eq!(rb.contains(1), false); /// ``` pub fn clear(&mut self) { self.map.clear(); } /// Returns `true` if there are no integers in this set. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// assert_eq!(rb.is_empty(), true); /// /// rb.insert(3); /// assert_eq!(rb.is_empty(), false); /// ``` pub fn is_empty(&self) -> bool { self.map.values().all(RoaringBitmap::is_empty) } /// Returns `true` if there are every possible integers in this set. /// /// # Examples /// /// ```rust,ignore /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::full(); /// assert!(!rb.is_empty()); /// assert!(rb.is_full()); /// ``` pub fn is_full(&self) -> bool { self.map.len() == (u32::MAX as usize + 1) && self.map.values().all(RoaringBitmap::is_full) } /// Returns the number of distinct integers added to the set. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// assert_eq!(rb.len(), 0); /// /// rb.insert(3); /// assert_eq!(rb.len(), 1); /// /// rb.insert(3); /// rb.insert(4); /// assert_eq!(rb.len(), 2); /// ``` pub fn len(&self) -> u64 { self.map.values().map(RoaringBitmap::len).sum() } /// Returns the minimum value in the set (if the set is non-empty). /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// assert_eq!(rb.min(), None); /// /// rb.insert(3); /// rb.insert(4); /// assert_eq!(rb.min(), Some(3)); /// ``` pub fn min(&self) -> Option { self.map .iter() .find(|&(_, rb)| rb.min().is_some()) .map(|(k, rb)| util::join(*k, rb.min().unwrap())) } /// Returns the maximum value in the set (if the set is non-empty). /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// assert_eq!(rb.max(), None); /// /// rb.insert(3); /// rb.insert(4); /// assert_eq!(rb.max(), Some(4)); /// ``` pub fn max(&self) -> Option { self.map .iter() .rev() .find(|&(_, rb)| rb.max().is_some()) .map(|(k, rb)| util::join(*k, rb.max().unwrap())) } /// Returns the number of integers that are <= value. rank(u64::MAX) == len() /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// assert_eq!(rb.rank(0), 0); /// /// rb.insert(3); /// rb.insert(4); /// assert_eq!(rb.rank(3), 1); /// assert_eq!(rb.rank(10), 2) /// ``` pub fn rank(&self, value: u64) -> u64 { // if len becomes cached for RoaringTreemap: return len if len > value let (hi, lo) = util::split(value); let mut iter = self.map.range(..=hi).rev(); iter.next() .map(|(&k, bitmap)| if k == hi { bitmap.rank(lo) } else { bitmap.len() }) .unwrap_or(0) + iter.map(|(_, bitmap)| bitmap.len()).sum::() } /// Returns the `n`th integer in the set or `None` if `n <= len()` /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// assert_eq!(rb.select(0), None); /// /// rb.append(vec![0, 10, 100]); /// /// assert_eq!(rb.select(0), Some(0)); /// assert_eq!(rb.select(1), Some(10)); /// assert_eq!(rb.select(2), Some(100)); /// assert_eq!(rb.select(3), None); /// ``` pub fn select(&self, mut n: u64) -> Option { for (&key, bitmap) in &self.map { let len = bitmap.len(); if len > n { return Some((key as u64) << 32 | bitmap.select(n as u32).unwrap() as u64); } n -= len; } None } } impl Default for RoaringTreemap { fn default() -> RoaringTreemap { RoaringTreemap::new() } } impl Clone for RoaringTreemap { fn clone(&self) -> Self { RoaringTreemap { map: self.map.clone() } } fn clone_from(&mut self, other: &Self) { self.map.clone_from(&other.map); } } roaring-0.10.2/src/treemap/iter.rs000064400000000000000000000241301046102023000151020ustar 00000000000000use std::collections::btree_map; use std::collections::BTreeMap; use std::iter::{self, FromIterator}; use super::util; use crate::bitmap::IntoIter as IntoIter32; use crate::bitmap::Iter as Iter32; use crate::{NonSortedIntegers, RoaringBitmap, RoaringTreemap}; struct To64Iter<'a> { hi: u32, inner: Iter32<'a>, } impl<'a> Iterator for To64Iter<'a> { type Item = u64; fn next(&mut self) -> Option { self.inner.next().map(|n| util::join(self.hi, n)) } } impl DoubleEndedIterator for To64Iter<'_> { fn next_back(&mut self) -> Option { self.inner.next_back().map(|n| util::join(self.hi, n)) } } fn to64iter<'a>(t: (&'a u32, &'a RoaringBitmap)) -> To64Iter<'a> { To64Iter { hi: *t.0, inner: t.1.iter() } } struct To64IntoIter { hi: u32, inner: IntoIter32, } impl Iterator for To64IntoIter { type Item = u64; fn next(&mut self) -> Option { self.inner.next().map(|n| util::join(self.hi, n)) } } impl DoubleEndedIterator for To64IntoIter { fn next_back(&mut self) -> Option { self.inner.next_back().map(|n| util::join(self.hi, n)) } } fn to64intoiter(t: (u32, RoaringBitmap)) -> To64IntoIter { To64IntoIter { hi: t.0, inner: t.1.into_iter() } } type InnerIter<'a> = iter::FlatMap< btree_map::Iter<'a, u32, RoaringBitmap>, To64Iter<'a>, fn((&'a u32, &'a RoaringBitmap)) -> To64Iter<'a>, >; type InnerIntoIter = iter::FlatMap< btree_map::IntoIter, To64IntoIter, fn((u32, RoaringBitmap)) -> To64IntoIter, >; /// An iterator for `RoaringTreemap`. pub struct Iter<'a> { inner: InnerIter<'a>, size_hint: u64, } /// An iterator for `RoaringTreemap`. pub struct IntoIter { inner: InnerIntoIter, size_hint: u64, } impl<'a> Iter<'a> { fn new(map: &BTreeMap) -> Iter { let size_hint: u64 = map.iter().map(|(_, r)| r.len()).sum(); let i = map.iter().flat_map(to64iter as _); Iter { inner: i, size_hint } } } impl IntoIter { fn new(map: BTreeMap) -> IntoIter { let size_hint = map.values().map(|r| r.len()).sum(); let i = map.into_iter().flat_map(to64intoiter as _); IntoIter { inner: i, size_hint } } } impl<'a> Iterator for Iter<'a> { type Item = u64; fn next(&mut self) -> Option { self.size_hint = self.size_hint.saturating_sub(1); self.inner.next() } fn size_hint(&self) -> (usize, Option) { if self.size_hint < usize::MAX as u64 { (self.size_hint as usize, Some(self.size_hint as usize)) } else { (usize::MAX, None) } } } impl DoubleEndedIterator for Iter<'_> { fn next_back(&mut self) -> Option { self.size_hint = self.size_hint.saturating_sub(1); self.inner.next_back() } } #[cfg(target_pointer_width = "64")] impl ExactSizeIterator for Iter<'_> { fn len(&self) -> usize { self.size_hint as usize } } impl Iterator for IntoIter { type Item = u64; fn next(&mut self) -> Option { self.size_hint = self.size_hint.saturating_sub(1); self.inner.next() } fn size_hint(&self) -> (usize, Option) { if self.size_hint < usize::MAX as u64 { (self.size_hint as usize, Some(self.size_hint as usize)) } else { (usize::MAX, None) } } } impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option { self.size_hint = self.size_hint.saturating_sub(1); self.inner.next_back() } } #[cfg(target_pointer_width = "64")] impl ExactSizeIterator for IntoIter { fn len(&self) -> usize { self.size_hint as usize } } impl RoaringTreemap { /// Iterator over each value stored in the RoaringTreemap, guarantees values are ordered by /// value. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// use std::iter::FromIterator; /// /// let bitmap = (1..3).collect::(); /// let mut iter = bitmap.iter(); /// /// assert_eq!(iter.next(), Some(1)); /// assert_eq!(iter.next(), Some(2)); /// assert_eq!(iter.next(), None); /// ``` pub fn iter(&self) -> Iter { Iter::new(&self.map) } /// Iterator over pairs of partition number and the corresponding RoaringBitmap. /// The partition number is defined by the 32 most significant bits of the bit index. /// /// # Examples /// /// ```rust /// use roaring::{RoaringBitmap, RoaringTreemap}; /// use std::iter::FromIterator; /// /// let original = (0..6000).collect::(); /// let mut bitmaps = original.bitmaps(); /// /// assert_eq!(bitmaps.next(), Some((0, &(0..6000).collect::()))); /// assert_eq!(bitmaps.next(), None); /// ``` pub fn bitmaps(&self) -> BitmapIter { BitmapIter(self.map.iter()) } /// Construct a RoaringTreemap from an iterator of partition number and RoaringBitmap pairs. /// The partition number is defined by the 32 most significant bits of the bit index. /// Note that repeated partitions, if present, will replace previously set partitions. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// use std::iter::FromIterator; /// /// let original = (0..6000).collect::(); /// let clone = RoaringTreemap::from_bitmaps(original.bitmaps().map(|(p, b)| (p, b.clone()))); /// /// assert_eq!(clone, original); /// ``` pub fn from_bitmaps>(iterator: I) -> Self { RoaringTreemap { map: iterator.into_iter().collect() } } } impl<'a> IntoIterator for &'a RoaringTreemap { type Item = u64; type IntoIter = Iter<'a>; fn into_iter(self) -> Iter<'a> { self.iter() } } impl IntoIterator for RoaringTreemap { type Item = u64; type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { IntoIter::new(self.map) } } impl From<[u64; N]> for RoaringTreemap { fn from(arr: [u64; N]) -> Self { RoaringTreemap::from_iter(arr) } } impl FromIterator for RoaringTreemap { fn from_iter>(iterator: I) -> RoaringTreemap { let mut rb = RoaringTreemap::new(); rb.extend(iterator); rb } } impl<'a> FromIterator<&'a u64> for RoaringTreemap { fn from_iter>(iterator: I) -> RoaringTreemap { let mut rb = RoaringTreemap::new(); rb.extend(iterator); rb } } impl Extend for RoaringTreemap { fn extend>(&mut self, iterator: I) { for value in iterator { self.insert(value); } } } impl<'a> Extend<&'a u64> for RoaringTreemap { fn extend>(&mut self, iterator: I) { for value in iterator { self.insert(*value); } } } impl RoaringTreemap { /// Create the set from a sorted iterator. Values must be sorted and deduplicated. /// /// The values of the iterator must be ordered and strictly greater than the greatest value /// in the set. If a value in the iterator doesn't satisfy this requirement, it is not added /// and the append operation is stopped. /// /// Returns `Ok` with the requested `RoaringTreemap`, `Err` with the number of elements /// we tried to append before an error occurred. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::from_sorted_iter(0..10).unwrap(); /// /// assert!(rb.iter().eq(0..10)); /// ``` pub fn from_sorted_iter>( iterator: I, ) -> Result { let mut rt = RoaringTreemap::new(); rt.append(iterator).map(|_| rt) } /// Extend the set with a sorted iterator. /// /// The values of the iterator must be ordered and strictly greater than the greatest value /// in the set. If a value in the iterator doesn't satisfy this requirement, it is not added /// and the append operation is stopped. /// /// Returns `Ok` with the number of elements appended to the set, `Err` with /// the number of elements we effectively appended before an error occurred. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// rb.append(0..10); /// /// assert!(rb.iter().eq(0..10)); /// ``` pub fn append>( &mut self, iterator: I, ) -> Result { let mut iterator = iterator.into_iter(); let mut prev = match (iterator.next(), self.max()) { (None, _) => return Ok(0), (Some(first), Some(max)) if first <= max => { return Err(NonSortedIntegers { valid_until: 0 }) } (Some(first), _) => first, }; // It is now guaranteed that so long as the values of the iterator are // monotonically increasing they must also be the greatest in the set. self.push_unchecked(prev); let mut count = 1; for value in iterator { if value <= prev { return Err(NonSortedIntegers { valid_until: count }); } else { self.push_unchecked(value); prev = value; count += 1; } } Ok(count) } } pub struct BitmapIter<'a>(btree_map::Iter<'a, u32, RoaringBitmap>); impl<'a> Iterator for BitmapIter<'a> { type Item = (u32, &'a RoaringBitmap); fn next(&mut self) -> Option { self.0.next().map(|(&p, b)| (p, b)) } fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } } impl FromIterator<(u32, RoaringBitmap)> for RoaringTreemap { fn from_iter>(iterator: I) -> RoaringTreemap { Self::from_bitmaps(iterator) } } roaring-0.10.2/src/treemap/mod.rs000064400000000000000000000014501046102023000147160ustar 00000000000000use crate::RoaringBitmap; use std::collections::BTreeMap; mod fmt; mod multiops; mod util; // Order of these modules matters as it determines the `impl` blocks order in // the docs mod arbitrary; mod cmp; mod inherent; mod iter; mod ops; #[cfg(feature = "serde")] mod serde; mod serialization; pub use self::iter::{IntoIter, Iter}; /// A compressed bitmap with u64 values. /// Implemented as a `BTreeMap` of `RoaringBitmap`s. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let mut rb = RoaringTreemap::new(); /// /// // insert all primes less than 10 /// rb.insert(2); /// rb.insert(3); /// rb.insert(5); /// rb.insert(7); /// println!("total bits set to true: {}", rb.len()); /// ``` #[derive(PartialEq)] pub struct RoaringTreemap { map: BTreeMap, } roaring-0.10.2/src/treemap/multiops.rs000064400000000000000000000255561046102023000160300ustar 00000000000000use std::{ borrow::Borrow, cmp::Ordering, collections::{binary_heap::PeekMut, BTreeMap, BinaryHeap}, mem, }; use crate::{MultiOps, RoaringBitmap, RoaringTreemap}; impl MultiOps for I where I: IntoIterator, { type Output = RoaringTreemap; fn union(self) -> Self::Output { try_simple_multi_op_owned::<_, _, UnionOp>( self.into_iter().map(Ok::<_, std::convert::Infallible>), ) .unwrap() } fn intersection(self) -> Self::Output { try_ordered_multi_op_owned::<_, _, IntersectionOp>( self.into_iter().map(Ok::<_, std::convert::Infallible>), ) .unwrap() } fn difference(self) -> Self::Output { try_ordered_multi_op_owned::<_, _, DifferenceOp>( self.into_iter().map(Ok::<_, std::convert::Infallible>), ) .unwrap() } fn symmetric_difference(self) -> Self::Output { try_simple_multi_op_owned::<_, _, SymmetricDifferenceOp>( self.into_iter().map(Ok::<_, std::convert::Infallible>), ) .unwrap() } } impl MultiOps> for I where I: IntoIterator>, { type Output = Result; fn union(self) -> Self::Output { try_simple_multi_op_owned::<_, _, UnionOp>(self) } fn intersection(self) -> Self::Output { try_ordered_multi_op_owned::<_, _, IntersectionOp>(self) } fn difference(self) -> Self::Output { try_ordered_multi_op_owned::<_, _, DifferenceOp>(self) } fn symmetric_difference(self) -> Self::Output { try_simple_multi_op_owned::<_, _, SymmetricDifferenceOp>(self) } } #[inline] fn try_simple_multi_op_owned(treemaps: I) -> Result where I: IntoIterator>, { let treemaps = treemaps.into_iter().collect::, _>>()?; let mut heap: BinaryHeap<_> = treemaps .into_iter() .filter_map(|treemap| { let mut iter = treemap.map.into_iter(); iter.next().map(|(key, bitmap)| PeekedRoaringBitmap { key, bitmap, iter }) }) .collect(); let mut bitmaps = Vec::new(); let mut map = BTreeMap::new(); while let Some(mut peek) = heap.peek_mut() { let (key, bitmap) = match peek.iter.next() { Some((next_key, next_bitmap)) => { let key = peek.key; peek.key = next_key; let bitmap = mem::replace(&mut peek.bitmap, next_bitmap); (key, bitmap) } None => { let poped = PeekMut::pop(peek); (poped.key, poped.bitmap) } }; if let Some((first_key, _)) = bitmaps.first() { if *first_key != key { let current_key = *first_key; let computed_bitmap = O::op_owned(bitmaps.drain(..).map(|(_, rb)| rb)); if !computed_bitmap.is_empty() { map.insert(current_key, computed_bitmap); } } } bitmaps.push((key, bitmap)); } if let Some((first_key, _)) = bitmaps.first() { let current_key = *first_key; let computed_bitmap = O::op_owned(bitmaps.drain(..).map(|(_, rb)| rb)); if !computed_bitmap.is_empty() { map.insert(current_key, computed_bitmap); } } Ok(RoaringTreemap { map }) } #[inline] fn try_ordered_multi_op_owned(treemaps: I) -> Result where I: IntoIterator>, { let mut treemaps = treemaps.into_iter(); let mut treemap = match treemaps.next().transpose()? { Some(treemap) => treemap, None => return Ok(RoaringTreemap::new()), }; let mut treemaps = treemaps.collect::, _>>()?; // for each key in the first treemap we're going to find and // accumulate all the corresponding bitmaps let keys: Vec<_> = treemap.map.keys().copied().collect(); for k in keys { // the unwrap is safe since we're iterating on our keys let current_bitmap = treemap.map.remove(&k).unwrap(); let new_bitmap = O::op_owned(std::iter::once(current_bitmap).chain( treemaps.iter_mut().map(|treemap| treemap.map.remove(&k).unwrap_or_default()), )); if !new_bitmap.is_empty() { treemap.map.insert(k, new_bitmap); } } Ok(treemap) } #[inline] fn try_ordered_multi_op_ref<'a, E: 'a, I, O: Op>(treemaps: I) -> Result where I: IntoIterator>, { let mut treemaps = treemaps.into_iter(); let treemap = match treemaps.next().transpose()? { Some(treemap) => treemap, None => return Ok(RoaringTreemap::new()), }; let treemaps = treemaps.collect::, _>>()?; let mut ret = RoaringTreemap::new(); // for each keys in the first treemap we're going find and accumulate all the corresponding bitmaps let keys: Vec<_> = treemap.map.keys().copied().collect(); let empty_bitmap = RoaringBitmap::new(); for k in keys { // the unwrap is safe since we're iterating on our keys let current_bitmap = treemap.map.get(&k).unwrap(); let new_bitmap = O::op_ref( std::iter::once(current_bitmap) .chain(treemaps.iter().map(|treemap| treemap.map.get(&k).unwrap_or(&empty_bitmap))), ); if !new_bitmap.is_empty() { ret.map.insert(k, new_bitmap); } } Ok(ret) } #[inline] fn try_simple_multi_op_ref<'a, E: 'a, I, O: Op>(treemaps: I) -> Result where I: IntoIterator>, { let treemaps = treemaps.into_iter().collect::, E>>()?; let mut heap: BinaryHeap<_> = treemaps .into_iter() .filter_map(|treemap| { let mut iter = treemap.map.iter(); iter.next().map(|(&key, bitmap)| PeekedRoaringBitmap { key, bitmap, iter }) }) .collect(); let mut bitmaps = Vec::new(); let mut map = BTreeMap::new(); while let Some(mut peek) = heap.peek_mut() { let (key, bitmap) = match peek.iter.next() { Some((&next_key, next_bitmap)) => { let key = peek.key; peek.key = next_key; let bitmap = mem::replace(&mut peek.bitmap, next_bitmap); (key, bitmap) } None => { let poped = PeekMut::pop(peek); (poped.key, poped.bitmap) } }; if let Some((first_key, _)) = bitmaps.first() { if *first_key != key { let current_key = *first_key; let computed_bitmap = O::op_ref(bitmaps.drain(..).map(|(_, rb)| rb)); if !computed_bitmap.is_empty() { map.insert(current_key, computed_bitmap); } } } bitmaps.push((key, bitmap)); } if let Some((first_key, _)) = bitmaps.first() { let current_key = *first_key; let computed_bitmap = O::op_ref(bitmaps.drain(..).map(|(_, rb)| rb)); if !computed_bitmap.is_empty() { map.insert(current_key, computed_bitmap); } } Ok(RoaringTreemap { map }) } trait Op { fn op_owned>(iter: I) -> RoaringBitmap; fn op_ref<'a, I: IntoIterator>(iter: I) -> RoaringBitmap; } enum UnionOp {} impl Op for UnionOp { fn op_owned>(iter: J) -> RoaringBitmap { iter.union() } fn op_ref<'a, J: IntoIterator>(iter: J) -> RoaringBitmap { iter.union() } } enum IntersectionOp {} impl Op for IntersectionOp { fn op_owned>(iter: J) -> RoaringBitmap { iter.intersection() } fn op_ref<'a, J: IntoIterator>(iter: J) -> RoaringBitmap { iter.intersection() } } enum DifferenceOp {} impl Op for DifferenceOp { fn op_owned>(iter: J) -> RoaringBitmap { iter.difference() } fn op_ref<'a, J: IntoIterator>(iter: J) -> RoaringBitmap { iter.difference() } } enum SymmetricDifferenceOp {} impl Op for SymmetricDifferenceOp { fn op_owned>(iter: J) -> RoaringBitmap { iter.symmetric_difference() } fn op_ref<'a, J: IntoIterator>(iter: J) -> RoaringBitmap { iter.symmetric_difference() } } impl<'a, I> MultiOps<&'a RoaringTreemap> for I where I: IntoIterator, { type Output = RoaringTreemap; fn union(self) -> Self::Output { try_simple_multi_op_ref::<_, _, UnionOp>( self.into_iter().map(Ok::<_, std::convert::Infallible>), ) .unwrap() } fn intersection(self) -> Self::Output { try_ordered_multi_op_ref::<_, _, IntersectionOp>( self.into_iter().map(Ok::<_, std::convert::Infallible>), ) .unwrap() } fn difference(self) -> Self::Output { try_ordered_multi_op_ref::<_, _, DifferenceOp>( self.into_iter().map(Ok::<_, std::convert::Infallible>), ) .unwrap() } fn symmetric_difference(self) -> Self::Output { try_simple_multi_op_ref::<_, _, SymmetricDifferenceOp>( self.into_iter().map(Ok::<_, std::convert::Infallible>), ) .unwrap() } } impl<'a, I, E: 'a> MultiOps> for I where I: IntoIterator>, { type Output = Result; fn union(self) -> Self::Output { try_simple_multi_op_ref::<_, _, UnionOp>(self) } fn intersection(self) -> Self::Output { try_ordered_multi_op_ref::<_, _, IntersectionOp>(self) } fn difference(self) -> Self::Output { try_ordered_multi_op_ref::<_, _, DifferenceOp>(self) } fn symmetric_difference(self) -> Self::Output { try_simple_multi_op_ref::<_, _, SymmetricDifferenceOp>(self) } } struct PeekedRoaringBitmap { key: u32, bitmap: R, iter: I, } impl, I> Ord for PeekedRoaringBitmap { fn cmp(&self, other: &Self) -> Ordering { self.key.cmp(&other.key).reverse() } } impl, I> PartialOrd for PeekedRoaringBitmap { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl, I> Eq for PeekedRoaringBitmap {} impl, I> PartialEq for PeekedRoaringBitmap { fn eq(&self, other: &Self) -> bool { self.key == other.key } } roaring-0.10.2/src/treemap/ops.rs000064400000000000000000000401621046102023000147430ustar 00000000000000use std::collections::btree_map::Entry; use std::mem; use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; use crate::RoaringTreemap; impl RoaringTreemap { /// Computes the len of the union with the specified other treemap without creating a new /// treemap. /// /// This is faster and more space efficient when you're only interested in the cardinality of /// the union. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let rb1: RoaringTreemap = (1..4).collect(); /// let rb2: RoaringTreemap = (3..5).collect(); /// /// /// assert_eq!(rb1.union_len(&rb2), (rb1 | rb2).len()); /// ``` pub fn union_len(&self, other: &RoaringTreemap) -> u64 { self.len().wrapping_add(other.len()).wrapping_sub(self.intersection_len(other)) } /// Computes the len of the intersection with the specified other treemap without creating a /// new treemap. /// /// This is faster and more space efficient when you're only interested in the cardinality of /// the intersection. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let rb1: RoaringTreemap = (1..4).collect(); /// let rb2: RoaringTreemap = (3..5).collect(); /// /// /// assert_eq!(rb1.intersection_len(&rb2), (rb1 & rb2).len()); /// ``` pub fn intersection_len(&self, other: &RoaringTreemap) -> u64 { self.pairs(other) .map(|pair| match pair { (Some(..), None) => 0, (None, Some(..)) => 0, (Some(lhs), Some(rhs)) => lhs.intersection_len(rhs), (None, None) => 0, }) .sum() } /// Computes the len of the difference with the specified other treemap without creating a new /// treemap. /// /// This is faster and more space efficient when you're only interested in the cardinality of /// the difference. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let rb1: RoaringTreemap = (1..4).collect(); /// let rb2: RoaringTreemap = (3..5).collect(); /// /// /// assert_eq!(rb1.difference_len(&rb2), (rb1 - rb2).len()); /// ``` pub fn difference_len(&self, other: &RoaringTreemap) -> u64 { self.len() - self.intersection_len(other) } /// Computes the len of the symmetric difference with the specified other treemap without /// creating a new bitmap. /// /// This is faster and more space efficient when you're only interested in the cardinality of /// the symmetric difference. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let rb1: RoaringTreemap = (1..4).collect(); /// let rb2: RoaringTreemap = (3..5).collect(); /// /// /// assert_eq!(rb1.symmetric_difference_len(&rb2), (rb1 ^ rb2).len()); /// ``` pub fn symmetric_difference_len(&self, other: &RoaringTreemap) -> u64 { let intersection_len = self.intersection_len(other); self.len() .wrapping_add(other.len()) .wrapping_sub(intersection_len) .wrapping_sub(intersection_len) } } impl BitOr for RoaringTreemap { type Output = RoaringTreemap; /// An `union` between two sets. fn bitor(mut self, rhs: RoaringTreemap) -> RoaringTreemap { BitOrAssign::bitor_assign(&mut self, rhs); self } } impl BitOr<&RoaringTreemap> for RoaringTreemap { type Output = RoaringTreemap; /// An `union` between two sets. fn bitor(mut self, rhs: &RoaringTreemap) -> RoaringTreemap { BitOrAssign::bitor_assign(&mut self, rhs); self } } impl BitOr for &RoaringTreemap { type Output = RoaringTreemap; /// An `union` between two sets. fn bitor(self, rhs: RoaringTreemap) -> RoaringTreemap { BitOr::bitor(rhs, self) } } impl BitOr<&RoaringTreemap> for &RoaringTreemap { type Output = RoaringTreemap; /// An `union` between two sets. fn bitor(self, rhs: &RoaringTreemap) -> RoaringTreemap { if self.len() <= rhs.len() { BitOr::bitor(rhs.clone(), self) } else { BitOr::bitor(self.clone(), rhs) } } } impl BitOrAssign for RoaringTreemap { /// An `union` between two sets. fn bitor_assign(&mut self, mut rhs: RoaringTreemap) { // We make sure that we apply the union operation on the biggest map. if self.len() < rhs.len() { mem::swap(self, &mut rhs); } for (key, other_rb) in rhs.map { match self.map.entry(key) { Entry::Vacant(ent) => { ent.insert(other_rb); } Entry::Occupied(mut ent) => { BitOrAssign::bitor_assign(ent.get_mut(), other_rb); } } } } } impl BitOrAssign<&RoaringTreemap> for RoaringTreemap { /// An `union` between two sets. fn bitor_assign(&mut self, rhs: &RoaringTreemap) { for (key, other_rb) in &rhs.map { match self.map.entry(*key) { Entry::Vacant(ent) => { ent.insert(other_rb.clone()); } Entry::Occupied(mut ent) => { BitOrAssign::bitor_assign(ent.get_mut(), other_rb); } } } } } impl BitAnd for RoaringTreemap { type Output = RoaringTreemap; /// An `intersection` between two sets. fn bitand(mut self, rhs: RoaringTreemap) -> RoaringTreemap { BitAndAssign::bitand_assign(&mut self, rhs); self } } impl BitAnd<&RoaringTreemap> for RoaringTreemap { type Output = RoaringTreemap; /// An `intersection` between two sets. fn bitand(mut self, rhs: &RoaringTreemap) -> RoaringTreemap { BitAndAssign::bitand_assign(&mut self, rhs); self } } impl BitAnd for &RoaringTreemap { type Output = RoaringTreemap; /// An `intersection` between two sets. fn bitand(self, rhs: RoaringTreemap) -> RoaringTreemap { BitAnd::bitand(rhs, self) } } impl BitAnd<&RoaringTreemap> for &RoaringTreemap { type Output = RoaringTreemap; /// An `intersection` between two sets. fn bitand(self, rhs: &RoaringTreemap) -> RoaringTreemap { if rhs.len() < self.len() { BitAnd::bitand(self.clone(), rhs) } else { BitAnd::bitand(rhs.clone(), self) } } } impl BitAndAssign for RoaringTreemap { /// An `intersection` between two sets. fn bitand_assign(&mut self, mut rhs: RoaringTreemap) { // We make sure that we apply the intersection operation on the smallest map. if rhs.len() < self.len() { mem::swap(self, &mut rhs); } BitAndAssign::bitand_assign(self, &rhs) } } impl BitAndAssign<&RoaringTreemap> for RoaringTreemap { /// An `intersection` between two sets. fn bitand_assign(&mut self, rhs: &RoaringTreemap) { let mut keys_to_remove: Vec = Vec::new(); for (key, self_rb) in &mut self.map { match rhs.map.get(key) { Some(other_rb) => { BitAndAssign::bitand_assign(self_rb, other_rb); if self_rb.is_empty() { keys_to_remove.push(*key); } } None => keys_to_remove.push(*key), } } for key in keys_to_remove { self.map.remove(&key); } } } impl Sub for RoaringTreemap { type Output = RoaringTreemap; /// A `difference` between two sets. fn sub(mut self, rhs: RoaringTreemap) -> RoaringTreemap { SubAssign::sub_assign(&mut self, rhs); self } } impl Sub<&RoaringTreemap> for RoaringTreemap { type Output = RoaringTreemap; /// A `difference` between two sets. fn sub(mut self, rhs: &RoaringTreemap) -> RoaringTreemap { SubAssign::sub_assign(&mut self, rhs); self } } impl Sub for &RoaringTreemap { type Output = RoaringTreemap; /// A `difference` between two sets. fn sub(self, rhs: RoaringTreemap) -> RoaringTreemap { Sub::sub(self.clone(), rhs) } } impl Sub<&RoaringTreemap> for &RoaringTreemap { type Output = RoaringTreemap; /// A `difference` between two sets. fn sub(self, rhs: &RoaringTreemap) -> RoaringTreemap { Sub::sub(self.clone(), rhs) } } impl SubAssign for RoaringTreemap { /// A `difference` between two sets. fn sub_assign(&mut self, rhs: RoaringTreemap) { SubAssign::sub_assign(self, &rhs) } } impl SubAssign<&RoaringTreemap> for RoaringTreemap { /// A `difference` between two sets. fn sub_assign(&mut self, rhs: &RoaringTreemap) { for (key, rhs_rb) in &rhs.map { match self.map.entry(*key) { Entry::Vacant(_entry) => (), Entry::Occupied(mut entry) => { SubAssign::sub_assign(entry.get_mut(), rhs_rb); if entry.get().is_empty() { entry.remove_entry(); } } } } } } impl BitXor for RoaringTreemap { type Output = RoaringTreemap; /// A `symmetric difference` between two sets. fn bitxor(mut self, rhs: RoaringTreemap) -> RoaringTreemap { BitXorAssign::bitxor_assign(&mut self, rhs); self } } impl BitXor<&RoaringTreemap> for RoaringTreemap { type Output = RoaringTreemap; /// A `symmetric difference` between two sets. fn bitxor(mut self, rhs: &RoaringTreemap) -> RoaringTreemap { BitXorAssign::bitxor_assign(&mut self, rhs); self } } impl BitXor for &RoaringTreemap { type Output = RoaringTreemap; /// A `symmetric difference` between two sets. fn bitxor(self, rhs: RoaringTreemap) -> RoaringTreemap { BitXor::bitxor(rhs, self) } } impl BitXor<&RoaringTreemap> for &RoaringTreemap { type Output = RoaringTreemap; /// A `symmetric difference` between two sets. fn bitxor(self, rhs: &RoaringTreemap) -> RoaringTreemap { if self.len() < rhs.len() { BitXor::bitxor(self, rhs.clone()) } else { BitXor::bitxor(self.clone(), rhs) } } } impl BitXorAssign for RoaringTreemap { /// A `symmetric difference` between two sets. fn bitxor_assign(&mut self, rhs: RoaringTreemap) { for (key, other_rb) in rhs.map { match self.map.entry(key) { Entry::Vacant(entry) => { entry.insert(other_rb); } Entry::Occupied(mut entry) => { BitXorAssign::bitxor_assign(entry.get_mut(), other_rb); if entry.get().is_empty() { entry.remove_entry(); } } } } } } impl BitXorAssign<&RoaringTreemap> for RoaringTreemap { /// A `symmetric difference` between two sets. fn bitxor_assign(&mut self, rhs: &RoaringTreemap) { for (key, other_rb) in &rhs.map { match self.map.entry(*key) { Entry::Vacant(entry) => { entry.insert(other_rb.clone()); } Entry::Occupied(mut entry) => { BitXorAssign::bitxor_assign(entry.get_mut(), other_rb); if entry.get().is_empty() { entry.remove_entry(); } } } } } } #[cfg(test)] mod test { use crate::{MultiOps, RoaringTreemap}; use proptest::prelude::*; // fast count tests proptest! { #[test] fn union_len_eq_len_of_materialized_union( a in RoaringTreemap::arbitrary(), b in RoaringTreemap::arbitrary() ) { prop_assert_eq!(a.union_len(&b), (a | b).len()); } #[test] fn intersection_len_eq_len_of_materialized_intersection( a in RoaringTreemap::arbitrary(), b in RoaringTreemap::arbitrary() ) { prop_assert_eq!(a.intersection_len(&b), (a & b).len()); } #[test] fn difference_len_eq_len_of_materialized_difference( a in RoaringTreemap::arbitrary(), b in RoaringTreemap::arbitrary() ) { prop_assert_eq!(a.difference_len(&b), (a - b).len()); } #[test] fn symmetric_difference_len_eq_len_of_materialized_symmetric_difference( a in RoaringTreemap::arbitrary(), b in RoaringTreemap::arbitrary() ) { prop_assert_eq!(a.symmetric_difference_len(&b), (a ^ b).len()); } #[test] fn all_union_give_the_same_result( a in RoaringTreemap::arbitrary(), b in RoaringTreemap::arbitrary(), c in RoaringTreemap::arbitrary() ) { let mut ref_assign = a.clone(); ref_assign |= &b; ref_assign |= &c; let mut own_assign = a.clone(); own_assign |= b.clone(); own_assign |= c.clone(); let ref_inline = &a | &b | &c; let own_inline = a.clone() | b.clone() | c.clone(); let ref_multiop = [&a, &b, &c].union(); let own_multiop = [a, b.clone(), c.clone()].union(); for roar in &[own_assign, ref_inline, own_inline, ref_multiop, own_multiop] { prop_assert_eq!(&ref_assign, roar); } } #[test] fn all_intersection_give_the_same_result( a in RoaringTreemap::arbitrary(), b in RoaringTreemap::arbitrary(), c in RoaringTreemap::arbitrary() ) { let mut ref_assign = a.clone(); ref_assign &= &b; ref_assign &= &c; let mut own_assign = a.clone(); own_assign &= b.clone(); own_assign &= c.clone(); let ref_inline = &a & &b & &c; let own_inline = a.clone() & b.clone() & c.clone(); let ref_multiop = [&a, &b, &c].intersection(); let own_multiop = [a, b.clone(), c.clone()].intersection(); for roar in &[own_assign, ref_inline, own_inline, ref_multiop, own_multiop] { prop_assert_eq!(&ref_assign, roar); } } #[test] fn all_difference_give_the_same_result( a in RoaringTreemap::arbitrary(), b in RoaringTreemap::arbitrary(), c in RoaringTreemap::arbitrary() ) { let mut ref_assign = a.clone(); ref_assign -= &b; ref_assign -= &c; let mut own_assign = a.clone(); own_assign -= b.clone(); own_assign -= c.clone(); let ref_inline = &a - &b - &c; let own_inline = a.clone() - b.clone() - c.clone(); let ref_multiop = [&a, &b, &c].difference(); let own_multiop = [a, b.clone(), c.clone()].difference(); for roar in &[own_assign, ref_inline, own_inline, ref_multiop, own_multiop] { prop_assert_eq!(&ref_assign, roar); } } #[test] fn all_symmetric_difference_give_the_same_result( a in RoaringTreemap::arbitrary(), b in RoaringTreemap::arbitrary(), c in RoaringTreemap::arbitrary() ) { let mut ref_assign = a.clone(); ref_assign ^= &b; ref_assign ^= &c; let mut own_assign = a.clone(); own_assign ^= b.clone(); own_assign ^= c.clone(); let ref_inline = &a ^ &b ^ &c; let own_inline = a.clone() ^ b.clone() ^ c.clone(); let ref_multiop = [&a, &b, &c].symmetric_difference(); let own_multiop = [a, b.clone(), c.clone()].symmetric_difference(); for roar in &[own_assign, ref_inline, own_inline, ref_multiop, own_multiop] { prop_assert_eq!(&ref_assign, roar); } } } } roaring-0.10.2/src/treemap/serde.rs000064400000000000000000000046001046102023000152410ustar 00000000000000use serde::de::SeqAccess; use serde::de::Visitor; use serde::Deserialize; use serde::Deserializer; use serde::Serialize; use crate::RoaringTreemap; impl<'de> Deserialize<'de> for RoaringTreemap { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { struct TreemapVisitor; impl<'de> Visitor<'de> for TreemapVisitor { type Value = RoaringTreemap; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("roaring bitmap") } fn visit_bytes(self, bytes: &[u8]) -> Result where E: serde::de::Error, { RoaringTreemap::deserialize_from(bytes).map_err(serde::de::Error::custom) } // in some case bytes will be serialized as a sequence thus we need to accept both // even if it means non optimal performance fn visit_seq(self, mut seq: A) -> Result where A: SeqAccess<'de>, { let mut bytes: Vec = Vec::new(); while let Some(el) = seq.next_element()? { bytes.push(el); } RoaringTreemap::deserialize_from(&*bytes).map_err(serde::de::Error::custom) } } deserializer.deserialize_bytes(TreemapVisitor) } } impl Serialize for RoaringTreemap { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { let mut buf = Vec::new(); self.serialize_into(&mut buf).map_err(serde::ser::Error::custom)?; serializer.serialize_bytes(&buf) } } #[cfg(test)] mod test { use crate::RoaringTreemap; use proptest::prelude::*; proptest! { #[test] fn test_serde_json( treemap in RoaringTreemap::arbitrary(), ) { let json = serde_json::to_vec(&treemap).unwrap(); prop_assert_eq!(treemap, serde_json::from_slice(&json).unwrap()); } #[test] fn test_bincode( treemap in RoaringTreemap::arbitrary(), ) { let buffer = bincode::serialize(&treemap).unwrap(); prop_assert_eq!(treemap, bincode::deserialize(&buffer).unwrap()); } } } roaring-0.10.2/src/treemap/serialization.rs000064400000000000000000000101111046102023000170060ustar 00000000000000use super::RoaringTreemap; use crate::RoaringBitmap; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use std::{io, mem::size_of}; impl RoaringTreemap { /// Return the size in bytes of the serialized output. /// This is compatible with the official C/C++, Java and Go implementations. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let rb1: RoaringTreemap = (1..4).collect(); /// let mut bytes = Vec::with_capacity(rb1.serialized_size()); /// rb1.serialize_into(&mut bytes).unwrap(); /// let rb2 = RoaringTreemap::deserialize_from(&bytes[..]).unwrap(); /// /// assert_eq!(rb1, rb2); /// ``` pub fn serialized_size(&self) -> usize { self.map .values() .fold(size_of::(), |acc, bitmap| acc + size_of::() + bitmap.serialized_size()) } /// Serialize this bitmap. /// This is compatible with the official C/C++, Java and Go implementations. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let rb1: RoaringTreemap = (1..4).collect(); /// let mut bytes = vec![]; /// rb1.serialize_into(&mut bytes).unwrap(); /// let rb2 = RoaringTreemap::deserialize_from(&bytes[..]).unwrap(); /// /// assert_eq!(rb1, rb2); /// ``` pub fn serialize_into(&self, mut writer: W) -> io::Result<()> { writer.write_u64::(self.map.len() as u64)?; for (key, bitmap) in &self.map { writer.write_u32::(*key)?; bitmap.serialize_into(&mut writer)?; } Ok(()) } /// Deserialize a bitmap into memory. /// /// This is compatible with the official C/C++, Java and Go implementations. /// This method checks that all of the internal values are valid. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let rb1: RoaringTreemap = (1..4).collect(); /// let mut bytes = vec![]; /// rb1.serialize_into(&mut bytes).unwrap(); /// let rb2 = RoaringTreemap::deserialize_from(&bytes[..]).unwrap(); /// /// assert_eq!(rb1, rb2); /// ``` pub fn deserialize_from(reader: R) -> io::Result { RoaringTreemap::deserialize_from_impl(reader, |reader| { RoaringBitmap::deserialize_from(reader) }) } /// Deserialize a bitmap into memory. /// /// This is compatible with the official C/C++, Java and Go implementations. /// This method is memory safe but will not check if the data is a valid bitmap. /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// /// let rb1: RoaringTreemap = (1..4).collect(); /// let mut bytes = vec![]; /// rb1.serialize_into(&mut bytes).unwrap(); /// let rb2 = RoaringTreemap::deserialize_unchecked_from(&bytes[..]).unwrap(); /// /// assert_eq!(rb1, rb2); /// ``` pub fn deserialize_unchecked_from(reader: R) -> io::Result { RoaringTreemap::deserialize_from_impl(reader, |reader| { RoaringBitmap::deserialize_unchecked_from(reader) }) } fn deserialize_from_impl(mut reader: R, mut deserialize_bitmap: F) -> io::Result where R: io::Read, F: FnMut(&mut R) -> io::Result, { let size = reader.read_u64::()?; let mut s = Self::new(); for _ in 0..size { let key = reader.read_u32::()?; let bitmap = deserialize_bitmap(&mut reader)?; s.map.insert(key, bitmap); } Ok(s) } } #[cfg(test)] mod test { use crate::RoaringTreemap; use proptest::prelude::*; proptest! { #[test] fn test_serialization( treemap in RoaringTreemap::arbitrary(), ) { let mut buffer = Vec::new(); treemap.serialize_into(&mut buffer).unwrap(); prop_assert_eq!(treemap, RoaringTreemap::deserialize_from(buffer.as_slice()).unwrap()); } } } roaring-0.10.2/src/treemap/util.rs000064400000000000000000000054541046102023000151240ustar 00000000000000use std::ops::{Bound, RangeBounds, RangeInclusive}; #[inline] pub fn split(value: u64) -> (u32, u32) { ((value >> 32) as u32, value as u32) } #[inline] pub fn join(high: u32, low: u32) -> u64 { (u64::from(high) << 32) | u64::from(low) } /// Convert a `RangeBounds` object to `RangeInclusive`, pub fn convert_range_to_inclusive(range: R) -> Option> where R: RangeBounds, { let start: u64 = match range.start_bound() { Bound::Included(&i) => i, Bound::Excluded(&u64::MAX) => return None, Bound::Excluded(&i) => i + 1, Bound::Unbounded => 0, }; let end: u64 = match range.end_bound() { Bound::Included(&i) => i, Bound::Excluded(&0) => return None, Bound::Excluded(&i) => i - 1, Bound::Unbounded => u64::MAX, }; if end < start { return None; } Some(start..=end) } #[cfg(test)] mod test { use super::{convert_range_to_inclusive, join, split}; #[test] fn test_split_u64() { assert_eq!((0x0000_0000u32, 0x0000_0000u32), split(0x0000_0000_0000_0000u64)); assert_eq!((0x0000_0000u32, 0x0000_0001u32), split(0x0000_0000_0000_0001u64)); assert_eq!((0x0000_0000u32, 0xFFFF_FFFEu32), split(0x0000_0000_FFFF_FFFEu64)); assert_eq!((0x0000_0000u32, 0xFFFF_FFFFu32), split(0x0000_0000_FFFF_FFFFu64)); assert_eq!((0x0000_0001u32, 0x0000_0000u32), split(0x0000_0001_0000_0000u64)); assert_eq!((0x0000_0001u32, 0x0000_0001u32), split(0x0000_0001_0000_0001u64)); assert_eq!((0xFFFF_FFFFu32, 0xFFFF_FFFEu32), split(0xFFFF_FFFF_FFFF_FFFEu64)); assert_eq!((0xFFFF_FFFFu32, 0xFFFF_FFFFu32), split(0xFFFF_FFFF_FFFF_FFFFu64)); } #[test] fn test_join_u64() { assert_eq!(0x0000_0000_0000_0000u64, join(0x0000_0000u32, 0x0000_0000u32)); assert_eq!(0x0000_0000_0000_0001u64, join(0x0000_0000u32, 0x0000_0001u32)); assert_eq!(0x0000_0000_FFFF_FFFEu64, join(0x0000_0000u32, 0xFFFF_FFFEu32)); assert_eq!(0x0000_0000_FFFF_FFFFu64, join(0x0000_0000u32, 0xFFFF_FFFFu32)); assert_eq!(0x0000_0001_0000_0000u64, join(0x0000_0001u32, 0x0000_0000u32)); assert_eq!(0x0000_0001_0000_0001u64, join(0x0000_0001u32, 0x0000_0001u32)); assert_eq!(0xFFFF_FFFF_FFFF_FFFEu64, join(0xFFFF_FFFFu32, 0xFFFF_FFFEu32)); assert_eq!(0xFFFF_FFFF_FFFF_FFFFu64, join(0xFFFF_FFFFu32, 0xFFFF_FFFFu32)); } #[test] fn test_convert_range_to_inclusive() { assert_eq!(Some(1..=5), convert_range_to_inclusive(1..6)); assert_eq!(Some(1..=u64::MAX), convert_range_to_inclusive(1..)); assert_eq!(Some(0..=u64::MAX), convert_range_to_inclusive(..)); assert_eq!(None, convert_range_to_inclusive(5..5)); assert_eq!(Some(16..=16), convert_range_to_inclusive(16..=16)) } } roaring-0.10.2/tests/bitmapwithoutruns.bin000064400000000000000000002156501046102023000170220ustar 00000000000000:0 A! $TUUUTUTU ? ŸQ ÿÿ ÿ4`ä((!(A(a((¡¨»¨Û¨ûèи  ˆpX@(#'ø*à.È2°6˜:€>hBPF8J NRðUØYÀ]¨aexi`mHq0uy}è€Ð„¸ˆ Œˆp”X˜@œ( ¤ø§à«È¯°³˜·€»h¿PÃ8Ç ËÏðÒØÖÀÚ¨Þâxæ`êHî0òöúèýи  ˆ pX@(!ø$à(È,°0˜4€8hADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý         ! $ ' * - 0 3 6 9 < ? B E H K N Q T W Z ] ` c f i l o r u x { ~ „ ‡ Š “ – ™ œ Ÿ ¢ ¥ ¨ « ® ± ´ · º ½ À Ã Æ É Ì Ï Ò Õ Ø Û Þ á ä ç ê í ð ó ö ù ü ÿ          # & ) , / 2 5 8 ; > A D G J M P S V Y \ _ b e h k n q t w z } € ƒ † ‰ Œ ’ • ˜ › ž ¡ ¤ § ª ­ ° ³ ¶ ¹ ¼ ¿ Â Å È Ë Î Ñ Ô × Ú Ý à ã æ é ì ï ò õ ø û þ          " % ( + . 1 4 7 : = @ C F I L O R U X [ ^ a d g j m p s v y |  ‚ … ˆ ‹ Ž ‘ ” — š   £ ¦ © ¬ ¯ ² µ ¸ » ¾ Á Ä Ç Ê Í Ð Ó Ö Ù Ü ß â å è ë î ñ ô ÷ ú ý         ! $ ' * - 0 3 6 9 < ? B E H K N Q T W Z ] ` c f i l o r u x { ~ „ ‡ Š “ – ™ œ Ÿ ¢ ¥ ¨ « ® ± ´ · º ½ À Ã Æ É Ì Ï Ò Õ Ø Û Þ á ä ç ê í ð ó ö ù ü ÿ          # & ) , / 2 5 8 ; > A D G J M P S V Y \ _ b e h k n q t w z } € ƒ † ‰ Œ ’ • ˜ › ž ¡ ¤ § ª ­ ° ³ ¶ ¹ ¼ ¿ Â Å È Ë Î Ñ Ô × Ú Ý à ã æ é ì ï ò õ ø û þ   "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ         " % ( + . 1 4 7 : = @ C F I L O R U X [ ^ a d g j m p s v y |  ‚ … ˆ ‹ Ž ‘ ” — š   £ ¦ © ¬ ¯ ² µ ¸ » ¾ Á Ä Ç Ê Í Ð Ó Ö Ù Ü ß â å è ë î ñ ô ÷ ú ý !!! ! !!!!!!!!!$!'!*!-!0!3!6!9!"A"D"G"J"M"P"S"V"Y"\"_"b"e"h"k"n"q"t"w"z"}"€"ƒ"†"‰"Œ""’"•"˜"›"ž"¡"¤"§"ª"­"°"³"¶"¹"¼"¿"Â"Å"È"Ë"Î"Ñ"Ô"×"Ú"Ý"à"ã"æ"é"ì"ï"ò"õ"ø"û"þ"### # #######"#%#(#+#.#1#4#7#:#=#@#C#F#I#L#O#R#U#X#[#^#a#d#g#j#m#p#s#v#y#|##‚#…#ˆ#‹#Ž#‘#”#—#š## #£#¦#©#¬#¯#²#µ#¸#»#¾#Á#Ä#Ç#Ê#Í#Ð#Ó#Ö#Ù#Ü#ß#â#å#è#ë#î#ñ#ô#÷#ú#ý#$$$ $ $$$$$$$!$$$'$*$-$0$3$6$9$<$?$B$E$H$K$N$Q$T$W$Z$]$`$c$f$i$l$o$r$u$x${$~$$„$‡$Š$$$“$–$™$œ$Ÿ$¢$¥$¨$«$®$±$´$·$º$½$À$Ã$Æ$É$Ì$Ï$Ò$Õ$Ø$Û$Þ$á$ä$ç$ê$í$ð$ó$ö$ù$ü$ÿ$%%% %%%%%%% %#%&%)%,%/%2%5%8%;%>%A%D%G%J%M%P%S%V%Y%\%_%b%e%h%k%n%q%t%w%z%}%€%ƒ%†%‰%Œ%%’%•%˜%›%ž%¡%¤%§%ª%­%°%³%¶%¹%¼%¿%Â%Å%È%Ë%Î%Ñ%Ô%×%Ú%Ý%à%ã%æ%é%ì%ï%ò%õ%ø%û%þ%&&& & &&&&&&&"&%&(&+&.&1&4&7&:&=&@&C&F&I&L&O&R&U&X&[&^&a&d&g&j&m&p&s&v&y&|&&‚&…&ˆ&‹&Ž&‘&”&—&š&& &£&¦&©&¬&¯&²&µ&¸&»&¾&Á&Ä&Ç&Ê&Í&Ð&Ó&Ö&Ù&Ü&ß&â&å&è&ë&î&ñ&ô&÷&ú&ý&''' ' '''''''!'$'''*'-'0'3'6'9'<'?'B'E'H'K'N'Q'T'W'Z']'`'c'f'i'l'o'r'u'x'{'~''„'‡'Š'''“'–'™'œ'Ÿ'¢'¥'¨'«'®'±'´'·'º'½'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿroaring-0.10.2/tests/bitmapwithruns.bin000064400000000000000000001356701046102023000162750ustar 00000000000000;0 A! $TUUUTUTU ? ŸQ ÿÿ ÿ4^â&&!&A&a&&¡¦»¬»²»èи  ˆpX@(#'ø*à.È2°6˜:€>hBPF8J NRðUØYÀ]¨aexi`mHq0uy}è€Ð„¸ˆ Œˆp”X˜@œ( ¤ø§à«È¯°³˜·€»h¿PÃ8Ç ËÏðÒØÖÀÚ¨Þâxæ`êHî0òöúèýи  ˆ pX@(!ø$à(È,°0˜4€8hADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý         ! $ ' * - 0 3 6 9 < ? B E H K N Q T W Z ] ` c f i l o r u x { ~ „ ‡ Š “ – ™ œ Ÿ ¢ ¥ ¨ « ® ± ´ · º ½ À Ã Æ É Ì Ï Ò Õ Ø Û Þ á ä ç ê í ð ó ö ù ü ÿ          # & ) , / 2 5 8 ; > A D G J M P S V Y \ _ b e h k n q t w z } € ƒ † ‰ Œ ’ • ˜ › ž ¡ ¤ § ª ­ ° ³ ¶ ¹ ¼ ¿ Â Å È Ë Î Ñ Ô × Ú Ý à ã æ é ì ï ò õ ø û þ          " % ( + . 1 4 7 : = @ C F I L O R U X [ ^ a d g j m p s v y |  ‚ … ˆ ‹ Ž ‘ ” — š   £ ¦ © ¬ ¯ ² µ ¸ » ¾ Á Ä Ç Ê Í Ð Ó Ö Ù Ü ß â å è ë î ñ ô ÷ ú ý         ! $ ' * - 0 3 6 9 < ? B E H K N Q T W Z ] ` c f i l o r u x { ~ „ ‡ Š “ – ™ œ Ÿ ¢ ¥ ¨ « ® ± ´ · º ½ À Ã Æ É Ì Ï Ò Õ Ø Û Þ á ä ç ê í ð ó ö ù ü ÿ          # & ) , / 2 5 8 ; > A D G J M P S V Y \ _ b e h k n q t w z } € ƒ † ‰ Œ ’ • ˜ › ž ¡ ¤ § ª ­ ° ³ ¶ ¹ ¼ ¿ Â Å È Ë Î Ñ Ô × Ú Ý à ã æ é ì ï ò õ ø û þ   "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ  "%(+.147:=@CFILORUX[^adgjmpsvy|‚…ˆ‹Ž‘”—𠣦©¬¯²µ¸»¾ÁÄÇÊÍÐÓÖÙÜßâåèëîñô÷úý  !$'*-0369<?BEHKNQTWZ]`cfilorux{~„‡Š“–™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏÒÕØÛÞáäçêíðóöùüÿ  #&),/258;>ADGJMPSVY\_behknqtwz}€ƒ†‰Œ’•˜›ž¡¤§ª­°³¶¹¼¿ÂÅÈËÎÑÔ×ÚÝàãæéìïòõøûþ         " % ( + . 1 4 7 : = @ C F I L O R U X [ ^ a d g j m p s v y |  ‚ … ˆ ‹ Ž ‘ ” — š   £ ¦ © ¬ ¯ ² µ ¸ » ¾ Á Ä Ç Ê Í Ð Ó Ö Ù Ü ß â å è ë î ñ ô ÷ ú ý !!! ! !!!!!!!!!$!'!*!-!0!3!6!9!"A"D"G"J"M"P"S"V"Y"\"_"b"e"h"k"n"q"t"w"z"}"€"ƒ"†"‰"Œ""’"•"˜"›"ž"¡"¤"§"ª"­"°"³"¶"¹"¼"¿"Â"Å"È"Ë"Î"Ñ"Ô"×"Ú"Ý"à"ã"æ"é"ì"ï"ò"õ"ø"û"þ"### # #######"#%#(#+#.#1#4#7#:#=#@#C#F#I#L#O#R#U#X#[#^#a#d#g#j#m#p#s#v#y#|##‚#…#ˆ#‹#Ž#‘#”#—#š## #£#¦#©#¬#¯#²#µ#¸#»#¾#Á#Ä#Ç#Ê#Í#Ð#Ó#Ö#Ù#Ü#ß#â#å#è#ë#î#ñ#ô#÷#ú#ý#$$$ $ $$$$$$$!$$$'$*$-$0$3$6$9$<$?$B$E$H$K$N$Q$T$W$Z$]$`$c$f$i$l$o$r$u$x${$~$$„$‡$Š$$$“$–$™$œ$Ÿ$¢$¥$¨$«$®$±$´$·$º$½$À$Ã$Æ$É$Ì$Ï$Ò$Õ$Ø$Û$Þ$á$ä$ç$ê$í$ð$ó$ö$ù$ü$ÿ$%%% %%%%%%% %#%&%)%,%/%2%5%8%;%>%A%D%G%J%M%P%S%V%Y%\%_%b%e%h%k%n%q%t%w%z%}%€%ƒ%†%‰%Œ%%’%•%˜%›%ž%¡%¤%§%ª%­%°%³%¶%¹%¼%¿%Â%Å%È%Ë%Î%Ñ%Ô%×%Ú%Ý%à%ã%æ%é%ì%ï%ò%õ%ø%û%þ%&&& & &&&&&&&"&%&(&+&.&1&4&7&:&=&@&C&F&I&L&O&R&U&X&[&^&a&d&g&j&m&p&s&v&y&|&&‚&…&ˆ&‹&Ž&‘&”&—&š&& &£&¦&©&¬&¯&²&µ&¸&»&¾&Á&Ä&Ç&Ê&Í&Ð&Ó&Ö&Ù&Ü&ß&â&å&è&ë&î&ñ&ô&÷&ú&ý&''' ' '''''''!'$'''*'-'0'3'6'9'<'?'B'E'H'K'N'Q'T'W'Z']'`'c'f'i'l'o'r'u'x'{'~''„'‡'Š'''“'–'™'œ'Ÿ'¢'¥'¨'«'®'±'´'·'º'½'`®ŸQÿÿÿ4roaring-0.10.2/tests/clone.rs000064400000000000000000000016701046102023000141610ustar 00000000000000extern crate roaring; use roaring::RoaringBitmap; #[test] #[allow(clippy::redundant_clone)] fn array() { let original = (0..2000).collect::(); let clone = original.clone(); assert_eq!(clone, original); } #[test] #[allow(clippy::redundant_clone)] fn bitmap() { let original = (0..6000).collect::(); let clone = original.clone(); assert_eq!(clone, original); } #[test] #[allow(clippy::redundant_clone)] fn arrays() { let original = (0..2000) .chain(1_000_000..1_002_000) .chain(2_000_000..2_001_000) .collect::(); let clone = original.clone(); assert_eq!(clone, original); } #[test] #[allow(clippy::redundant_clone)] fn bitmaps() { let original = (0..6000) .chain(1_000_000..1_012_000) .chain(2_000_000..2_010_000) .collect::(); let clone = original.clone(); assert_eq!(clone, original); } roaring-0.10.2/tests/difference_with.rs000064400000000000000000000063061046102023000162070ustar 00000000000000extern crate roaring; use roaring::RoaringBitmap; #[test] fn array() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..3000).collect::(); let bitmap3 = (0..1000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn no_difference() { let mut bitmap1 = (1..3).collect::(); let bitmap2 = (1..3).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, RoaringBitmap::new()); } #[test] fn array_and_bitmap() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..8000).collect::(); let bitmap3 = (0..1000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_to_bitmap() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (6000..18000).collect::(); let bitmap3 = (0..6000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_to_array() { let mut bitmap1 = (0..6000).collect::(); let bitmap2 = (3000..9000).collect::(); let bitmap3 = (0..3000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_and_array_to_bitmap() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (9000..12000).collect::(); let bitmap3 = (0..9000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_and_array_to_array() { let mut bitmap1 = (0..6000).collect::(); let bitmap2 = (3000..6000).collect::(); let bitmap3 = (0..3000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn arrays() { let mut bitmap1 = (0..2000) .chain(1_000_000..1_002_000) .chain(2_000_000..2_001_000) .collect::(); let bitmap2 = (1000..3000) .chain(1_001_000..1_003_000) .chain(2_000_000..2_001_000) .collect::(); let bitmap3 = (0..1000).chain(1_000_000..1_001_000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn arrays_removing_one_whole_container() { let mut bitmap1 = (0..2000) .chain(1_000_000..1_002_000) .chain(2_000_000..2_001_000) .collect::(); let bitmap2 = (0..3000) .chain(1_001_000..1_003_000) .chain(2_000_000..2_001_000) .collect::(); let bitmap3 = (1_000_000..1_001_000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmaps() { let mut bitmap1 = (0..6000) .chain(1_000_000..1_012_000) .chain(2_000_000..2_010_000) .collect::(); let bitmap2 = (3000..9000) .chain(1_006_000..1_018_000) .chain(2_000_000..2_010_000) .collect::(); let bitmap3 = (0..3000).chain(1_000_000..1_006_000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } roaring-0.10.2/tests/intersect_with.rs000064400000000000000000000047531046102023000161210ustar 00000000000000extern crate roaring; use roaring::RoaringBitmap; #[test] fn array() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..3000).collect::(); let bitmap3 = (1000..2000).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn no_intersection() { let mut bitmap1 = (0..2).collect::(); let bitmap2 = (3..4).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, RoaringBitmap::new()); } #[test] fn array_and_bitmap() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..8000).collect::(); let bitmap3 = (1000..2000).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_to_bitmap() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (6000..18000).collect::(); let bitmap3 = (6000..12000).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_to_array() { let mut bitmap1 = (0..6000).collect::(); let bitmap2 = (3000..9000).collect::(); let bitmap3 = (3000..6000).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_and_array() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (7000..9000).collect::(); let bitmap3 = (7000..9000).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn arrays() { let mut bitmap1 = (0..2000) .chain(1_000_000..1_002_000) .chain(3_000_000..3_001_000) .collect::(); let bitmap2 = (1000..3000) .chain(1_001_000..1_003_000) .chain(2_000_000..2_001_000) .collect::(); let bitmap3 = (1000..2000).chain(1_001_000..1_002_000).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmaps() { let mut bitmap1 = (0..6000) .chain(1_000_000..1_012_000) .chain(3_000_000..3_010_000) .collect::(); let bitmap2 = (3000..9000) .chain(1_006_000..1_018_000) .chain(2_000_000..2_010_000) .collect::(); let bitmap3 = (3000..6000).chain(1_006_000..1_012_000).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, bitmap3); } roaring-0.10.2/tests/is_disjoint.rs000064400000000000000000000037371046102023000154050ustar 00000000000000extern crate roaring; use roaring::RoaringBitmap; #[test] fn array() { let bitmap1 = (0..2000).collect::(); let bitmap2 = (4000..6000).collect::(); assert!(bitmap1.is_disjoint(&bitmap2)); } #[test] fn array_not() { let bitmap1 = (0..4000).collect::(); let bitmap2 = (2000..6000).collect::(); assert!(!bitmap1.is_disjoint(&bitmap2)); } #[test] fn bitmap() { let bitmap1 = (0..6000).collect::(); let bitmap2 = (10000..16000).collect::(); assert!(bitmap1.is_disjoint(&bitmap2)); } #[test] fn bitmap_not() { let bitmap1 = (0..10000).collect::(); let bitmap2 = (5000..15000).collect::(); assert!(!bitmap1.is_disjoint(&bitmap2)); } #[test] fn arrays() { let bitmap1 = (0..2000) .chain(1_000_000..1_002_000) .chain(2_000_000..2_002_000) .collect::(); let bitmap2 = (100_000..102_000).chain(1_100_000..1_102_000).collect::(); assert!(bitmap1.is_disjoint(&bitmap2)); } #[test] fn arrays_not() { let bitmap1 = (0..2_000) .chain(1_000_000..1_002_000) .chain(2_000_000..2_002_000) .collect::(); let bitmap2 = (100_000..102_000).chain(1_001_000..1_003_000).collect::(); assert!(!bitmap1.is_disjoint(&bitmap2)); } #[test] fn bitmaps() { let bitmap1 = (0..6000) .chain(1_000_000..1_006_000) .chain(2_000_000..2_006_000) .collect::(); let bitmap2 = (100_000..106_000).chain(1_100_000..1_106_000).collect::(); assert!(bitmap1.is_disjoint(&bitmap2)); } #[test] fn bitmaps_not() { let bitmap1 = (0..6000) .chain(1_000_000..1_006_000) .chain(2_000_000..2_006_000) .collect::(); let bitmap2 = (100_000..106_000).chain(1_004_000..1_008_000).collect::(); assert!(!bitmap1.is_disjoint(&bitmap2)); } roaring-0.10.2/tests/is_subset.rs000064400000000000000000000042461046102023000150630ustar 00000000000000extern crate roaring; use roaring::RoaringBitmap; #[test] fn array_not() { let sup = (0..2000).collect::(); let sub = (1000..3000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn array() { let sup = (0..4000).collect::(); let sub = (2000..3000).collect::(); assert!(sub.is_subset(&sup)); } #[test] fn array_bitmap_not() { let sup = (0..2000).collect::(); let sub = (1000..15000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn bitmap_not() { let sup = (0..6000).collect::(); let sub = (4000..10000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn bitmap() { let sup = (0..20000).collect::(); let sub = (5000..15000).collect::(); assert!(sub.is_subset(&sup)); } #[test] fn bitmap_array_not() { let sup = (0..20000).collect::(); let sub = (19000..21000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn bitmap_array() { let sup = (0..20000).collect::(); let sub = (18000..20000).collect::(); assert!(sub.is_subset(&sup)); } #[test] fn arrays_not() { let sup = (0..2000).chain(1_000_000..1_002_000).collect::(); let sub = (100_000..102_000).chain(1_100_000..1_102_000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn arrays() { let sup = (0..3000).chain(100_000..103_000).collect::(); let sub = (0..2000).chain(100_000..102_000).collect::(); assert!(sub.is_subset(&sup)); } #[test] fn bitmaps_not() { let sup = (0..6000) .chain(1_000_000..1_006_000) .chain(2_000_000..2_010_000) .collect::(); let sub = (100_000..106_000).chain(1_100_000..1_106_000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn bitmaps() { let sup = (0..1_000_000).chain(2_000_000..2_010_000).collect::(); let sub = (0..10_000).chain(500_000..510_000).collect::(); assert!(sub.is_subset(&sup)); } roaring-0.10.2/tests/iter.rs000064400000000000000000000077541046102023000140350ustar 00000000000000use proptest::arbitrary::any; use proptest::collection::btree_set; use proptest::proptest; use std::iter::FromIterator; use roaring::RoaringBitmap; #[test] fn range() { let original = (0..2000).collect::(); let clone = RoaringBitmap::from_iter(&original); let clone2 = RoaringBitmap::from_iter(original.clone()); assert_eq!(clone, original); assert_eq!(clone2, original); } #[test] fn array() { let original = (0..5).collect::(); let clone = RoaringBitmap::from([0, 1, 2, 3, 4]); assert_eq!(clone, original); } #[test] fn bitmap() { let original = (0..100_000).collect::(); let clone = RoaringBitmap::from_iter(&original); let clone2 = RoaringBitmap::from_iter(original.clone()); assert_eq!(clone, original); assert_eq!(clone2, original); } #[test] fn arrays() { let original = (0..2000) .chain(1_000_000..1_002_000) .chain(2_000_000..2_001_000) .collect::(); let clone = RoaringBitmap::from_iter(&original); let clone2 = RoaringBitmap::from_iter(original.clone()); assert_eq!(clone, original); assert_eq!(clone2, original); } #[test] fn bitmaps() { let original = (0..100_000) .chain(1_000_000..1_012_000) .chain(2_000_000..2_010_000) .collect::(); let clone = RoaringBitmap::from_iter(&original); let clone2 = RoaringBitmap::from_iter(original.clone()); assert_eq!(clone, original); assert_eq!(clone2, original); } proptest! { #[test] fn iter(values in btree_set(any::(), ..=10_000)) { let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap(); // Iterator::eq != PartialEq::eq - cannot use assert_eq macro assert!(values.into_iter().eq(bitmap)); } } #[test] fn rev_array() { let values = 0..100; let bitmap = values.clone().collect::(); assert!(values.into_iter().rev().eq(bitmap.iter().rev())); } #[test] fn rev_bitmap() { let values = 0..=100_000; let bitmap = values.clone().collect::(); assert!(values.into_iter().rev().eq(bitmap.iter().rev())); } proptest! { #[test] fn rev_iter(values in btree_set(any::(), ..=10_000)) { let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap(); assert!(values.into_iter().rev().eq(bitmap.iter().rev())); } } #[test] fn from_iter() { // This test verifies that the public API allows conversion from iterators // with u32 as well as &u32 elements. let vals = vec![1, 5, 10000]; let a = RoaringBitmap::from_iter(vals.iter()); let b = RoaringBitmap::from_iter(vals); assert_eq!(a, b); } #[derive(Clone, Debug)] pub struct OutsideInIter(bool, T); impl Iterator for OutsideInIter where I: DoubleEndedIterator, { type Item = T; fn next(&mut self) -> Option { let res = if self.0 { self.1.next() } else { self.1.next_back() }; self.0 = !self.0; res } } pub fn outside_in(into_iter: I) -> OutsideInIter where U: DoubleEndedIterator, I: IntoIterator, { OutsideInIter(true, into_iter.into_iter()) } // Sanity check that outside_in does what we expect #[test] fn outside_in_iterator() { let values = 0..10; assert!(outside_in(values).eq(vec![0, 9, 1, 8, 2, 7, 3, 6, 4, 5])); } #[test] fn interleaved_array() { let values = 0..100; let bitmap = values.clone().collect::(); assert!(outside_in(values).eq(outside_in(bitmap))); } #[test] fn interleaved_bitmap() { let values = 0..=4097; let bitmap = values.clone().collect::(); assert!(outside_in(values).eq(outside_in(bitmap))); } proptest! { #[test] fn interleaved_iter(values in btree_set(any::(), 50_000..=100_000)) { let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap(); assert!(outside_in(values).eq(outside_in(bitmap))); } } roaring-0.10.2/tests/lib.rs000064400000000000000000000072131046102023000136260ustar 00000000000000extern crate roaring; use roaring::RoaringBitmap; #[test] fn smoke() { let mut bitmap = RoaringBitmap::new(); assert_eq!(bitmap.len(), 0); assert!(bitmap.is_empty()); bitmap.remove(0); assert_eq!(bitmap.len(), 0); assert!(bitmap.is_empty()); bitmap.insert(1); assert!(bitmap.contains(1)); assert_eq!(bitmap.len(), 1); assert!(!bitmap.is_empty()); bitmap.insert(u32::max_value() - 2); assert!(bitmap.contains(u32::max_value() - 2)); assert_eq!(bitmap.len(), 2); bitmap.insert(u32::max_value()); assert!(bitmap.contains(u32::max_value())); assert_eq!(bitmap.len(), 3); bitmap.insert(2); assert!(bitmap.contains(2)); assert_eq!(bitmap.len(), 4); bitmap.remove(2); assert!(!bitmap.contains(2)); assert_eq!(bitmap.len(), 3); assert!(!bitmap.contains(0)); assert!(bitmap.contains(1)); assert!(!bitmap.contains(100)); assert!(bitmap.contains(u32::max_value() - 2)); assert!(!bitmap.contains(u32::max_value() - 1)); assert!(bitmap.contains(u32::max_value())); } #[test] fn remove_range() { let ranges = [0u32, 1, 63, 64, 65, 100, 4096 - 1, 4096, 4096 + 1, 65536 - 1, 65536, 65536 + 1]; for (i, &a) in ranges.iter().enumerate() { for &b in &ranges[i..] { let mut bitmap = (0..=65536).collect::(); assert_eq!(bitmap.remove_range(a..b), u64::from(b - a)); assert_eq!(bitmap, (0..a).chain(b..=65536).collect::()); } } } #[test] #[allow(clippy::range_plus_one)] // remove_range needs an exclusive range fn remove_range_array() { let mut bitmap = (0..1000).collect::(); for i in 0..1000 { assert_eq!(bitmap.remove_range(i..i), 0); assert_eq!(bitmap.remove_range(i..i + 1), 1); } // insert 0, 2, 4, .. // remove [0, 2), [2, 4), .. let mut bitmap = (0..1000).map(|x| x * 2).collect::(); for i in 0..1000 { assert_eq!(bitmap.remove_range(i * 2..(i + 1) * 2), 1); } // remove [0, 2), [2, 4), .. let mut bitmap = (0..1000).collect::(); for i in 0..1000 / 2 { assert_eq!(bitmap.remove_range(i * 2..(i + 1) * 2), 2); } } #[test] #[allow(clippy::range_plus_one)] // remove_range needs an exclusive range fn remove_range_bitmap() { let mut bitmap = (0..4096 + 1000).collect::(); for i in 0..1000 { assert_eq!(bitmap.remove_range(i..i), 0); assert_eq!(bitmap.remove_range(i..i + 1), 1); } // insert 0, 2, 4, .. // remove [0, 2), [2, 4), .. let mut bitmap = ((0..4096 + 1000).map(|x| x * 2)).collect::(); for i in 0..1000 { assert_eq!(bitmap.remove_range(i * 2..(i + 1) * 2), 1); } // remove [0, 2), [2, 4), .. let mut bitmap = (0..4096 + 1000).collect::(); for i in 0..1000 / 2 { assert_eq!(bitmap.remove_range(i * 2..(i + 1) * 2), 2); } // remove [1, 3), [3, 5), .. let mut bitmap = (0..4096 + 1000).collect::(); for i in 0..1000 / 2 { assert_eq!(bitmap.remove_range(i * 2 + 1..(i + 1) * 2 + 1), 2); } } #[test] fn to_bitmap() { let bitmap = (0..5000).collect::(); assert_eq!(bitmap.len(), 5000); for i in 1..5000 { assert!(bitmap.contains(i)); } assert!(!bitmap.contains(5001)); } #[test] fn to_array() { let mut bitmap = (0..5000).collect::(); for i in 3000..5000 { bitmap.remove(i); } assert_eq!(bitmap.len(), 3000); for i in 0..3000 { assert!(bitmap.contains(i)); } for i in 3000..5000 { assert!(!bitmap.contains(i)); } } roaring-0.10.2/tests/ops.rs000064400000000000000000000036471046102023000136700ustar 00000000000000extern crate roaring; use roaring::RoaringBitmap; #[test] fn or() { let mut rb1 = (1..4).collect::(); let rb2 = (3..6).collect::(); let rb3 = (1..6).collect::(); assert_eq!(rb3, &rb1 | &rb2); assert_eq!(rb3, &rb1 | rb2.clone()); assert_eq!(rb3, rb1.clone() | &rb2); assert_eq!(rb3, rb1.clone() | rb2.clone()); assert_eq!(rb3.len(), rb1.union_len(&rb2)); rb1 |= &rb2; rb1 |= rb2; assert_eq!(rb3, rb1); } #[test] fn and() { let mut rb1 = (1..4).collect::(); let rb2 = (3..6).collect::(); let rb3 = (3..4).collect::(); assert_eq!(rb3, &rb1 & &rb2); assert_eq!(rb3, &rb1 & rb2.clone()); assert_eq!(rb3, rb1.clone() & &rb2); assert_eq!(rb3, rb1.clone() & rb2.clone()); assert_eq!(rb3.len(), rb1.intersection_len(&rb2)); rb1 &= &rb2; rb1 &= rb2; assert_eq!(rb3, rb1); } #[test] fn sub() { let mut rb1 = (1..4000).collect::(); let rb2 = (3..5000).collect::(); let rb3 = (1..3).collect::(); assert_eq!(rb3, &rb1 - &rb2); assert_eq!(rb3, &rb1 - rb2.clone()); assert_eq!(rb3, rb1.clone() - &rb2); assert_eq!(rb3, rb1.clone() - rb2.clone()); assert_eq!(rb3.len(), rb1.difference_len(&rb2)); rb1 -= &rb2; rb1 -= rb2; assert_eq!(rb3, rb1); } #[test] fn xor() { let mut rb1 = (1..4).collect::(); let rb2 = (3..6).collect::(); let rb3 = (1..3).chain(4..6).collect::(); let rb4 = (0..0).collect::(); assert_eq!(rb3, &rb1 ^ &rb2); assert_eq!(rb3, &rb1 ^ rb2.clone()); assert_eq!(rb3, rb1.clone() ^ &rb2); assert_eq!(rb3, rb1.clone() ^ rb2.clone()); assert_eq!(rb3.len(), rb1.symmetric_difference_len(&rb2)); rb1 ^= &rb2; assert_eq!(rb3, rb1); rb1 ^= rb3; assert_eq!(rb4, rb1); } roaring-0.10.2/tests/push.rs000064400000000000000000000033461046102023000140420ustar 00000000000000extern crate roaring; use roaring::{RoaringBitmap, RoaringTreemap}; use std::iter::FromIterator; /// macro created to reduce code duplication macro_rules! test_from_sorted_iter { ($values: expr, $class: ty) => {{ let rb1 = <$class>::from_iter($values.clone()); let rb2 = <$class>::from_sorted_iter($values).unwrap(); for (x, y) in rb1.iter().zip(rb2.iter()) { assert_eq!(x, y); } assert_eq!(rb1.len(), rb2.len()); assert_eq!(rb1.min(), rb2.min()); assert_eq!(rb1.max(), rb2.max()); assert_eq!(rb1.is_empty(), rb2.is_empty()); assert_eq!(rb1, rb2); }}; } #[test] fn append() { test_from_sorted_iter!((0..1_000_000).map(|x| 13 * x).collect::>(), RoaringBitmap); test_from_sorted_iter!(vec![1, 2, 4, 5, 7, 8, 9], RoaringBitmap); } #[test] fn append_empty() { assert_eq!(RoaringBitmap::new().append(vec![]), Ok(0u64)) } #[test] fn append_error() { match [100u32].iter().cloned().collect::().append(vec![10, 20, 0]) { Ok(_) => { panic!("The 0th element in the iterator was < the max of the bitmap") } Err(non_sorted_error) => { assert_eq!(non_sorted_error.valid_until(), 0) } } match [100u32].iter().cloned().collect::().append(vec![200, 201, 201]) { Ok(_) => { panic!("The 3rd element in the iterator was < 2nd") } Err(non_sorted_error) => { assert_eq!(non_sorted_error.valid_until(), 2) } } } #[test] fn append_tree() { test_from_sorted_iter!((0..1_000_000).map(|x| 13 * x).collect::>(), RoaringTreemap); test_from_sorted_iter!(vec![1, 2, 4, 5, 7, 8, 9], RoaringTreemap); } roaring-0.10.2/tests/range_checks.rs000064400000000000000000000053571046102023000155030ustar 00000000000000use proptest::collection::hash_set; use proptest::prelude::*; use roaring::RoaringBitmap; #[test] fn u32_max() { let mut bitmap = RoaringBitmap::new(); bitmap.insert(u32::MAX); assert!(bitmap.contains_range(u32::MAX..=u32::MAX)); assert!(!bitmap.contains_range(u32::MAX - 1..=u32::MAX)); bitmap.insert_range(4_000_000_000..); assert!(bitmap.contains_range(4_000_000_000..)); assert!(bitmap.contains_range(4_000_000_000..u32::MAX)); assert!(bitmap.contains_range(4_000_000_000..=u32::MAX)); assert!(bitmap.contains_range(4_100_000_000..=u32::MAX)); } proptest! { #[test] fn proptest_range( start in ..=262_143_u32, len in ..=262_143_u32, extra in hash_set(..=462_143_u32, ..=100), ){ let end = start + len; let range = start..end; let inverse_empty_range = (start+len)..start; let mut bitmap = RoaringBitmap::new(); bitmap.insert_range(range.clone()); assert!(bitmap.contains_range(range.clone())); assert!(bitmap.contains_range(inverse_empty_range.clone())); assert_eq!(bitmap.range_cardinality(range.clone()) as usize, range.len()); for &val in &extra { bitmap.insert(val); assert!(bitmap.contains_range(range.clone())); assert!(bitmap.contains_range(inverse_empty_range.clone())); assert_eq!(bitmap.range_cardinality(range.clone()) as usize, range.len()); } for (i, &val) in extra.iter().filter(|x| range.contains(x)).enumerate() { bitmap.remove(val); assert!(!bitmap.contains_range(range.clone())); assert!(bitmap.contains_range(inverse_empty_range.clone())); assert_eq!(bitmap.range_cardinality(range.clone()) as usize, range.len() - i - 1); } } #[test] fn proptest_range_boundaries( // Ensure we can always subtract one from start start in 1..=262_143_u32, len in 0..=262_143_u32, ) { let mut bitmap = RoaringBitmap::new(); let end = start + len; let half = start + len / 2; bitmap.insert_range(start..end); assert!(bitmap.contains_range(start..end)); assert!(bitmap.contains_range(start+1..end)); assert!(bitmap.contains_range(start..end - 1)); assert!(bitmap.contains_range(start+1..end - 1)); assert!(!bitmap.contains_range(start - 1..end)); assert!(!bitmap.contains_range(start - 1..end - 1)); assert!(!bitmap.contains_range(start..end + 1)); assert!(!bitmap.contains_range(start + 1..end + 1)); assert!(!bitmap.contains_range(start - 1..end + 1)); assert!(!bitmap.contains_range(start - 1..half)); assert!(!bitmap.contains_range(half..end + 1)); } } roaring-0.10.2/tests/rank.rs000064400000000000000000000036631046102023000140200ustar 00000000000000extern crate roaring; use proptest::collection::{btree_set, vec}; use proptest::prelude::*; use roaring::RoaringBitmap; #[test] fn rank() { let mut bitmap = RoaringBitmap::from_sorted_iter(0..2000).unwrap(); bitmap.insert_range(200_000..210_000); // No matching container assert_eq!(bitmap.rank(80_000), 2000); assert_eq!(bitmap.rank(u32::MAX), 12_000); // Array container at key assert_eq!(bitmap.rank(0), 1); assert_eq!(bitmap.rank(100), 101); assert_eq!(bitmap.rank(2000), 2000); // Bitmap container at key assert_eq!(bitmap.rank(200_000), 2001); assert_eq!(bitmap.rank(210_000), 12_000); } #[test] fn rank_array() { let bitmap = RoaringBitmap::from_sorted_iter(0..2000).unwrap(); // No matching container assert_eq!(bitmap.rank(u32::MAX), 2000); // Has container (array) assert_eq!(bitmap.rank(0), 1); assert_eq!(bitmap.rank(100), 101); assert_eq!(bitmap.rank(2000), 2000); assert_eq!(bitmap.rank(3000), 2000); } #[test] fn rank_bitmap() { let bitmap = RoaringBitmap::from_sorted_iter(0..5000).unwrap(); // key: 0, bit: 0 assert_eq!(bitmap.rank(0), 1); // key: 0, bit: 63 (mask of all ones) assert_eq!(bitmap.rank(63), 64); // key: 1023, bit: 0 assert_eq!(bitmap.rank(65535), 5000); // key: 1023, bit: 63 (mask of all ones) assert_eq!(bitmap.rank(65472), 5000); assert_eq!(bitmap.rank(1), 2); assert_eq!(bitmap.rank(100), 101); assert_eq!(bitmap.rank(1000), 1001); assert_eq!(bitmap.rank(4999), 5000); } proptest! { #[test] fn proptest_rank( values in btree_set(..=262_143_u32, ..=1000), checks in vec(..=262_143_u32, ..=100) ){ let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap(); for i in checks { let expected = values.iter().take_while(|&&x| x <= i).count() as u64; assert_eq!(bitmap.rank(i), expected); } } } roaring-0.10.2/tests/select.rs000064400000000000000000000025221046102023000143350ustar 00000000000000extern crate roaring; use proptest::collection::btree_set; use proptest::prelude::*; use roaring::RoaringBitmap; #[test] fn select() { let bitmap = (0..2000).collect::(); assert_eq!(bitmap.select(0), Some(0)); } #[test] fn select_array() { let bitmap = (0..2000).collect::(); assert_eq!(bitmap.select(0), Some(0)); assert_eq!(bitmap.select(100), Some(100)); assert_eq!(bitmap.select(1000), Some(1000)); assert_eq!(bitmap.select(1999), Some(1999)); assert_eq!(bitmap.select(2000), None); } #[test] fn select_bitmap() { let bitmap = (0..100_000).collect::(); assert_eq!(bitmap.select(0), Some(0)); assert_eq!(bitmap.select(63), Some(63)); assert_eq!(bitmap.select(1000), Some(1000)); assert_eq!(bitmap.select(65535), Some(65535)); } #[test] fn select_empty() { let bitmap = RoaringBitmap::new(); assert_eq!(bitmap.select(0), None); assert_eq!(bitmap.select(1024), None); assert_eq!(bitmap.select(u32::MAX), None); } proptest! { #[test] fn proptest_select(values in btree_set(any::(), 1000)) { let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap(); for (i, value) in values.iter().cloned().enumerate() { prop_assert_eq!(bitmap.select(i as u32), Some(value)); } } } roaring-0.10.2/tests/serialization.rs000064400000000000000000001252531046102023000157420ustar 00000000000000extern crate roaring; use roaring::RoaringBitmap; // Test data from https://github.com/RoaringBitmap/RoaringFormatSpec/tree/master/testdata static BITMAP_WITHOUT_RUNS: &[u8] = include_bytes!("bitmapwithoutruns.bin"); static BITMAP_WITH_RUNS: &[u8] = include_bytes!("bitmapwithruns.bin"); fn test_data_bitmap() -> RoaringBitmap { (0..100) .map(|i| i * 1000) .chain((100_000..200_000).map(|i| i * 3)) .chain(700_000..800_000) .collect::() } fn serialize_and_deserialize(bitmap: &RoaringBitmap) -> RoaringBitmap { let mut buffer = vec![]; bitmap.serialize_into(&mut buffer).unwrap(); assert_eq!(buffer.len(), bitmap.serialized_size()); RoaringBitmap::deserialize_from(&buffer[..]).unwrap() } #[test] fn test_deserialize_without_runs_from_provided_data() { assert_eq!(RoaringBitmap::deserialize_from(BITMAP_WITHOUT_RUNS).unwrap(), test_data_bitmap()); } #[test] fn test_deserialize_with_runs_from_provided_data() { assert_eq!( RoaringBitmap::deserialize_from(&mut &BITMAP_WITH_RUNS[..]).unwrap(), test_data_bitmap() ); } #[test] fn test_serialize_into_provided_data() { let bitmap = test_data_bitmap(); let mut buffer = vec![]; bitmap.serialize_into(&mut buffer).unwrap(); assert!(BITMAP_WITHOUT_RUNS == &buffer[..]); } #[test] fn test_empty() { let original = RoaringBitmap::new(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_one() { let original = (1..2).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_array() { let original = (1000..3000).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_array_boundary() { let original = (1000..5096).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_bitmap_boundary() { let original = (1000..5097).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_bitmap_high16bits() { let mut bitmap = RoaringBitmap::new(); for i in 0..1 << 16 { let value = i << 16; bitmap.insert(value); } let mut buffer = vec![]; bitmap.serialize_into(&mut buffer).unwrap(); let new = RoaringBitmap::deserialize_from(&buffer[..]); assert!(new.is_ok()); assert_eq!(bitmap, new.unwrap()); } #[test] fn test_bitmap() { let original = (1000..6000).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_arrays() { let original = (1000..3000).chain(70000..74000).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_bitmaps() { let original = (1000..6000).chain(70000..77000).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_mixed() { let original = (1000..3000).chain(70000..77000).collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } #[test] fn test_strange() { const ARRAY: &[u32] = &[ 6619162, 6619180, 6619181, 6619217, 6619218, 6619257, 6619258, 6619259, 6619260, 6619261, 6619262, 6619263, 6619264, 6619265, 6619266, 6619292, 6619294, 6619322, 6619461, 6619485, 6619490, 6619500, 6619594, 6619619, 6619620, 6619623, 6619630, 6619632, 6619700, 6619701, 6619702, 6619703, 6619813, 6619896, 6619967, 6620022, 6620034, 6620038, 6620110, 6620182, 6620189, 6620194, 6620200, 6620262, 6620289, 6620321, 6620353, 6620354, 6620355, 6620356, 6620384, 6620403, 6620431, 6620501, 6620529, 6620596, 6620674, 6620691, 6620770, 6620813, 6620889, 6620890, 6620891, 6620892, 6620893, 6620894, 6620895, 6620928, 6620929, 6620948, 6621023, 6621035, 6621046, 6621183, 6621224, 6621227, 6621261, 6621274, 6621345, 6621346, 6621347, 6621348, 6621349, 6621350, 6621351, 6621352, 6621353, 6621354, 6621355, 6621356, 6621357, 6621358, 6621359, 6621360, 6621361, 6621362, 6621363, 6621364, 6621365, 6621395, 6621442, 6621457, 6621518, 6621519, 6621520, 6621521, 6621522, 6621523, 6621524, 6621525, 6621526, 6621527, 6621538, 6621539, 6621540, 6621541, 6621542, 6621543, 6621544, 6621545, 6621546, 6621547, 6621548, 6621553, 6621666, 6621715, 6621724, 6621738, 6621844, 6621845, 6621859, 6621875, 6621891, 6621912, 6621964, 6621969, 6621998, 6621999, 6622037, 6622068, 6622125, 6622126, 6622137, 6622196, 6622327, 6622328, 6622331, 6622333, 6622355, 6622374, 6622390, 6622410, 6622411, 6622412, 6622417, 6622418, 6622419, 6622420, 6622421, 6622422, 6622423, 6622424, 6622425, 6622426, 6622427, 6622428, 6622429, 6622430, 6622431, 6622432, 6622433, 6622434, 6622518, 6622519, 6622551, 6622571, 6622588, 6622597, 6622599, 6622619, 6622638, 6622703, 6622704, 6622705, 6622714, 6622734, 6622778, 6622833, 6622834, 6622849, 6622872, 6622891, 6622964, 6622986, 6623000, 6623004, 6623037, 6623053, 6623054, 6623128, 6623153, 6623233, 6623243, 6623247, 6623249, 6623267, 6623271, 6623302, 6623339, 6623341, 6623342, 6623350, 6623353, 6623419, 6623437, 6623513, 6623603, 6623632, 6623656, 6623683, 6623684, 6623685, 6623686, 6623687, 6623688, 6623689, 6623690, 6623691, 6623692, 6623693, 6623694, 6623765, 6623767, 6623769, 6623776, 6623785, 6623816, 6623824, 6623840, 6623888, 6623949, 6623974, 6623979, 6624005, 6624019, 6624053, 6624054, 6624069, 6624079, 6624085, 6624122, 6624140, 6624144, 6624265, 6624275, 6624276, 6624277, 6624278, 6624350, 6624365, 6624371, 6624379, 6624384, 6624389, 6624390, 6624415, 6624433, 6624483, 6624492, 6624495, 6624509, 6624537, 6624563, 6624622, 6624628, 6624748, 6624766, 6624801, 6624813, 6624870, 6624874, 6624887, 6624936, 6624961, 6625015, 6625042, 6625064, 6625065, 6625066, 6625072, 6625113, 6625114, 6625115, 6625116, 6625117, 6625118, 6625132, 6625209, 6625235, 6625250, 6625282, 6625308, 6625404, 6625410, 6625411, 6625415, 6625445, 6625472, 6625501, 6625502, 6625544, 6625578, 6625581, 6625627, 6625654, 6625771, 6625772, 6625773, 6625774, 6625775, 6625776, 6625829, 6625831, 6625841, 6625863, 6625872, 6625885, 6625925, 6625933, 6625950, 6626001, 6626026, 6626038, 6626089, 6626148, 6626273, 6626326, 6626327, 6626328, 6626329, 6626330, 6626331, 6626332, 6626333, 6626334, 6626335, 6626336, 6626337, 6626423, 6626436, 6626477, 6626570, 6626571, 6626572, 6626573, 6626583, 6626585, 6626607, 6626608, 6626609, 6626610, 6626611, 6626612, 6626613, 6626614, 6626615, 6626687, 6626688, 6626689, 6626690, 6626705, 6626751, 6626835, 6626843, 6626891, 6626903, 6626925, 6626999, 6627003, 6627071, 6627077, 6627085, 6627118, 6627182, 6627183, 6627184, 6627185, 6627186, 6627187, 6627188, 6627189, 6627190, 6627191, 6627192, 6627234, 6627241, 6627270, 6627304, 6627305, 6627306, 6627307, 6627308, 6627309, 6627310, 6627311, 6627312, 6627313, 6627314, 6627315, 6627316, 6627317, 6627332, 6627333, 6627334, 6627335, 6627358, 6627453, 6627507, 6627542, 6627543, 6627544, 6627545, 6627560, 6627571, 6627580, 6627636, 6627637, 6627638, 6627639, 6627640, 6627641, 6627642, 6627643, 6627644, 6627645, 6627707, 6627708, 6627709, 6627710, 6627711, 6627712, 6627713, 6627714, 6627715, 6627716, 6627717, 6627718, 6627746, 6627747, 6627748, 6627749, 6627760, 6627769, 6627809, 6627861, 6627989, 6627995, 6628007, 6628009, 6628034, 6628035, 6628036, 6628037, 6628038, 6628039, 6628040, 6628041, 6628105, 6628124, 6628132, 6628149, 6628228, 6628229, 6628386, 6628387, 6628406, 6628440, 6628503, 6628546, 6628711, 6628714, 6628715, 6628716, 6628721, 6628760, 6628761, 6628804, 6628920, 6629022, 6629086, 6629088, 6629100, 6629102, 6629164, 6629167, 6629168, 6629177, 6629180, 6629181, 6629182, 6629183, 6629204, 6629222, 6629228, 6629245, 6629270, 6629271, 6629272, 6629273, 6629274, 6629275, 6629276, 6629277, 6629278, 6629279, 6629280, 6629281, 6629282, 6629283, 6629291, 6629292, 6629345, 6629503, 6629555, 6629556, 6629594, 6629595, 6629596, 6629597, 6629614, 6629647, 6629648, 6629649, 6629650, 6629673, 6629692, 6629701, 6629713, 6629719, 6629720, 6629721, 6629722, 6629723, 6629724, 6629725, 6629728, 6629753, 6629786, 6629789, 6629809, 6629812, 6629819, 6629879, 6629890, 6629980, 6629981, 6629982, 6629983, 6629984, 6629985, 6629986, 6629987, 6629988, 6629989, 6629990, 6629991, 6629992, 6630012, 6630026, 6630076, 6630110, 6630190, 6630191, 6630195, 6630221, 6630227, 6630237, 6630245, 6630340, 6630341, 6630342, 6630343, 6630482, 6630524, 6630531, 6630532, 6630535, 6630543, 6630571, 6630591, 6630607, 6630611, 6630615, 6630624, 6630634, 6630643, 6630665, 6630666, 6630667, 6630668, 6630669, 6630670, 6630671, 6630672, 6630673, 6630674, 6630675, 6630676, 6630677, 6630731, 6630743, 6630745, 6630753, 6630797, 6630849, 6630850, 6630851, 6630852, 6630853, 6630854, 6630855, 6630856, 6630857, 6630858, 6630859, 6630860, 6630884, 6630893, 6630896, 6630902, 6630910, 6630918, 6630922, 6630923, 6630979, 6630986, 6630998, 6631010, 6631060, 6631061, 6631062, 6631063, 6631064, 6631065, 6631066, 6631067, 6631068, 6631069, 6631070, 6631071, 6631099, 6631130, 6631141, 6631148, 6631158, 6631176, 6631181, 6631183, 6631238, 6631261, 6631289, 6631294, 6631410, 6631453, 6631458, 6631470, 6631581, 6631603, 6631627, 6631650, 6631709, 6631711, 6631734, 6631789, 6631793, 6631815, 6631834, 6631897, 6631950, 6631995, 6631997, 6632005, 6632007, 6632199, 6632223, 6632224, 6632295, 6632365, 6632440, 6632441, 6632466, 6632473, 6632491, 6632492, 6632495, 6632496, 6632497, 6632498, 6632499, 6632500, 6632501, 6632502, 6632503, 6632504, 6632505, 6632506, 6632510, 6632514, 6632524, 6632541, 6632565, 6632646, 6632647, 6632648, 6632649, 6632650, 6632651, 6632652, 6632653, 6632654, 6632655, 6632662, 6632746, 6632822, 6632831, 6632840, 6632859, 6632901, 6632902, 6632908, 6632911, 6632912, 6632913, 6632914, 6632915, 6632916, 6632917, 6632918, 6632919, 6632920, 6632921, 6632924, 6632927, 6632983, 6632987, 6632991, 6632994, 6633069, 6633071, 6633103, 6633110, 6633126, 6633155, 6633172, 6633249, 6633275, 6633407, 6633446, 6633537, 6633560, 6633576, 6633680, 6633735, 6633752, 6633791, 6633845, 6633846, 6633847, 6633848, 6633855, 6633860, 6633867, 6633885, 6633894, 6633898, 6633903, 6633929, 6633980, 6633995, 6634093, 6634114, 6634167, 6634170, 6634215, 6634270, 6634399, 6634410, 6634546, 6634588, 6634599, 6634821, 6634822, 6634823, 6634824, 6634825, 6634826, 6634901, 6634911, 6634913, 6634914, 6634915, 6634920, 6634921, 6634924, 6634996, 6635018, 6635037, 6635082, 6635117, 6635140, 6635163, 6635165, 6635167, 6635170, 6635172, 6635223, 6635241, 6635295, 6635296, 6635361, 6635365, 6635416, 6635417, 6635418, 6635419, 6635420, 6635421, 6635422, 6635447, 6635603, 6635682, 6635732, 6635735, 6635738, 6635765, 6635793, 6635815, 6635832, 6635840, 6635856, 6636059, 6636060, 6636071, 6636124, 6636125, 6636163, 6636164, 6636165, 6636166, 6636167, 6636168, 6636169, 6636170, 6636171, 6636172, 6636173, 6636174, 6636212, 6636248, 6636272, 6636284, 6636367, 6636403, 6636412, 6636414, 6636453, 6636454, 6636455, 6636456, 6636457, 6636458, 6636459, 6636460, 6636461, 6636462, 6636463, 6636464, 6636465, 6636466, 6636467, 6636468, 6636469, 6636470, 6636471, 6636472, 6636473, 6636474, 6636475, 6636476, 6636477, 6636478, 6636479, 6636480, 6636481, 6636482, 6636483, 6636534, 6636666, 6636735, 6636746, 6636757, 6636797, 6636846, 6636863, 6636864, 6636913, 6636980, 6636981, 6636982, 6636983, 6636984, 6636985, 6636986, 6636987, 6636988, 6636989, 6636998, 6637054, 6637055, 6637056, 6637057, 6637058, 6637059, 6637060, 6637061, 6637062, 6637063, 6637065, 6637068, 6637071, 6637076, 6637113, 6637218, 6637240, 6637429, 6637453, 6637468, 6637526, 6637563, 6637581, 6637587, 6637615, 6637619, 6637656, 6637680, 6637681, 6637682, 6637713, 6637757, 6637813, 6637895, 6637899, 6637912, 6637917, 6637948, 6637949, 6638051, 6638052, 6638075, 6638093, 6638229, 6638250, 6638315, 6638334, 6638335, 6638336, 6638337, 6638372, 6638373, 6638383, 6638384, 6638386, 6638387, 6638401, 6638415, 6638545, 6638546, 6638560, 6638561, 6638562, 6638563, 6638564, 6638565, 6638566, 6638567, 6638568, 6638569, 6638570, 6638571, 6638575, 6638608, 6638609, 6638631, 6638673, 6638675, 6638683, 6638687, 6638694, 6638697, 6638701, 6638706, 6638735, 6638736, 6638737, 6638738, 6638761, 6638769, 6638809, 6638810, 6638864, 6638873, 6638874, 6638875, 6638876, 6638877, 6638878, 6638879, 6638880, 6638881, 6638882, 6638883, 6638936, 6638966, 6639029, 6639058, 6639066, 6639196, 6639236, 6639266, 6639267, 6639268, 6639269, 6639273, 6639282, 6639293, 6639295, 6639299, 6639303, 6639444, 6639467, 6639491, 6639560, 6639573, 6639574, 6639575, 6639576, 6639577, 6639578, 6639602, 6639619, 6639636, 6639677, 6639693, 6639694, 6639709, 6639763, 6639770, 6639810, 6639898, 6639920, 6639983, 6639991, 6640019, 6640020, 6640021, 6640022, 6640023, 6640024, 6640025, 6640026, 6640027, 6640028, 6640029, 6640030, 6640031, 6640032, 6640033, 6640034, 6640035, 6640036, 6640037, 6640081, 6640134, 6640139, 6640140, 6640141, 6640142, 6640143, 6640144, 6640145, 6640146, 6640147, 6640148, 6640149, 6640150, 6640151, 6640152, 6640153, 6640239, 6640272, 6640273, 6640274, 6640275, 6640276, 6640282, 6640287, 6640404, 6640419, 6640420, 6640421, 6640422, 6640442, 6640510, 6640512, 6640527, 6640528, 6640532, 6640566, 6640585, 6640588, 6640678, 6640708, 6640736, 6640738, 6640767, 6640768, 6640844, 6640856, 6640881, 6640928, 6641043, 6641082, 6641090, 6641116, 6641117, 6641125, 6641126, 6641127, 6641198, 6641213, 6641217, 6641222, 6641226, 6641247, 6641326, 6641365, 6641373, 6641394, 6641456, 6641459, 6641464, 6641515, 6641527, 6641536, 6641572, 6641573, 6641574, 6641575, 6641576, 6641577, 6641578, 6641579, 6641580, 6641581, 6641582, 6641583, 6641584, 6641585, 6641586, 6641590, 6641593, 6641604, 6641612, 6641733, 6641734, 6641735, 6641736, 6641737, 6641738, 6641762, 6641771, 6641793, 6641811, 6641830, 6641862, 6642040, 6642073, 6642083, 6642084, 6642085, 6642086, 6642087, 6642088, 6642089, 6642090, 6642091, 6642092, 6642093, 6642094, 6642159, 6642167, 6642172, 6642173, 6642177, 6642183, 6642269, 6642270, 6642271, 6642304, 6642306, 6642308, 6642338, 6642384, 6642459, 6642545, 6642558, 6642559, 6642560, 6642561, 6642562, 6642563, 6642564, 6642565, 6642566, 6642567, 6642568, 6642569, 6642570, 6642571, 6642572, 6642732, 6642752, 6642754, 6642761, 6642849, 6642850, 6643035, 6643047, 6643075, 6643093, 6643107, 6643113, 6643130, 6643154, 6643161, 6643169, 6643170, 6643171, 6643172, 6643173, 6643174, 6643175, 6643176, 6643177, 6643178, 6643179, 6643180, 6643181, 6643230, 6643241, 6643261, 6643351, 6643353, 6643354, 6643355, 6643370, 6643379, 6643537, 6643538, 6643563, 6643572, 6643655, 6643656, 6643661, 6643662, 6643663, 6643664, 6643665, 6643666, 6643667, 6643668, 6643669, 6643670, 6643671, 6643672, 6643675, 6643766, 6643806, 6643837, 6643838, 6643839, 6643879, 6643899, 6643900, 6643902, 6643984, 6644030, 6644032, 6644043, 6644050, 6644051, 6644052, 6644053, 6644054, 6644055, 6644056, 6644057, 6644058, 6644059, 6644060, 6644061, 6644066, 6644067, 6644075, 6644085, 6644089, 6644109, 6644154, 6644155, 6644164, 6644165, 6644172, 6644173, 6644174, 6644175, 6644176, 6644177, 6644178, 6644179, 6644180, 6644181, 6644182, 6644183, 6644184, 6644185, 6644201, 6644250, 6644260, 6644263, 6644345, 6644427, 6644428, 6644432, 6644522, 6644551, 6644584, 6644619, 6644620, 6644621, 6644661, 6644680, 6644681, 6644777, 6644779, 6644785, 6644789, 6644802, 6644803, 6644900, 6644919, 6644930, 6645031, 6645133, 6645171, 6645197, 6645235, 6645236, 6645237, 6645238, 6645239, 6645240, 6645241, 6645242, 6645243, 6645244, 6645245, 6645246, 6645247, 6645248, 6645250, 6645251, 6645267, 6645268, 6645269, 6645270, 6645271, 6645272, 6645273, 6645274, 6645289, 6645303, 6645307, 6645308, 6645309, 6645310, 6645311, 6645312, 6645313, 6645314, 6645315, 6645316, 6645317, 6645318, 6645319, 6645344, 6645362, 6645365, 6645412, 6645413, 6645414, 6645415, 6645416, 6645417, 6645418, 6645419, 6645420, 6645421, 6645422, 6645427, 6645435, 6645438, 6645458, 6645479, 6645498, 6645499, 6645500, 6645501, 6645523, 6645536, 6645645, 6645646, 6645647, 6645648, 6645649, 6645650, 6645651, 6645652, 6645653, 6645654, 6645655, 6645656, 6645657, 6645658, 6645659, 6645660, 6645661, 6645662, 6645663, 6645664, 6645665, 6645692, 6645709, 6645710, 6645711, 6645712, 6645751, 6645852, 6645908, 6645909, 6645910, 6645930, 6645931, 6645932, 6645933, 6645935, 6645936, 6645950, 6646040, 6646050, 6646060, 6646064, 6646065, 6646069, 6646082, 6646103, 6646202, 6646240, 6646241, 6646242, 6646243, 6646244, 6646245, 6646246, 6646247, 6646248, 6646249, 6646266, 6646267, 6646269, 6646275, 6646276, 6646277, 6646278, 6646279, 6646280, 6646281, 6646282, 6646283, 6646284, 6646302, 6646303, 6646304, 6646305, 6646390, 6646391, 6646392, 6646393, 6646394, 6646395, 6646396, 6646397, 6646398, 6646399, 6646400, 6646414, 6646420, 6646436, 6646473, 6646494, 6646529, 6646536, 6646537, 6646538, 6646539, 6646540, 6646541, 6646569, 6646570, 6646571, 6646572, 6646573, 6646574, 6646575, 6646576, 6646577, 6646578, 6646585, 6646661, 6646682, 6646771, 6646845, 6646855, 6646865, 6646866, 6646867, 6646868, 6646869, 6646870, 6646871, 6646872, 6646873, 6646874, 6646875, 6646876, 6646877, 6646882, 6646932, 6646941, 6646974, 6647028, 6647119, 6647124, 6647165, 6647193, 6647207, 6647226, 6647230, 6647268, 6647269, 6647270, 6647271, 6647322, 6647364, 6647375, 6647489, 6647508, 6647518, 6647560, 6647573, 6647590, 6647629, 6647770, 6647781, 6647783, 6647903, 6647977, 6647978, 6647979, 6647980, 6647981, 6647982, 6647983, 6647984, 6647985, 6647986, 6647987, 6647988, 6647989, 6647990, 6647991, 6647992, 6647993, 6648069, 6648083, 6648084, 6648085, 6648086, 6648111, 6648179, 6648184, 6648203, 6648218, 6648243, 6648335, 6648342, 6648389, 6648391, 6648481, 6648548, 6648587, 6648588, 6648589, 6648590, 6648591, 6648592, 6648593, 6648594, 6648595, 6648596, 6648597, 6648598, 6648599, 6648600, 6648601, 6648602, 6648603, 6648604, 6648605, 6648606, 6648607, 6648608, 6648609, 6648687, 6648688, 6648689, 6648690, 6648691, 6648692, 6648693, 6648694, 6648695, 6648696, 6648697, 6648698, 6648699, 6648700, 6648763, 6648781, 6648788, 6648845, 6648846, 6648847, 6648848, 6648849, 6648850, 6648851, 6648852, 6648853, 6648854, 6648857, 6648866, 6648966, 6648967, 6648992, 6649011, 6649012, 6649015, 6649032, 6649047, 6649064, 6649065, 6649066, 6649067, 6649068, 6649069, 6649070, 6649071, 6649072, 6649073, 6649074, 6649075, 6649076, 6649077, 6649084, 6649087, 6649156, 6649159, 6649374, 6649410, 6649495, 6649505, 6649673, 6649683, 6649684, 6649718, 6649733, 6649758, 6649773, 6649784, 6649809, 6649872, 6649931, 6649935, 6650007, 6650014, 6650016, 6650071, 6650072, 6650073, 6650074, 6650075, 6650076, 6650077, 6650106, 6650107, 6650108, 6650109, 6650110, 6650111, 6650112, 6650113, 6650118, 6650119, 6650120, 6650121, 6650122, 6650123, 6650124, 6650180, 6650181, 6650182, 6650183, 6650184, 6650185, 6650186, 6650187, 6650188, 6650189, 6650190, 6650220, 6650221, 6650269, 6650270, 6650271, 6650272, 6650299, 6650303, 6650364, 6650380, 6650390, 6650392, 6650435, 6650469, 6650471, 6650523, 6650524, 6650525, 6650526, 6650527, 6650528, 6650529, 6650530, 6650531, 6650532, 6650533, 6650534, 6650535, 6650536, 6650537, 6650538, 6650582, 6650673, 6650693, 6650711, 6650712, 6650767, 6650886, 6650921, 6650955, 6650970, 6650977, 6651003, 6651039, 6651060, 6651061, 6651062, 6651063, 6651064, 6651065, 6651066, 6651067, 6651068, 6651073, 6651087, 6651088, 6651089, 6651090, 6651091, 6651138, 6651175, 6651262, 6651270, 6651271, 6651272, 6651273, 6651297, 6651315, 6651316, 6651317, 6651319, 6651321, 6651342, 6651351, 6651432, 6651468, 6651469, 6651470, 6651506, 6651549, 6651561, 6651592, 6651604, 6651616, 6651627, 6651646, 6651682, 6651687, 6651719, 6651720, 6651729, 6651734, 6651754, 6651795, 6651837, 6651856, 6651881, 6651934, 6651935, 6651936, 6651937, 6651939, 6651948, 6651949, 6651950, 6651951, 6651954, 6651967, 6651970, 6651989, 6651995, 6652053, 6652115, 6652140, 6652147, 6652151, 6652154, 6652161, 6652185, 6652220, 6652221, 6652222, 6652223, 6652224, 6652225, 6652226, 6652227, 6652229, 6652230, 6652242, 6652282, 6652370, 6652376, 6652385, 6652471, 6652472, 6652473, 6652474, 6652481, 6652482, 6652502, 6652549, 6652552, 6652651, 6652652, 6652653, 6652654, 6652671, 6652683, 6652687, 6652688, 6652689, 6652690, 6652691, 6652692, 6652700, 6652741, 6652754, 6652790, 6652895, 6653068, 6653122, 6653171, 6653189, 6653191, 6653202, 6653264, 6653268, 6653274, 6653279, 6653288, 6653396, 6653413, 6653414, 6653415, 6653416, 6653417, 6653441, 6653442, 6653443, 6653444, 6653445, 6653484, 6653534, 6653536, 6653583, 6653628, 6653677, 6653683, 6653736, 6653811, 6653865, 6653866, 6653867, 6653868, 6653869, 6653870, 6653871, 6653872, 6653873, 6653896, 6653922, 6653923, 6653924, 6653925, 6653926, 6653927, 6653928, 6653929, 6653930, 6653931, 6653932, 6653933, 6653936, 6653941, 6654031, 6654050, 6654055, 6654155, 6654166, 6654254, 6654257, 6654258, 6654259, 6654260, 6654290, 6654316, 6654317, 6654325, 6654342, 6654408, 6654409, 6654410, 6654411, 6654412, 6654413, 6654414, 6654415, 6654416, 6654417, 6654418, 6654419, 6654469, 6654470, 6654471, 6654472, 6654511, 6654564, 6654565, 6654566, 6654567, 6654568, 6654569, 6654570, 6654571, 6654572, 6654719, 6654746, 6654799, 6654815, 6654829, 6654831, 6654837, 6654853, 6654854, 6654855, 6654856, 6654857, 6654858, 6654859, 6654860, 6654861, 6654862, 6654863, 6654864, 6654865, 6654866, 6654908, 6654912, 6654949, 6654951, 6654952, 6654954, 6654956, 6654959, 6654961, 6655039, 6655040, 6655041, 6655042, 6655043, 6655044, 6655045, 6655046, 6655047, 6655048, 6655049, 6655050, 6655051, 6655052, 6655053, 6655054, 6655055, 6655059, 6655060, 6655096, 6655127, 6655128, 6655129, 6655130, 6655131, 6655132, 6655133, 6655134, 6655135, 6655136, 6655137, 6655138, 6655139, 6655195, 6655217, 6655230, 6655385, 6655386, 6655424, 6655425, 6655426, 6655427, 6655428, 6655429, 6655430, 6655431, 6655432, 6655433, 6655434, 6655450, 6655536, 6655562, 6655566, 6655600, 6655627, 6655793, 6655830, 6655856, 6655943, 6655978, 6656053, 6656184, 6656201, 6656205, 6656301, 6656304, 6656315, 6656316, 6656343, 6656419, 6656424, 6656442, 6656447, 6656535, 6656536, 6656537, 6656538, 6656539, 6656540, 6656542, 6656558, 6656583, 6656680, 6656696, 6656774, 6656828, 6656829, 6656830, 6656831, 6656834, 6656865, 6656906, 6656935, 6656964, 6657189, 6657198, 6657215, 6657229, 6657238, 6657242, 6657284, 6657290, 6657298, 6657303, 6657420, 6657426, 6657429, 6657430, 6657509, 6657560, 6657574, 6657589, 6657591, 6657617, 6657631, 6657644, 6657649, 6657653, 6657694, 6657741, 6657747, 6657797, 6657874, 6657875, 6657876, 6657877, 6657878, 6657885, 6657897, 6657898, 6657899, 6657900, 6657901, 6657902, 6657903, 6657904, 6657905, 6657906, 6657951, 6658009, 6658039, 6658040, 6658041, 6658043, 6658061, 6658126, 6658130, 6658158, 6658267, 6658268, 6658271, 6658272, 6658273, 6658274, 6658275, 6658276, 6658277, 6658278, 6658279, 6658280, 6658281, 6658282, 6658283, 6658284, 6658285, 6658286, 6658287, 6658288, 6658289, 6658290, 6658291, 6658333, 6658400, 6658422, 6658433, 6658477, 6658515, 6658516, 6658517, 6658518, 6658519, 6658604, 6658688, 6658689, 6658701, 6658702, 6658703, 6658704, 6658706, 6658743, 6658764, 6658767, 6658796, 6658885, 6658912, 6658920, 6659115, 6659130, 6659208, 6659209, 6659282, 6659289, 6659326, 6659345, 6659346, 6659347, 6659348, 6659349, 6659350, 6659351, 6659352, 6659353, 6659354, 6659355, 6659356, 6659371, 6659430, 6659497, 6659528, 6659539, 6659564, 6659591, 6659638, 6659662, 6659663, 6659664, 6659665, 6659666, 6659667, 6659668, 6659669, 6659670, 6659671, 6659672, 6659673, 6659674, 6659675, 6659676, 6659677, 6659678, 6659679, 6659680, 6659681, 6659682, 6659683, 6659684, 6659685, 6659686, 6659687, 6659688, 6659689, 6659690, 6659691, 6659692, 6659693, 6659694, 6659695, 6659696, 6659697, 6659698, 6659713, 6659715, 6659753, 6659844, 6659845, 6659846, 6659847, 6659848, 6659849, 6659850, 6659851, 6659852, 6659867, 6659893, 6659977, 6659978, 6659979, 6659980, 6659981, 6659982, 6659983, 6659984, 6659985, 6659986, 6659987, 6659988, 6660062, 6660079, 6660083, 6660173, 6660184, 6660185, 6660186, 6660212, 6660242, 6660248, 6660265, 6660277, 6660278, 6660302, 6660304, 6660311, 6660355, 6660357, 6660358, 6660362, 6660366, 6660368, 6660369, 6660386, 6660408, 6660409, 6660484, 6660492, 6660529, 6660530, 6660531, 6660734, 6660755, 6660756, 6660762, 6660770, 6660862, 6660863, 6660868, 6660869, 6660870, 6660871, 6660872, 6660873, 6660989, 6661021, 6661026, 6661030, 6661074, 6661075, 6661076, 6661079, 6661176, 6661188, 6661272, 6661276, 6661278, 6661282, 6661291, 6661331, 6661398, 6661412, 6661452, 6661466, 6661475, 6661477, 6661490, 6661492, 6661512, 6661579, 6661646, 6661711, 6661712, 6661713, 6661714, 6661715, 6661716, 6661717, 6661718, 6661719, 6661727, 6661736, 6661778, 6661779, 6661780, 6661781, 6661853, 6661860, 6661900, 6661980, 6662016, 6662017, 6662018, 6662019, 6662020, 6662021, 6662022, 6662023, 6662024, 6662027, 6662028, 6662062, 6662083, 6662104, 6662119, 6662143, 6662144, 6662371, 6662474, 6662540, 6662558, 6662572, 6662573, 6662574, 6662575, 6662576, 6662577, 6662653, 6662666, 6662721, 6662740, 6662798, 6662856, 6663006, 6663021, 6663046, 6663047, 6663048, 6663049, 6663050, 6663051, 6663052, 6663053, 6663054, 6663055, 6663056, 6663057, 6663058, 6663059, 6663060, 6663061, 6663062, 6663063, 6663064, 6663065, 6663066, 6663067, 6663068, 6663069, 6663070, 6663071, 6663072, 6663073, 6663074, 6663084, 6663085, 6663086, 6663087, 6663088, 6663089, 6663090, 6663091, 6663092, 6663093, 6663094, 6663095, 6663096, 6663097, 6663098, 6663152, 6663251, 6663252, 6663255, 6663256, 6663257, 6663258, 6663259, 6663260, 6663261, 6663262, 6663297, 6663298, 6663300, 6663302, 6663319, 6663340, 6663345, 6663368, 6663369, 6663370, 6663371, 6663372, 6663373, 6663374, 6663391, 6663412, 6663462, 6663463, 6663527, 6663568, 6663569, 6663570, 6663571, 6663572, 6663573, 6663574, 6663575, 6663576, 6663577, 6663578, 6663579, 6663601, 6663602, 6663603, 6663604, 6663605, 6663606, 6663607, 6663608, 6663609, 6663610, 6663658, 6663659, 6663666, 6663669, 6663696, 6663697, 6663744, 6663777, 6663778, 6663779, 6663780, 6663781, 6663782, 6663783, 6663784, 6663785, 6663786, 6663787, 6663788, 6663789, 6663790, 6663791, 6663792, 6663793, 6663794, 6663795, 6663796, 6663797, 6663798, 6663799, 6663800, 6663801, 6663809, 6663810, 6663838, 6663843, 6663975, 6663989, 6663990, 6663991, 6663994, 6663995, 6663996, 6663998, 6664001, 6664003, 6664004, 6664035, 6664055, 6664142, 6664143, 6664159, 6664188, 6664197, 6664203, 6664254, 6664354, 6664368, 6664487, 6664530, 6664561, 6664562, 6664563, 6664564, 6664565, 6664566, 6664567, 6664568, 6664569, 6664570, 6664571, 6664572, 6664573, 6664574, 6664575, 6664576, 6664577, 6664578, 6664579, 6664580, 6664581, 6664582, 6664583, 6664629, 6664631, 6664641, 6664646, 6664670, 6664686, 6664687, 6664688, 6664705, 6664770, 6664798, 6664799, 6664800, 6664801, 6664802, 6664803, 6664804, 6664805, 6664806, 6664863, 6664864, 6664909, 6664910, 6664983, 6665030, 6665147, 6665157, 6665174, 6665175, 6665176, 6665180, 6665183, 6665190, 6665244, 6665245, 6665249, 6665250, 6665251, 6665252, 6665253, 6665254, 6665255, 6665256, 6665268, 6665428, 6665447, 6665485, 6665486, 6665487, 6665488, 6665489, 6665490, 6665491, 6665499, 6665578, 6665579, 6665640, 6665641, 6665642, 6665643, 6665644, 6665645, 6665646, 6665647, 6665648, 6665649, 6665650, 6665651, 6665652, 6665653, 6665654, 6665704, 6665711, 6665712, 6665719, 6665786, 6665818, 6665896, 6665963, 6665986, 6666041, 6666042, 6666051, 6666096, 6666097, 6666098, 6666107, 6666116, 6666129, 6666138, 6666164, 6666168, 6666325, 6666339, 6666359, 6666365, 6666366, 6666367, 6666368, 6666369, 6666370, 6666371, 6666372, 6666381, 6666455, 6666515, 6666526, 6666527, 6666545, 6666546, 6666547, 6666548, 6666549, 6666550, 6666551, 6666552, 6666553, 6666554, 6666555, 6666556, 6666557, 6666558, 6666559, 6666587, 6666588, 6666589, 6666590, 6666591, 6666592, 6666619, 6666624, 6666625, 6666626, 6666627, 6666628, 6666629, 6666630, 6666636, 6666678, 6666708, 6666716, 6666752, 6666753, 6666776, 6666777, 6666778, 6666779, 6666780, 6666781, 6666782, 6666783, 6666784, 6666785, 6666786, 6666787, 6666788, 6666789, 6666790, 6666791, 6666873, 6666895, 6666921, 6666922, 6666923, 6666924, 6666925, 6666926, 6666927, 6666928, 6666929, 6666930, 6666931, 6666932, 6666933, 6666934, 6666935, 6666936, 6666937, 6666938, 6666939, 6666940, 6666941, 6666942, 6666998, 6667028, 6667044, 6667045, 6667046, 6667047, 6667048, 6667084, 6667106, 6667116, 6667181, 6667235, 6667236, 6667237, 6667238, 6667239, 6667240, 6667241, 6667242, 6667243, 6667244, 6667245, 6667246, 6667247, 6667248, 6667249, 6667250, 6667251, 6667252, 6667253, 6667254, 6667255, 6667256, 6667257, 6667258, 6667259, 6667260, 6667261, 6667262, 6667263, 6667264, 6667341, 6667342, 6667343, 6667344, 6667345, 6667346, 6667347, 6667349, 6667350, 6667351, 6667352, 6667353, 6667354, 6667355, 6667356, 6667357, 6667358, 6667374, 6667381, 6667391, 6667444, 6667458, 6667459, 6667460, 6667461, 6667462, 6667463, 6667464, 6667465, 6667466, 6667467, 6667468, 6667469, 6667496, 6667561, 6667592, 6667621, 6667622, 6667682, 6667683, 6667684, 6667685, 6667686, 6667687, 6667700, 6667727, 6667728, 6667729, 6667730, 6667731, 6667732, 6667733, 6667734, 6667735, 6667736, 6667737, 6667738, 6667739, 6667740, 6667741, 6667748, 6667752, 6667767, 6667768, 6667769, 6667770, 6667771, 6667772, 6667773, 6667774, 6667775, 6667776, 6667777, 6667778, 6667779, 6667780, 6667781, 6667782, 6667783, 6667784, 6667785, 6667794, 6667811, 6667812, 6667853, 6667883, 6667884, 6667887, 6667896, 6667906, 6668079, 6668240, 6668266, 6668281, 6668347, 6668348, 6668351, 6668369, 6668370, 6668371, 6668372, 6668456, 6668471, 6668492, 6668503, 6668507, 6668508, 6668521, 6668542, 6668635, 6668651, 6668658, 6668700, 6668701, 6668708, 6668833, 6668930, 6668931, 6668932, 6668933, 6668934, 6668935, 6668936, 6668937, 6668938, 6668939, 6668946, 6668972, 6668998, 6669023, 6669026, 6669032, 6669033, 6669034, 6669035, 6669076, 6669120, 6669143, 6669150, 6669166, 6669224, 6669279, 6669295, 6669367, 6669373, 6669374, 6669375, 6669376, 6669377, 6669378, 6669379, 6669380, 6669381, 6669382, 6669441, 6669590, 6669603, 6669654, 6669655, 6669715, 6669773, 6669778, 6669787, 6669811, 6669812, 6669868, 6669869, 6669886, 6669980, 6669981, 6669982, 6669983, 6669984, 6669985, 6669986, 6670014, 6670015, 6670016, 6670017, 6670060, 6670066, 6670074, 6670077, 6670078, 6670079, 6670111, 6670145, 6670147, 6670172, 6670182, 6670252, 6670266, 6670268, 6670352, 6670420, 6670422, 6670522, 6670623, 6670641, 6670649, 6670650, 6670655, 6670696, 6670705, 6670709, 6670713, 6670727, 6670788, 6670808, 6670891, 6670892, 6670893, 6670894, 6670895, 6670896, 6670897, 6670898, 6670899, 6670900, 6670901, 6670902, 6670903, 6670920, 6670921, 6670922, 6670923, 6670924, 6670947, 6670970, 6671006, 6671007, 6671022, 6671089, 6671134, 6671135, 6671136, 6671137, 6671138, 6671139, 6671140, 6671162, 6671201, 6671205, 6671223, 6671277, 6671365, 6671419, 6671423, 6671427, 6671431, 6671435, 6671439, 6671443, 6671447, 6671451, 6671455, 6671459, 6671463, 6671467, 6671471, 6671473, 6671477, 6671481, 6671485, 6671489, 6671496, 6671497, 6671498, 6671499, 6671500, 6671501, 6671502, 6671503, 6671504, 6671505, 6671506, 6671507, 6671508, 6671526, 6671540, 6671575, 6671581, 6671639, 6671695, 6671697, 6671737, 6671753, 6671793, 6671830, 6671842, 6671943, 6671990, 6671991, 6671992, 6672084, 6672086, 6672109, 6672110, 6672172, 6672196, 6672197, 6672200, 6672201, 6672252, 6672257, 6672258, 6672259, 6672260, 6672264, 6672326, 6672327, 6672328, 6672329, 6672330, 6672331, 6672332, 6672333, 6672334, 6672335, 6672336, 6672337, 6672344, 6672347, 6672376, 6672386, 6672391, 6672392, 6672393, 6672394, 6672395, 6672396, 6672397, 6672398, 6672399, 6672400, 6672413, 6672431, 6672432, 6672483, 6672566, 6672567, 6672572, 6672596, 6672606, 6672686, 6672687, 6672719, 6672735, 6672750, 6672751, 6672770, 6672825, 6672857, 6672934, 6672946, 6672950, 6673007, 6673020, 6673047, 6673061, 6673064, 6673143, 6673172, 6673173, 6673174, 6673175, 6673176, 6673177, 6673178, 6673179, 6673192, 6673219, 6673220, 6673225, 6673280, 6673281, 6673284, 6673285, 6673301, 6673302, 6673402, 6673404, 6673424, 6673468, 6673514, 6673522, 6673525, 6673526, 6673551, 6673662, 6673681, 6673760, 6673863, 6673871, 6673872, 6673873, 6673874, 6673875, 6673876, 6673877, 6673878, 6673879, 6673880, 6673892, 6673893, 6673894, 6673895, 6673908, 6673909, 6673910, 6673911, 6673912, 6673913, 6673914, 6673915, 6673916, 6673917, 6673918, 6673919, 6673920, 6673921, 6673922, 6673923, 6673924, 6673929, 6673988, 6674035, 6674053, 6674054, 6674093, 6674103, 6674107, 6674111, 6674147, 6674240, 6674254, 6674255, 6674256, 6674257, 6674258, 6674259, 6674260, 6674261, 6674262, 6674263, 6674264, 6674280, 6674283, 6674302, 6674328, 6674333, 6674342, 6674346, 6674350, 6674385, 6674386, 6674387, 6674388, 6674389, 6674390, 6674391, 6674392, 6674393, 6674394, 6674395, 6674396, 6674397, 6674398, 6674399, 6674418, 6674453, 6674454, 6674594, 6674607, 6674739, 6674745, 6674756, 6674761, 6674763, 6674836, 6674848, 6674854, 6674863, 6674904, 6674906, 6674913, 6674914, 6674923, 6674924, 6674925, 6674926, 6674927, 6674928, 6674929, 6674930, 6674939, 6675054, 6675067, 6675069, 6675090, 6675093, 6675102, 6675114, 6675121, 6675123, 6675154, 6675170, 6675171, 6675238, 6675256, 6675290, 6675324, 6675371, 6675372, 6675373, 6675374, 6675375, 6675376, 6675377, 6675378, 6675379, 6675380, 6675383, 6675386, 6675410, 6675411, 6675423, 6675434, 6675484, 6675485, 6675507, 6675511, 6675530, 6675540, 6675547, 6675553, 6675554, 6675642, 6675643, 6675644, 6675645, 6675646, 6675647, 6675648, 6675649, 6675650, 6675651, 6675652, 6675653, 6675654, 6675664, 6675713, 6675725, 6675733, 6675744, 6675775, 6675824, 6675879, 6675900, 6675902, 6675945, 6675949, 6676070, 6676099, 6676108, 6676121, 6676129, 6676130, 6676131, 6676132, 6676133, 6676134, 6676135, 6676136, 6676137, 6676138, 6676139, 6676140, 6676181, 6676183, 6676215, 6676346, 6676367, 6676395, 6676412, 6676440, 6676468, 6676507, 6676538, 6676580, 6676631, 6676634, 6676664, 6676675, 6676676, 6676677, 6676678, 6676679, 6676680, 6676681, 6676714, 6676715, 6676716, 6676717, 6676718, 6676719, 6676720, 6676721, 6676722, 6676723, 6676724, 6676725, 6676726, 6676727, 6676728, 6676729, 6676751, 6676756, 6676800, 6676853, 6676854, 6676952, 6676953, 6676954, 6676955, 6676959, 6677111, 6677112, 6677123, 6677128, 6677152, 6677170, 6677235, 6677238, 6677244, 6677254, 6677262, 6677281, 6677293, 6677303, 6677316, 6677398, 6677449, 6677450, 6677451, 6677452, 6677453, 6677454, 6677455, 6677456, 6677457, 6677458, 6677459, 6677460, 6677461, 6677462, 6677463, 6677464, 6677465, 6677466, 6677467, 6677468, 6677469, 6677470, 6677471, 6677472, 6677473, 6677474, 6677475, 6677476, 6677477, 6677478, 6677479, 6677480, 6677481, 6677530, 6677531, 6677532, 6677533, 6677534, 6677535, 6677536, 6677537, 6677561, 6677570, 6677605, 6677606, 6677657, 6677660, 6677683, 6677710, 6677772, 6677787, 6677810, 6677819, 6677821, 6677848, 6677898, 6677922, 6677931, 6677939, 6677944, 6677945, 6677946, 6677947, 6677948, 6677949, 6677950, 6677951, 6677952, 6677953, 6677954, 6677955, 6677956, 6677957, 6677958, 6678075, 6678089, 6678126, 6678217, 6678218, 6678219, 6678221, 6678237, 6678331, 6678349, 6678350, 6678411, 6678412, 6678413, 6678414, 6678415, 6678416, 6678417, 6678418, 6678419, 6678420, 6678421, 6678422, 6678423, 6678424, 6678425, 6678426, 6678427, 6678428, 6678429, 6678430, 6678431, 6678432, 6678433, 6678434, 6678435, 6678436, 6678437, 6678438, 6678439, 6678448, 6678454, 6678608, 6678609, 6678655, 6678821, 6678866, 6678915, 6678917, 6678994, 6679027, 6679029, 6679036, 6679044, 6679100, 6679101, 6679102, 6679103, 6679104, 6679105, 6679106, 6679107, 6679108, 6679109, 6679110, 6679111, 6679112, 6679148, 6679163, 6679195, 6679196, 6679197, 6679198, 6679199, 6679200, 6679201, 6679202, 6679203, 6679204, 6679235, 6679236, 6679237, 6679238, 6679239, 6679240, 6679241, 6679242, 6679243, 6679244, 6679245, 6679246, 6679261, 6679264, 6679296, 6679316, 6679342, 6679404, 6679511, 6679534, 6679548, 6679549, 6679585, 6679596, 6679598, 6679623, 6679628, 6679641, 6679646, 6679671, 6679693, 6679701, 6679710, 6679716, 6679731, 6679735, 6679737, 6679764, 6679812, 6679813, 6679814, 6679815, 6679816, 6679817, 6679818, 6679819, 6679820, 6679821, 6679822, 6679823, 6679824, 6679825, 6679826, 6679827, 6679901, 6679902, 6679903, 6679904, 6679946, 6679974, 6680017, 6680160, 6680161, 6680162, 6680163, 6680164, 6680165, 6680167, 6680169, 6680171, 6680172, 6680173, 6680174, 6680175, 6680176, 6680178, 6680179, 6680180, 6680182, 6680183, 6680203, 6680265, 6680304, 6680319, 6680342, 6680375, 6680434, 6680441, 6680442, 6680448, 6680449, 6680450, 6680451, 6680452, 6680453, 6680454, 6680455, 6680456, 6680457, 6680458, 6680459, 6680460, 6680461, 6680462, 6680508, 6680539, 6680567, 6680594, 6680616, 6680628, 6680646, 6680676, 6680745, 6680746, 6680747, 6680748, 6680749, 6680750, 6680751, 6680752, 6680753, 6680754, 6680755, 6680756, 6680757, 6680758, 6680759, 6680760, 6680761, 6680762, 6680763, 6680764, 6680765, 6680766, 6680767, 6680768, 6680769, 6680770, 6680771, 6680772, 6680773, 6680774, 6680775, 6680776, 6680777, 6680778, 6680779, 6680780, 6680781, 6680782, 6680783, 6680784, 6680785, 6680786, 6680787, 6680788, 6680789, 6680790, 6680791, 6680792, 6680793, 6680794, 6680795, 6680796, 6680797, 6680798, 6680799, 6680800, 6680801, 6680802, 6680820, 6680955, 6680956, 6680957, 6680958, 6680959, 6680960, 6680961, 6680962, 6680963, 6680964, 6680965, 6680966, 6680967, 6680968, 6680969, 6680970, 6680971, 6680972, 6680973, 6680974, 6680975, 6680976, 6680977, 6680978, 6680979, 6680980, 6680981, 6680982, 6680983, 6680984, 6680985, 6680986, 6680987, 6680988, 6680989, 6680990, 6680991, 6680992, 6680993, 6680994, 6680995, 6680996, 6680997, 6680998, 6680999, 6681060, 6681111, 6681145, 6681190, 6681201, 6681227, 6681229, 6681235, 6681237, 6681257, 6681383, 6681436, 6681476, 6681477, 6681478, 6681479, 6681480, 6681481, 6681482, 6681483, 6681484, 6681485, 6681550, 6681554, 6681576, 6681600, 6681614, 6681621, 6681789, 6681798, 6681818, 6681819, 6681820, 6681821, 6681822, 6681823, 6681824, 6681825, 6681826, 6681827, 6681828, 6681829, 6681830, 6681831, 6681832, 6681833, 6681864, 6681951, 6681952, 6681953, 6681954, 6681955, 6681956, 6681957, 6681958, 6681959, 6681960, 6681961, 6681962, 6681966, 6681993, 6682073, 6682074, 6682093, 6682115, 6682131, 6682176, 6682204, 6682291, 6682359, 6682393, 6682399, 6682433, 6682445, 6682508, 6682522, 6682523, 6682524, 6682528, 6682629, 6682697, 6682724, 6682754, 6682829, 6682830, 6682831, 6682832, 6682833, 6682834, 6682835, 6682836, 6682837, 6682838, 6682839, 6682840, 6682841, 6682842, 6682843, 6682844, 6682845, 6682846, 6682847, 6682880, 6682897, 6682932, 6682966, 6682969, 6682981, 6682992, 6682999, 6683023, 6683030, 6683038, 6683042, 6683062, 6683080, 6683081, 6683082, 6683083, 6683084, 6683085, 6683086, 6683087, 6683088, 6683089, 6683090, 6683091, 6683092, 6683093, 6683094, 6683095, 6683096, 6683097, 6683098, 6683099, 6683100, 6683101, 6683102, 6683103, 6683104, 6683105, 6683106, 6683107, 6683108, 6683136, 6683140, 6683211, 6683212, 6683213, 6683233, 6683248, 6683251, 6683263, 6683339, 6683363, 6683365, 6683369, 6683370, 6683371, 6683372, 6683418, 6683431, 6683441, 6683447, 6683541, 6683604, 6683626, 6683627, 6683628, 6683629, 6683630, 6683631, 6683632, 6683633, 6683634, 6683635, 6683636, 6683747, 6683758, 6683878, 6683984, 6684040, 6684070, 6684115, 6684116, 6684117, 6684118, 6684119, 6684120, 6684145, 6684154, 6684156, 6684258, 6684261, 6684262, 6684282, 6684283, 6684285, 6684314, 6684316, 6684318, 6684320, 6684323, 6684324, 6684325, 6684326, 6684327, 6684328, 6684329, 6684330, 6684331, 6684332, 6684333, 6684334, 6684335, 6684336, 6684337, 6684378, 6684407, 6684414, 6684416, 6684424, 6684472, 6684563, 6684574, 6684575, 6684576, 6684577, 6684601, 6684635, 6684636, 6684639, 6684640, 6684641, 6684642, 6684666, 108658947, ]; let original = ARRAY.iter().cloned().collect::(); let new = serialize_and_deserialize(&original); assert_eq!(original, new); } roaring-0.10.2/tests/size_hint.rs000064400000000000000000000034311046102023000150520ustar 00000000000000extern crate roaring; use roaring::RoaringBitmap; #[test] fn array() { let bitmap = (0..2000).collect::(); let mut iter = bitmap.iter(); assert_eq!((2000, Some(2000)), iter.size_hint()); iter.by_ref().take(1000).for_each(drop); assert_eq!((1000, Some(1000)), iter.size_hint()); iter.by_ref().for_each(drop); assert_eq!((0, Some(0)), iter.size_hint()); } #[test] fn bitmap() { let bitmap = (0..6000).collect::(); let mut iter = bitmap.iter(); assert_eq!((6000, Some(6000)), iter.size_hint()); iter.by_ref().take(3000).for_each(drop); assert_eq!((3000, Some(3000)), iter.size_hint()); iter.by_ref().for_each(drop); assert_eq!((0, Some(0)), iter.size_hint()); } #[test] fn arrays() { let bitmap = (0..2000) .chain(1_000_000..1_002_000) .chain(2_000_000..2_001_000) .collect::(); let mut iter = bitmap.iter(); assert_eq!((5000, Some(5000)), iter.size_hint()); iter.by_ref().take(3000).for_each(drop); assert_eq!((2000, Some(2000)), iter.size_hint()); iter.by_ref().for_each(drop); assert_eq!((0, Some(0)), iter.size_hint()); } #[test] fn bitmaps() { let bitmap = (0..6000) .chain(1_000_000..1_012_000) .chain(2_000_000..2_010_000) .collect::(); let mut iter = bitmap.iter(); assert_eq!((28000, Some(28000)), iter.size_hint()); iter.by_ref().take(2000).for_each(drop); assert_eq!((26000, Some(26000)), iter.size_hint()); iter.by_ref().take(5000).for_each(drop); assert_eq!((21000, Some(21000)), iter.size_hint()); iter.by_ref().take(20000).for_each(drop); assert_eq!((1000, Some(1000)), iter.size_hint()); iter.by_ref().for_each(drop); assert_eq!((0, Some(0)), iter.size_hint()); } roaring-0.10.2/tests/symmetric_difference_with.rs000064400000000000000000000062511046102023000203020ustar 00000000000000extern crate roaring; use roaring::RoaringBitmap; #[test] fn array() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..3000).collect::(); let bitmap3 = (0..1000).chain(2000..3000).collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn no_symmetric_difference() { let mut bitmap1 = (0..2).collect::(); let bitmap2 = (0..2).collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, RoaringBitmap::new()); } #[test] fn array_and_bitmap() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..8000).collect::(); let bitmap3 = (0..1000).chain(2000..8000).collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_to_bitmap() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (6000..18000).collect::(); let bitmap3 = (0..6000).chain(12000..18000).collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_to_array() { let mut bitmap1 = (0..6000).collect::(); let bitmap2 = (2000..7000).collect::(); let bitmap3 = (0..2000).chain(6000..7000).collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_and_array_to_bitmap() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (11000..14000).collect::(); let bitmap3 = (0..11000).chain(12000..14000).collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_and_array_to_array() { let mut bitmap1 = (0..6000).collect::(); let bitmap2 = (3000..7000).collect::(); let bitmap3 = (0..3000).chain(6000..7000).collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn arrays() { let mut bitmap1 = (0..2000) .chain(1_000_000..1_002_000) .chain(3_000_000..3_001_000) .collect::(); let bitmap2 = (1000..3000) .chain(1_001_000..1_003_000) .chain(2_000_000..2_000_001) .collect::(); let bitmap3 = (0..1000) .chain(1_000_000..1_001_000) .chain(2000..3000) .chain(1_002_000..1_003_000) .chain(2_000_000..2_000_001) .chain(3_000_000..3_001_000) .collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmaps() { let mut bitmap1 = (0..6000) .chain(1_000_000..1_012_000) .chain(3_000_000..3_010_000) .collect::(); let bitmap2 = (3000..7000) .chain(1_006_000..1_018_000) .chain(2_000_000..2_010_000) .collect::(); let bitmap3 = (0..3000) .chain(1_000_000..1_006_000) .chain(6000..7000) .chain(1_012_000..1_018_000) .chain(2_000_000..2_010_000) .chain(3_000_000..3_010_000) .collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } roaring-0.10.2/tests/treemap_clone.rs000064400000000000000000000016351046102023000156770ustar 00000000000000extern crate roaring; use roaring::RoaringTreemap; #[test] #[allow(clippy::redundant_clone)] fn array() { let original = (0..2000).collect::(); let clone = original.clone(); assert_eq!(clone, original); } #[test] #[allow(clippy::redundant_clone)] fn bitmap() { let original = (0..6000).collect::(); let clone = original.clone(); assert_eq!(clone, original); } #[test] #[allow(clippy::redundant_clone)] fn arrays() { let original = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) .collect::(); let clone = original.clone(); assert_eq!(clone, original); } #[test] #[allow(clippy::redundant_clone)] fn bitmaps() { let original = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) .collect::(); let clone = original.clone(); assert_eq!(clone, original); } roaring-0.10.2/tests/treemap_difference_with.rs000064400000000000000000000062111046102023000177170ustar 00000000000000extern crate roaring; use roaring::RoaringTreemap; #[test] fn array() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..3000).collect::(); let bitmap3 = (0..1000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn no_difference() { let mut bitmap1 = (1..3).collect::(); let bitmap2 = (1..3).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, RoaringTreemap::new()); } #[test] fn array_and_bitmap() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..8000).collect::(); let bitmap3 = (0..1000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_to_bitmap() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (6000..18000).collect::(); let bitmap3 = (0..6000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_to_array() { let mut bitmap1 = (0..6000).collect::(); let bitmap2 = (3000..9000).collect::(); let bitmap3 = (0..3000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_and_array_to_bitmap() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (9000..12000).collect::(); let bitmap3 = (0..9000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_and_array_to_array() { let mut bitmap1 = (0..6000).collect::(); let bitmap2 = (3000..6000).collect::(); let bitmap3 = (0..3000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn arrays() { let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) .collect::(); let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) .collect::(); let bitmap3 = ((0..1000).chain(1_000_000..1_001_000)).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn arrays_removing_one_whole_container() { let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) .collect::(); let bitmap2 = ((0..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) .collect::(); let bitmap3 = (1_000_000..1_001_000).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmaps() { let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) .collect::(); let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) .collect::(); let bitmap3 = ((0..3000).chain(1_000_000..1_006_000)).collect::(); bitmap1 -= bitmap2; assert_eq!(bitmap1, bitmap3); } roaring-0.10.2/tests/treemap_intersect_with.rs000064400000000000000000000047101046102023000176270ustar 00000000000000extern crate roaring; use roaring::RoaringTreemap; #[test] fn array() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..3000).collect::(); let bitmap3 = (1000..2000).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn no_intersection() { let mut bitmap1 = (0..2).collect::(); let bitmap2 = (3..4).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, RoaringTreemap::new()); } #[test] fn array_and_bitmap() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..8000).collect::(); let bitmap3 = (1000..2000).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_to_bitmap() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (6000..18000).collect::(); let bitmap3 = (6000..12000).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_to_array() { let mut bitmap1 = (0..6000).collect::(); let bitmap2 = (3000..9000).collect::(); let bitmap3 = (3000..6000).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_and_array() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (7000..9000).collect::(); let bitmap3 = (7000..9000).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn arrays() { let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)) .collect::(); let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) .collect::(); let bitmap3 = ((1000..2000).chain(1_001_000..1_002_000)).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmaps() { let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)) .collect::(); let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) .collect::(); let bitmap3 = ((3000..6000).chain(1_006_000..1_012_000)).collect::(); bitmap1 &= bitmap2; assert_eq!(bitmap1, bitmap3); } roaring-0.10.2/tests/treemap_is_disjoint.rs000064400000000000000000000036701046102023000171160ustar 00000000000000extern crate roaring; use roaring::RoaringTreemap; #[test] fn array() { let bitmap1 = (0..2000).collect::(); let bitmap2 = (4000..6000).collect::(); assert!(bitmap1.is_disjoint(&bitmap2)); } #[test] fn array_not() { let bitmap1 = (0..4000).collect::(); let bitmap2 = (2000..6000).collect::(); assert!(!bitmap1.is_disjoint(&bitmap2)); } #[test] fn bitmap() { let bitmap1 = (0..6000).collect::(); let bitmap2 = (10000..16000).collect::(); assert!(bitmap1.is_disjoint(&bitmap2)); } #[test] fn bitmap_not() { let bitmap1 = (0..10000).collect::(); let bitmap2 = (5000..15000).collect::(); assert!(!bitmap1.is_disjoint(&bitmap2)); } #[test] fn arrays() { let bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_002_000)) .collect::(); let bitmap2 = ((100_000..102_000).chain(1_100_000..1_102_000)).collect::(); assert!(bitmap1.is_disjoint(&bitmap2)); } #[test] fn arrays_not() { let bitmap1 = ((0..2_000).chain(1_000_000..1_002_000).chain(2_000_000..2_002_000)) .collect::(); let bitmap2 = ((100_000..102_000).chain(1_001_000..1_003_000)).collect::(); assert!(!bitmap1.is_disjoint(&bitmap2)); } #[test] fn bitmaps() { let bitmap1 = ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_006_000)) .collect::(); let bitmap2 = ((100_000..106_000).chain(1_100_000..1_106_000)).collect::(); assert!(bitmap1.is_disjoint(&bitmap2)); } #[test] fn bitmaps_not() { let bitmap1 = ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_006_000)) .collect::(); let bitmap2 = ((100_000..106_000).chain(1_004_000..1_008_000)).collect::(); assert!(!bitmap1.is_disjoint(&bitmap2)); } roaring-0.10.2/tests/treemap_is_subset.rs000064400000000000000000000042731046102023000166000ustar 00000000000000extern crate roaring; use roaring::RoaringTreemap; #[test] fn array_not() { let sup = (0..2000).collect::(); let sub = (1000..3000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn array() { let sup = (0..4000).collect::(); let sub = (2000..3000).collect::(); assert!(sub.is_subset(&sup)); } #[test] fn array_bitmap_not() { let sup = (0..2000).collect::(); let sub = (1000..15000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn bitmap_not() { let sup = (0..6000).collect::(); let sub = (4000..10000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn bitmap() { let sup = (0..20000).collect::(); let sub = (5000..15000).collect::(); assert!(sub.is_subset(&sup)); } #[test] fn bitmap_array_not() { let sup = (0..20000).collect::(); let sub = (19000..21000).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn bitmap_array() { let sup = (0..20000).collect::(); let sub = (18000..20000).collect::(); assert!(sub.is_subset(&sup)); } #[test] fn arrays_not() { let sup = ((0..2000).chain(1_000_000..1_002_000)).collect::(); let sub = ((100_000..102_000).chain(1_100_000..1_102_000)).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn arrays() { let sup = ((0..3000).chain(100_000..103_000)).collect::(); let sub = ((0..2000).chain(100_000..102_000)).collect::(); assert!(sub.is_subset(&sup)); } #[test] fn bitmaps_not() { let sup = ((0..6000).chain(1_000_000..1_006_000).chain(2_000_000..2_010_000)) .collect::(); let sub = ((100_000..106_000).chain(1_100_000..1_106_000)).collect::(); assert!(!sub.is_subset(&sup)); } #[test] fn bitmaps() { let sup = ((0..1_000_000).chain(2_000_000..2_010_000)).collect::(); let sub = ((0..10_000).chain(500_000..510_000)).collect::(); assert!(sub.is_subset(&sup)); } roaring-0.10.2/tests/treemap_iter.rs000064400000000000000000000071021046102023000155350ustar 00000000000000extern crate roaring; mod iter; use roaring::RoaringTreemap; use iter::outside_in; use proptest::arbitrary::any; use proptest::collection::btree_set; use proptest::proptest; use std::iter::FromIterator; #[test] fn range() { let original = (0..2000).collect::(); let clone = RoaringTreemap::from_iter(&original); let clone2 = RoaringTreemap::from_iter(original.clone()); assert_eq!(clone, original); assert_eq!(clone2, original); } #[test] fn array() { let original = (0..5).collect::(); let clone = RoaringTreemap::from([0, 1, 2, 3, 4]); assert_eq!(clone, original); } #[test] fn bitmap() { let original = (0..6000).collect::(); let clone = RoaringTreemap::from_iter(&original); let clone2 = RoaringTreemap::from_iter(original.clone()); assert_eq!(clone, original); assert_eq!(clone2, original); } #[test] fn arrays() { let original = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) .collect::(); let clone = RoaringTreemap::from_iter(&original); let clone2 = RoaringTreemap::from_iter(original.clone()); assert_eq!(clone, original); assert_eq!(clone2, original); } #[test] fn bitmaps() { let original = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) .collect::(); let clone = RoaringTreemap::from_iter(&original); let clone2 = RoaringTreemap::from_iter(original.clone()); assert_eq!(clone, original); assert_eq!(clone2, original); } #[test] fn bitmaps_iterator() { let original = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) .collect::(); let clone = RoaringTreemap::from_bitmaps(original.bitmaps().map(|(p, b)| (p, b.clone()))); let clone2 = original.bitmaps().map(|(p, b)| (p, b.clone())).collect::(); assert_eq!(clone, original); assert_eq!(clone2, original); } proptest! { #[test] fn iter(values in btree_set(any::(), ..=10_000)) { let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); assert!(values.into_iter().eq(bitmap)); } } #[test] fn rev() { let values = (1..3) .chain(1_000_000..1_012_003) .chain(2_000_001..2_000_003) .chain(2_000_000_000_001..2_000_000_000_003); let bitmap = RoaringTreemap::from_iter(values.clone()); assert!(values.into_iter().rev().eq(bitmap.iter().rev())); } proptest! { #[test] fn rev_iter(values in btree_set(any::(), ..=10_000)) { let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); assert!(values.into_iter().rev().eq(bitmap.iter().rev())); } } #[test] fn from_iter() { // This test verifies that the public API allows conversion from iterators // with u64 as well as &u64 elements. let vals = vec![1, 5, 1_000_000_000_000_000]; let a = RoaringTreemap::from_iter(vals.iter()); let b = RoaringTreemap::from_iter(vals); assert_eq!(a, b); } #[test] fn interleaved() { let values = (1..3) .chain(1_000_000..1_012_003) .chain(2_000_001..2_000_003) .chain(2_000_000_000_001..2_000_000_000_003); let bitmap = RoaringTreemap::from_iter(values.clone()); assert!(outside_in(values).eq(outside_in(bitmap))); } proptest! { #[test] fn interleaved_iter(values in btree_set(any::(), 50_000..=100_000)) { let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); assert!(outside_in(values).eq(outside_in(bitmap))); } } roaring-0.10.2/tests/treemap_lib.rs000064400000000000000000000062771046102023000153540ustar 00000000000000extern crate roaring; use roaring::RoaringTreemap; #[test] fn smoke() { let mut bitmap = RoaringTreemap::new(); assert_eq!(bitmap.len(), 0); assert!(bitmap.is_empty()); bitmap.remove(0); assert_eq!(bitmap.len(), 0); assert!(bitmap.is_empty()); bitmap.insert(1); assert!(bitmap.contains(1)); assert_eq!(bitmap.len(), 1); assert!(!bitmap.is_empty()); bitmap.insert(u64::MAX - 2); assert!(bitmap.contains(u64::MAX - 2)); assert_eq!(bitmap.len(), 2); bitmap.insert(u64::MAX); assert!(bitmap.contains(u64::MAX)); assert_eq!(bitmap.len(), 3); bitmap.insert(2); assert!(bitmap.contains(2)); assert_eq!(bitmap.len(), 4); bitmap.remove(2); assert!(!bitmap.contains(2)); assert_eq!(bitmap.len(), 3); assert!(!bitmap.contains(0)); assert!(bitmap.contains(1)); assert!(!bitmap.contains(100)); assert!(bitmap.contains(u64::MAX - 2)); assert!(!bitmap.contains(u64::MAX - 1)); assert!(bitmap.contains(u64::MAX)); } #[test] fn insert_range() { let ranges = 0..0x1000; const SIGMA: u64 = u32::MAX as u64; let mut bitmap = RoaringTreemap::new(); assert_eq!(bitmap.insert_range(ranges), 0x1000); assert_eq!(bitmap.len(), 0x1000); assert_eq!(bitmap.max(), Some(0xFFF)); assert_eq!(bitmap.insert_range(u32::MAX as u64 - 1..u32::MAX as u64 + 1), 2); assert!(bitmap.contains(2)); assert!(bitmap.contains(0xFFF)); assert!(!bitmap.contains(0x1000)); bitmap.clear(); bitmap.insert_range(2 * SIGMA..=4 * SIGMA); assert_eq!(bitmap.min(), Some(2 * SIGMA)); assert_eq!(bitmap.max(), Some(4 * SIGMA)); assert!(bitmap.contains(3 * SIGMA)); } #[test] fn remove_range() { let ranges = [0u64, 1, 63, 64, 65, 100, 4096 - 1, 4096, 4096 + 1, 65536 - 1]; for (i, &a) in ranges.iter().enumerate() { for &b in &ranges[i..] { let mut bitmap = (0..=65536).collect::(); assert_eq!(bitmap.remove_range(a..b), (b - a)); assert_eq!(bitmap, ((0..a).chain(b..=65536)).collect::()); } } } #[test] fn test_max() { let mut bitmap = RoaringTreemap::new(); assert_eq!(bitmap.max(), None); bitmap.insert(0); assert_eq!(bitmap.max(), Some(0)); bitmap.insert(1); assert_eq!(bitmap.max(), Some(1)); bitmap.insert(u64::MAX); assert_eq!(bitmap.max(), Some(u64::MAX)); } #[test] fn test_min() { let mut bitmap = RoaringTreemap::new(); assert_eq!(bitmap.min(), None); bitmap.insert(u64::MAX); assert_eq!(bitmap.min(), Some(u64::MAX)); bitmap.insert(1); assert_eq!(bitmap.min(), Some(1)); bitmap.insert(0); assert_eq!(bitmap.min(), Some(0)); } #[test] fn to_bitmap() { let bitmap = (0..5000).collect::(); assert_eq!(bitmap.len(), 5000); for i in 1..5000 { assert!(bitmap.contains(i)); } assert!(!bitmap.contains(5001)); } #[test] fn to_array() { let mut bitmap = (0..5000).collect::(); for i in 3000..5000 { bitmap.remove(i); } assert_eq!(bitmap.len(), 3000); for i in 0..3000 { assert!(bitmap.contains(i)); } for i in 3000..5000 { assert!(!bitmap.contains(i)); } } roaring-0.10.2/tests/treemap_ops.rs000064400000000000000000000036611046102023000154010ustar 00000000000000extern crate roaring; use roaring::RoaringTreemap; #[test] fn or() { let mut rb1 = (1..4).collect::(); let rb2 = (3..6).collect::(); let rb3 = (1..6).collect::(); assert_eq!(rb3, &rb1 | &rb2); assert_eq!(rb3, &rb1 | rb2.clone()); assert_eq!(rb3, rb1.clone() | &rb2); assert_eq!(rb3, rb1.clone() | rb2.clone()); assert_eq!(rb3.len(), rb1.union_len(&rb2)); rb1 |= &rb2; rb1 |= rb2; assert_eq!(rb3, rb1); } #[test] fn and() { let mut rb1 = (1..4).collect::(); let rb2 = (3..6).collect::(); let rb3 = (3..4).collect::(); assert_eq!(rb3, &rb1 & &rb2); assert_eq!(rb3, &rb1 & rb2.clone()); assert_eq!(rb3, rb1.clone() & &rb2); assert_eq!(rb3, rb1.clone() & rb2.clone()); assert_eq!(rb3.len(), rb1.intersection_len(&rb2)); rb1 &= &rb2; rb1 &= rb2; assert_eq!(rb3, rb1); } #[test] fn sub() { let mut rb1 = (1..4).collect::(); let rb2 = (3..6).collect::(); let rb3 = (1..3).collect::(); assert_eq!(rb3, &rb1 - &rb2); assert_eq!(rb3, &rb1 - rb2.clone()); assert_eq!(rb3, rb1.clone() - &rb2); assert_eq!(rb3, rb1.clone() - rb2.clone()); assert_eq!(rb3.len(), rb1.difference_len(&rb2)); rb1 -= &rb2; rb1 -= rb2; assert_eq!(rb3, rb1); } #[test] fn xor() { let mut rb1 = (1..4).collect::(); let rb2 = (3..6).collect::(); let rb3 = ((1..3).chain(4..6)).collect::(); let rb4 = (0..0).collect::(); assert_eq!(rb3, &rb1 ^ &rb2); assert_eq!(rb3, &rb1 ^ rb2.clone()); assert_eq!(rb3, rb1.clone() ^ &rb2); assert_eq!(rb3, rb1.clone() ^ rb2.clone()); assert_eq!(rb3.len(), rb1.symmetric_difference_len(&rb2)); rb1 ^= &rb2; assert_eq!(rb3, rb1); rb1 ^= rb3; assert_eq!(rb4, rb1); } roaring-0.10.2/tests/treemap_rank.rs000064400000000000000000000033731046102023000155330ustar 00000000000000extern crate roaring; use proptest::collection::{btree_set, vec}; use proptest::prelude::*; use roaring::RoaringTreemap; use std::ops::RangeInclusive; const BITMAP_MAX: u64 = u32::MAX as u64; #[test] fn rank_roaring_bitmaps() { // A treemap with two roaring bitmaps. // The lower one contains one array container with the highest 1000 values // The higher one contains one bitmap at with the lowest 5000 values let treemap = RoaringTreemap::from_sorted_iter(BITMAP_MAX - 1000..BITMAP_MAX + 5000).unwrap(); // start of treemap assert_eq!(treemap.rank(0), 0); // low boundary assert_eq!(treemap.rank(BITMAP_MAX - 1002), 0); assert_eq!(treemap.rank(BITMAP_MAX - 1001), 0); assert_eq!(treemap.rank(BITMAP_MAX - 1000), 1); // middle range (spans two roaring bitmaps) assert_eq!(treemap.rank(BITMAP_MAX - 1), 1000); assert_eq!(treemap.rank(BITMAP_MAX), 1001); assert_eq!(treemap.rank(BITMAP_MAX + 1), 1002); // high boundary assert_eq!(treemap.rank(BITMAP_MAX + 4998), 5999); assert_eq!(treemap.rank(BITMAP_MAX + 4999), 6000); assert_eq!(treemap.rank(BITMAP_MAX + 5000), 6000); // end of treemap assert_eq!(treemap.rank(u64::MAX), 6000); } // A range that spans 2 roaring bitmaps with 2 containers each const PROP_RANGE: RangeInclusive = BITMAP_MAX - (1 << 17)..=BITMAP_MAX + (1 << 17); proptest! { #[test] fn proptest_rank( values in btree_set(PROP_RANGE, ..=1000), checks in vec(PROP_RANGE, ..=100) ){ let treemap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); for i in checks { let expected = values.iter().take_while(|&&x| x <= i).count() as u64; assert_eq!(treemap.rank(i), expected); } } } roaring-0.10.2/tests/treemap_select.rs000064400000000000000000000024071046102023000160540ustar 00000000000000extern crate roaring; use proptest::collection::btree_set; use proptest::prelude::*; use roaring::RoaringTreemap; #[test] fn select() { let bitmap = (0..2000).collect::(); assert_eq!(bitmap.select(0), Some(0)); } #[test] fn select_multiple_bitmap() { let mut bitmap = (0..100_000).collect::(); bitmap.append(u32::MAX as u64..u32::MAX as u64 + 100_000).expect("sorted integers"); assert_eq!(bitmap.select(0), Some(0)); assert_eq!(bitmap.select(99_999), Some(99_999)); assert_eq!(bitmap.select(100_000), Some(u32::MAX as u64)); assert_eq!(bitmap.select(199_999), Some(u32::MAX as u64 + 99_999)); assert_eq!(bitmap.select(200_000), None); assert_eq!(bitmap.select(u64::MAX), None); } #[test] fn select_empty() { let bitmap = RoaringTreemap::new(); assert_eq!(bitmap.select(0), None); assert_eq!(bitmap.select(1024), None); assert_eq!(bitmap.select(u64::MAX), None); } proptest! { #[test] fn proptest_select(values in btree_set(any::(), 1000)) { let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); for (i, value) in values.iter().cloned().enumerate() { prop_assert_eq!(bitmap.select(i as u64), Some(value)); } } } roaring-0.10.2/tests/treemap_serialization.rs000064400000000000000000000017441046102023000174550ustar 00000000000000use roaring::RoaringTreemap; use std::iter::FromIterator; fn serialize_deserialize(dataset: Dataset) where Dataset: IntoIterator, I: Iterator, { let rb = RoaringTreemap::from_iter(dataset); let mut buffer = vec![]; rb.serialize_into(&mut buffer).unwrap(); assert_eq!(buffer.len(), rb.serialized_size()); let new_rb = RoaringTreemap::deserialize_from(&buffer[..]).unwrap(); assert_eq!(rb, new_rb); } #[test] fn empty() { serialize_deserialize(vec![]) } #[test] fn basic() { serialize_deserialize(vec![1, 2, 3, 4, 5, 100, 1000]) } #[test] fn basic_2() { serialize_deserialize(vec![1, 2, 3, 4, 5, 100, 1000, 10000, 100000, 1000000]) } #[test] fn basic_3() { let u32max = u32::MAX as u64; serialize_deserialize( vec![1, 2, 3, 4, 5, 100, 1000, 10000, 100000, 1000000, u32max + 10, u32max << 10] .into_iter() .chain(u32max..(u32max + 2 * (1 << 16))), ) } roaring-0.10.2/tests/treemap_size_hint.rs000064400000000000000000000033761046102023000165770ustar 00000000000000extern crate roaring; use roaring::RoaringTreemap; #[test] fn array() { let bitmap = (0..2000).collect::(); let mut iter = bitmap.iter(); assert_eq!((2000, Some(2000)), iter.size_hint()); iter.by_ref().take(1000).for_each(drop); assert_eq!((1000, Some(1000)), iter.size_hint()); iter.by_ref().for_each(drop); assert_eq!((0, Some(0)), iter.size_hint()); } #[test] fn bitmap() { let bitmap = (0..6000).collect::(); let mut iter = bitmap.iter(); assert_eq!((6000, Some(6000)), iter.size_hint()); iter.by_ref().take(3000).for_each(drop); assert_eq!((3000, Some(3000)), iter.size_hint()); iter.by_ref().for_each(drop); assert_eq!((0, Some(0)), iter.size_hint()); } #[test] fn arrays() { let bitmap = ((0..2000).chain(1_000_000..1_002_000).chain(2_000_000..2_001_000)) .collect::(); let mut iter = bitmap.iter(); assert_eq!((5000, Some(5000)), iter.size_hint()); iter.by_ref().take(3000).for_each(drop); assert_eq!((2000, Some(2000)), iter.size_hint()); iter.by_ref().for_each(drop); assert_eq!((0, Some(0)), iter.size_hint()); } #[test] fn bitmaps() { let bitmap = ((0..6000).chain(1_000_000..1_012_000).chain(2_000_000..2_010_000)) .collect::(); let mut iter = bitmap.iter(); assert_eq!((28000, Some(28000)), iter.size_hint()); iter.by_ref().take(2000).for_each(drop); assert_eq!((26000, Some(26000)), iter.size_hint()); iter.by_ref().take(5000).for_each(drop); assert_eq!((21000, Some(21000)), iter.size_hint()); iter.by_ref().take(20000).for_each(drop); assert_eq!((1000, Some(1000)), iter.size_hint()); iter.by_ref().for_each(drop); assert_eq!((0, Some(0)), iter.size_hint()); } roaring-0.10.2/tests/treemap_symmetric_difference_with.rs000064400000000000000000000062151046102023000220170ustar 00000000000000extern crate roaring; use roaring::RoaringTreemap; #[test] fn array() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..3000).collect::(); let bitmap3 = ((0..1000).chain(2000..3000)).collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn no_symmetric_difference() { let mut bitmap1 = (0..2).collect::(); let bitmap2 = (0..2).collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, RoaringTreemap::new()); } #[test] fn array_and_bitmap() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..8000).collect::(); let bitmap3 = ((0..1000).chain(2000..8000)).collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_to_bitmap() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (6000..18000).collect::(); let bitmap3 = ((0..6000).chain(12000..18000)).collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_to_array() { let mut bitmap1 = (0..6000).collect::(); let bitmap2 = (2000..7000).collect::(); let bitmap3 = ((0..2000).chain(6000..7000)).collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_and_array_to_bitmap() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (11000..14000).collect::(); let bitmap3 = ((0..11000).chain(12000..14000)).collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_and_array_to_array() { let mut bitmap1 = (0..6000).collect::(); let bitmap2 = (3000..7000).collect::(); let bitmap3 = ((0..3000).chain(6000..7000)).collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn arrays() { let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)) .collect::(); let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_000_001)) .collect::(); let bitmap3 = ((0..1000) .chain(1_000_000..1_001_000) .chain(2000..3000) .chain(1_002_000..1_003_000) .chain(2_000_000..2_000_001) .chain(3_000_000..3_001_000)) .collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmaps() { let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)) .collect::(); let bitmap2 = ((3000..7000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) .collect::(); let bitmap3 = ((0..3000) .chain(1_000_000..1_006_000) .chain(6000..7000) .chain(1_012_000..1_018_000) .chain(2_000_000..2_010_000) .chain(3_000_000..3_010_000)) .collect::(); bitmap1 ^= bitmap2; assert_eq!(bitmap1, bitmap3); } roaring-0.10.2/tests/treemap_union_with.rs000064400000000000000000000046111046102023000167570ustar 00000000000000extern crate roaring; use roaring::RoaringTreemap; #[test] fn array_to_array() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..3000).collect::(); let bitmap3 = (0..3000).collect::(); bitmap1 |= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn array_to_bitmap() { let mut bitmap1 = (0..4000).collect::(); let bitmap2 = (4000..8000).collect::(); let bitmap3 = (0..8000).collect::(); bitmap1 |= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn array_and_bitmap() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..8000).collect::(); let bitmap3 = (0..8000).collect::(); bitmap1 |= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (6000..18000).collect::(); let bitmap3 = (0..18000).collect::(); bitmap1 |= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_and_array() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (10000..13000).collect::(); let bitmap3 = (0..13000).collect::(); bitmap1 |= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn arrays() { let mut bitmap1 = ((0..2000).chain(1_000_000..1_002_000).chain(3_000_000..3_001_000)) .collect::(); let bitmap2 = ((1000..3000).chain(1_001_000..1_003_000).chain(2_000_000..2_001_000)) .collect::(); let bitmap3 = ((0..3000) .chain(1_000_000..1_003_000) .chain(2_000_000..2_001_000) .chain(3_000_000..3_001_000)) .collect::(); bitmap1 |= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmaps() { let mut bitmap1 = ((0..6000).chain(1_000_000..1_012_000).chain(3_000_000..3_010_000)) .collect::(); let bitmap2 = ((3000..9000).chain(1_006_000..1_018_000).chain(2_000_000..2_010_000)) .collect::(); let bitmap3 = ((0..9000) .chain(1_000_000..1_018_000) .chain(2_000_000..2_010_000) .chain(3_000_000..3_010_000)) .collect::(); bitmap1 |= bitmap2; assert_eq!(bitmap1, bitmap3); } roaring-0.10.2/tests/union_with.rs000064400000000000000000000046671046102023000152550ustar 00000000000000extern crate roaring; use roaring::RoaringBitmap; #[test] fn array_to_array() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..3000).collect::(); let bitmap3 = (0..3000).collect::(); bitmap1 |= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn array_to_bitmap() { let mut bitmap1 = (0..4000).collect::(); let bitmap2 = (4000..8000).collect::(); let bitmap3 = (0..8000).collect::(); bitmap1 |= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn array_and_bitmap() { let mut bitmap1 = (0..2000).collect::(); let bitmap2 = (1000..8000).collect::(); let bitmap3 = (0..8000).collect::(); bitmap1 |= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (6000..18000).collect::(); let bitmap3 = (0..18000).collect::(); bitmap1 |= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmap_and_array() { let mut bitmap1 = (0..12000).collect::(); let bitmap2 = (10000..13000).collect::(); let bitmap3 = (0..13000).collect::(); bitmap1 |= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn arrays() { let mut bitmap1 = (0..2000) .chain(1_000_000..1_002_000) .chain(3_000_000..3_001_000) .collect::(); let bitmap2 = (1000..3000) .chain(1_001_000..1_003_000) .chain(2_000_000..2_001_000) .collect::(); let bitmap3 = (0..3000) .chain(1_000_000..1_003_000) .chain(2_000_000..2_001_000) .chain(3_000_000..3_001_000) .collect::(); bitmap1 |= bitmap2; assert_eq!(bitmap1, bitmap3); } #[test] fn bitmaps() { let mut bitmap1 = (0..6000) .chain(1_000_000..1_012_000) .chain(3_000_000..3_010_000) .collect::(); let bitmap2 = (3000..9000) .chain(1_006_000..1_018_000) .chain(2_000_000..2_010_000) .collect::(); let bitmap3 = (0..9000) .chain(1_000_000..1_018_000) .chain(2_000_000..2_010_000) .chain(3_000_000..3_010_000) .collect::(); bitmap1 |= bitmap2; assert_eq!(bitmap1, bitmap3); }