roaring-0.10.12/.cargo_vcs_info.json0000644000000001450000000000100126360ustar { "git": { "sha1": "9496afe1e6ad93a8875f901c2579761f7acdc5b0" }, "path_in_vcs": "roaring" }roaring-0.10.12/Cargo.lock0000644000000311020000000000100106060ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "atomic-polyfill" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" dependencies = [ "critical-section", ] [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bit-set" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bytemuck" version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" [[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cobs" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" [[package]] name = "critical-section" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "embedded-io" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" [[package]] name = "embedded-io" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" [[package]] name = "fastrand" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" dependencies = [ "instant", ] [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "getrandom" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" dependencies = [ "cfg-if", "libc", "wasi", ] [[package]] name = "hash32" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" dependencies = [ "byteorder", ] [[package]] name = "heapless" version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" dependencies = [ "atomic-polyfill", "hash32", "rustc_version", "serde", "spin", "stable_deref_trait", ] [[package]] name = "instant" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", ] [[package]] name = "itoa" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" version = "0.2.119" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" [[package]] name = "lock_api" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", ] [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "num-traits" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", ] [[package]] name = "postcard" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "170a2601f67cc9dba8edd8c4870b15f71a6a2dc196daec8c83f72b59dff628a8" dependencies = [ "cobs", "embedded-io 0.4.0", "embedded-io 0.6.1", "heapless", "serde", ] [[package]] name = "ppv-lite86" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ "bit-set", "bit-vec", "bitflags 2.5.0", "lazy_static", "num-traits", "rand", "rand_chacha", "rand_xorshift", "regex-syntax", "rusty-fork", "tempfile", "unarray", ] [[package]] name = "quick-error" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] [[package]] name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core", ] [[package]] name = "rand_chacha" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ "getrandom", ] [[package]] name = "rand_xorshift" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" dependencies = [ "rand_core", ] [[package]] name = "redox_syscall" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "regex-syntax" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "remove_dir_all" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ "winapi", ] [[package]] name = "roaring" version = "0.10.12" dependencies = [ "bytemuck", "byteorder", "postcard", "proptest", "serde", "serde_json", ] [[package]] name = "rustc_version" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rusty-fork" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" dependencies = [ "fnv", "quick-error", "tempfile", "wait-timeout", ] [[package]] name = "ryu" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" [[package]] name = "serde" version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", "ryu", "serde", ] [[package]] name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" dependencies = [ "lock_api", ] [[package]] name = "stable_deref_trait" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "syn" version = "2.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "tempfile" version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ "cfg-if", "fastrand", "libc", "redox_syscall", "remove_dir_all", "winapi", ] [[package]] name = "unarray" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "wait-timeout" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" dependencies = [ "libc", ] [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" roaring-0.10.12/Cargo.toml0000644000000072510000000000100106410ustar # 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.12" authors = [ "Wim Looman ", "Kerollmops ", ] build = false autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = "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" [features] default = ["std"] serde = [ "dep:serde", "std", ] simd = [] std = [ "dep:bytemuck", "dep:byteorder", ] [lib] name = "roaring" path = "src/lib.rs" [[test]] name = "clone" path = "tests/clone.rs" [[test]] name = "difference_with" path = "tests/difference_with.rs" [[test]] name = "intersect_with" path = "tests/intersect_with.rs" [[test]] name = "is_disjoint" path = "tests/is_disjoint.rs" [[test]] name = "is_subset" path = "tests/is_subset.rs" [[test]] name = "iter" path = "tests/iter.rs" [[test]] name = "iter_advance_to" path = "tests/iter_advance_to.rs" [[test]] name = "iter_range" path = "tests/iter_range.rs" [[test]] name = "lib" path = "tests/lib.rs" [[test]] name = "ops" path = "tests/ops.rs" [[test]] name = "push" path = "tests/push.rs" [[test]] name = "range_checks" path = "tests/range_checks.rs" [[test]] name = "rank" path = "tests/rank.rs" [[test]] name = "select" path = "tests/select.rs" [[test]] name = "serialization" path = "tests/serialization.rs" [[test]] name = "size_hint" path = "tests/size_hint.rs" [[test]] name = "symmetric_difference_with" path = "tests/symmetric_difference_with.rs" [[test]] name = "treemap_clone" path = "tests/treemap_clone.rs" [[test]] name = "treemap_difference_with" path = "tests/treemap_difference_with.rs" [[test]] name = "treemap_intersect_with" path = "tests/treemap_intersect_with.rs" [[test]] name = "treemap_is_disjoint" path = "tests/treemap_is_disjoint.rs" [[test]] name = "treemap_is_subset" path = "tests/treemap_is_subset.rs" [[test]] name = "treemap_iter" path = "tests/treemap_iter.rs" [[test]] name = "treemap_iter_advance_to" path = "tests/treemap_iter_advance_to.rs" [[test]] name = "treemap_lib" path = "tests/treemap_lib.rs" [[test]] name = "treemap_ops" path = "tests/treemap_ops.rs" [[test]] name = "treemap_rank" path = "tests/treemap_rank.rs" [[test]] name = "treemap_select" path = "tests/treemap_select.rs" [[test]] name = "treemap_serialization" path = "tests/treemap_serialization.rs" [[test]] name = "treemap_size_hint" path = "tests/treemap_size_hint.rs" [[test]] name = "treemap_symmetric_difference_with" path = "tests/treemap_symmetric_difference_with.rs" [[test]] name = "treemap_union_with" path = "tests/treemap_union_with.rs" [[test]] name = "union_with" path = "tests/union_with.rs" [dependencies.bytemuck] version = "1.21.0" optional = true [dependencies.byteorder] version = "1.5.0" optional = true [dependencies.serde] version = "1.0.217" optional = true [dev-dependencies.postcard] version = "1.1" features = ["alloc"] [dev-dependencies.proptest] version = "1.6.0" [dev-dependencies.serde_json] version = "1.0.138" roaring-0.10.12/Cargo.toml.orig000064400000000000000000000015441046102023000143210ustar 00000000000000[package] name = "roaring" version = "0.10.12" rust-version = "1.65.0" authors = ["Wim Looman ", "Kerollmops "] description = "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 = { workspace = true, optional = true } byteorder = { workspace = true, optional = true } serde = { workspace = true, optional = true } [features] default = ["std"] serde = ["dep:serde", "std"] simd = [] std = ["dep:bytemuck", "dep:byteorder"] [dev-dependencies] proptest = { workspace = true } serde_json = { workspace = true } postcard = { workspace = true } roaring-0.10.12/README.md000064400000000000000000000057661046102023000127230ustar 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 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. The [benchmarks directory](./benchmarks) 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.12/src/bitmap/arbitrary.rs000064400000000000000000000113621046102023000160410ustar 00000000000000#[cfg(test)] mod test { use crate::bitmap::container::Container; use crate::bitmap::store::{ArrayStore, BitmapStore, Store}; use crate::RoaringBitmap; use core::fmt::{Debug, Formatter}; use proptest::bits::{BitSetLike, SampledBitSetStrategy}; use proptest::collection::{vec, SizeRange}; use proptest::prelude::*; #[cfg(not(feature = "std"))] use alloc::vec::Vec; impl Debug for BitmapStore { fn fmt(&self, f: &mut Formatter<'_>) -> core::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 sampled( size: impl Into, bits: impl Into, ) -> SampledBitSetStrategy { SampledBitSetStrategy::new(size.into(), bits.into()) } } impl Debug for ArrayStore { fn fmt(&self, f: &mut Formatter<'_>) -> core::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 sampled( size: impl Into, bits: impl Into, ) -> SampledBitSetStrategy { SampledBitSetStrategy::new(size.into(), bits.into()) } } impl Debug for Store { fn fmt(&self, f: &mut Formatter<'_>) -> core::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(crate) fn arbitrary()(bitmap in (0usize..=16).prop_flat_map(containers)) -> RoaringBitmap { bitmap } } } } roaring-0.10.12/src/bitmap/cmp.rs000064400000000000000000000100021046102023000146070ustar 00000000000000use core::borrow::Borrow; use core::cmp::Ordering; use core::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(crate) 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.12/src/bitmap/container.rs000064400000000000000000000225561046102023000160330ustar 00000000000000use core::fmt; use core::ops::{ BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, RangeInclusive, Sub, SubAssign, }; use super::store::{self, Store}; use super::util; pub const ARRAY_LIMIT: u64 = 4096; #[cfg(not(feature = "std"))] use alloc::vec::Vec; #[derive(PartialEq, Clone)] pub(crate) struct Container { pub key: u16, pub store: Store, } #[derive(Clone)] pub(crate) 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() } } pub fn from_lsb0_bytes(key: u16, bytes: &[u8], byte_offset: usize) -> Option { Some(Container { key, store: Store::from_lsb0_bytes(bytes, byte_offset)? }) } } impl Container { pub fn len(&self) -> u64 { self.store.len() } pub fn is_empty(&self) -> bool { self.store.is_empty() } #[inline] 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() } #[inline] 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 Iterator for Iter<'_> { type Item = u32; fn next(&mut self) -> Option { self.inner.next().map(|i| util::join(self.key, i)) } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } fn count(self) -> usize where Self: Sized, { self.inner.count() } fn nth(&mut self, n: usize) -> Option { self.inner.nth(n).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 ExactSizeIterator for Iter<'_> {} impl Iter<'_> { pub(crate) fn advance_to(&mut self, index: u16) { self.inner.advance_to(index); } pub(crate) fn advance_back_to(&mut self, index: u16) { self.inner.advance_back_to(index); } } 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.12/src/bitmap/fmt.rs000064400000000000000000000010531046102023000146240ustar 00000000000000use core::fmt; use crate::RoaringBitmap; #[cfg(not(feature = "std"))] use alloc::vec::Vec; 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.12/src/bitmap/inherent.rs000064400000000000000000001033451046102023000156610ustar 00000000000000use core::cmp::Ordering; use core::mem::size_of; use core::ops::RangeBounds; use crate::bitmap::store::BITMAP_LENGTH; use crate::RoaringBitmap; use super::container::Container; use super::util; #[cfg(not(feature = "std"))] use alloc::vec::Vec; 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() } } /// Creates a `RoaringBitmap` from a byte slice, interpreting the bytes as a bitmap with a specified offset. /// /// # Arguments /// /// - `offset: u32` - The starting position in the bitmap where the byte slice will be applied, specified in bits. /// This means that if `offset` is `n`, the first byte in the slice will correspond to the `n`th bit(0-indexed) in the bitmap. /// - `bytes: &[u8]` - The byte slice containing the bitmap data. The bytes are interpreted in "Least-Significant-First" bit order. /// /// # Interpretation of `bytes` /// /// The `bytes` slice is interpreted in "Least-Significant-First" bit order. Each byte is read from least significant bit (LSB) to most significant bit (MSB). /// For example, the byte `0b00000101` represents the bits `1, 0, 1, 0, 0, 0, 0, 0` in that order (see Examples section). /// /// /// # Panics /// /// This function will panic if `bytes.len() + offset` is greater than 2^32. /// /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let bytes = [0b00000101, 0b00000010, 0b00000000, 0b10000000]; /// // ^^^^^^^^ ^^^^^^^^ ^^^^^^^^ ^^^^^^^^ /// // 76543210 98 /// let rb = RoaringBitmap::from_lsb0_bytes(0, &bytes); /// assert!(rb.contains(0)); /// assert!(!rb.contains(1)); /// assert!(rb.contains(2)); /// assert!(rb.contains(9)); /// assert!(rb.contains(31)); /// /// let rb = RoaringBitmap::from_lsb0_bytes(8, &bytes); /// assert!(rb.contains(8)); /// assert!(!rb.contains(9)); /// assert!(rb.contains(10)); /// assert!(rb.contains(17)); /// assert!(rb.contains(39)); /// /// let rb = RoaringBitmap::from_lsb0_bytes(3, &bytes); /// assert!(rb.contains(3)); /// assert!(!rb.contains(4)); /// assert!(rb.contains(5)); /// assert!(rb.contains(12)); /// assert!(rb.contains(34)); /// ``` pub fn from_lsb0_bytes(offset: u32, mut bytes: &[u8]) -> RoaringBitmap { fn shift_bytes(bytes: &[u8], amount: usize) -> Vec { let mut result = Vec::with_capacity(bytes.len() + 1); let mut carry = 0u8; for &byte in bytes { let shifted = (byte << amount) | carry; carry = byte >> (8 - amount); result.push(shifted); } if carry != 0 { result.push(carry); } result } if offset % 8 != 0 { let shift = offset as usize % 8; let shifted_bytes = shift_bytes(bytes, shift); return RoaringBitmap::from_lsb0_bytes(offset - shift as u32, &shifted_bytes); } if bytes.is_empty() { return RoaringBitmap::new(); } // Using inclusive range avoids overflow: the max exclusive value is 2^32 (u32::MAX + 1). let end_bit_inc = u32::try_from(bytes.len()) .ok() .and_then(|len_bytes| len_bytes.checked_mul(8)) // `bytes` is non-empty, so len_bits is > 0 .and_then(|len_bits| offset.checked_add(len_bits - 1)) .expect("offset + bytes.len() must be <= 2^32"); // offsets are in bytes let (mut start_container, start_offset) = (offset as usize >> 16, (offset as usize % 0x1_0000) / 8); let (end_container_inc, end_offset) = (end_bit_inc as usize >> 16, (end_bit_inc as usize % 0x1_0000 + 1) / 8); let n_containers_needed = end_container_inc + 1 - start_container; let mut containers = Vec::with_capacity(n_containers_needed); // Handle a partial first container if start_offset != 0 { let end_byte = if end_container_inc == start_container { end_offset } else { BITMAP_LENGTH * size_of::() }; let (src, rest) = bytes.split_at(end_byte - start_offset); bytes = rest; if let Some(container) = Container::from_lsb0_bytes(start_container as u16, src, start_offset) { containers.push(container); } start_container += 1; } // Handle all full containers for full_container_key in start_container..end_container_inc { let (src, rest) = bytes.split_at(BITMAP_LENGTH * size_of::()); bytes = rest; if let Some(container) = Container::from_lsb0_bytes(full_container_key as u16, src, 0) { containers.push(container); } } // Handle a last container if !bytes.is_empty() { if let Some(container) = Container::from_lsb0_bytes(end_container_inc as u16, bytes, 0) { containers.push(container); } } RoaringBitmap { containers } } /// 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); /// ``` #[inline] 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) } /// Searches for the specific container by the given key. /// Creates a new container if it doesn't exist. /// /// Return the index of the target container. #[inline] pub(crate) 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)); /// ``` #[inline] pub fn insert_range(&mut self, range: R) -> u64 where R: RangeBounds, { let (start, end) = match util::convert_range_to_inclusive(range) { Ok(range) => (*range.start(), *range.end()), Err(_) => 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]); /// ``` #[inline] 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() #[inline] 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); /// ``` #[inline] 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].is_empty() { 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); /// ``` #[inline] pub fn remove_range(&mut self, range: R) -> u64 where R: RangeBounds, { let (start, end) = match util::convert_range_to_inclusive(range) { Ok(range) => (*range.start(), *range.end()), Err(_) => 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].is_empty() { 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); /// ``` #[inline] 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)); /// ``` #[inline] pub fn contains_range(&self, range: R) -> bool where R: RangeBounds, { let (start, end) = match util::convert_range_to_inclusive(range) { Ok(range) => (*range.start(), *range.end()), // Empty/Invalid ranges are always contained Err(_) => 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); /// ``` #[inline] pub fn range_cardinality(&self, range: R) -> u64 where R: RangeBounds, { let (start, end) = match util::convert_range_to_inclusive(range) { Ok(range) => (*range.start(), *range.end()), // Empty/invalid ranges have 0 bits set in them Err(_) => 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); /// ``` #[inline] 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); /// ``` #[inline] 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()); /// ``` #[inline] 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); /// ``` #[inline] 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)); /// ``` #[inline] 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)); /// ``` #[inline] 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) /// ``` #[inline] 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); /// ``` #[inline] 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])); #[inline] 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])); #[inline] 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 {i} in bitmap={bitmap_has} and range={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.12/src/bitmap/iter.rs000064400000000000000000000655361046102023000150210ustar 00000000000000use alloc::vec; use core::iter::FusedIterator; use core::ops::RangeBounds; use core::slice; use super::container::Container; use super::{container, util}; use crate::{NonSortedIntegers, RoaringBitmap}; #[cfg(not(feature = "std"))] use alloc::vec::Vec; /// An iterator for `RoaringBitmap`. #[derive(Clone)] pub struct Iter<'a> { front: Option>, containers: slice::Iter<'a, Container>, back: Option>, } /// An iterator for `RoaringBitmap`. #[derive(Clone)] pub struct IntoIter { front: Option>, containers: vec::IntoIter, back: Option>, } #[inline] fn and_then_or_clear(opt: &mut Option, f: impl FnOnce(&mut T) -> Option) -> Option { let x = f(opt.as_mut()?); if x.is_none() { *opt = None; } x } fn advance_to_impl<'a, It>( n: u32, front_iter: &mut Option>, containers: &mut It, back_iter: &mut Option>, ) where It: Iterator, It: AsRef<[Container]>, It::Item: IntoIterator>, { let (key, index) = util::split(n); if let Some(iter) = front_iter { match key.cmp(&iter.key) { core::cmp::Ordering::Less => return, core::cmp::Ordering::Equal => { iter.advance_to(index); return; } core::cmp::Ordering::Greater => { *front_iter = None; } } } let containers_slice = containers.as_ref(); let containers_len = containers_slice.len(); let to_skip = match containers_slice.binary_search_by_key(&key, |c| c.key) { Ok(n) => { let container = containers.nth(n).expect("binary search returned a valid index"); let mut container_iter = container.into_iter(); container_iter.advance_to(index); *front_iter = Some(container_iter); return; } Err(n) => n, }; if let Some(n) = to_skip.checked_sub(1) { containers.nth(n); } if to_skip != containers_len { // There are still containers with keys greater than the key we are looking for, // the key we're looking _can't_ be in the back iterator. return; } if let Some(iter) = back_iter { match key.cmp(&iter.key) { core::cmp::Ordering::Less => {} core::cmp::Ordering::Equal => { iter.advance_to(index); } core::cmp::Ordering::Greater => { *back_iter = None; } } } } fn advance_back_to_impl<'a, It>( n: u32, front_iter: &mut Option>, containers: &mut It, back_iter: &mut Option>, ) where It: DoubleEndedIterator, It: AsRef<[Container]>, It::Item: IntoIterator>, { let (key, index) = util::split(n); if let Some(iter) = back_iter { match key.cmp(&iter.key) { core::cmp::Ordering::Greater => return, core::cmp::Ordering::Equal => { iter.advance_back_to(index); return; } core::cmp::Ordering::Less => { *back_iter = None; } } } let containers_slice = containers.as_ref(); let containers_len = containers_slice.len(); let to_skip = match containers_slice.binary_search_by_key(&key, |c| c.key) { Ok(n) => { // n must be less than containers_len, so this can never underflow let n = containers_len - n - 1; let container = containers.nth_back(n).expect("binary search returned a valid index"); let mut container_iter = container.into_iter(); container_iter.advance_back_to(index); *back_iter = Some(container_iter); return; } Err(n) => containers_len - n, }; if let Some(n) = to_skip.checked_sub(1) { containers.nth_back(n); } if to_skip != containers_len { // There are still containers with keys less than the key we are looking for, // the key we're looking _can't_ be in the front iterator. return; } if let Some(iter) = front_iter { match key.cmp(&iter.key) { core::cmp::Ordering::Greater => {} core::cmp::Ordering::Equal => { iter.advance_back_to(index); } core::cmp::Ordering::Less => { *front_iter = None; } } } } impl Iter<'_> { fn new(containers: &[Container]) -> Iter { Iter { front: None, containers: containers.iter(), back: None } } fn empty() -> Self { Self::new(&[]) } /// Advance the iterator to the first position where the item has a value >= `n` /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// use core::iter::FromIterator; /// /// let bitmap = (1..3).collect::(); /// let mut iter = bitmap.iter(); /// iter.advance_to(2); /// /// assert_eq!(iter.next(), Some(2)); /// assert_eq!(iter.next(), None); /// ``` pub fn advance_to(&mut self, n: u32) { advance_to_impl(n, &mut self.front, &mut self.containers, &mut self.back); } /// Advance the back of the iterator to the first position where the item has a value <= `n` /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// use core::iter::FromIterator; /// /// let bitmap = (1..3).collect::(); /// let mut iter = bitmap.iter(); /// iter.advance_back_to(1); /// /// assert_eq!(iter.next_back(), Some(1)); /// assert_eq!(iter.next_back(), None); /// ``` pub fn advance_back_to(&mut self, n: u32) { advance_back_to_impl(n, &mut self.front, &mut self.containers, &mut self.back); } } impl IntoIter { fn new(containers: Vec) -> IntoIter { IntoIter { front: None, containers: containers.into_iter(), back: None } } fn empty() -> Self { Self::new(Vec::new()) } /// Advance the iterator to the first position where the item has a value >= `n` /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// use core::iter::FromIterator; /// /// let bitmap = (1..3).collect::(); /// let mut iter = bitmap.iter(); /// iter.advance_to(2); /// /// assert_eq!(iter.next(), Some(2)); /// assert_eq!(iter.next(), None); /// ``` pub fn advance_to(&mut self, n: u32) { advance_to_impl(n, &mut self.front, &mut self.containers, &mut self.back); } /// Advance the back of the iterator to the first position where the item has a value <= `n` /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// use core::iter::FromIterator; /// /// let bitmap = (1..3).collect::(); /// let mut iter = bitmap.into_iter(); /// iter.advance_back_to(1); /// /// assert_eq!(iter.next_back(), Some(1)); /// assert_eq!(iter.next_back(), None); /// ``` pub fn advance_back_to(&mut self, n: u32) { advance_back_to_impl(n, &mut self.front, &mut self.containers, &mut self.back); } } fn size_hint_impl( front: &Option>, containers: &impl AsRef<[Container]>, back: &Option>, ) -> (usize, Option) { let first_size = front.as_ref().map_or(0, |it| it.len()); let last_size = back.as_ref().map_or(0, |it| it.len()); let mut size = first_size + last_size; for container in containers.as_ref() { match size.checked_add(container.len() as usize) { Some(new_size) => size = new_size, None => return (usize::MAX, None), } } (size, Some(size)) } impl Iterator for Iter<'_> { type Item = u32; fn next(&mut self) -> Option { loop { if let Some(x) = and_then_or_clear(&mut self.front, Iterator::next) { return Some(x); } self.front = match self.containers.next() { Some(inner) => Some(inner.into_iter()), None => return and_then_or_clear(&mut self.back, Iterator::next), } } } fn size_hint(&self) -> (usize, Option) { size_hint_impl(&self.front, &self.containers, &self.back) } #[inline] fn fold(mut self, mut init: B, mut f: F) -> B where Self: Sized, F: FnMut(B, Self::Item) -> B, { if let Some(iter) = &mut self.front { init = iter.fold(init, &mut f); } init = self.containers.fold(init, |acc, container| { let iter = <&Container>::into_iter(container); iter.fold(acc, &mut f) }); if let Some(iter) = &mut self.back { init = iter.fold(init, &mut f); }; init } fn count(self) -> usize where Self: Sized, { let mut count = self.front.map_or(0, Iterator::count); count += self.containers.map(|container| container.len() as usize).sum::(); count += self.back.map_or(0, Iterator::count); count } fn nth(&mut self, n: usize) -> Option { let mut n = n; let nth_advance = |it: &mut container::Iter| { let len = it.len(); if n < len { it.nth(n) } else { n -= len; None } }; if let Some(x) = and_then_or_clear(&mut self.front, nth_advance) { return Some(x); } for container in self.containers.by_ref() { let len = container.len() as usize; if n < len { let mut front_iter = container.into_iter(); let result = front_iter.nth(n); self.front = Some(front_iter); return result; } n -= len; } and_then_or_clear(&mut self.back, |it| it.nth(n)) } } impl DoubleEndedIterator for Iter<'_> { fn next_back(&mut self) -> Option { loop { if let Some(x) = and_then_or_clear(&mut self.back, DoubleEndedIterator::next_back) { return Some(x); } self.back = match self.containers.next_back() { Some(inner) => Some(inner.into_iter()), None => return and_then_or_clear(&mut self.front, DoubleEndedIterator::next_back), } } } #[inline] fn rfold(mut self, mut init: Acc, mut fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, { if let Some(iter) = &mut self.back { init = iter.rfold(init, &mut fold); } init = self.containers.rfold(init, |acc, container| { let iter = container.into_iter(); iter.rfold(acc, &mut fold) }); if let Some(iter) = &mut self.front { init = iter.rfold(init, &mut fold); }; init } fn nth_back(&mut self, n: usize) -> Option { let mut n = n; let nth_advance = |it: &mut container::Iter| { let len = it.len(); if n < len { it.nth_back(n) } else { n -= len; None } }; if let Some(x) = and_then_or_clear(&mut self.back, nth_advance) { return Some(x); } for container in self.containers.by_ref().rev() { let len = container.len() as usize; if n < len { let mut front_iter = container.into_iter(); let result = front_iter.nth_back(n); self.back = Some(front_iter); return result; } n -= len; } and_then_or_clear(&mut self.front, |it| it.nth_back(n)) } } #[cfg(target_pointer_width = "64")] impl ExactSizeIterator for Iter<'_> {} impl FusedIterator for Iter<'_> {} impl Iterator for IntoIter { type Item = u32; fn next(&mut self) -> Option { loop { if let Some(x) = and_then_or_clear(&mut self.front, Iterator::next) { return Some(x); } match self.containers.next() { Some(inner) => self.front = Some(inner.into_iter()), None => return and_then_or_clear(&mut self.back, Iterator::next), } } } fn size_hint(&self) -> (usize, Option) { size_hint_impl(&self.front, &self.containers, &self.back) } #[inline] fn fold(mut self, mut init: B, mut f: F) -> B where Self: Sized, F: FnMut(B, Self::Item) -> B, { if let Some(iter) = &mut self.front { init = iter.fold(init, &mut f); } init = self.containers.fold(init, |acc, container| { let iter = ::into_iter(container); iter.fold(acc, &mut f) }); if let Some(iter) = &mut self.back { init = iter.fold(init, &mut f); }; init } fn count(self) -> usize where Self: Sized, { let mut count = self.front.map_or(0, Iterator::count); count += self.containers.map(|container| container.len() as usize).sum::(); count += self.back.map_or(0, Iterator::count); count } fn nth(&mut self, n: usize) -> Option { let mut n = n; let nth_advance = |it: &mut container::Iter| { let len = it.len(); if n < len { it.nth(n) } else { n -= len; None } }; if let Some(x) = and_then_or_clear(&mut self.front, nth_advance) { return Some(x); } for container in self.containers.by_ref() { let len = container.len() as usize; if n < len { let mut front_iter = container.into_iter(); let result = front_iter.nth(n); self.front = Some(front_iter); return result; } n -= len; } and_then_or_clear(&mut self.back, |it| it.nth(n)) } } impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option { loop { if let Some(x) = and_then_or_clear(&mut self.back, DoubleEndedIterator::next_back) { return Some(x); } match self.containers.next_back() { Some(inner) => self.back = Some(inner.into_iter()), None => return and_then_or_clear(&mut self.front, DoubleEndedIterator::next_back), } } } #[inline] fn rfold(mut self, mut init: Acc, mut fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, { if let Some(iter) = &mut self.back { init = iter.rfold(init, &mut fold); } init = self.containers.rfold(init, |acc, container| { let iter = container.into_iter(); iter.rfold(acc, &mut fold) }); if let Some(iter) = &mut self.front { init = iter.rfold(init, &mut fold); }; init } fn nth_back(&mut self, n: usize) -> Option { let mut n = n; let nth_advance = |it: &mut container::Iter| { let len = it.len(); if n < len { it.nth_back(n) } else { n -= len; None } }; if let Some(x) = and_then_or_clear(&mut self.back, nth_advance) { return Some(x); } for container in self.containers.by_ref().rev() { let len = container.len() as usize; if n < len { let mut front_iter = container.into_iter(); let result = front_iter.nth_back(n); self.back = Some(front_iter); return result; } n -= len; } and_then_or_clear(&mut self.front, |it| it.nth_back(n)) } } #[cfg(target_pointer_width = "64")] impl ExactSizeIterator for IntoIter {} impl FusedIterator for IntoIter {} impl RoaringBitmap { /// Iterator over each value stored in the RoaringBitmap, guarantees values are ordered by value. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// use core::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) } /// Iterator over values within a range stored in the RoaringBitmap. /// /// # Examples /// /// ```rust /// use core::ops::Bound; /// use roaring::RoaringBitmap; /// /// let bitmap = RoaringBitmap::from([0, 1, 2, 3, 4, 5, 10, 11, 12, 20, 21, u32::MAX]); /// let mut iter = bitmap.range(10..20); /// /// assert_eq!(iter.next(), Some(10)); /// assert_eq!(iter.next(), Some(11)); /// assert_eq!(iter.next(), Some(12)); /// assert_eq!(iter.next(), None); /// /// let mut iter = bitmap.range(100..); /// assert_eq!(iter.next(), Some(u32::MAX)); /// assert_eq!(iter.next(), None); /// /// let mut iter = bitmap.range((Bound::Excluded(0), Bound::Included(10))); /// assert_eq!(iter.next(), Some(1)); /// assert_eq!(iter.next(), Some(2)); /// assert_eq!(iter.next(), Some(3)); /// assert_eq!(iter.next(), Some(4)); /// assert_eq!(iter.next(), Some(5)); /// assert_eq!(iter.next(), Some(10)); /// assert_eq!(iter.next(), None); /// ``` pub fn range(&self, range: R) -> Iter<'_> where R: RangeBounds, { let range = match util::convert_range_to_inclusive(range) { Ok(range) => range, Err(util::ConvertRangeError::Empty) => return Iter::empty(), Err(util::ConvertRangeError::StartGreaterThanEnd) => { panic!("range start is greater than range end") } Err(util::ConvertRangeError::StartAndEndEqualExcluded) => { panic!("range start and end are equal and excluded") } }; let (start, end) = (*range.start(), *range.end()); let mut iter = self.iter(); if start != 0 { iter.advance_to(start); } if end != u32::MAX { iter.advance_back_to(end); } iter } /// Iterator over values within a range stored in the RoaringBitmap. /// /// # Examples /// /// ```rust /// use core::ops::Bound; /// use roaring::RoaringBitmap; /// /// fn bitmap() -> RoaringBitmap { /// RoaringBitmap::from([0, 1, 2, 3, 4, 5, 10, 11, 12, 20, 21, u32::MAX]) /// } /// /// let mut iter = bitmap().into_range(10..20); /// /// assert_eq!(iter.next(), Some(10)); /// assert_eq!(iter.next(), Some(11)); /// assert_eq!(iter.next(), Some(12)); /// assert_eq!(iter.next(), None); /// /// let mut iter = bitmap().into_range(100..); /// assert_eq!(iter.next(), Some(u32::MAX)); /// assert_eq!(iter.next(), None); /// /// let mut iter = bitmap().into_range((Bound::Excluded(0), Bound::Included(10))); /// assert_eq!(iter.next(), Some(1)); /// assert_eq!(iter.next(), Some(2)); /// assert_eq!(iter.next(), Some(3)); /// assert_eq!(iter.next(), Some(4)); /// assert_eq!(iter.next(), Some(5)); /// assert_eq!(iter.next(), Some(10)); /// assert_eq!(iter.next(), None); /// ``` pub fn into_range(self, range: R) -> IntoIter where R: RangeBounds, { let range = match util::convert_range_to_inclusive(range) { Ok(range) => range, Err(util::ConvertRangeError::Empty) => return IntoIter::empty(), Err(util::ConvertRangeError::StartGreaterThanEnd) => { panic!("range start is greater than range end") } Err(util::ConvertRangeError::StartAndEndEqualExcluded) => { panic!("range start and end are equal and excluded") } }; let (start, end) = (*range.start(), *range.end()); let mut iter = self.into_iter(); if start != 0 { iter.advance_to(start); } if end != u32::MAX { iter.advance_back_to(end); } iter } } 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 { /// Inserts multiple values and returns the count of new additions. /// This is expected to be faster than calling [`RoaringBitmap::insert`] on each value. /// /// The provided integers values don't have to be in sorted order, but it may be preferable /// to sort them from a performance point of view. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// rb.extend([1, 2, 3, 4, 1500, 1508, 1507, 1509]); /// assert!(rb.contains(2)); /// assert!(rb.contains(1508)); /// assert!(!rb.contains(5)); /// ``` #[inline] fn extend>(&mut self, values: I) { let mut values = values.into_iter(); let value = match values.next() { Some(value) => value, None => return, }; let (mut currenthb, lowbit) = util::split(value); let mut current_container_index = self.find_container_by_key(currenthb); let mut current_cont = &mut self.containers[current_container_index]; current_cont.insert(lowbit); for val in values { let (newhb, lowbit) = util::split(val); if currenthb == newhb { // easy case, this could be quite frequent current_cont.insert(lowbit); } else { currenthb = newhb; current_container_index = self.find_container_by_key(currenthb); current_cont = &mut self.containers[current_container_index]; current_cont.insert(lowbit); } } } } impl<'a> Extend<&'a u32> for RoaringBitmap { /// Inserts multiple values and returns the count of new additions. /// This is expected to be faster than calling [`RoaringBitmap::insert`] on each value. /// /// The provided integers values don't have to be in sorted order, but it may be preferable /// to sort them from a performance point of view. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// /// let mut rb = RoaringBitmap::new(); /// rb.extend([1, 2, 3, 4, 1500, 1508, 1507, 1509]); /// assert!(rb.contains(2)); /// assert!(rb.contains(1508)); /// assert!(!rb.contains(5)); /// ``` #[inline] fn extend>(&mut self, values: I) { self.extend(values.into_iter().copied()); } } 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.12/src/bitmap/mod.rs000064400000000000000000000017661046102023000146300ustar 00000000000000mod arbitrary; mod container; mod fmt; mod multiops; mod proptests; mod statistics; 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 = "std")] mod ops_with_serialized; #[cfg(feature = "serde")] mod serde; #[cfg(feature = "std")] mod serialization; use self::cmp::Pairs; pub use self::iter::IntoIter; pub use self::iter::Iter; pub use self::statistics::Statistics; #[cfg(not(feature = "std"))] use alloc::vec::Vec; /// 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.12/src/bitmap/multiops.rs000064400000000000000000000325201046102023000157150ustar 00000000000000use core::{ cmp::Reverse, convert::Infallible, mem, ops::{BitOrAssign, BitXorAssign}, }; use alloc::borrow::Cow; use crate::{MultiOps, RoaringBitmap}; use super::{container::Container, store::Store}; #[cfg(not(feature = "std"))] use alloc::vec::Vec; /// 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); } containers.retain_mut(|container| { if !container.is_empty() { 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); } containers.retain_mut(|container| { if !container.is_empty() { 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.is_empty()) .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.is_empty()) .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.12/src/bitmap/ops.rs000064400000000000000000000467571046102023000146630ustar 00000000000000use core::mem; use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; use crate::bitmap::container::Container; use crate::bitmap::Pairs; use crate::RoaringBitmap; #[cfg(not(feature = "std"))] use alloc::vec::Vec; 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.is_empty() { 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); } self.containers.retain_mut(|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.is_empty() } Err(_) => false, } }) } } impl BitAndAssign<&RoaringBitmap> for RoaringBitmap { /// An `intersection` between two sets. fn bitand_assign(&mut self, rhs: &RoaringBitmap) { self.containers.retain_mut(|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.is_empty() } 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.is_empty() { 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) { self.containers.retain_mut(|cont| { match rhs.containers.binary_search_by_key(&cont.key, |c| c.key) { Ok(loc) => { SubAssign::sub_assign(cont, &rhs.containers[loc]); !cont.is_empty() } 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.is_empty() { 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.is_empty() { 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.is_empty() { 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 core::convert::Infallible; use proptest::prelude::*; // 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.12/src/bitmap/ops_with_serialized.rs000064400000000000000000000275241046102023000201200ustar 00000000000000use bytemuck::cast_slice_mut; use byteorder::{LittleEndian, ReadBytesExt}; use core::convert::Infallible; use std::error::Error; use std::io::{self, SeekFrom}; use std::mem; use std::ops::RangeInclusive; use crate::bitmap::container::Container; use crate::bitmap::serialization::{ NO_OFFSET_THRESHOLD, SERIAL_COOKIE, SERIAL_COOKIE_NO_RUNCONTAINER, }; use crate::RoaringBitmap; use super::container::ARRAY_LIMIT; use super::store::{ArrayStore, BitmapStore, Store, BITMAP_LENGTH}; impl RoaringBitmap { /// Computes the intersection between a materialized [`RoaringBitmap`] and a serialized one. /// /// This is faster and more space efficient when you only need the intersection result. /// It reduces the number of deserialized internal container and therefore /// the number of allocations and copies of bytes. /// /// # Examples /// /// ```rust /// use roaring::RoaringBitmap; /// use std::io::Cursor; /// /// let rb1: RoaringBitmap = (1..4).collect(); /// let rb2: RoaringBitmap = (3..5).collect(); /// /// // Let's say the rb2 bitmap is serialized /// let mut bytes = Vec::new(); /// rb2.serialize_into(&mut bytes).unwrap(); /// let rb2_bytes = Cursor::new(bytes); /// /// assert_eq!( /// rb1.intersection_with_serialized_unchecked(rb2_bytes).unwrap(), /// rb1 & rb2, /// ); /// ``` pub fn intersection_with_serialized_unchecked(&self, other: R) -> io::Result where R: io::Read + io::Seek, { RoaringBitmap::intersection_with_serialized_impl::( self, other, |values| Ok(ArrayStore::from_vec_unchecked(values)), |len, values| Ok(BitmapStore::from_unchecked(len, values)), ) } fn intersection_with_serialized_impl( &self, mut reader: R, a: A, b: B, ) -> io::Result where R: io::Read + io::Seek, 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 descriptions = vec![[0; 2]; size]; reader.read_exact(cast_slice_mut(&mut descriptions))?; descriptions.iter_mut().for_each(|[ref mut key, ref mut len]| { *key = u16::from_le(*key); *len = u16::from_le(*len); }); if has_offsets { let mut offsets = vec![0; size]; reader.read_exact(cast_slice_mut(&mut offsets))?; offsets.iter_mut().for_each(|offset| *offset = u32::from_le(*offset)); return self.intersection_with_serialized_impl_with_offsets( reader, a, b, &descriptions, &offsets, run_container_bitmap.as_deref(), ); } // Read each container and skip the useless ones let mut containers = Vec::new(); for (i, &[key, len_minus_one]) in descriptions.iter().enumerate() { let container = match self.containers.binary_search_by_key(&key, |c| c.key) { Ok(index) => self.containers.get(index), Err(_) => None, }; let cardinality = u64::from(len_minus_one) + 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::()?; match container { Some(_) => { 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().try_for_each( |[s, len]| -> Result<(), io::ErrorKind> { let end = s.checked_add(len).ok_or(io::ErrorKind::InvalidData)?; store.insert_range(RangeInclusive::new(s, end)); Ok(()) }, )?; store } None => { let runs_size = mem::size_of::() * 2 * runs as usize; reader.seek(SeekFrom::Current(runs_size as i64))?; continue; } } } else if cardinality <= ARRAY_LIMIT { match container { Some(_) => { 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) } None => { let array_size = mem::size_of::() * cardinality as usize; reader.seek(SeekFrom::Current(array_size as i64))?; continue; } } } else { match container { Some(_) => { 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) } None => { let bitmap_size = mem::size_of::() * BITMAP_LENGTH; reader.seek(SeekFrom::Current(bitmap_size as i64))?; continue; } } }; if let Some(container) = container { let mut other_container = Container { key, store }; other_container &= container; if !other_container.is_empty() { containers.push(other_container); } } } Ok(RoaringBitmap { containers }) } fn intersection_with_serialized_impl_with_offsets( &self, mut reader: R, a: A, b: B, descriptions: &[[u16; 2]], offsets: &[u32], run_container_bitmap: Option<&[u8]>, ) -> io::Result where R: io::Read + io::Seek, A: Fn(Vec) -> Result, AErr: Error + Send + Sync + 'static, B: Fn(u64, Box<[u64; 1024]>) -> Result, BErr: Error + Send + Sync + 'static, { let mut containers = Vec::new(); for container in &self.containers { let i = match descriptions.binary_search_by_key(&container.key, |[k, _]| *k) { Ok(index) => index, Err(_) => continue, }; // Seek to the bytes of the container we want. reader.seek(SeekFrom::Start(offsets[i] as u64))?; let [key, len_minus_one] = descriptions[i]; let cardinality = u64::from(len_minus_one) + 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::().unwrap(); let mut intervals = vec![[0, 0]; runs as usize]; reader.read_exact(cast_slice_mut(&mut intervals)).unwrap(); 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().try_for_each(|[s, len]| -> Result<(), io::ErrorKind> { let end = s.checked_add(len).ok_or(io::ErrorKind::InvalidData)?; store.insert_range(RangeInclusive::new(s, end)); Ok(()) })?; store } else if cardinality <= ARRAY_LIMIT { let mut values = vec![0; cardinality as usize]; reader.read_exact(cast_slice_mut(&mut values)).unwrap(); 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[..])).unwrap(); 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) }; let mut other_container = Container { key, store }; other_container &= container; if !other_container.is_empty() { containers.push(other_container); } } Ok(RoaringBitmap { containers }) } } #[cfg(test)] mod test { use crate::RoaringBitmap; use proptest::prelude::*; use std::io::Cursor; // fast count tests proptest! { #[test] fn intersection_with_serialized_eq_materialized_intersection( a in RoaringBitmap::arbitrary(), b in RoaringBitmap::arbitrary() ) { let mut serialized_bytes_b = Vec::new(); b.serialize_into(&mut serialized_bytes_b).unwrap(); let serialized_bytes_b = &serialized_bytes_b[..]; prop_assert_eq!(a.intersection_with_serialized_unchecked(Cursor::new(serialized_bytes_b)).unwrap(), a & b); } } } roaring-0.10.12/src/bitmap/proptests.rs000064400000000000000000000655041046102023000161140ustar 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.12/src/bitmap/serde.rs000064400000000000000000000045621046102023000151500ustar 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 core::fmt::Formatter) -> core::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_postcard( bitmap in RoaringBitmap::arbitrary(), ) { let buffer = postcard::to_allocvec(&bitmap).unwrap(); prop_assert_eq!(bitmap, postcard::from_bytes(&buffer).unwrap()); } } } roaring-0.10.12/src/bitmap/serialization.rs000064400000000000000000000323071046102023000167210ustar 00000000000000use crate::bitmap::container::{Container, ARRAY_LIMIT}; use crate::bitmap::store::{ArrayStore, BitmapStore, Store, BITMAP_LENGTH}; use crate::RoaringBitmap; use bytemuck::cast_slice_mut; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use core::convert::Infallible; use core::ops::RangeInclusive; use std::error::Error; use std::io; pub(crate) const SERIAL_COOKIE_NO_RUNCONTAINER: u32 = 12346; pub(crate) const SERIAL_COOKIE: u16 = 12347; pub(crate) const NO_OFFSET_THRESHOLD: usize = 4; // Sizes of header structures pub(crate) const DESCRIPTION_BYTES: usize = 4; pub(crate) 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().try_for_each(|[s, len]| -> Result<(), io::ErrorKind> { let end = s.checked_add(len).ok_or(io::ErrorKind::InvalidData)?; store.insert_range(RangeInclusive::new(s, end)); Ok(()) })?; 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::{bitmap::store::BITMAP_LENGTH, 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()); } } #[test] fn test_from_lsb0_bytes() { const CONTAINER_OFFSET: u32 = u64::BITS * BITMAP_LENGTH as u32; const CONTAINER_OFFSET_IN_BYTES: u32 = CONTAINER_OFFSET / 8; let mut bytes = vec![0xff; CONTAINER_OFFSET_IN_BYTES as usize]; bytes.extend([0x00; CONTAINER_OFFSET_IN_BYTES as usize]); bytes.extend([0b00000001, 0b00000010, 0b00000011, 0b00000100]); let offset = 32; let rb = RoaringBitmap::from_lsb0_bytes(offset, &bytes); for i in 0..offset { assert!(!rb.contains(i), "{i} should not be in the bitmap"); } for i in offset..offset + CONTAINER_OFFSET { assert!(rb.contains(i), "{i} should be in the bitmap"); } for i in offset + CONTAINER_OFFSET..offset + CONTAINER_OFFSET * 2 { assert!(!rb.contains(i), "{i} should not be in the bitmap"); } for bit in [0, 9, 16, 17, 26] { let i = bit + offset + CONTAINER_OFFSET * 2; assert!(rb.contains(i), "{i} should be in the bitmap"); } assert_eq!(rb.len(), CONTAINER_OFFSET as u64 + 5); // Ensure the empty container is not created let mut bytes = vec![0x00u8; CONTAINER_OFFSET_IN_BYTES as usize]; bytes.extend([0xff]); let rb = RoaringBitmap::from_lsb0_bytes(0, &bytes); assert_eq!(rb.min(), Some(CONTAINER_OFFSET)); let rb = RoaringBitmap::from_lsb0_bytes(8, &bytes); assert_eq!(rb.min(), Some(CONTAINER_OFFSET + 8)); // Ensure we can set the last byte in an array container let bytes = [0x80]; let rb = RoaringBitmap::from_lsb0_bytes(0xFFFFFFF8, &bytes); assert_eq!(rb.len(), 1); assert!(rb.contains(u32::MAX)); // Ensure we can set the last byte in a bitmap container let bytes = vec![0xFF; 0x1_0000 / 8]; let rb = RoaringBitmap::from_lsb0_bytes(0xFFFF0000, &bytes); assert_eq!(rb.len(), 0x1_0000); assert!(rb.contains(u32::MAX)); } #[test] fn test_from_lsb0_bytes_not_multiple_of_8() { const CONTAINER_OFFSET: u32 = u64::BITS * BITMAP_LENGTH as u32; const CONTAINER_OFFSET_IN_BYTES: u32 = CONTAINER_OFFSET / 8; let mut bytes = vec![0b0101_1001]; bytes.extend([0x00; CONTAINER_OFFSET_IN_BYTES as usize]); bytes.extend([0b00000001, 0b00000010, 0b00000011, 0b00000100]); let mut indices = vec![0, 3, 4, 6]; indices.extend([0, 9, 16, 17, 26].map(|i| 8 + CONTAINER_OFFSET + i)); for offset in 0..8 { let rb = RoaringBitmap::from_lsb0_bytes(offset, &bytes); for i in indices.iter().map(|&i| i + offset) { assert!(rb.contains(i), "{i} should be in the bitmap"); } } } #[test] #[should_panic(expected = "<= 2^32")] fn test_from_lsb0_bytes_overflow() { let bytes = [0x01, 0x01]; RoaringBitmap::from_lsb0_bytes(u32::MAX - 7, &bytes); } #[test] fn test_deserialize_overflow_s_plus_len() { let data = vec![59, 48, 0, 0, 255, 130, 254, 59, 48, 2, 0, 41, 255, 255, 166, 197, 4, 0, 2]; let res = RoaringBitmap::deserialize_from(data.as_slice()); assert!(res.is_err()); } } roaring-0.10.12/src/bitmap/statistics.rs000064400000000000000000000075731046102023000162450ustar 00000000000000use core::mem; use crate::bitmap::container::Container; use crate::RoaringBitmap; use super::store::Store; /// Detailed statistics on the composition of a bitmap. #[derive(Clone, Copy, PartialEq, Debug)] #[non_exhaustive] pub struct Statistics { /// Number of containers in the bitmap pub n_containers: u32, /// Number of array containers in the bitmap pub n_array_containers: u32, /// Number of run containers in the bitmap pub n_run_containers: u32, /// Number of bitset containers in the bitmap pub n_bitset_containers: u32, /// Number of values stored in array containers pub n_values_array_containers: u32, /// Number of values stored in run containers pub n_values_run_containers: u32, /// Number of values stored in bitset containers pub n_values_bitset_containers: u64, /// Number of bytes used by array containers pub n_bytes_array_containers: u64, /// Number of bytes used by run containers pub n_bytes_run_containers: u64, /// Number of bytes used by bitset containers pub n_bytes_bitset_containers: u64, /// Maximum value stored in the bitmap pub max_value: Option, /// Minimum value stored in the bitmap pub min_value: Option, /// Number of values stored in the bitmap pub cardinality: u64, } impl RoaringBitmap { /// Returns statistics about the composition of a roaring bitmap. /// /// ``` /// use roaring::RoaringBitmap; /// /// let mut bitmap: RoaringBitmap = (1..100).collect(); /// let statistics = bitmap.statistics(); /// /// assert_eq!(statistics.n_containers, 1); /// assert_eq!(statistics.n_array_containers, 1); /// assert_eq!(statistics.n_run_containers, 0); /// assert_eq!(statistics.n_bitset_containers, 0); /// assert_eq!(statistics.n_values_array_containers, 99); /// assert_eq!(statistics.n_values_run_containers, 0); /// assert_eq!(statistics.n_values_bitset_containers, 0); /// assert_eq!(statistics.n_bytes_array_containers, 512); /// assert_eq!(statistics.n_bytes_run_containers, 0); /// assert_eq!(statistics.n_bytes_bitset_containers, 0); /// assert_eq!(statistics.max_value, Some(99)); /// assert_eq!(statistics.min_value, Some(1)); /// assert_eq!(statistics.cardinality, 99); /// ``` pub fn statistics(&self) -> Statistics { let mut n_containers = 0; let mut n_array_containers = 0; let mut n_bitset_containers = 0; let mut n_values_array_containers = 0; let mut n_values_bitset_containers = 0; let mut n_bytes_array_containers = 0; let mut n_bytes_bitset_containers = 0; let mut cardinality = 0; for Container { key: _, store } in &self.containers { match store { Store::Array(array) => { cardinality += array.len(); n_values_array_containers += array.len() as u32; n_bytes_array_containers += (array.capacity() * mem::size_of::()) as u64; n_array_containers += 1; } Store::Bitmap(bitmap) => { cardinality += bitmap.len(); n_values_bitset_containers += bitmap.len(); n_bytes_bitset_containers += bitmap.capacity() as u64; n_bitset_containers += 1; } } n_containers += 1; } Statistics { n_containers, n_array_containers, n_run_containers: 0, n_bitset_containers, n_values_array_containers, n_values_run_containers: 0, n_values_bitset_containers, n_bytes_array_containers, n_bytes_run_containers: 0, n_bytes_bitset_containers, max_value: self.max(), min_value: self.min(), cardinality, } } } roaring-0.10.12/src/bitmap/store/array_store/mod.rs000064400000000000000000000462651046102023000203210ustar 00000000000000mod scalar; mod vector; mod visitor; use crate::bitmap::store::array_store::visitor::{CardinalityCounter, VecWriter}; use core::cmp::Ordering; use core::cmp::Ordering::*; use core::fmt::{Display, Formatter}; use core::mem::size_of; use core::ops::{BitAnd, BitAndAssign, BitOr, BitXor, RangeInclusive, Sub, SubAssign}; #[cfg(not(feature = "std"))] use alloc::vec::Vec; #[cfg(not(feature = "std"))] use alloc::boxed::Box; use super::bitmap_store::{bit, key, BitmapStore, BITMAP_LENGTH}; #[derive(Clone, Eq, PartialEq)] pub(crate) struct ArrayStore { vec: Vec, } impl ArrayStore { pub fn new() -> ArrayStore { ArrayStore { vec: vec![] } } #[cfg(feature = "std")] pub fn with_capacity(capacity: usize) -> ArrayStore { ArrayStore { vec: Vec::with_capacity(capacity) } } /// The number of total values that can be inserted without needing to reallocate. pub fn capacity(&self) -> usize { self.vec.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 from_lsb0_bytes(bytes: &[u8], byte_offset: usize, bits_set: u64) -> Self { type Word = u64; let mut vec = Vec::with_capacity(bits_set as usize); let chunks = bytes.chunks_exact(size_of::()); let remainder = chunks.remainder(); for (index, chunk) in chunks.enumerate() { let bit_index = (byte_offset + index * size_of::()) * 8; let mut word = Word::from_le_bytes(chunk.try_into().unwrap()); while word != 0 { vec.push((word.trailing_zeros() + bit_index as u32) as u16); word &= word - 1; } } for (index, mut byte) in remainder.iter().copied().enumerate() { let bit_index = (byte_offset + (bytes.len() - remainder.len()) + index) * 8; while byte != 0 { vec.push((byte.trailing_zeros() + bit_index as u32) as u16); byte &= byte - 1; } } Self::from_vec_unchecked(vec) } #[inline] 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 is_empty(&self) -> bool { self.vec.is_empty() } pub fn min(&self) -> Option { self.vec.first().copied() } #[inline] 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) -> core::slice::Iter { self.vec.iter() } pub fn into_iter(self) -> alloc::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<'_>) -> core::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) } } } } #[cfg(feature = "std")] 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.12/src/bitmap/store/array_store/scalar.rs000064400000000000000000000055251046102023000210010ustar 00000000000000//! Scalar arithmetic binary set operations on `ArrayStore`'s inner types use crate::bitmap::store::array_store::visitor::BinaryOperationVisitor; use core::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.12/src/bitmap/store/array_store/vector.rs000064400000000000000000000774461046102023000210510ustar 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::cmp::{SimdPartialEq, SimdPartialOrd}; use core::simd::{ mask16x8, simd_swizzle, u16x8, LaneCount, Mask, Simd, SimdElement, SupportedLaneCount, }; // 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::concat_swizzle(new, old); let mask = 255 - tmp.simd_eq(new).to_bitmask() as u8; 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].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::LEN) * u16x8::LEN; let st_b = (rhs.len() / u16x8::LEN) * u16x8::LEN; 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() as u8; visitor.visit_vector(v_a, mask); let a_max: u16 = lhs[i + u16x8::LEN - 1]; let b_max: u16 = rhs[j + u16x8::LEN - 1]; if a_max <= b_max { i += u16x8::LEN; if i == st_a { break; } v_a = load(&lhs[i..]); } if b_max <= a_max { j += u16x8::LEN; 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::concat_swizzle(new, old); let tmp2: u16x8 = Shr1::concat_swizzle(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() as u8; 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].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::LEN) * u16x8::LEN; let st_b = (rhs.len() / u16x8::LEN) * u16x8::LEN; 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() as u8; 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::LEN - 1]; let b_max: u16 = rhs[j + u16x8::LEN - 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::LEN; 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::LEN; 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() as u8; 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::LEN; } } // 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 { core::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 { core::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_elements_left::<1>()) | a.simd_eq(b.rotate_elements_left::<2>()) | a.simd_eq(b.rotate_elements_left::<3>()) | a.simd_eq(b.rotate_elements_left::<4>()) | a.simd_eq(b.rotate_elements_left::<5>()) | a.simd_eq(b.rotate_elements_left::<6>()) | a.simd_eq(b.rotate_elements_left::<7>()) } use crate::bitmap::store::array_store::visitor::BinaryOperationVisitor; use core::simd::Swizzle; /// 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 Swizzle<8> for Shr1 { const INDEX: [usize; 8] = [15, 0, 1, 2, 3, 4, 5, 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 Swizzle<8> for Shr2 { const INDEX: [usize; 8] = [14, 15, 0, 1, 2, 3, 4, 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_elements_left::<1>(); let mut min: Simd = lanes_min_u16(tmp, max); for _ in 0..6 { max = lanes_max_u16(tmp, max); tmp = min.rotate_elements_left::<1>(); min = lanes_min_u16(tmp, max); } max = lanes_max_u16(tmp, max); min = min.rotate_elements_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.12/src/bitmap/store/array_store/visitor.rs000064400000000000000000000057201046102023000212300ustar 00000000000000#[cfg(feature = "simd")] use crate::bitmap::store::array_store::vector::swizzle_to_front; #[cfg(not(feature = "std"))] use alloc::vec::Vec; /// 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. // Exactly 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.len() - 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.12/src/bitmap/store/bitmap_store.rs000064400000000000000000000565451046102023000177020ustar 00000000000000use core::borrow::Borrow; use core::cmp::Ordering; use core::fmt::{Display, Formatter}; use core::mem::size_of; use core::ops::{BitAndAssign, BitOrAssign, BitXorAssign, RangeInclusive, SubAssign}; use super::ArrayStore; #[cfg(not(feature = "std"))] use alloc::boxed::Box; #[cfg(not(feature = "std"))] use alloc::vec::Vec; 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 capacity(&self) -> usize { BITMAP_LENGTH * u64::BITS as usize } 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 }) } } pub fn from_lsb0_bytes_unchecked(bytes: &[u8], byte_offset: usize, bits_set: u64) -> Self { const BITMAP_BYTES: usize = BITMAP_LENGTH * size_of::(); assert!(byte_offset.checked_add(bytes.len()).map_or(false, |sum| sum <= BITMAP_BYTES)); // If we know we're writing the full bitmap, we can avoid the initial memset to 0 let mut bits = if bytes.len() == BITMAP_BYTES { debug_assert_eq!(byte_offset, 0); // Must be true from the above assert // Safety: We've checked that the length is correct, and we use an unaligned load in case // the bytes are not 8 byte aligned. // The optimizer can see through this, and avoid the double copy to copy directly into // the allocated box from bytes with memcpy let bytes_as_words = unsafe { bytes.as_ptr().cast::<[u64; BITMAP_LENGTH]>().read_unaligned() }; Box::new(bytes_as_words) } else { let mut bits = Box::new([0u64; BITMAP_LENGTH]); // Safety: It's safe to reinterpret u64s as u8s because u8 has less alignment requirements, // and has no padding/uninitialized data. let dst = unsafe { core::slice::from_raw_parts_mut(bits.as_mut_ptr().cast::(), BITMAP_BYTES) }; let dst = &mut dst[byte_offset..][..bytes.len()]; dst.copy_from_slice(bytes); bits }; if !cfg!(target_endian = "little") { // Convert all words we touched (even partially) to little-endian let start_word = byte_offset / size_of::(); let end_word = (byte_offset + bytes.len() + (size_of::() - 1)) / size_of::(); // The 0th byte is the least significant byte, so we've written the bytes in little-endian for word in &mut bits[start_word..end_word] { *word = u64::from_le(*word); } } Self::from_unchecked(bits_set, 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 } } } #[inline] 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(crate) 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 is_empty(&self) -> bool { self.len == 0 } 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) } #[inline] 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(crate) 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) } #[cfg(feature = "std")] 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<'_>) -> core::fmt::Result { match self.kind { ErrorKind::Cardinality { expected, actual } => { write!(f, "Expected cardinality was {expected} but was {actual}") } } } } #[cfg(feature = "std")] impl std::error::Error for Error {} #[derive(Clone)] pub struct BitmapIter> { key: u16, value: u64, key_back: u16, // If key_back <= key, current back value is actually in `value` value_back: u64, bits: B, } impl> BitmapIter { fn new(bits: B) -> BitmapIter { BitmapIter { key: 0, value: bits.borrow()[0], key_back: BITMAP_LENGTH as u16 - 1, value_back: bits.borrow()[BITMAP_LENGTH - 1], bits, } } /// Advance the iterator to the first value greater than or equal to `n`. pub(crate) fn advance_to(&mut self, index: u16) { let new_key = key(index) as u16; let value = match new_key.cmp(&self.key) { Ordering::Less => return, Ordering::Equal => self.value, Ordering::Greater => { let bits = self.bits.borrow(); let cmp = new_key.cmp(&self.key_back); // Match arms can be reordered, this ordering is perf sensitive if cmp == Ordering::Less { // new_key is > self.key, < self.key_back, so it must be in bounds unsafe { *bits.get_unchecked(new_key as usize) } } else if cmp == Ordering::Equal { self.value_back } else { self.value_back = 0; return; } } }; let bit = bit(index); let low_bits = (1 << bit) - 1; self.key = new_key; self.value = value & !low_bits; } /// Advance the back of iterator to the first value less than or equal to `n`. pub(crate) fn advance_back_to(&mut self, index: u16) { let new_key = key(index) as u16; let (value, dst) = match new_key.cmp(&self.key_back) { Ordering::Greater => return, Ordering::Equal => { let dst = if self.key_back <= self.key { &mut self.value } else { &mut self.value_back }; (*dst, dst) } Ordering::Less => { let bits = self.bits.borrow(); let cmp = new_key.cmp(&self.key); // Match arms can be reordered, this ordering is perf sensitive if cmp == Ordering::Greater { // new_key is > self.key, < self.key_back, so it must be in bounds let value = unsafe { *bits.get_unchecked(new_key as usize) }; (value, &mut self.value_back) } else if cmp == Ordering::Equal { (self.value, &mut self.value) } else { (0, &mut self.value) } } }; let bit = bit(index); let low_bits = u64::MAX >> (64 - bit - 1); self.key_back = new_key; *dst = value & low_bits; } } impl> Iterator for BitmapIter { type Item = u16; fn next(&mut self) -> Option { if self.value == 0 { 'get_val: { if self.key >= self.key_back { return None; } for key in self.key + 1..self.key_back { self.value = unsafe { *self.bits.borrow().get_unchecked(key as usize) }; if self.value != 0 { self.key = key; break 'get_val; } } self.key = self.key_back; self.value = self.value_back; if self.value == 0 { return None; } } } let index = self.value.trailing_zeros() as u16; self.value &= self.value - 1; Some(64 * self.key + index) } fn size_hint(&self) -> (usize, Option) { let mut len: u32 = self.value.count_ones(); if self.key < self.key_back { for v in &self.bits.borrow()[self.key as usize + 1..self.key_back as usize] { len += v.count_ones(); } len += self.value_back.count_ones(); } (len as usize, Some(len as usize)) } fn count(self) -> usize where Self: Sized, { self.len() } } 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 as usize) }; continue; } let index_from_left = value.leading_zeros() as u16; let index = 63 - index_from_left; *value &= !(1 << index); return Some(64 * self.key_back + index); } } } impl> ExactSizeIterator for BitmapIter {} #[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.12/src/bitmap/store/mod.rs000064400000000000000000000457221046102023000157640ustar 00000000000000mod array_store; mod bitmap_store; use alloc::vec; use core::mem; use core::ops::{ BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, RangeInclusive, Sub, SubAssign, }; use core::slice; pub use self::bitmap_store::BITMAP_LENGTH; use self::Store::{Array, Bitmap}; pub(crate) use self::array_store::ArrayStore; pub use self::bitmap_store::{BitmapIter, BitmapStore}; use crate::bitmap::container::ARRAY_LIMIT; #[cfg(not(feature = "std"))] use alloc::boxed::Box; #[derive(Clone)] pub(crate) enum Store { Array(ArrayStore), Bitmap(BitmapStore), } #[derive(Clone)] pub(crate) 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()) } #[cfg(feature = "std")] 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 from_lsb0_bytes(bytes: &[u8], byte_offset: usize) -> Option { assert!(byte_offset + bytes.len() <= BITMAP_LENGTH * mem::size_of::()); // It seems to be pretty considerably faster to count the bits // using u64s than for each byte let bits_set = { let mut bits_set = 0; let chunks = bytes.chunks_exact(mem::size_of::()); let remainder = chunks.remainder(); for chunk in chunks { let chunk = u64::from_ne_bytes(chunk.try_into().unwrap()); bits_set += u64::from(chunk.count_ones()); } for byte in remainder { bits_set += u64::from(byte.count_ones()); } bits_set }; if bits_set == 0 { return None; } Some(if bits_set < ARRAY_LIMIT { Array(ArrayStore::from_lsb0_bytes(bytes, byte_offset, bits_set)) } else { Bitmap(BitmapStore::from_lsb0_bytes_unchecked(bytes, byte_offset, bits_set)) }) } #[inline] 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 is_empty(&self) -> bool { match self { Array(vec) => vec.is_empty(), Bitmap(bits) => bits.is_empty(), } } pub fn min(&self) -> Option { match self { Array(vec) => vec.min(), Bitmap(bits) => bits.min(), } } #[inline] 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 Iter<'_> { /// Advance the iterator to the first value greater than or equal to `n`. pub(crate) fn advance_to(&mut self, n: u16) { match self { Iter::Array(inner) => { let skip = inner.as_slice().partition_point(|&i| i < n); if let Some(nth) = skip.checked_sub(1) { inner.nth(nth); } } Iter::Vec(inner) => { let skip = inner.as_slice().partition_point(|&i| i < n); if let Some(nth) = skip.checked_sub(1) { inner.nth(nth); } } Iter::BitmapBorrowed(inner) => inner.advance_to(n), Iter::BitmapOwned(inner) => inner.advance_to(n), } } pub(crate) fn advance_back_to(&mut self, n: u16) { match self { Iter::Array(inner) => { let slice = inner.as_slice(); let from_front = slice.partition_point(|&i| i <= n); let skip = slice.len() - from_front; if let Some(nth) = skip.checked_sub(1) { inner.nth_back(nth); } } Iter::Vec(inner) => { let slice = inner.as_slice(); let from_front = slice.partition_point(|&i| i <= n); let skip = slice.len() - from_front; if let Some(nth) = skip.checked_sub(1) { inner.nth_back(nth); } } Iter::BitmapBorrowed(inner) => inner.advance_back_to(n), Iter::BitmapOwned(inner) => inner.advance_back_to(n), } } } impl Iterator for Iter<'_> { 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(), } } fn size_hint(&self) -> (usize, Option) { match self { Iter::Array(inner) => inner.size_hint(), Iter::Vec(inner) => inner.size_hint(), Iter::BitmapBorrowed(inner) => inner.size_hint(), Iter::BitmapOwned(inner) => inner.size_hint(), } } fn count(self) -> usize where Self: Sized, { match self { Iter::Array(inner) => inner.count(), Iter::Vec(inner) => inner.count(), Iter::BitmapBorrowed(inner) => inner.count(), Iter::BitmapOwned(inner) => inner.count(), } } fn nth(&mut self, n: usize) -> Option { match self { Iter::Array(inner) => inner.nth(n).copied(), Iter::Vec(inner) => inner.nth(n), Iter::BitmapBorrowed(inner) => inner.nth(n), Iter::BitmapOwned(inner) => inner.nth(n), } } } 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(), } } } impl ExactSizeIterator for Iter<'_> {} roaring-0.10.12/src/bitmap/util.rs000064400000000000000000000111261046102023000150150ustar 00000000000000use core::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) } #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum ConvertRangeError { Empty, StartGreaterThanEnd, StartAndEndEqualExcluded, } /// Convert a `RangeBounds` object to `RangeInclusive`, pub fn convert_range_to_inclusive(range: R) -> Result, ConvertRangeError> where R: RangeBounds, { let start_bound = range.start_bound().cloned(); let end_bound = range.end_bound().cloned(); match (start_bound, end_bound) { (Bound::Excluded(s), Bound::Excluded(e)) if s == e => { Err(ConvertRangeError::StartAndEndEqualExcluded) } (Bound::Included(s) | Bound::Excluded(s), Bound::Included(e) | Bound::Excluded(e)) if s > e => { Err(ConvertRangeError::StartGreaterThanEnd) } _ => { let start = match start_bound { Bound::Included(s) => s, Bound::Excluded(s) => s.checked_add(1).ok_or(ConvertRangeError::Empty)?, Bound::Unbounded => 0, }; let end = match end_bound { Bound::Included(e) => e, Bound::Excluded(e) => e.checked_sub(1).ok_or(ConvertRangeError::Empty)?, Bound::Unbounded => u32::MAX, }; if start > end { // This handles e.g. `x..x`: we've ruled out `start > end` overall, so a value must // have been changed via exclusion. Err(ConvertRangeError::Empty) } else { Ok(start..=end) } } } } #[cfg(test)] mod test { use super::{convert_range_to_inclusive, join, split, ConvertRangeError}; use core::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!(Ok(1..=5), convert_range_to_inclusive(1..6)); assert_eq!(Ok(1..=u32::MAX), convert_range_to_inclusive(1..)); assert_eq!(Ok(0..=u32::MAX), convert_range_to_inclusive(..)); assert_eq!(Ok(16..=16), convert_range_to_inclusive(16..=16)); assert_eq!( Ok(11..=19), convert_range_to_inclusive((Bound::Excluded(10), Bound::Excluded(20))) ); assert_eq!(Err(ConvertRangeError::Empty), convert_range_to_inclusive(0..0)); assert_eq!(Err(ConvertRangeError::Empty), convert_range_to_inclusive(5..5)); assert_eq!(Err(ConvertRangeError::StartGreaterThanEnd), convert_range_to_inclusive(1..0)); assert_eq!(Err(ConvertRangeError::StartGreaterThanEnd), convert_range_to_inclusive(10..5)); assert_eq!( Err(ConvertRangeError::Empty), convert_range_to_inclusive((Bound::Excluded(u32::MAX), Bound::Included(u32::MAX))) ); assert_eq!( Err(ConvertRangeError::StartAndEndEqualExcluded), convert_range_to_inclusive((Bound::Excluded(u32::MAX), Bound::Excluded(u32::MAX))) ); assert_eq!( Err(ConvertRangeError::Empty), convert_range_to_inclusive((Bound::Excluded(0), Bound::Included(0))) ); } } roaring-0.10.12/src/lib.rs000064400000000000000000000056421046102023000133400ustar 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(not(feature = "std"), no_std)] #![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 #![allow(clippy::doc_overindented_list_items)] #![deny(unnameable_types)] #[cfg(feature = "std")] extern crate byteorder; #[macro_use] extern crate alloc; use core::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()) } } #[cfg(feature = "std")] impl std::error::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.12/src/treemap/arbitrary.rs000064400000000000000000000012611046102023000162170ustar 00000000000000#[cfg(test)] mod test { use crate::{RoaringBitmap, RoaringTreemap}; use proptest::collection::btree_map; use proptest::prelude::*; impl RoaringTreemap { prop_compose! { pub(crate) 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.12/src/treemap/cmp.rs000064400000000000000000000073351046102023000150070ustar 00000000000000use alloc::collections::btree_map; use core::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.12/src/treemap/fmt.rs000064400000000000000000000010571046102023000150110ustar 00000000000000use core::fmt; use crate::RoaringTreemap; #[cfg(not(feature = "std"))] use alloc::vec::Vec; 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.12/src/treemap/inherent.rs000064400000000000000000000304321046102023000160360ustar 00000000000000use alloc::collections::btree_map::{BTreeMap, Entry}; use core::iter; use core::ops::RangeBounds; use crate::RoaringBitmap; use crate::RoaringTreemap; use super::util; #[cfg(not(feature = "std"))] use alloc::vec::Vec; 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_default().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_default().insert_range(start_lo..=end_lo) } else if hi == start_hi { entry.or_default().insert_range(start_lo..=u32::MAX) } else if hi == end_hi { entry.or_default().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_default().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.12/src/treemap/iter.rs000064400000000000000000000455321046102023000151740ustar 00000000000000use alloc::collections::{btree_map, BTreeMap}; use core::iter; use core::ops::Add; 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 To64Iter<'_> { fn advance_to(&mut self, n: u32) { self.inner.advance_to(n) } fn advance_back_to(&mut self, n: u32) { self.inner.advance_back_to(n) } } impl Iterator for To64Iter<'_> { type Item = u64; fn next(&mut self) -> Option { self.inner.next().map(|n| util::join(self.hi, n)) } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } #[inline] fn fold(self, init: B, mut f: F) -> B where Self: Sized, F: FnMut(B, Self::Item) -> B, { self.inner.fold(init, move |b, lo| f(b, ((self.hi as u64) << 32) + (lo as u64))) } } impl DoubleEndedIterator for To64Iter<'_> { fn next_back(&mut self) -> Option { self.inner.next_back().map(|n| util::join(self.hi, n)) } #[inline] fn rfold(self, init: B, mut f: F) -> B where Self: Sized, F: FnMut(B, Self::Item) -> B, { self.inner.rfold(init, move |b, lo| f(b, ((self.hi as u64) << 32) + (lo as u64))) } } fn to64iter(t: (u32, &RoaringBitmap)) -> To64Iter<'_> { 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)) } #[inline] fn fold(self, init: B, mut f: F) -> B where Self: Sized, F: FnMut(B, Self::Item) -> B, { self.inner.fold(init, move |b, lo| f(b, ((self.hi as u64) << 32) + (lo as u64))) } } impl DoubleEndedIterator for To64IntoIter { fn next_back(&mut self) -> Option { self.inner.next_back().map(|n| util::join(self.hi, n)) } #[inline] fn rfold(self, init: B, mut f: F) -> B where Self: Sized, F: FnMut(B, Self::Item) -> B, { self.inner.rfold(init, move |b, lo| f(b, ((self.hi as u64) << 32) + (lo as u64))) } } fn to64intoiter(t: (u32, RoaringBitmap)) -> To64IntoIter { To64IntoIter { hi: t.0, inner: t.1.into_iter() } } type InnerIntoIter = iter::FlatMap< btree_map::IntoIter, To64IntoIter, fn((u32, RoaringBitmap)) -> To64IntoIter, >; /// An iterator for `RoaringTreemap`. pub struct Iter<'a> { outer: BitmapIter<'a>, front: Option>, back: Option>, } /// An iterator for `RoaringTreemap`. pub struct IntoIter { inner: InnerIntoIter, size_hint: u64, } impl Iter<'_> { fn new(map: &BTreeMap) -> Iter { let outer = BitmapIter::new(map); Iter { outer, front: None, back: None } } /// Advance the iterator to the first position where the item has a value >= `n` /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// use core::iter::FromIterator; /// /// let bitmap = (1..3).collect::(); /// let mut iter = bitmap.iter(); /// iter.advance_to(2); /// /// assert_eq!(iter.next(), Some(2)); /// assert_eq!(iter.next(), None); /// ``` pub fn advance_to(&mut self, n: u64) { let (key, index) = util::split(n); self.outer.advance_to(key); if self.front.is_none() { let Some(next) = self.outer.next() else { // if the current front iterator is empty or not yet initialized, // but the outer bitmap iterator is empty, then consume the back // iterator from the front if it is not also exhausted if let Some(ref mut back) = self.back { back.advance_to(index); } return; }; self.front = Some(to64iter(next)); } if let Some(ref mut front) = self.front { front.advance_to(index); } } /// Advance the back of the iterator to the first position where the item has a value <= `n` /// /// # Examples /// /// ```rust /// use roaring::RoaringTreemap; /// use core::iter::FromIterator; /// /// let bitmap = (1..3).collect::(); /// let mut iter = bitmap.iter(); /// iter.advance_back_to(1); /// /// assert_eq!(iter.next_back(), Some(1)); /// assert_eq!(iter.next_back(), None); /// ``` pub fn advance_back_to(&mut self, n: u64) { let (key, index) = util::split(n); self.outer.advance_back_to(key); if self.back.is_none() { let Some(next_back) = self.outer.next_back() else { // if the current back iterator is empty or not yet initialized, // but the outer bitmap iterator is empty, then consume the front // iterator from the back if it is not also exhausted if let Some(ref mut front) = self.front { front.advance_back_to(index); } return; }; self.back = Some(to64iter(next_back)); } if let Some(ref mut back) = self.back { back.advance_back_to(index); } } } 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 Iterator for Iter<'_> { type Item = u64; fn next(&mut self) -> Option { if let Some(ref mut front) = &mut self.front { if let Some(inner) = front.next() { return Some(inner); } } let Some(outer_next) = self.outer.next() else { // if the current front iterator is empty or not yet initialized, // but the outer bitmap iterator is empty, then consume the back // iterator from the front if it is not also exhausted if let Some(ref mut back) = &mut self.back { if let Some(next) = back.next() { return Some(next); } } return None; }; self.front = Some(to64iter(outer_next)); self.next() } fn size_hint(&self) -> (usize, Option) { let front_size_hint = self.front.as_ref().map_or(0, |f| f.size_hint().0); let back_size_hint = self.back.as_ref().map_or(0, |b| b.size_hint().0); let size_hint = front_size_hint .saturating_add(back_size_hint) .saturating_add(self.outer.remaining() as usize); (size_hint, Some(size_hint)) } } impl DoubleEndedIterator for Iter<'_> { fn next_back(&mut self) -> Option { if let Some(ref mut back) = &mut self.back { if let Some(inner) = back.next_back() { return Some(inner); } } let Some(outer_next_back) = self.outer.next_back() else { // if the current back iterator is empty or not yet initialized, // but the outer bitmap iterator is empty, then consume the front // iterator from the back if it is not also exhausted if let Some(ref mut front) = &mut self.front { if let Some(next_back) = front.next_back() { return Some(next_back); } } return None; }; self.back = Some(to64iter(outer_next_back)); self.next_back() } } #[cfg(target_pointer_width = "64")] impl ExactSizeIterator for Iter<'_> { fn len(&self) -> usize { self.size_hint().0 } } 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) } } #[inline] fn fold(self, init: B, f: F) -> B where Self: Sized, F: FnMut(B, Self::Item) -> B, { self.inner.fold(init, f) } } impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option { self.size_hint = self.size_hint.saturating_sub(1); self.inner.next_back() } #[inline] fn rfold(self, init: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, { self.inner.rfold(init, fold) } } #[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 core::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 core::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::new(&self.map) } /// 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 core::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) } } /// An iterator of `RoaringBitmap`s for `RoaringTreemap`. pub struct BitmapIter<'a> { treemap: &'a BTreeMap, range: btree_map::Range<'a, u32, RoaringBitmap>, latest_front_idx: Option, latest_back_idx: Option, } impl<'a> BitmapIter<'a> { fn new(treemap: &'a BTreeMap) -> Self { let range = treemap.range(..); Self { treemap, range, latest_back_idx: None, latest_front_idx: None } } fn advance_to(&mut self, new_front_idx: u32) { match self.latest_back_idx { Some(latest_back_idx) => match self.latest_front_idx { Some(last_idx) if last_idx >= new_front_idx => {} _ => { // if asked to advance to beyond the back iterator, // update the self.range iterator to be empty if new_front_idx >= latest_back_idx { self.range = self.treemap.range(0..1); self.range.next_back(); } else { // otherwise shrink the remaining range from the front self.range = self.treemap.range(new_front_idx..latest_back_idx); } // self.range = self.treemap.range(new_front_idx..latest_back_idx); } }, None => match self.latest_front_idx { Some(latest_idx) if latest_idx >= new_front_idx => {} _ => { self.range = self.treemap.range(new_front_idx..); } }, } } fn advance_back_to(&mut self, new_back_idx: u32) { match self.latest_front_idx { Some(latest_front_idx) => match self.latest_back_idx { // do nothing if asked to advance back to a higher index than the back is already at Some(latest_back_idx) if latest_back_idx <= new_back_idx => {} _ => { // if asked to advance back to beyond the front iterator, // update the self.range iterator to be empty if new_back_idx <= latest_front_idx { self.range = self.treemap.range(0..1); self.range.next_back(); } else { // otherwise shrink the remaining range from the back self.range = self.treemap.range((latest_front_idx + 1)..new_back_idx); } } }, None => match self.latest_back_idx { Some(latest_back_idx) if latest_back_idx <= new_back_idx => {} _ => { self.range = self.treemap.range(..=new_back_idx); } }, } } fn remaining(&self) -> u64 { let range = self.range.clone(); range.fold(0, |acc, (_, bitmap)| acc.add(bitmap.len())) } } impl<'a> Iterator for BitmapIter<'a> { type Item = (u32, &'a RoaringBitmap); fn next(&mut self) -> Option { match self.range.next().map(|(&p, b)| (p, b)) { None => { self.latest_front_idx = None; None } Some((next_idx, next_map)) => { self.latest_front_idx = Some(next_idx); Some((next_idx, next_map)) } } } fn size_hint(&self) -> (usize, Option) { self.range.size_hint() } } impl FromIterator<(u32, RoaringBitmap)> for RoaringTreemap { fn from_iter>(iterator: I) -> RoaringTreemap { Self::from_bitmaps(iterator) } } impl DoubleEndedIterator for BitmapIter<'_> { fn next_back(&mut self) -> Option { match self.range.next_back().map(|(&p, b)| (p, b)) { None => { self.latest_back_idx = None; None } Some((next_back_idx, next_back_map)) => { self.latest_back_idx = Some(next_back_idx); Some((next_back_idx, next_back_map)) } } } } roaring-0.10.12/src/treemap/mod.rs000064400000000000000000000015161046102023000150020ustar 00000000000000use crate::RoaringBitmap; use alloc::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; #[cfg(feature = "std")] mod serialization; pub use self::iter::{BitmapIter, 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.12/src/treemap/multiops.rs000064400000000000000000000256521046102023000161060ustar 00000000000000use alloc::collections::{binary_heap::PeekMut, BTreeMap, BinaryHeap}; use core::{borrow::Borrow, cmp::Ordering, mem}; use crate::{MultiOps, RoaringBitmap, RoaringTreemap}; #[cfg(not(feature = "std"))] use alloc::vec::Vec; 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::<_, core::convert::Infallible>), ) .unwrap() } fn intersection(self) -> Self::Output { try_ordered_multi_op_owned::<_, _, IntersectionOp>( self.into_iter().map(Ok::<_, core::convert::Infallible>), ) .unwrap() } fn difference(self) -> Self::Output { try_ordered_multi_op_owned::<_, _, DifferenceOp>( self.into_iter().map(Ok::<_, core::convert::Infallible>), ) .unwrap() } fn symmetric_difference(self) -> Self::Output { try_simple_multi_op_owned::<_, _, SymmetricDifferenceOp>( self.into_iter().map(Ok::<_, core::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 popped = PeekMut::pop(peek); (popped.key, popped.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(core::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( core::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 popped = PeekMut::pop(peek); (popped.key, popped.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::<_, core::convert::Infallible>), ) .unwrap() } fn intersection(self) -> Self::Output { try_ordered_multi_op_ref::<_, _, IntersectionOp>( self.into_iter().map(Ok::<_, core::convert::Infallible>), ) .unwrap() } fn difference(self) -> Self::Output { try_ordered_multi_op_ref::<_, _, DifferenceOp>( self.into_iter().map(Ok::<_, core::convert::Infallible>), ) .unwrap() } fn symmetric_difference(self) -> Self::Output { try_simple_multi_op_ref::<_, _, SymmetricDifferenceOp>( self.into_iter().map(Ok::<_, core::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.12/src/treemap/ops.rs000064400000000000000000000402511046102023000150230ustar 00000000000000use alloc::collections::btree_map::Entry; use core::mem; use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; use crate::RoaringTreemap; #[cfg(not(feature = "std"))] use alloc::vec::Vec; 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.12/src/treemap/serde.rs000064400000000000000000000046061046102023000153300ustar 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 core::fmt::Formatter) -> core::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_postcard( treemap in RoaringTreemap::arbitrary(), ) { let buffer = postcard::to_allocvec(&treemap).unwrap(); prop_assert_eq!(treemap, postcard::from_bytes(&buffer).unwrap()); } } } roaring-0.10.12/src/treemap/serialization.rs000064400000000000000000000101111046102023000170670ustar 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.12/src/treemap/util.rs000064400000000000000000000054551046102023000152060ustar 00000000000000use core::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.12/tests/bitmapwithoutruns.bin000064400000000000000000002156501046102023000171030ustar 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.12/tests/bitmapwithruns.bin000064400000000000000000001356701046102023000163560ustar 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.12/tests/clone.rs000064400000000000000000000016701046102023000142420ustar 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.12/tests/difference_with.rs000064400000000000000000000063061046102023000162700ustar 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.12/tests/intersect_with.rs000064400000000000000000000047531046102023000162020ustar 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.12/tests/is_disjoint.rs000064400000000000000000000037371046102023000154660ustar 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.12/tests/is_subset.rs000064400000000000000000000042461046102023000151440ustar 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.12/tests/iter.rs000064400000000000000000000135621046102023000141100ustar 00000000000000use proptest::arbitrary::any; use proptest::collection::btree_set; use proptest::proptest; 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)); } } proptest! { #[test] fn fold(values in btree_set(any::(), ..=10_000)) { let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap(); let mut val_iter = values.into_iter(); // `Iterator::all` uses currently unimplementable `try_fold`, we test `fold` #[allow(clippy::unnecessary_fold)] let r = bitmap.into_iter().fold(true, |b, i| { b && i == val_iter.next().unwrap() }); assert!(r) } } proptest! { #[test] fn nth(values in btree_set(any::(), ..=10_000), nth in 0..10_005usize) { let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap(); let mut orig_iter = bitmap.iter().fuse(); let mut iter = bitmap.iter(); for _ in 0..nth { if orig_iter.next().is_none() { break; } } let expected = orig_iter.next(); assert_eq!(expected, iter.nth(nth)); let expected_next = orig_iter.next(); assert_eq!(expected_next, iter.next()); let mut val_iter = values.into_iter(); assert_eq!(expected, val_iter.nth(nth)); assert_eq!(expected_next, val_iter.next()); } } #[test] fn huge_nth() { let bitmap = RoaringBitmap::new(); let mut iter = bitmap.iter(); assert_eq!(None, iter.nth(usize::MAX)); } proptest! { #[test] fn count(values in btree_set(any::(), ..=10_000), skip in 0..10_005usize) { let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap(); let mut iter = bitmap.iter(); if let Some(n) = skip.checked_sub(1) { iter.nth(n); } let expected_count = values.len().saturating_sub(skip); let size_hint = iter.size_hint(); assert_eq!(expected_count, size_hint.0); assert_eq!(Some(expected_count), size_hint.1); assert_eq!(expected_count, iter.count()); } } #[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.12/tests/iter_advance_to.rs000064400000000000000000000130541046102023000162670ustar 00000000000000use roaring::RoaringBitmap; #[test] fn iter_basic() { let bm = RoaringBitmap::from([1, 2, 3, 4, 11, 12, 13, 14]); let mut i = bm.iter(); i.advance_to(10); for n in 11..=14 { assert_eq!(i.next(), Some(n)) } assert_eq!(i.next(), None); } #[test] fn to_missing_container() { let bm = RoaringBitmap::from([1, 0x2_0001, 0x2_0002]); let mut i = bm.iter(); i.advance_to(0x1_0000); assert_eq!(i.next(), Some(0x2_0001)); assert_eq!(i.next(), Some(0x2_0002)); assert_eq!(i.next(), None); } #[test] fn iter_back_basic() { let bm = RoaringBitmap::from([1, 2, 3, 4, 11, 12, 13, 14]); let mut i = bm.iter(); i.advance_back_to(10); assert_eq!(i.next(), Some(1)); assert_eq!(i.next(), Some(2)); assert_eq!(i.next_back(), Some(4)); assert_eq!(i.next_back(), Some(3)); assert_eq!(i.next(), None); assert_eq!(i.next_back(), None); } #[test] fn iter_advance_past_end() { let bm = RoaringBitmap::from([1, 2, 3, 4, 11, 12, 13, 14]); let mut i = bm.iter(); i.advance_to(15); assert_eq!(i.size_hint(), (0, Some(0))); assert_eq!(i.next(), None); } #[test] fn iter_multi_container() { let bm = RoaringBitmap::from([1, 2, 3, 100000, 100001]); let mut i = bm.iter(); i.advance_to(3); assert_eq!(i.size_hint(), (3, Some(3))); assert_eq!(i.next(), Some(3)); assert_eq!(i.size_hint(), (2, Some(2))); assert_eq!(i.next(), Some(100000)); assert_eq!(i.size_hint(), (1, Some(1))); assert_eq!(i.next(), Some(100001)); assert_eq!(i.size_hint(), (0, Some(0))); assert_eq!(i.next(), None); assert_eq!(i.size_hint(), (0, Some(0))); } #[test] fn iter_empty() { let bm = RoaringBitmap::new(); let mut i = bm.iter(); i.advance_to(31337); assert_eq!(i.size_hint(), (0, Some(0))); assert_eq!(i.next(), None) } #[test] fn iter_back_empty() { let bm = RoaringBitmap::new(); let mut i = bm.iter(); i.advance_back_to(31337); assert_eq!(i.size_hint(), (0, Some(0))); assert_eq!(i.next(), None) } #[test] fn into_iter_basic() { let bm = RoaringBitmap::from([1, 2, 3, 4, 11, 12, 13, 14]); let mut i = bm.into_iter(); i.advance_to(10); let mut expected_size_hint = 4; assert_eq!(i.size_hint(), (expected_size_hint, Some(expected_size_hint))); for n in 11..=14 { assert_eq!(i.next(), Some(n)); expected_size_hint -= 1; assert_eq!(i.size_hint(), (expected_size_hint, Some(expected_size_hint))); } assert_eq!(i.next(), None); } #[test] fn into_iter_multi_container() { let bm = RoaringBitmap::from([1, 2, 3, 100000, 100001]); let mut i = bm.into_iter(); i.advance_to(3); assert_eq!(i.size_hint(), (3, Some(3))); assert_eq!(i.next(), Some(3)); assert_eq!(i.next(), Some(100000)); assert_eq!(i.next(), Some(100001)); assert_eq!(i.next(), None); } #[test] fn into_iter_empty() { let bm = RoaringBitmap::new(); let mut i = bm.into_iter(); i.advance_to(31337); assert_eq!(i.size_hint(), (0, Some(0))); assert_eq!(i.next(), None) } #[test] fn into_iter_back_empty() { let bm = RoaringBitmap::new(); let mut i = bm.into_iter(); i.advance_back_to(31337); assert_eq!(i.size_hint(), (0, Some(0))); assert_eq!(i.next(), None) } #[test] fn advance_to_with_tail_iter() { let bm = RoaringBitmap::from([1, 2, 3, 100000, 100001]); let mut i = bm.iter(); i.next_back(); i.advance_to(100000); assert_eq!(i.size_hint(), (1, Some(1))); assert_eq!(i.next(), Some(100000)); assert_eq!(i.size_hint(), (0, Some(0))); assert_eq!(i.next(), None); } #[test] fn advance_to_end() { let bitmap = RoaringBitmap::from([u32::MAX]); let mut iter = bitmap.iter(); iter.advance_to(u32::MAX); assert_eq!(Some(u32::MAX), iter.next()); assert_eq!(None, iter.next()); } #[test] fn advance_bitset() { let mut bitmap = RoaringBitmap::new(); for i in (0..=0x2_0000).step_by(2) { bitmap.insert(i); } let mut iter = bitmap.iter(); iter.advance_to(0x1_0000 - 4); // 0x1_0000 + 5 is not in the bitmap, so the next value will be the first value less than that iter.advance_back_to(0x1_0000 + 5); assert_eq!(iter.next(), Some(0x1_0000 - 4)); assert_eq!(iter.next_back(), Some(0x1_0000 + 4)); assert_eq!(iter.next(), Some(0x1_0000 - 2)); assert_eq!(iter.next(), Some(0x1_0000)); assert_eq!(iter.next(), Some(0x1_0000 + 2)); assert_eq!(iter.next(), None); assert_eq!(iter.next_back(), None); } #[test] fn advance_bitset_current_word() { let mut bitmap = RoaringBitmap::new(); for i in (0..=0x2_0000).step_by(2) { bitmap.insert(i); } let mut iter = bitmap.iter(); iter.advance_to(4); iter.advance_back_to(0x2_0000 - 4); for i in (4..=(0x2_0000 - 4)).step_by(2) { assert_eq!(iter.next(), Some(i)); } assert_eq!(iter.next(), None); } #[test] fn advance_bitset_to_end_word() { let mut bitmap = RoaringBitmap::new(); for i in (0..=0x2_0000).step_by(2) { bitmap.insert(i); } let mut iter = bitmap.iter(); iter.advance_to(0x1_0000 - 4); for i in ((0x1_0000 - 4)..=0x2_0000).step_by(2) { assert_eq!(iter.next(), Some(i)); } assert_eq!(iter.next(), None); } #[test] fn advance_bitset_back_to_start_word() { let mut bitmap = RoaringBitmap::new(); for i in (0..=0x2_0000).step_by(2) { bitmap.insert(i); } let mut iter = bitmap.iter(); iter.advance_back_to(0x1_0000 - 4); for i in (0..=(0x1_0000 - 4)).step_by(2) { assert_eq!(iter.next(), Some(i)); } assert_eq!(iter.next(), None); } roaring-0.10.12/tests/iter_range.rs000064400000000000000000000054571046102023000152700ustar 00000000000000use proptest::collection::btree_set; use proptest::prelude::*; use roaring::RoaringBitmap; use std::ops::Bound; #[test] fn range_array() { let mut rb = RoaringBitmap::new(); rb.insert(0); rb.insert(1); rb.insert(10); rb.insert(100_000); rb.insert(999_999); rb.insert(1_000_000); let expected = vec![1, 10, 100_000, 999_999]; let actual: Vec = rb.range(1..=999_999).collect(); assert_eq!(expected, actual); } #[test] fn range_bitmap() { let rb = RoaringBitmap::from_sorted_iter(10..5000).unwrap(); let expected = vec![10, 11, 12]; let actual: Vec = rb.range(0..13).collect(); assert_eq!(expected, actual); } #[test] fn empty_range() { let rb = RoaringBitmap::from_sorted_iter(10..5000).unwrap(); let mut it = rb.range(0..0); assert_eq!(it.next(), None); let mut it = rb.range(..0); assert_eq!(it.next(), None); it = rb.range(13..13); assert_eq!(it.next(), None); it = rb.range((Bound::Excluded(1), Bound::Included(1))); assert_eq!(it.next(), None); it = rb.range(u32::MAX..u32::MAX); assert_eq!(it.next(), None); it = rb.range((Bound::Excluded(u32::MAX), Bound::Included(u32::MAX))); assert_eq!(it.next(), None); it = rb.range((Bound::Excluded(u32::MAX), Bound::Unbounded)); assert_eq!(it.next(), None); } #[test] #[should_panic(expected = "range start is greater than range end")] fn invalid_range() { let rb = RoaringBitmap::from_sorted_iter(10..5000).unwrap(); #[allow(clippy::reversed_empty_ranges)] let _ = rb.range(13..0); } #[test] #[should_panic(expected = "range start and end are equal and excluded")] fn invalid_range_equal_excluded() { let rb = RoaringBitmap::from_sorted_iter(10..5000).unwrap(); let _ = rb.range((Bound::Excluded(13), Bound::Excluded(13))); } #[test] #[should_panic(expected = "range start is greater than range end")] fn into_invalid_range() { let rb = RoaringBitmap::from_sorted_iter(10..5000).unwrap(); #[allow(clippy::reversed_empty_ranges)] let _ = rb.into_range(13..0); } #[test] #[should_panic(expected = "range start and end are equal and excluded")] fn into_invalid_range_equal_excluded() { let rb = RoaringBitmap::from_sorted_iter(10..5000).unwrap(); let _ = rb.into_range((Bound::Excluded(13), Bound::Excluded(13))); } proptest! { #[test] fn proptest_range( values in btree_set(..=262_143_u32, ..=1000), range_a in 0u32..262_143, range_b in 0u32..262_143, ){ let range = range_a.min(range_b)..=range_a.max(range_b); let bitmap = RoaringBitmap::from_sorted_iter(values.iter().cloned()).unwrap(); let expected: Vec = values.range(range.clone()).copied().collect(); let actual: Vec = bitmap.range(range.clone()).collect(); assert_eq!(expected, actual); } } roaring-0.10.12/tests/lib.rs000064400000000000000000000071231046102023000137070ustar 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 - 2); assert!(bitmap.contains(u32::MAX - 2)); assert_eq!(bitmap.len(), 2); bitmap.insert(u32::MAX); assert!(bitmap.contains(u32::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(u32::MAX - 2)); assert!(!bitmap.contains(u32::MAX - 1)); assert!(bitmap.contains(u32::MAX)); } #[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.12/tests/ops.rs000064400000000000000000000036471046102023000137510ustar 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.12/tests/push.rs000064400000000000000000000033111046102023000141130ustar 00000000000000extern crate roaring; use roaring::{RoaringBitmap, RoaringTreemap}; /// 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.12/tests/range_checks.rs000064400000000000000000000053571046102023000155640ustar 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.12/tests/rank.rs000064400000000000000000000036631046102023000141010ustar 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.12/tests/select.rs000064400000000000000000000025221046102023000144160ustar 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.12/tests/serialization.rs000064400000000000000000001253051046102023000160210ustar 00000000000000#![cfg(feature = "std")] extern 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.12/tests/size_hint.rs000064400000000000000000000034311046102023000151330ustar 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.12/tests/symmetric_difference_with.rs000064400000000000000000000062511046102023000203630ustar 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.12/tests/treemap_clone.rs000064400000000000000000000016351046102023000157600ustar 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.12/tests/treemap_difference_with.rs000064400000000000000000000062111046102023000200000ustar 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.12/tests/treemap_intersect_with.rs000064400000000000000000000047101046102023000177100ustar 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.12/tests/treemap_is_disjoint.rs000064400000000000000000000036701046102023000171770ustar 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.12/tests/treemap_is_subset.rs000064400000000000000000000042731046102023000166610ustar 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.12/tests/treemap_iter.rs000064400000000000000000000100161046102023000156140ustar 00000000000000extern crate roaring; mod iter; use roaring::RoaringTreemap; use iter::outside_in; use proptest::arbitrary::any; use proptest::collection::btree_set; use proptest::proptest; #[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)); } } proptest! { #[test] fn fold(values in btree_set(any::(), ..=10_000)) { let bitmap = RoaringTreemap::from_sorted_iter(values.iter().cloned()).unwrap(); let mut val_iter = values.into_iter(); // `Iterator::all` uses currently unimplementable `try_fold`, we test `fold` #[allow(clippy::unnecessary_fold)] let r = bitmap.into_iter().fold(true, |b, i| { b && i == val_iter.next().unwrap() }); assert!(r) } } #[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.12/tests/treemap_iter_advance_to.rs000064400000000000000000000162751046102023000200140ustar 00000000000000extern crate roaring; use roaring::RoaringTreemap; #[test] fn iter_basic() { let bm = RoaringTreemap::from([1, 2, 3, 4, 11, 12, 13, 14]); let mut i = bm.iter(); i.advance_to(10); for n in 11..=14 { assert_eq!(i.next(), Some(n)) } assert_eq!(i.next(), None); } #[test] fn to_missing_container() { let bm = RoaringTreemap::from([1, 0x2_0001, 0x2_0002]); let mut i = bm.iter(); i.advance_to(0x1_0000); assert_eq!(i.next(), Some(0x2_0001)); assert_eq!(i.next(), Some(0x2_0002)); assert_eq!(i.next(), None); } #[test] fn to_next_bitmap() { let bm = RoaringTreemap::from([1u64, 0x2_0001u64 + u32::MAX as u64, 0x2_0002u64 + u32::MAX as u64]); let mut i = bm.iter(); i.advance_to(0x1_0000); assert_eq!(i.next(), Some(0x2_0001u64 + u32::MAX as u64)); assert_eq!(i.next(), Some(0x2_0002u64 + u32::MAX as u64)); assert_eq!(i.next(), None); } #[test] fn iter_back_basic() { let bm = RoaringTreemap::from([1, 2, 3, 4, 11, 12, 13, 14]); let mut i = bm.iter(); i.advance_back_to(10); assert_eq!(i.next(), Some(1)); assert_eq!(i.next(), Some(2)); assert_eq!(i.next_back(), Some(4)); assert_eq!(i.next_back(), Some(3)); assert_eq!(i.next(), None); assert_eq!(i.next_back(), None); } #[test] fn iter_advance_past_end() { let bm = RoaringTreemap::from([1, 2, 3, 4, 11, 12, 13, 14]); let mut i = bm.iter(); i.advance_to(15); assert_eq!(i.next(), None); assert_eq!(i.size_hint(), (0, Some(0))); } #[test] fn iter_multi_container() { let bm = RoaringTreemap::from([1, 2, 3, 100000, 100001]); let mut i = bm.iter(); i.advance_to(3); assert_eq!(i.size_hint(), (3, Some(3))); assert_eq!(i.next(), Some(3)); assert_eq!(i.size_hint(), (2, Some(2))); assert_eq!(i.next(), Some(100000)); assert_eq!(i.size_hint(), (1, Some(1))); assert_eq!(i.next(), Some(100001)); assert_eq!(i.size_hint(), (0, Some(0))); assert_eq!(i.next(), None); assert_eq!(i.size_hint(), (0, Some(0))); } #[test] fn iter_multi_container_multi_bitmap() { let bm = RoaringTreemap::from([ 1, 2, 3, 100000, 100001, 1u64 + u32::MAX as u64, 2u64 + u32::MAX as u64, 3u64 + u32::MAX as u64, 100000u64 + u32::MAX as u64, 100001u64 + u32::MAX as u64, ]); let mut i = bm.iter(); i.advance_to(3); assert_eq!(i.size_hint(), (8, Some(8))); assert_eq!(i.next(), Some(3)); assert_eq!(i.size_hint(), (7, Some(7))); assert_eq!(i.next(), Some(100000)); assert_eq!(i.size_hint(), (6, Some(6))); assert_eq!(i.next(), Some(100001)); assert_eq!(i.size_hint(), (5, Some(5))); assert_eq!(i.next(), Some(1u64 + u32::MAX as u64)); assert_eq!(i.size_hint(), (4, Some(4))); assert_eq!(i.next(), Some(2u64 + u32::MAX as u64)); assert_eq!(i.size_hint(), (3, Some(3))); assert_eq!(i.next(), Some(3u64 + u32::MAX as u64)); assert_eq!(i.size_hint(), (2, Some(2))); assert_eq!(i.next(), Some(100000u64 + u32::MAX as u64)); assert_eq!(i.size_hint(), (1, Some(1))); assert_eq!(i.next(), Some(100001u64 + u32::MAX as u64)); assert_eq!(i.size_hint(), (0, Some(0))); assert_eq!(i.next(), None); assert_eq!(i.size_hint(), (0, Some(0))); } #[test] fn iter_empty() { let bm = RoaringTreemap::new(); let mut i = bm.iter(); i.advance_to(31337); assert_eq!(i.size_hint(), (0, Some(0))); assert_eq!(i.next(), None) } #[test] fn iter_back_empty() { let bm = RoaringTreemap::new(); let mut i = bm.iter(); i.advance_back_to(31337); assert_eq!(i.size_hint(), (0, Some(0))); assert_eq!(i.next(), None) } /*#[test] fn into_iter_basic() { let bm = RoaringTreemap::from([1, 2, 3, 4, 11, 12, 13, 14]); let mut i = bm.into_iter(); i.advance_to(10); let mut expected_size_hint = 4; assert_eq!(i.size_hint(), (expected_size_hint, Some(expected_size_hint))); for n in 11..=14 { assert_eq!(i.next(), Some(n)); expected_size_hint -= 1; assert_eq!(i.size_hint(), (expected_size_hint, Some(expected_size_hint))); } assert_eq!(i.next(), None); }*/ /*#[test] fn into_iter_multi_container() { let bm = RoaringTreemap::from([1, 2, 3, 100000, 100001]); let mut i = bm.into_iter(); i.advance_to(3); assert_eq!(i.size_hint(), (3, Some(3))); assert_eq!(i.next(), Some(3)); assert_eq!(i.next(), Some(100000)); assert_eq!(i.next(), Some(100001)); assert_eq!(i.next(), None); }*/ /*#[test] fn into_iter_empty() { let bm = RoaringTreemap::new(); let mut i = bm.into_iter(); i.advance_to(31337); assert_eq!(i.size_hint(), (0, Some(0))); assert_eq!(i.next(), None) }*/ /*#[test] fn into_iter_back_empty() { let bm = RoaringTreemap::new(); let mut i = bm.into_iter(); i.advance_back_to(31337); assert_eq!(i.size_hint(), (0, Some(0))); assert_eq!(i.next(), None) }*/ #[test] fn advance_to_with_tail_iter() { let bm = RoaringTreemap::from([1, 2, 3, 100000, 100001]); let mut i = bm.iter(); i.next_back(); i.advance_to(100000); assert_eq!(i.size_hint(), (1, Some(1))); assert_eq!(i.next(), Some(100000)); assert_eq!(i.size_hint(), (0, Some(0))); assert_eq!(i.next(), None); } #[test] fn advance_to_end() { let bitmap = RoaringTreemap::from([u64::MAX]); let mut iter = bitmap.iter(); iter.advance_to(u64::MAX); assert_eq!(Some(u64::MAX), iter.next()); assert_eq!(None, iter.next()); } #[test] fn advance_bitset() { let mut bitmap = RoaringTreemap::new(); for i in (0..=0x2_0000).step_by(2) { bitmap.insert(i); } let mut iter = bitmap.iter(); iter.advance_to(0x1_0000 - 4); // 0x1_0000 + 5 is not in the bitmap, so the next value will be the first value less than that iter.advance_back_to(0x1_0000 + 5); assert_eq!(iter.next(), Some(0x1_0000 - 4)); assert_eq!(iter.next_back(), Some(0x1_0000 + 4)); assert_eq!(iter.next(), Some(0x1_0000 - 2)); assert_eq!(iter.next(), Some(0x1_0000)); assert_eq!(iter.next(), Some(0x1_0000 + 2)); assert_eq!(iter.next(), None); assert_eq!(iter.next_back(), None); } #[test] fn advance_bitset_current_word() { let mut bitmap = RoaringTreemap::new(); for i in (0..=0x2_0000).step_by(2) { bitmap.insert(i); } let mut iter = bitmap.iter(); iter.advance_to(4); iter.advance_back_to(0x2_0000 - 4); for i in (4..=(0x2_0000 - 4)).step_by(2) { assert_eq!(iter.next(), Some(i)); } assert_eq!(iter.next(), None); } #[test] fn advance_bitset_to_end_word() { let mut bitmap = RoaringTreemap::new(); for i in (0..=0x2_0000).step_by(2) { bitmap.insert(i); } let mut iter = bitmap.iter(); iter.advance_to(0x1_0000 - 4); for i in ((0x1_0000 - 4)..=0x2_0000).step_by(2) { assert_eq!(iter.next(), Some(i)); } assert_eq!(iter.next(), None); } #[test] fn advance_bitset_back_to_start_word() { let mut bitmap = RoaringTreemap::new(); for i in (0..=0x2_0000).step_by(2) { bitmap.insert(i); } let mut iter = bitmap.iter(); iter.advance_back_to(0x1_0000 - 4); for i in (0..=(0x1_0000 - 4)).step_by(2) { assert_eq!(iter.next(), Some(i)); } assert_eq!(iter.next(), None); } roaring-0.10.12/tests/treemap_lib.rs000064400000000000000000000062771046102023000154350ustar 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.12/tests/treemap_ops.rs000064400000000000000000000036611046102023000154620ustar 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.12/tests/treemap_rank.rs000064400000000000000000000033741046102023000156150ustar 00000000000000extern crate roaring; use core::ops::RangeInclusive; use proptest::collection::{btree_set, vec}; use proptest::prelude::*; use roaring::RoaringTreemap; 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.12/tests/treemap_select.rs000064400000000000000000000024071046102023000161350ustar 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.12/tests/treemap_serialization.rs000064400000000000000000000017411046102023000175330ustar 00000000000000#![cfg(feature = "std")] use roaring::RoaringTreemap; 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.12/tests/treemap_size_hint.rs000064400000000000000000000033761046102023000166600ustar 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.12/tests/treemap_symmetric_difference_with.rs000064400000000000000000000062151046102023000221000ustar 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.12/tests/treemap_union_with.rs000064400000000000000000000046111046102023000170400ustar 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.12/tests/union_with.rs000064400000000000000000000046671046102023000153360ustar 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); }