diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 68c4804..94db84f 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -8,18 +8,15 @@ on: branches: - master -env: - RUSTFLAGS: -A warnings - jobs: test: - name: Test on ${{ matrix.os }} using Rust ${{ matrix.rust }} with bindgen features '${{ matrix.cargo_features }}' + name: Test on ${{ matrix.os }} using Rust ${{ matrix.rust }} with features '${{ matrix.cargo_features }}' runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] rust: [stable, nightly] - cargo_features: [''] + cargo_features: ['', 'alloc', 'default'] steps: - uses: hecrj/setup-rust-action@v2 @@ -44,33 +41,20 @@ jobs: if: matrix.os == 'ubuntu-latest' && matrix.rust == 'nightly' - name: Cargo clippy - run: cargo +${{ matrix.rust }} clippy --all-targets --workspace --features "${{ matrix.cargo_features }}" - if: matrix.os == 'ubuntu-latest' && matrix.rust == 'nightly' && matrix.cargo_features != '' - - - name: Cargo clippy - run: cargo +${{ matrix.rust }} clippy --all-targets --workspace - if: matrix.os == 'ubuntu-latest' && matrix.rust == 'nightly' && matrix.cargo_features == '' - - - name: Build - run: cargo +${{ matrix.rust }} build --features "${{ matrix.cargo_features }}" - if: matrix.cargo_features != '' - - - name: Build - run: cargo +${{ matrix.rust }} build - if: matrix.cargo_features == '' - - - name: Test - run: cargo +${{ matrix.rust }} test --features "${{ matrix.cargo_features }}" - if: matrix.cargo_features != '' + run: cargo +${{ matrix.rust }} clippy --all-targets --workspace --no-default-features --features "${{ matrix.cargo_features }}" + if: matrix.os == 'ubuntu-latest' && matrix.rust == 'nightly' && matrix.cargo_features == 'default' - name: Test - run: cargo +${{ matrix.rust }} test - if: matrix.cargo_features == '' + run: cargo +${{ matrix.rust }} test --no-default-features --features "${{ matrix.cargo_features }}" - name: Benchmark - if: matrix.rust == 'nightly' - run: cargo +${{ matrix.rust }} bench + run: cargo +${{ matrix.rust }} bench --no-default-features --features "${{ matrix.cargo_features }}" + if: matrix.rust == 'nightly' && matrix.cargo_features == 'default' - name: Minimal versions - if: matrix.rust == 'nightly' - run: cargo +${{ matrix.rust }} -Zdirect-minimal-versions test + run: cargo +${{ matrix.rust }} -Zdirect-minimal-versions test --no-default-features --features "${{ matrix.cargo_features }}" + if: matrix.rust == 'nightly' && matrix.cargo_features == 'default' + + - name: Updated versions + run: cargo update && cargo +${{ matrix.rust }} test --no-default-features --features "${{ matrix.cargo_features }}" + if: matrix.rust == 'stable' && matrix.cargo_features == 'default' diff --git a/.gitignore b/.gitignore index ced7a25..083546c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ target -Cargo.lock .DS_Store .idea \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..b84ae4d --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,834 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytemuck" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cc" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstyle", + "clap_lex", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "croaring" +version = "2.0.0" +dependencies = [ + "criterion", + "croaring-sys", + "proptest", + "roaring", +] + +[[package]] +name = "croaring-sys" +version = "2.1.0" +dependencies = [ + "cc", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "either" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[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.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + +[[package]] +name = "plotters" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" + +[[package]] +name = "plotters-svg" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags", + "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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +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 = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "roaring" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b26f4c25a604fcb3a1bcd96dd6ba37c93840de95de8198d94c0d571a74a804d1" +dependencies = [ + "bytemuck", + "byteorder", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[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.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "serde" +version = "1.0.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "2.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[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 = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/Makefile b/Makefile index 434616a..25d8c27 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,7 @@ bindgen: --allowlist-item '(?i-u:roaring|bitset).*' \ --allowlist-var '(?i-u:roaring|bitset).*' \ --no-layout-tests \ + --use-core \ -o bindgen_bundled_version.rs \ roaring.h diff --git a/croaring-sys/CRoaring/bindgen_bundled_version.rs b/croaring-sys/CRoaring/bindgen_bundled_version.rs index 846f5e7..2cb2d5b 100644 --- a/croaring-sys/CRoaring/bindgen_bundled_version.rs +++ b/croaring-sys/CRoaring/bindgen_bundled_version.rs @@ -4,25 +4,25 @@ pub const ROARING_VERSION: &[u8; 6] = b"3.0.1\0"; pub const ROARING_VERSION_MAJOR: _bindgen_ty_1 = 3; pub const ROARING_VERSION_MINOR: _bindgen_ty_1 = 0; pub const ROARING_VERSION_REVISION: _bindgen_ty_1 = 1; -pub type _bindgen_ty_1 = ::std::os::raw::c_uint; +pub type _bindgen_ty_1 = ::core::ffi::c_uint; #[doc = " Roaring arrays are array-based key-value pairs having containers as values\n and 16-bit integer keys. A roaring bitmap might be implemented as such."] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct roaring_array_s { pub size: i32, pub allocation_size: i32, - pub containers: *mut *mut ::std::os::raw::c_void, + pub containers: *mut *mut ::core::ffi::c_void, pub keys: *mut u16, pub typecodes: *mut u8, pub flags: u8, } #[doc = " Roaring arrays are array-based key-value pairs having containers as values\n and 16-bit integer keys. A roaring bitmap might be implemented as such."] pub type roaring_array_t = roaring_array_s; -pub type roaring_iterator = ::std::option::Option< - unsafe extern "C" fn(value: u32, param: *mut ::std::os::raw::c_void) -> bool, +pub type roaring_iterator = ::core::option::Option< + unsafe extern "C" fn(value: u32, param: *mut ::core::ffi::c_void) -> bool, >; -pub type roaring_iterator64 = ::std::option::Option< - unsafe extern "C" fn(value: u64, param: *mut ::std::os::raw::c_void) -> bool, +pub type roaring_iterator64 = ::core::option::Option< + unsafe extern "C" fn(value: u64, param: *mut ::core::ffi::c_void) -> bool, >; #[doc = " (For advanced users.)\n The roaring_statistics_t can be used to collect detailed statistics about\n the composition of a roaring bitmap."] #[repr(C)] @@ -55,12 +55,11 @@ pub struct roaring_container_iterator_s { pub type roaring_container_iterator_t = roaring_container_iterator_s; extern "C" { #[doc = " result might be undefined when input_num is zero"] - pub fn roaring_trailing_zeroes(input_num: ::std::os::raw::c_ulonglong) - -> ::std::os::raw::c_int; + pub fn roaring_trailing_zeroes(input_num: ::core::ffi::c_ulonglong) -> ::core::ffi::c_int; } extern "C" { #[doc = " result might be undefined when input_num is zero"] - pub fn roaring_leading_zeroes(input_num: ::std::os::raw::c_ulonglong) -> ::std::os::raw::c_int; + pub fn roaring_leading_zeroes(input_num: ::core::ffi::c_ulonglong) -> ::core::ffi::c_int; } #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -174,14 +173,14 @@ extern "C" { startfrom: *mut usize, ) -> usize; } -pub type bitset_iterator = ::std::option::Option< - unsafe extern "C" fn(value: usize, param: *mut ::std::os::raw::c_void) -> bool, +pub type bitset_iterator = ::core::option::Option< + unsafe extern "C" fn(value: usize, param: *mut ::core::ffi::c_void) -> bool, >; extern "C" { pub fn bitset_for_each( b: *const bitset_t, iterator: bitset_iterator, - ptr: *mut ::std::os::raw::c_void, + ptr: *mut ::core::ffi::c_void, ) -> bool; } extern "C" { @@ -372,8 +371,8 @@ extern "C" { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct roaring_bulk_context_s { - pub container: *mut ::std::os::raw::c_void, - pub idx: ::std::os::raw::c_int, + pub container: *mut ::core::ffi::c_void, + pub idx: ::core::ffi::c_int, pub key: u16, pub typecode: u8, } @@ -500,17 +499,17 @@ extern "C" { #[doc = " Write the bitmap to an output pointer, this output buffer should refer to\n at least `roaring_bitmap_size_in_bytes(r)` allocated bytes.\n\n See `roaring_bitmap_portable_serialize()` if you want a format that's\n compatible with Java and Go implementations. This format can sometimes be\n more space efficient than the portable form, e.g. when the data is sparse.\n\n Returns how many bytes written, should be `roaring_bitmap_size_in_bytes(r)`.\n\n This function is endian-sensitive. If you have a big-endian system (e.g., a\n mainframe IBM s390x), the data format is going to be big-endian and not\n compatible with little-endian systems."] pub fn roaring_bitmap_serialize( r: *const roaring_bitmap_t, - buf: *mut ::std::os::raw::c_char, + buf: *mut ::core::ffi::c_char, ) -> usize; } extern "C" { #[doc = " Use with `roaring_bitmap_serialize()`.\n\n (See `roaring_bitmap_portable_deserialize()` if you want a format that's\n compatible with Java and Go implementations).\n\n This function is endian-sensitive. If you have a big-endian system (e.g., a\n mainframe IBM s390x), the data format is going to be big-endian and not\n compatible with little-endian systems."] - pub fn roaring_bitmap_deserialize(buf: *const ::std::os::raw::c_void) -> *mut roaring_bitmap_t; + pub fn roaring_bitmap_deserialize(buf: *const ::core::ffi::c_void) -> *mut roaring_bitmap_t; } extern "C" { #[doc = " Use with `roaring_bitmap_serialize()`.\n\n (See `roaring_bitmap_portable_deserialize_safe()` if you want a format that's\n compatible with Java and Go implementations).\n\n This function is endian-sensitive. If you have a big-endian system (e.g., a\n mainframe IBM s390x), the data format is going to be big-endian and not\n compatible with little-endian systems.\n\n The difference with `roaring_bitmap_deserialize()` is that this function\n checks that the input buffer is a valid bitmap. If the buffer is too small,\n NULL is returned."] pub fn roaring_bitmap_deserialize_safe( - buf: *const ::std::os::raw::c_void, + buf: *const ::core::ffi::c_void, maxbytes: usize, ) -> *mut roaring_bitmap_t; } @@ -521,26 +520,26 @@ extern "C" { extern "C" { #[doc = " Read bitmap from a serialized buffer.\n In case of failure, NULL is returned.\n\n This function is unsafe in the sense that if there is no valid serialized\n bitmap at the pointer, then many bytes could be read, possibly causing a\n buffer overflow. See also roaring_bitmap_portable_deserialize_safe().\n\n This is meant to be compatible with the Java and Go versions:\n https://github.com/RoaringBitmap/RoaringFormatSpec\n\n This function is endian-sensitive. If you have a big-endian system (e.g., a\n mainframe IBM s390x), the data format is going to be big-endian and not\n compatible with little-endian systems."] pub fn roaring_bitmap_portable_deserialize( - buf: *const ::std::os::raw::c_char, + buf: *const ::core::ffi::c_char, ) -> *mut roaring_bitmap_t; } extern "C" { #[doc = " Read bitmap from a serialized buffer safely (reading up to maxbytes).\n In case of failure, NULL is returned.\n\n This is meant to be compatible with the Java and Go versions:\n https://github.com/RoaringBitmap/RoaringFormatSpec\n\n The function itself is safe in the sense that it will not cause buffer\n overflows. However, for correct operations, it is assumed that the bitmap\n read was once serialized from a valid bitmap (i.e., it follows the format\n specification). If you provided an incorrect input (garbage), then the bitmap\n read may not be in a valid state and following operations may not lead to\n sensible results. In particular, the serialized array containers need to be\n in sorted order, and the run containers should be in sorted non-overlapping\n order. This is is guaranteed to happen when serializing an existing bitmap,\n but not for random inputs.\n\n You may use roaring_bitmap_internal_validate to check the validity of the\n bitmap prior to using it. You may also use other strategies to check for\n corrupted inputs (e.g., checksums).\n\n This function is endian-sensitive. If you have a big-endian system (e.g., a\n mainframe IBM s390x), the data format is going to be big-endian and not\n compatible with little-endian systems."] pub fn roaring_bitmap_portable_deserialize_safe( - buf: *const ::std::os::raw::c_char, + buf: *const ::core::ffi::c_char, maxbytes: usize, ) -> *mut roaring_bitmap_t; } extern "C" { #[doc = " Read bitmap from a serialized buffer.\n In case of failure, NULL is returned.\n\n Bitmap returned by this function can be used in all readonly contexts.\n Bitmap must be freed as usual, by calling roaring_bitmap_free().\n Underlying buffer must not be freed or modified while it backs any bitmaps.\n\n The function is unsafe in the following ways:\n 1) It may execute unaligned memory accesses.\n 2) A buffer overflow may occur if buf does not point to a valid serialized\n bitmap.\n\n This is meant to be compatible with the Java and Go versions:\n https://github.com/RoaringBitmap/RoaringFormatSpec\n\n This function is endian-sensitive. If you have a big-endian system (e.g., a\n mainframe IBM s390x), the data format is going to be big-endian and not\n compatible with little-endian systems."] pub fn roaring_bitmap_portable_deserialize_frozen( - buf: *const ::std::os::raw::c_char, + buf: *const ::core::ffi::c_char, ) -> *mut roaring_bitmap_t; } extern "C" { #[doc = " Check how many bytes would be read (up to maxbytes) at this pointer if there\n is a bitmap, returns zero if there is no valid bitmap.\n\n This is meant to be compatible with the Java and Go versions:\n https://github.com/RoaringBitmap/RoaringFormatSpec"] pub fn roaring_bitmap_portable_deserialize_size( - buf: *const ::std::os::raw::c_char, + buf: *const ::core::ffi::c_char, maxbytes: usize, ) -> usize; } @@ -552,7 +551,7 @@ extern "C" { #[doc = " Write a bitmap to a char buffer. The output buffer should refer to at least\n `roaring_bitmap_portable_size_in_bytes(r)` bytes of allocated memory.\n\n Returns how many bytes were written which should match\n `roaring_bitmap_portable_size_in_bytes(r)`.\n\n This is meant to be compatible with the Java and Go versions:\n https://github.com/RoaringBitmap/RoaringFormatSpec\n\n This function is endian-sensitive. If you have a big-endian system (e.g., a\n mainframe IBM s390x), the data format is going to be big-endian and not\n compatible with little-endian systems."] pub fn roaring_bitmap_portable_serialize( r: *const roaring_bitmap_t, - buf: *mut ::std::os::raw::c_char, + buf: *mut ::core::ffi::c_char, ) -> usize; } extern "C" { @@ -563,13 +562,13 @@ extern "C" { #[doc = " Serializes bitmap using frozen format.\n Buffer size must be at least roaring_bitmap_frozen_size_in_bytes().\n\n This function is endian-sensitive. If you have a big-endian system (e.g., a\n mainframe IBM s390x), the data format is going to be big-endian and not\n compatible with little-endian systems."] pub fn roaring_bitmap_frozen_serialize( r: *const roaring_bitmap_t, - buf: *mut ::std::os::raw::c_char, + buf: *mut ::core::ffi::c_char, ); } extern "C" { #[doc = " Creates constant bitmap that is a view of a given buffer.\n Buffer data should have been written by `roaring_bitmap_frozen_serialize()`\n Its beginning must also be aligned by 32 bytes.\n Length must be equal exactly to `roaring_bitmap_frozen_size_in_bytes()`.\n In case of failure, NULL is returned.\n\n Bitmap returned by this function can be used in all readonly contexts.\n Bitmap must be freed as usual, by calling roaring_bitmap_free().\n Underlying buffer must not be freed or modified while it backs any bitmaps.\n\n This function is endian-sensitive. If you have a big-endian system (e.g., a\n mainframe IBM s390x), the data format is going to be big-endian and not\n compatible with little-endian systems."] pub fn roaring_bitmap_frozen_view( - buf: *const ::std::os::raw::c_char, + buf: *const ::core::ffi::c_char, length: usize, ) -> *const roaring_bitmap_t; } @@ -578,7 +577,7 @@ extern "C" { pub fn roaring_iterate( r: *const roaring_bitmap_t, iterator: roaring_iterator, - ptr: *mut ::std::os::raw::c_void, + ptr: *mut ::core::ffi::c_void, ) -> bool; } extern "C" { @@ -586,7 +585,7 @@ extern "C" { r: *const roaring_bitmap_t, iterator: roaring_iterator64, high_bits: u64, - ptr: *mut ::std::os::raw::c_void, + ptr: *mut ::core::ffi::c_void, ) -> bool; } extern "C" { @@ -687,7 +686,7 @@ extern "C" { #[doc = " Perform internal consistency checks. Returns true if the bitmap is\n consistent. It may be useful to call this after deserializing bitmaps from\n untrusted sources. If roaring_bitmap_internal_validate returns true, then the\n bitmap should be consistent and can be trusted not to cause crashes or memory\n corruption.\n\n Note that some operations intentionally leave bitmaps in an inconsistent\n state temporarily, for example, `roaring_bitmap_lazy_*` functions, until\n `roaring_bitmap_repair_after_lazy` is called.\n\n If reason is non-null, it will be set to a string describing the first\n inconsistency found if any."] pub fn roaring_bitmap_internal_validate( r: *const roaring_bitmap_t, - reason: *mut *const ::std::os::raw::c_char, + reason: *mut *const ::core::ffi::c_char, ) -> bool; } #[doc = " A struct used to keep iterator state. Users should only access\n `current_value` and `has_value`, the rest of the type should be treated as\n opaque."] @@ -695,7 +694,7 @@ extern "C" { #[derive(Debug, Copy, Clone)] pub struct roaring_uint32_iterator_s { pub parent: *const roaring_bitmap_t, - pub container: *const ::std::os::raw::c_void, + pub container: *const ::core::ffi::c_void, pub typecode: u8, pub container_index: i32, pub highbits: u32, @@ -753,23 +752,20 @@ extern "C" { ) -> u32; } pub type roaring_malloc_p = - ::std::option::Option *mut ::std::os::raw::c_void>; -pub type roaring_realloc_p = ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: usize, - ) -> *mut ::std::os::raw::c_void, + ::core::option::Option *mut ::core::ffi::c_void>; +pub type roaring_realloc_p = ::core::option::Option< + unsafe extern "C" fn(arg1: *mut ::core::ffi::c_void, arg2: usize) -> *mut ::core::ffi::c_void, >; -pub type roaring_calloc_p = ::std::option::Option< - unsafe extern "C" fn(arg1: usize, arg2: usize) -> *mut ::std::os::raw::c_void, +pub type roaring_calloc_p = ::core::option::Option< + unsafe extern "C" fn(arg1: usize, arg2: usize) -> *mut ::core::ffi::c_void, >; pub type roaring_free_p = - ::std::option::Option; -pub type roaring_aligned_malloc_p = ::std::option::Option< - unsafe extern "C" fn(arg1: usize, arg2: usize) -> *mut ::std::os::raw::c_void, + ::core::option::Option; +pub type roaring_aligned_malloc_p = ::core::option::Option< + unsafe extern "C" fn(arg1: usize, arg2: usize) -> *mut ::core::ffi::c_void, >; pub type roaring_aligned_free_p = - ::std::option::Option; + ::core::option::Option; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct roaring_memory_s { @@ -785,25 +781,23 @@ extern "C" { pub fn roaring_init_memory_hook(memory_hook: roaring_memory_t); } extern "C" { - pub fn roaring_malloc(arg1: usize) -> *mut ::std::os::raw::c_void; + pub fn roaring_malloc(arg1: usize) -> *mut ::core::ffi::c_void; } extern "C" { - pub fn roaring_realloc( - arg1: *mut ::std::os::raw::c_void, - arg2: usize, - ) -> *mut ::std::os::raw::c_void; + pub fn roaring_realloc(arg1: *mut ::core::ffi::c_void, arg2: usize) + -> *mut ::core::ffi::c_void; } extern "C" { - pub fn roaring_calloc(arg1: usize, arg2: usize) -> *mut ::std::os::raw::c_void; + pub fn roaring_calloc(arg1: usize, arg2: usize) -> *mut ::core::ffi::c_void; } extern "C" { - pub fn roaring_free(arg1: *mut ::std::os::raw::c_void); + pub fn roaring_free(arg1: *mut ::core::ffi::c_void); } extern "C" { - pub fn roaring_aligned_malloc(arg1: usize, arg2: usize) -> *mut ::std::os::raw::c_void; + pub fn roaring_aligned_malloc(arg1: usize, arg2: usize) -> *mut ::core::ffi::c_void; } extern "C" { - pub fn roaring_aligned_free(arg1: *mut ::std::os::raw::c_void); + pub fn roaring_aligned_free(arg1: *mut ::core::ffi::c_void); } #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -983,7 +977,7 @@ extern "C" { #[doc = " Perform internal consistency checks.\n\n Returns true if the bitmap is consistent. It may be useful to call this\n after deserializing bitmaps from untrusted sources. If\n roaring64_bitmap_internal_validate returns true, then the bitmap is\n consistent and can be trusted not to cause crashes or memory corruption.\n\n If reason is non-null, it will be set to a string describing the first\n inconsistency found if any."] pub fn roaring64_bitmap_internal_validate( r: *const roaring64_bitmap_t, - reason: *mut *const ::std::os::raw::c_char, + reason: *mut *const ::core::ffi::c_char, ) -> bool; } extern "C" { @@ -1136,20 +1130,20 @@ extern "C" { #[doc = " Write a bitmap to a buffer. The output buffer should refer to at least\n `roaring64_bitmap_portable_size_in_bytes(r)` bytes of allocated memory.\n\n Returns how many bytes were written, which should match\n `roaring64_bitmap_portable_size_in_bytes(r)`.\n\n This is meant to be compatible with other languages:\n https://github.com/RoaringBitmap/RoaringFormatSpec#extension-for-64-bit-implementations\n\n This function is endian-sensitive. If you have a big-endian system (e.g., a\n mainframe IBM s390x), the data format is going to be big-endian and not\n compatible with little-endian systems."] pub fn roaring64_bitmap_portable_serialize( r: *const roaring64_bitmap_t, - buf: *mut ::std::os::raw::c_char, + buf: *mut ::core::ffi::c_char, ) -> usize; } extern "C" { #[doc = " Check how many bytes would be read (up to maxbytes) at this pointer if there\n is a valid bitmap, returns zero if there is no valid bitmap.\n\n This is meant to be compatible with other languages\n https://github.com/RoaringBitmap/RoaringFormatSpec#extension-for-64-bit-implementations"] pub fn roaring64_bitmap_portable_deserialize_size( - buf: *const ::std::os::raw::c_char, + buf: *const ::core::ffi::c_char, maxbytes: usize, ) -> usize; } extern "C" { #[doc = " Read a bitmap from a serialized buffer safely (reading up to maxbytes).\n In case of failure, NULL is returned.\n\n This is meant to be compatible with other languages\n https://github.com/RoaringBitmap/RoaringFormatSpec#extension-for-64-bit-implementations\n\n The function itself is safe in the sense that it will not cause buffer\n overflows. However, for correct operations, it is assumed that the bitmap\n read was once serialized from a valid bitmap (i.e., it follows the format\n specification). If you provided an incorrect input (garbage), then the bitmap\n read may not be in a valid state and following operations may not lead to\n sensible results. In particular, the serialized array containers need to be\n in sorted order, and the run containers should be in sorted non-overlapping\n order. This is is guaranteed to happen when serializing an existing bitmap,\n but not for random inputs.\n\n This function is endian-sensitive. If you have a big-endian system (e.g., a\n mainframe IBM s390x), the data format is going to be big-endian and not\n compatible with little-endian systems."] pub fn roaring64_bitmap_portable_deserialize_safe( - buf: *const ::std::os::raw::c_char, + buf: *const ::core::ffi::c_char, maxbytes: usize, ) -> *mut roaring64_bitmap_t; } @@ -1158,7 +1152,7 @@ extern "C" { pub fn roaring64_bitmap_iterate( r: *const roaring64_bitmap_t, iterator: roaring_iterator64, - ptr: *mut ::std::os::raw::c_void, + ptr: *mut ::core::ffi::c_void, ) -> bool; } extern "C" { diff --git a/croaring-sys/Cargo.toml b/croaring-sys/Cargo.toml index 04af8e4..59405b1 100644 --- a/croaring-sys/Cargo.toml +++ b/croaring-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "croaring-sys" -version = "2.0.0" +version = "2.1.0" edition = "2021" authors = ["croaring-rs developers"] license = "Apache-2.0" @@ -9,12 +9,10 @@ readme = "../README.md" documentation = "https://docs.rs/croaring-sys" build = "build.rs" description = "Raw bindings to CRoaring" +categories = ["no-std::no-alloc", "external-ffi-bindings", "data-structures"] [features] default = [] -# This feature is now a no-op, but we keep it for backwards compatibility -# pre-built bindgen is _always_ used -buildtime_bindgen = [] [lib] doctest = false diff --git a/croaring-sys/src/lib.rs b/croaring-sys/src/lib.rs index de17745..717f013 100644 --- a/croaring-sys/src/lib.rs +++ b/croaring-sys/src/lib.rs @@ -1,3 +1,4 @@ +#![no_std] #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] diff --git a/croaring/Cargo.toml b/croaring/Cargo.toml index 060fc0c..a135dc5 100644 --- a/croaring/Cargo.toml +++ b/croaring/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "croaring" -version = "1.1.0" +version = "2.0.0" edition = "2021" authors = ["croaring-rs developers"] license = "Apache-2.0" @@ -8,13 +8,16 @@ description = "Rust wrapper for CRoaring" repository = "https://github.com/RoaringBitmap/croaring-rs.git" readme = "../README.md" keywords = ["RoaringBitmap", "croaring", "bitmap"] +categories = ["data-structures", "api-bindings", "no-std::no-alloc"] documentation = "https://docs.rs/croaring" [features] -default = [] -# This feature is now a no-op, but we keep it for backwards compatibility -# pre-built bindgen is _always_ used -buildtime_bindgen = [] +default = ["std"] +# Include alloc to get features that depend on an allocator (treemap, serializing to vec, etc) +# enabled by default +alloc = [] + +std = ["alloc"] [dev-dependencies] proptest = "1" @@ -22,8 +25,7 @@ roaring = "0.10" criterion = { version = "0.5", features = ["html_reports"] } [dependencies] -ffi = { package = "croaring-sys", path = "../croaring-sys", version = "2.0.0" } -byteorder = "1.4.3" +ffi = { package = "croaring-sys", path = "../croaring-sys", version = "2.1.0" } [[bench]] name = "benches" diff --git a/croaring/proptest-regressions/lib.txt b/croaring/proptest-regressions/lib.txt new file mode 100644 index 0000000..8b81808 --- /dev/null +++ b/croaring/proptest-regressions/lib.txt @@ -0,0 +1,7 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc 91d6a6fbae74bcb91989fb9abbd433778d75e68f3feada1dffa55c161eacaddf # shrinks to indices = [891356785185887597, 5931734396597637553, 1937949831787240042, 7817287975427563808, 16438273333826779968, 8032238103515303638, 6202491848071020099, 16480544353906349312, 15237681986118120453, 15279857918486643866, 17076761052138227417, 11157520221629981390, 13447005396530794871, 3296316096390312051, 13530615960501846081, 1019926300733416809, 1428288626726193319, 3421864929269945931, 4289314971578290264, 5182182495686383528, 11345965420221183142, 11218958036839954355, 17256921056126065291, 754825225965953981, 5189596795032457787, 1028092298873689730, 14202685879807725355, 6242568359650025507, 2256058200745878123, 4296241698325660395, 3410023410716467640, 875897966385681423, 921170346872456457, 15750487067380963950, 3497511373654561964, 10297581404534941938, 6679758043858687763, 15051405053011011337, 12310330784976325039, 4379069120671709769, 168161843284301352, 13225082938073629510, 3235565105585626607, 14497434658801788761, 9781332594899718014, 17312984080807505693, 9578856087808723856, 8643144330714844316, 4203348687523955697, 15874765121101141700, 8265452977541111632, 11852370847027154938, 16645283361687650519, 12766824022702864673, 1761735195149307202, 1816201379364648440, 12671120149658310796, 6106286842617631756, 1937150303318386288, 13076577135757657119, 16601920704953870479, 15786797093450329193, 17448061282055610546, 13162289723978614981, 10979440865181386480, 17433785016994053244, 5088124313985325558, 13611237765908768820, 16883091809723301415, 1124154688414924243, 14572024942733249338, 11700568462804235994, 9943739298406554372, 10215089061178365367, 14722503629670904165, 12781899231260531357, 10047296535285808959, 925265218884318605, 575185344214100932, 4805980983984772985, 3691617504636187292, 877131243098728292, 8451304936536131461, 4722146967206851361, 8502754709637801928, 17840671719110386229, 6188352207507215725, 17198245725349645471, 3661163110449690374, 6924176236904465569, 15771085923081733187, 12981766983357127705, 5772108547242630515, 14823602377760111065, 4932059664738774527, 180109782639117374, 16574012737589900321, 769993308062143957, 16130923087710590742, 8164606636605768183, 14136539666737210600, 2423720975099544828, 13993104626330902807, 7156474502313303812, 17708250603431514828, 15987448051803825793, 9429082776116060491, 3297319743173056955, 3877270006423288402, 12827547156910427689, 2523556729758504878, 8059696217706387849, 2783789660451893114, 10928677573026352336, 6999288885940565575, 3931945073856761243, 11502405017993551465, 2882770300914319397, 9768501719682729355, 8260291690201205257, 9179943655845640038, 5166683982422078902, 16196496497088816465, 6017049731719313078, 3866869981589874402, 18444655228661369858, 6744830295944179474, 7034541015821781169, 14411771846523571550, 1138306694341755375, 599807214417461608, 11151681681234564821, 1863366468556457786, 16003768432968392126, 17487837621224713095, 11159950906980476478, 9420307918112472870, 2059430348797585416, 7974121883225819006, 10133599097214561921, 18139594061367488215, 4978494618346324309, 4385205694716279848, 17586478850626722704, 17956613665744136507, 16683928813894190527, 11275547753466387725, 10166581051036655745, 15231480324661798277, 13804040930853974620, 11655350445623603429, 10921211510422041329, 6135994797301129412, 14982015243409287561, 15793452577130031281, 3522423108282496001, 4555275520845306526, 1804446945313414039, 5179565386456902627, 15755135183656520602, 1252777920838482811, 37289348370099483, 3208262970266908942, 18427503935254542758, 9999579088963114506, 9208709703725086932, 9626465666729925932, 17369913047763515825, 6443861647066840985, 8932621128622082749, 5748171145709993384, 11424174698992174767, 10172015900192994547, 11433567765581236519, 1086184475740188478, 9952979091860146942, 7426026852704179852, 8279973222861734992, 14193993593772758285, 1686765319395788036, 14018940108919779248, 7715969477797857307, 11413532801354507517, 1597392072607655826, 272013932628772663, 4345549829872127638, 2100039165133305818, 14113817615913933000, 3276372874813514393, 1897197145913323666, 6526943137727225079, 6411555506877910948, 7622653326985906110, 1096664872524692706, 14283594024561852142, 12092384137553389853, 714324027911586423, 15633686985994736562, 5718536766830500291, 9351525542756113640, 914379128193971065, 14576982215961747203, 4120251290851363920, 7113900823459836891, 15559773928007247514, 17585484251233217109, 7824048763313655984, 7050684737462226356, 1276454782699868898, 4061416948536392264, 3812031600118081824, 8733398519916807461, 8594731313289021464, 9619273888147211107, 17472119534332371960, 10048649640269624758, 901012827489310058, 10484469648797407089, 2755908873980657193, 7691739295949932613, 2140841525214762808, 17603223487482758601, 13906531886368104725, 16865267079014706085, 12740839835820334440, 8761982719577371197, 8807702059985671941, 11168951153913654606, 16033737815415475790, 15298714988589971182, 13628635598228421364, 10611773176068380930, 1672799571460921594, 11206125966653709303, 279517106188284122, 17738278125338278080, 13669385933774073005, 7955235861206703773, 4928603370666485453, 4372098807087997034, 12746601307648574815, 2052198754109494722, 5198481642165138694, 16874946335522887978, 16964652353913506705, 14513138471080425249, 11867229899051114408, 17394340412304495916, 717498470554262621, 15126234518588842217, 15263613088206393834, 15235445838033878853, 73449903979592062, 15936118993795084335, 14879131504242280703, 5963718896456039110, 11200498580931211208, 6764482283273195509, 17600822257423175566, 12910582470984732165, 9066691603829110135, 13493055768309298333, 11599612665760334746, 17194189120667234945, 8535168394075950612, 2602545793097611139, 4519220462559198596, 6072643704007835488, 2076976770123191985, 10326973602064792534, 4697120410269802530, 14790776628756764400, 8887405147212413469, 2259531979060394344, 2881064747810372412, 6617397478763197987, 1180410070110521591, 5035674153385518118, 14321928475694308720, 14207705688113991579, 17578977670833103841, 15118106706914695119, 13432294910050866969, 7612404407883729937, 10710526445107774447, 10434572181296564807, 16897633015996358472, 13072467751657836350, 9143140305532484139, 1004141019033003883, 5860089853929976216, 1743616796104950956, 15669511511651677475, 13805105278848279672, 2273797609988514950, 12013969120759851668, 5826553463524079961, 14910260677276542005, 385250834797304085, 12740648440812437866, 278016417598049600, 17646197681790870415, 15984455078770830524, 17894721124550862217, 3592684011460004539, 16372254388141675482, 2573858466163229298, 8463890577008200000, 7454023868342913567, 2886521977302779411, 9310029505422032134, 14432503569781735723, 8066870800708655976, 2057940958800476143, 1134724706566660872, 1032069408061300071, 6357553583728862961, 16167070733725038213, 3442426233852050103, 9995616447556590877, 8475672035509167553, 6050673072699610858, 8025038107131116992, 12245899614368588229, 15841954548215962369, 11240178522682478321, 14342424863810323170, 11888862389485407210, 1929896471199851394, 7386992932704136925, 14989063489267806428, 9574419202607897552, 503904824692421494, 11093273139653117513, 9714944636696942494, 11932116761979219945, 180625363575424877, 2003317946953212984, 14877748014834888805, 8061909820945658898, 15976080864240627467, 8591523465364400700, 6900705284926604695, 4001318244806583275, 4227029053047393435, 1427055150654826912, 12722328828760687460, 1404010781791675188, 17094031695599580299, 13496927728393163493, 17919073594126696238, 3298869950838253713, 8827810089759127047, 18329527667771023360, 11651872207757655705, 12624069971315611562, 12043919014251364327, 207955801984516850, 8203450809406356361, 15315585225245605261, 4045078565944452411, 16895323897040576467, 17270841806378050643, 4620791957479864083, 17124981672620352895, 15719023359046692619, 15638204947757227844, 170841243263937645, 1300490789206150751, 4054569264893250978, 7595165887846591227, 15040544726911841891, 2833187587129263429, 9063331466397321479, 6687265798534897314, 6902036305021714243, 1951317599241297749, 15202861599449684478, 16782694997843103468, 9083443756218593114, 5983780197724728045, 8128091615212671211, 14383493239243447291, 17627589585555113844, 9936751424723718756, 2896377835572587605, 13815842736530349775, 18019790752421622313, 8631954223328896715, 18013156702155922225, 12403547374068473289, 6693428679235484833, 11512226148352691012, 3529282826480833623, 614193917466926018, 8600399372456476234, 6877268584266907377, 14483024536513994093, 6581238678359133426, 11177474730921628813, 13004795348660576828, 2698689637647723810, 7945683206800545262, 3896329842000604952, 6091254727798586676, 10016803487303742210, 8927259754531376616, 4809387664233930298, 16163426157916178524, 3721130141243591272, 1510580194615974286, 5757226784896472269, 3989008699476130225, 10632620249131548053, 13305828807129665681, 4748971759551433769, 10983692635326610935, 6727033927830422864, 9489198259830077650, 3653485388353277977, 11564115750582673356, 4528658118581210170, 10021199216996153615, 6135558069043182760, 13886622255193027448, 3336549964285714929, 11549713303356897758, 10747194695506216529, 17085319256166153359, 7530047129450228168, 1975127965813512451, 9338883640614554203, 2207760281674795785, 17841860384785805121, 8808428790389701066, 11733006483564504784, 14822398668134457132, 1703509428722442255, 16423649558240076239, 11373406654383293348, 3458661594767155187, 7880090146933132518, 3260990414412816711, 13562225473475944050, 18290377040441540971, 11008992437539984384, 16122637472547238824, 10481783677055203316, 6049820371253563760, 12556452704382080570, 6784475292603877866, 14368819732565695461, 17078228842906849520, 12833078633342240703, 14260213084345491116, 11956523650900277310, 15378660804716901102, 3302312643386111498, 2685844228118182208, 9511706301518170238, 4529692942779685463, 6211452731169969582, 14121001473403064266, 7086869375924492497, 1019346862930445198, 13553715340113003990, 6313119116814800305, 8052984698573414937, 7209347201893269351, 960421206066283813, 176991598871928845, 13471247803327459983, 7537573047672634684, 98024401869298782, 16102746598374204252, 7635780830368527210, 4660021315964734034, 3894610271555663207, 14590449164200288832, 14199373063996878525, 14077027643785061838, 3756764178435796238, 14860366266301648497, 11383439683225763230, 13996178978378133605, 15314141848020094580, 4429706938606829499, 15531140980236763684, 10246879304552553114, 3047719950084476244, 16140742151113319213, 12476771349659400723, 3708297363576705353, 3924727900151704029, 871062190099617852, 17803102609725324688, 371794844279433099, 16374385867119081758, 2335064444713113688, 10553929963800419752, 3462384916272674229, 16934817176005822380, 11605278032517243452, 15144222093478263228, 16555344391186726375, 6571341779632972420, 18265870338297203476, 9561457223541786727, 3959301353946309525, 14282416180601195641, 2002091491359682459, 13157302344537743503, 8573533028720559870, 5843608745891290847, 9146365756126030370, 8159229917324065907, 3941841516135303966, 17189567179701577450, 5830039402601577836, 6270272634969765171, 3040974543532036622, 6236269050221526689, 6183223833097427692, 8263944302562551636, 8699791396700812172, 18307277899477817117, 15839306880628866260, 317162558560304858, 1528107031191785162, 17030895361693066825, 18082469166764448726, 11130718178084266948, 18004997720462071553, 11186041950334868665, 1777873940978929110, 3983728734543974648, 8282564002766721138, 12738332020864911948, 2880605997419522570, 1255265113921083222, 6099450798776769415, 15829077045319748510, 7940579651167032654, 9409803915578766682, 2838901562132257215, 3900966879530158971, 4106251949129065455, 9130415874528034191, 648229863726443762, 1670207387392639063, 5955284985443144815, 10593215639177252098, 6792015016894228721, 9766558625148689766, 14361359294853068030, 3565376551695198767, 9801226839522337438, 11208170812283461817, 4648817380541936170, 9236978865325893372, 17528606266758808519, 513326650241201767, 11246520289177578679, 1109097312318920878, 18258754127340454172, 18013701547705048739, 10915691888056180481, 4659377727357817226, 2613006719582638958, 16393819955836347976, 8680172404726726960, 8864589494453480226, 10949267800373340295, 10300193271093310285, 8439599222322638480, 16609868954177046181, 10665539825642025531, 12914931093123367203, 15320779408569606118, 15086577671381095819, 14839749047880964538, 15067376001107154127, 2907340920019760870, 12803047345416602092, 10001631307516976297, 4171280154772523432, 3804201734042398625, 6065733314408015453, 7161668375246433049, 18053923611691983179, 561782565437037240, 1901416169613658318, 12447687873908397479, 1920822181349067172, 2678738351110925215, 4976285402318362198, 16906855205272848640, 490084096652595272, 11404318183316194539, 24183860739367213, 8560992693204075489, 6950172233581145569, 4392170514653613545, 13456402836016194035, 3461487299243751030, 689045308274408754, 17255687418581269803, 6712439007268996848, 2536716377798694351, 8024224131677163703, 10772980337192647339, 9288282518767118339, 3432239351125569646, 15278702775605856950, 13242713789032973493, 4282219818532846405, 10075530677670944943, 6485816136966172354, 10220376261919023358, 8895190287208611818, 18051834690500441969, 11524648781189468477, 3964280915931678997, 3013607292646383136, 1721580637383090655, 5066500679492057978, 15727946476993810529, 8380963148881775917, 7653340120375144249, 4145107636458983773, 2570669985881944574, 16685096779047006021, 10270273863827711277, 13194309744795475170, 18231676805238527661, 7945118754870498185, 11101843976166485956, 5205022832241302881, 9565596625330824188, 7827781414821594448, 14437912768667226253, 34035692283010206, 17219033859803125241, 1783416985886664233, 15382553796188475072, 15330704150236414447, 10065851731532396132, 16352611578932905216, 4046694528545083232, 13790526835535272237, 2416911232033516883, 14986902890858991730, 4209126569001233617, 16801315926696303202, 950194730463290982, 3433010267086726967, 7926604904113943138, 7350970978026875786, 4938692546032136505, 5942171594857905229, 2088465556805866198, 3800132978422269345, 754130267759647550, 9735910111412561993, 17334720367963887491, 3094316966493785139, 10872317107123608317, 10828418561293023503, 12463254462448465602, 13070678981559893419, 1487699321195762521, 12025651224017597782, 7472310685876226913, 7308084995772786806, 2445958027375153604, 13509183881878025906, 8778857611476529568, 890870391604072318, 4623474561088628216, 5091559576743392447, 7250649772620237597, 2445932593732685181, 9062229802512167922, 15365215300972025512, 15285997301271077376, 16216715578384280596, 10153004934279731037, 1095830492912076391, 18270018487118293295, 12678783966350401982, 14174021061215640558, 10943503186490259392, 17054488109206516544, 15603213030215338912, 5047687136205313379, 14302136728919073562, 17545650358329179844, 12535394746474337992, 3612761276331234999, 686919480536948157, 9756569229066745305, 1625846666056212025, 14233194119881441866, 2538811525496960757, 11841378454461185572, 7792346212523349081, 2114748474922774949, 6409789453057324440, 6688018784198393125, 11434390165133878696, 13309111365635283998, 13532036590704305144, 15483205231705706250, 15075182908887073818, 14817216815620865051, 5493422630000058707, 16855021235575705, 10204428478361297179, 65232249287887956, 5640775984923864986, 11761323060263748908, 10966523370821192133, 8100252595407074064, 15518547862126200878, 4081164541748717586, 16259643937677369498, 9203429817413753177, 4141663776299035658, 13703031494372773687, 306982364817286335, 551885207197774125, 9690531049373043885, 6020629284782664854, 3891447704537113679, 9394367442902883572, 2114189738873578280, 4291117566882354104, 6320579641190520184, 773175803117679733, 9175337008639199245, 7963436626387281669, 11493405643520721212, 14060645231397942047, 2811157189145604319, 701527399437128016, 1872361597801615526, 8152001963057239058, 464902701816337644, 5352472106790623592, 6308646629286080472, 9388713082291375544, 11498884691945356036, 4879636656530844763, 9634546002057155283, 9035859147590936847, 16075249500047371102, 1899555818491418424, 14326310546021516265, 16160707537042490381, 14700606760579584209, 2274846588585916075, 15755219564225502085, 17196932689771815840, 14384339421225057804, 1879402649210439643, 17450568678471796689, 10626307473422688774, 11336531185397924653, 3958577569330001858, 715912493244829478, 9337717448447798798, 8831892793466818909, 11063469246165521453, 4299611704082045832, 9650220259349365066, 346614389743767141, 15660522123643100975, 14765248958283687132, 16829456276206564179, 16889530725193564191, 13854889856489929493, 4933902245683208188, 17568863345096623976, 12036921008211084900, 4586034411689234448, 11020950405991839943, 1950476580753995480, 9747034017296940779, 9668699735021669417, 3235063483199470721, 4804550330616912683, 8588951524135350251, 4321187797487575489, 11053147065786649939, 18439526185853851601, 10167283570578913682, 493741088429182953, 17171703973264907601, 14945014317761830021, 10579368061560178750, 1100198140902608796, 12112212196922601497, 16210154701327365553, 9368004675068292248, 18306620330122607396, 3442392914213944032, 2073163236365405739, 13172620426841292372, 4475978989113136376, 10856596996880378922, 1943857606913970638, 12513862129563053833, 8698153018036257481, 15027821408918482575, 4948246312817855025, 3657727966950328578, 17180851359208819647, 16694365608139716575, 11898391065775677320, 15880063960642191708, 15060810901685700210, 14099273793539773228, 16767900353273515125, 6675162846862289579, 3279245364039452251, 15512278443188003883, 18365911801757777707, 13980736354216976819, 7220398545875475374, 14693858615149795825, 13275698868600913064, 9606508338978084683, 13229229454599600393, 443661921804327145, 17608936171817310588, 11715921537107273291, 18314150559659512621, 8143302977630557587, 1357248461704514597, 12245482707431363857, 7273509184914030198, 11260747347123510546, 7410080246589657193, 1153879065331749321, 18087874270264159659, 8961403161199892647, 16318669753944905649, 4565756147887956962, 12505281138964642760, 4945150459425216349, 9936249108234839237, 917371432593047674, 13869722986315889825, 2681467240463349021, 11351710567279650517, 4948766246558688937, 15560834442990603058, 748969605788516390, 4534203812250612821, 5573892093473365257, 5677313032629313111, 13936562352489412010, 5315698916770510148, 8102355394561691438, 15491671231618863931, 17031827074977365945, 6485781450552106796, 9661463477783078131, 14495444589829103412, 8473168869522079020, 6937895025805585758, 1750353792347383473, 16881804084623889856, 2670656010572459436, 1128860117797284624, 11182866049914631894, 6277200971979526298, 599732074624198492, 8561627300864818640, 9676399923948533499, 7957669049293253066, 2779582884149411615, 11380365183266875834, 319138129718872811, 9790542796543570584, 16395883953132400545, 4546963482290036583, 6382886952945126451, 3427109914991269070, 11344215488151184823, 13913777710688076716, 1099685578507724567, 9199005566261205609, 11566208663489472850, 13231332944890377055, 7526646087499288755, 14456722416047442237, 11676835275519610912, 12514947148362782452, 18024873507861426324, 16102625004604197514, 11954869559037422379, 18444075596556381108, 18333128061533247961, 6238129318963066063, 8840504229347449380, 14734849802031406385, 7129179048302730548, 17261516472345682650, 4590089141163438641, 7131760081259107867, 3580794664559545822, 8628109919991703764, 1059103022362315663, 6987497394970971541, 8307461999261521024, 3184039545175172033, 16621231945589911388, 7864822667803195504, 8733557273986697626, 17591938975732502719, 9752453933511175934, 10663817373634223100, 2679922276209308336, 8005407914967970782, 4553890057273040769, 6542007606527898010, 11055984307642801162, 2677428844586991303, 14559750421103150250, 4338074021799698558, 2434021928327607095, 15168838893096803145, 8953237775569703864, 12166271920473341557, 9220472584239475570, 12117155726747595722, 15984592060717228321, 5421933509917462762, 12224684384642439420, 9692004873584953482, 11322042641248181439, 2244631540106672276, 11578784711884485694, 13850943916163913544, 13618912145144808075, 13355400608225477374, 15138462881799398231, 10401181676257976280, 14109911732314410137, 8959921023375120235, 18395350869344948750, 1976277310832926480, 13120773104052504893, 16563236312127351173, 14710551883813849653, 7792669362242397931, 15109990150606972684, 11754211661844256632, 11098135512749248630, 15124036024878216717, 10002567401423065225, 4827171069930451037, 7578757651114066954, 18210175495378903913, 4967544208314998371, 1360450089809350450, 8829974313279695721, 3843509122550571086, 8869551084769556718, 4633864078188926987, 7509795860144355480, 594926377715008397, 2270589102570850923, 125182487837501932, 4234405032894257239, 9558173093421095636, 7219104200949051507, 12047933684815309881, 558032799903841623, 6089797139857549285, 16327378294640787105, 9732031820326402438, 18342684499758511151, 16678644940360302226, 637797809916022277, 5175711335334669949, 16387195705970665554, 10330785016458649140, 7921194206219568599, 16839352561604602837, 51143575565297326, 5906739763986832699, 11952874873646231124, 2355863491788141635, 12592029083602900130, 15511619931262543760, 7949391145248406717, 5419874143704026987, 13852657506116783922, 11414449991254198122, 15436985369114896697, 8947028007955232088, 8770488301086714569, 16391220872665251577, 8576194687630430200, 12507149783249188255, 12691006902355672872, 2597144236190346265, 11774001998461755136, 3110677368431288177, 33952189892572219, 17550214496360771980, 5358751643586740366, 1464357713120680814, 1790506407246953059, 8574012362536950035, 13808670892906068564, 5903109762906002491, 7278099819509899826, 13004786022735082034, 3616753368561586872, 3377124878218327788, 2594055515235060716, 16164854351150420243, 4725054205976531173, 13599925081485387968, 7780355800922861282, 430130067219121296, 16937403485927997878, 14031595824631562316, 1465248007424772673, 6097788252219404491, 5733334423368457285, 5978898368137804743, 4632039084480768254, 8290310474174331589, 7478904951944097220, 13555989204955951710, 11416902165989402160, 1366139189509160729, 4253296930232014929, 18128171599210579680, 11749348304677101719, 3473926777328610501, 12979533540974115262, 14558264507086590743, 4261627195464610452, 10805234484119666363, 6814692242542601192, 4796037701692300512, 16301080341555945374, 7653905424158885663, 6346009793259885355, 11896636484656877337, 17149461039194243468, 3764970482606376989, 4565748591175297141, 18185666634758092687, 12283137617088577110, 11771336773735392184, 13902755936551481927, 8192739963281002129, 447993796021626821, 885707879501419479, 1256622458609363677, 6580419296268761504, 1506870958365021810, 340988945520896959, 6532155061756924171, 2286231482165136376, 7535368592373328373, 9104846858636290976, 12354613518243363283, 6575034474405880943, 4121821864650454871, 3717021766521903372, 7650630893207026880, 11407923974412492591, 11546918380933497990, 6346379490786629840, 4496164348708239677, 15938716621239888646, 1623149391058580519, 678433149980301617, 8021969710380724014, 6512235531862522236, 9602856905587839305, 12377698637044489755, 10642769959422530080, 7999339155036643386, 6986576809181039530, 16918233869441549115, 16203751405332413786, 1183484787514716911, 5948243353991647804, 5771186592354117640, 8546948980197680881, 14139807101983481687, 15503766813603041258, 13652482422695577258, 17039198734100565101, 12443617397623746368, 4855449690596629651, 3614672267935409105, 6452345013580577494, 17152649922661780334, 7462261348697443434, 7790475602146717893, 11486221111585861064, 16856257883604887707, 16225677545955757169, 11271975605513109872, 2627271083281442525, 13261935927838209705, 10454872832160970095, 8845180884298744181, 12818357182439388194, 11285338392144416455, 10207219087902146837, 18284572586676561719, 3028716463659879811, 12570077357180927544, 11318357674745754719, 1958144591548952270, 597013643303149062, 834648479240300076, 848482958808556072, 3955758077386683344, 9480412685811950332, 1503699957417322725, 6304208425462173850, 10472384295504052074, 12722511842587442669, 4926129238544188906, 1306345126121079760, 17997928849474492145, 10997641282427554335, 11383987564603237175, 8107525354595214187, 14153722224252900048, 2418359490495524798, 380619871753881278, 8139298885519440213, 14943224831023661439, 12490812559320113547, 16767144852277312090, 6058172424866809714, 1645634359220638115, 5423064052648773928, 11247909230490430759, 14126142007879566734, 5058364560402299088, 10204619461846696185, 11367576179529613794, 10407416394668668060, 17488224118758638491, 11049673907902475319, 978515166737563721, 17007201833221174449, 15093585958700306053, 7989907340011088317, 11016006229520486933, 12361290100273946264, 17995330464876416812, 2418838413071936923, 10397907213006040526, 10124962682972823093, 6658884966931893162, 7883687595706666452, 3368659778959471381, 11821116915482091563, 7948748887141072803, 13810026408746050557, 14704658355377478277, 8381375980525181408, 2652792184263813611, 15101601156487790268, 144010612349451569, 14841954703099501005, 11293942561685591442, 14786428014020418907, 14134349335911802585, 2135275570804361921, 326545248987803996, 18011344609669717748, 15601260632306499739, 1972928843776960580, 7334641110686358083, 2436236604695405939, 1797082016635467423, 629097951538259478, 11197964000065204987, 492131323000078212, 655181421523532502, 1000883218738814807, 7990854916418092849, 15090931106904697488, 14274634986471045705, 10658198636720071686, 11316504228800365814, 16310590457299820735, 17734348104284528888, 6001021096180207316, 14148045645482997266, 16525909744121822833, 17780888181295029345, 10166394086830587180, 14420054289737090524, 2387773556279613493, 12876084185297020567, 8166921522304464743, 9915198664402961071, 18349050687508995808, 9267489314078290014, 16086951195278857666, 8807755801855469360, 8044715654922067437, 5808755002736986261, 3957348472434863304, 1536465950749947694, 9048000634644282975, 4935563793038614689, 172638424901955040, 7082726838658299743, 5756617759249496668, 408034446300089155, 12325404844133572189, 13492881144113209246, 18259492403821969624, 14101604051045916954, 13932945711835765356, 15405675954202233469, 17344886786964935255, 5368606591339618971, 4854865250245411167, 11707583011669253780, 16592527774786315760, 12572333489548741181, 11646451984519907612, 17352914852405859649, 5620609011791396722, 10691517964693533261, 12220257114169612988, 7949996465923939161, 65331891865974404, 10369674485839169295, 1214974211639696757, 13544045277410288888, 11208933334368449021, 8732912910359243546] diff --git a/croaring/src/bitmap/imp.rs b/croaring/src/bitmap/imp.rs index 0a0ffa3..f6f7b57 100644 --- a/croaring/src/bitmap/imp.rs +++ b/croaring/src/bitmap/imp.rs @@ -1,12 +1,15 @@ -use crate::callback::CallbackWrapper; +use super::serialization::{Deserializer, Serializer}; +use super::{Bitmap, Statistics}; use crate::Bitset; +use core::ffi::c_void; +use core::mem; +use core::ops::{Bound, ControlFlow, RangeBounds}; use ffi::roaring_bitmap_t; -use std::ffi::{c_void, CStr}; -use std::ops::{Bound, ControlFlow, RangeBounds}; -use std::{mem, panic, ptr}; -use super::serialization::{Deserializer, Serializer}; -use super::{Bitmap, Statistics}; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; +use core::ffi::CStr; +use core::prelude::v1::*; impl Bitmap { #[inline] @@ -292,7 +295,7 @@ impl Bitmap { /// use croaring::Bitmap; /// let mut bitmap = Bitmap::of(&[1, 2, 3, 4, 5, 6, 7, 8, 9]); /// bitmap.remove_many(&[1, 2, 3, 4, 5, 6, 7, 8]); - /// assert_eq!(bitmap.to_vec(), vec![9]); + /// assert_eq!(bitmap.iter().collect::>(), vec![9]); /// ``` #[inline] #[doc(alias = "roaring_bitmap_remove_many")] @@ -331,11 +334,11 @@ impl Bitmap { /// /// let bitmap1 = Bitmap::of(&[0, 1, 1000, u32::MAX]); /// let shifted_down = bitmap1.add_offset(-1); - /// assert_eq!(shifted_down.to_vec(), [0, 999, u32::MAX - 1]); + /// assert_eq!(shifted_down.iter().collect::>(), [0, 999, u32::MAX - 1]); /// let shifted_up = bitmap1.add_offset(1); - /// assert_eq!(shifted_up.to_vec(), [1, 2, 1001]); + /// assert_eq!(shifted_up.iter().collect::>(), [1, 2, 1001]); /// let big_shifted = bitmap1.add_offset(i64::from(u32::MAX) + 1); - /// assert_eq!(big_shifted.to_vec(), []); + /// assert_eq!(big_shifted.iter().collect::>(), []); /// ``` #[inline] #[doc(alias = "roaring_bitmap_add_offset")] @@ -513,10 +516,11 @@ impl Bitmap { #[inline] #[doc(alias = "roaring_bitmap_or_many")] #[must_use] + #[cfg(feature = "alloc")] pub fn fast_or(bitmaps: &[&Bitmap]) -> Self { let mut bms: Vec<*const ffi::roaring_bitmap_s> = bitmaps .iter() - .map(|item| ptr::addr_of!(item.bitmap)) + .map(|item| core::ptr::addr_of!(item.bitmap)) .collect(); unsafe { Self::take_heap(ffi::roaring_bitmap_or_many(bms.len(), bms.as_mut_ptr())) } @@ -544,10 +548,11 @@ impl Bitmap { #[inline] #[doc(alias = "roaring_bitmap_or_many_heap")] #[must_use] + #[cfg(feature = "alloc")] pub fn fast_or_heap(bitmaps: &[&Bitmap]) -> Self { let mut bms: Vec<*const ffi::roaring_bitmap_s> = bitmaps .iter() - .map(|item| ptr::addr_of!(item.bitmap)) + .map(|item| core::ptr::addr_of!(item.bitmap)) .collect(); let count = u32::try_from(bms.len()).expect("can only or up to 2^32 bitmaps"); @@ -624,10 +629,11 @@ impl Bitmap { #[inline] #[doc(alias = "roaring_bitmap_xor_many")] #[must_use] + #[cfg(feature = "alloc")] pub fn fast_xor(bitmaps: &[&Bitmap]) -> Self { let mut bms: Vec<*const ffi::roaring_bitmap_s> = bitmaps .iter() - .map(|item| ptr::addr_of!(item.bitmap)) + .map(|item| core::ptr::addr_of!(item.bitmap)) .collect(); unsafe { Self::take_heap(ffi::roaring_bitmap_xor_many(bms.len(), bms.as_mut_ptr())) } @@ -707,7 +713,7 @@ impl Bitmap { /// assert!(bitmap2.contains(4)); /// /// let bitmap3 = bitmap1.flip(1..=5); - /// assert_eq!(bitmap3.to_vec(), [1, 2, 3, 5]) + /// assert_eq!(bitmap3.iter().collect::>(), [1, 2, 3, 5]) /// ``` #[inline] #[doc(alias = "roaring_bitmap_flip")] @@ -735,7 +741,7 @@ impl Bitmap { /// assert!(!bitmap1.contains(3)); /// assert!(bitmap1.contains(4)); /// bitmap1.flip_inplace(4..=4); - /// assert_eq!(bitmap1.to_vec(), [1, 2]); + /// assert_eq!(bitmap1.iter().collect::>(), [1, 2]); /// ``` #[inline] #[doc(alias = "roaring_bitmap_flip_inplace")] @@ -776,14 +782,22 @@ impl Bitmap { where F: FnMut(u32) -> ControlFlow, { - let mut callback_wrapper = CallbackWrapper::new(f); - let (callback, context) = callback_wrapper.callback_and_ctx(); - unsafe { - ffi::roaring_iterate(&self.bitmap, Some(callback), context); + // If we have std, we can use `roaring_iterate` with a closure, and capture any panics + #[cfg(feature = "std")] + { + let mut callback_wrapper = crate::callback::CallbackWrapper::new(f); + let (callback, context) = callback_wrapper.callback_and_ctx(); + unsafe { + ffi::roaring_iterate(&self.bitmap, Some(callback), context); + } + match callback_wrapper.result() { + Ok(cf) => cf, + Err(e) => std::panic::resume_unwind(e), + } } - match callback_wrapper.result() { - Ok(cf) => cf, - Err(e) => panic::resume_unwind(e), + #[cfg(not(feature = "std"))] + { + self.iter().try_for_each(f) } } @@ -800,6 +814,7 @@ impl Bitmap { #[inline] #[doc(alias = "roaring_bitmap_to_uint32_array")] #[must_use] + #[cfg(feature = "alloc")] pub fn to_vec(&self) -> Vec { let bitmap_size: usize = self.cardinality().try_into().unwrap(); @@ -820,6 +835,8 @@ impl Bitmap { /// Serializes a bitmap to a slice of bytes in format `S`. /// + /// This function cannot be used with formats that require alignment, such as [`crate::Frozen`]. + /// /// # Examples /// /// ``` @@ -833,11 +850,23 @@ impl Bitmap { /// /// assert_eq!(original_bitmap, deserialized_bitmap); /// ``` + /// + /// ```compile_fail + /// use croaring::{Bitmap, Frozen}; + /// + /// let original_bitmap = Bitmap::of(&[1, 2, 3]); + /// // This will not compile, as `Frozen` requires alignment, and we can't guarantee that the + /// // start of the vec is aligned correctly + /// let serialized_buffer = original_bitmap.serialize::(); + /// ``` + /// #[inline] #[must_use] - pub fn serialize(&self) -> Vec { + #[cfg(feature = "alloc")] + pub fn serialize(&self) -> Vec { let mut dst = Vec::new(); - self.serialize_into::(&mut dst); + let res = self.serialize_into_vec::(&mut dst); + debug_assert_eq!(res.as_ptr(), dst.as_ptr()); dst } @@ -857,14 +886,29 @@ impl Bitmap { /// let mut data = Vec::new(); /// for bitmap in [original_bitmap_1, original_bitmap_2] { /// data.clear(); - /// bitmap.serialize_into::(&mut data); + /// bitmap.try_serialize_into::(&mut data); /// // do something with data /// } /// ``` #[inline] - #[doc(alias = "roaring_bitmap_portable_serialize")] - pub fn serialize_into<'a, S: Serializer>(&self, dst: &'a mut Vec) -> &'a [u8] { - S::serialize_into(self, dst) + #[cfg(feature = "alloc")] + pub fn serialize_into_vec<'a, S: Serializer>(&self, dst: &'a mut Vec) -> &'a mut [u8] { + S::serialize_into_vec(self, dst) + } + + /// Serializes a bitmap to a slice of bytes in format `S` + /// + /// Returns the serialized data if the buffer was large enough, otherwise None. + /// + /// See [`Self::get_serialized_size_in_bytes`] to determine the required buffer size. + /// Note also that some ([`crate::Frozen`]) formats require alignment, so the buffer size may need to + /// be larger than the serialized size. + /// + /// See also [`Self::serialize_into_vec`] for a version that uses a Vec instead, or, for + /// advanced use-cases, see [`Serializer::try_serialize_into`]. + #[inline] + pub fn try_serialize_into<'a, S: Serializer>(&self, dst: &'a mut [u8]) -> Option<&'a mut [u8]> { + S::try_serialize_into_aligned(self, dst) } /// Given a serialized bitmap as slice of bytes in format `S`, returns a `Bitmap` instance. @@ -875,6 +919,8 @@ impl Bitmap { /// # Examples /// /// ``` + /// # #[cfg(feature = "alloc")] + /// # { /// use croaring::{Bitmap, Portable}; /// /// let original_bitmap: Bitmap = (1..5).collect(); @@ -886,6 +932,7 @@ impl Bitmap { /// let invalid_buffer: Vec = vec![3]; /// let deserialized_bitmap = Bitmap::try_deserialize::(&invalid_buffer); /// assert!(deserialized_bitmap.is_none()); + /// # } /// ``` #[inline] #[must_use] @@ -943,13 +990,13 @@ impl Bitmap { /// use croaring::Bitmap; /// /// let bitmap1 = Bitmap::from_range(5..10); - /// assert_eq!(bitmap1.to_vec(), [5, 6, 7, 8, 9]); + /// assert_eq!(bitmap1.iter().collect::>(), [5, 6, 7, 8, 9]); /// /// let bitmap2 = Bitmap::from_range(5..=7); - /// assert_eq!(bitmap2.to_vec(), [5, 6, 7]); + /// assert_eq!(bitmap2.iter().collect::>(), [5, 6, 7]); /// /// let bitmap3 = Bitmap::from_range((Bound::Excluded(2), Bound::Excluded(6))); - /// assert_eq!(bitmap3.to_vec(), [3, 4, 5]); + /// assert_eq!(bitmap3.iter().collect::>(), [3, 4, 5]); #[inline] #[doc(alias = "roaring_bitmap_from_range")] pub fn from_range>(range: R) -> Self { @@ -970,7 +1017,7 @@ impl Bitmap { /// use croaring::Bitmap; /// /// let bitmap = Bitmap::from_range_with_step(0..10, 3); - /// assert_eq!(bitmap.to_vec(), [0, 3, 6, 9]); + /// assert_eq!(bitmap.iter().collect::>(), [0, 3, 6, 9]); /// /// // empty ranges /// assert_eq!(Bitmap::from_range_with_step(0..0, 1), Bitmap::new()); @@ -987,14 +1034,14 @@ impl Bitmap { /// /// // Exclusive ranges still step from the start, but do not include it /// let bitmap = Bitmap::from_range_with_step((Bound::Excluded(10), Bound::Included(30)), 10); - /// assert_eq!(bitmap.to_vec(), [20, 30]); + /// assert_eq!(bitmap.iter().collect::>(), [20, 30]); /// /// // Ranges including max value /// let bitmap = Bitmap::from_range_with_step((u32::MAX - 1)..=u32::MAX, 1); - /// assert_eq!(bitmap.to_vec(), vec![u32::MAX - 1, u32::MAX]); + /// assert_eq!(bitmap.iter().collect::>(), vec![u32::MAX - 1, u32::MAX]); /// /// let bitmap = Bitmap::from_range_with_step((u32::MAX - 1)..=u32::MAX, 3); - /// assert_eq!(bitmap.to_vec(), vec![u32::MAX - 1]); + /// assert_eq!(bitmap.iter().collect::>(), vec![u32::MAX - 1]); /// ``` #[inline] #[doc(alias = "roaring_bitmap_from_range")] @@ -1512,7 +1559,7 @@ impl Bitmap { #[doc(alias = "roaring_bitmap_statistics")] #[must_use] pub fn statistics(&self) -> Statistics { - let mut statistics: ffi::roaring_statistics_s = unsafe { ::std::mem::zeroed() }; + let mut statistics: ffi::roaring_statistics_s = unsafe { mem::zeroed() }; unsafe { ffi::roaring_bitmap_statistics(&self.bitmap, &mut statistics) }; @@ -1563,17 +1610,17 @@ impl Bitmap { #[inline] #[doc(alias = "roaring_bitmap_internal_validate")] #[doc(hidden)] - pub fn internal_validate(&self) -> Result<(), String> { - let mut error_str = ptr::null(); + pub fn internal_validate(&self) -> Result<(), &'static str> { + let mut error_str = core::ptr::null(); let valid = unsafe { ffi::roaring_bitmap_internal_validate(&self.bitmap, &mut error_str) }; if valid { Ok(()) } else { if error_str.is_null() { - return Err(String::from("Unknown error")); + return Err("Unknown error"); } let reason = unsafe { CStr::from_ptr(error_str) }; - Err(reason.to_string_lossy().into_owned()) + Err(reason.to_str().unwrap_or("Invalid UTF-8 in error")) } } } diff --git a/croaring/src/bitmap/iter.rs b/croaring/src/bitmap/iter.rs index 7925107..331e1bb 100644 --- a/croaring/src/bitmap/iter.rs +++ b/croaring/src/bitmap/iter.rs @@ -1,5 +1,5 @@ -use std::marker::PhantomData; -use std::mem::MaybeUninit; +use core::marker::PhantomData; +use core::mem::MaybeUninit; use super::Bitmap; diff --git a/croaring/src/bitmap/lazy.rs b/croaring/src/bitmap/lazy.rs index 8ccf4fe..0c3de50 100644 --- a/croaring/src/bitmap/lazy.rs +++ b/croaring/src/bitmap/lazy.rs @@ -39,14 +39,14 @@ impl<'a> LazyBitmap<'a> { } } -impl<'a> std::ops::BitOrAssign<&Bitmap> for LazyBitmap<'a> { +impl<'a> core::ops::BitOrAssign<&Bitmap> for LazyBitmap<'a> { #[inline] fn bitor_assign(&mut self, other: &Bitmap) { self.or_inplace(other, false); } } -impl<'a> std::ops::BitXorAssign<&Bitmap> for LazyBitmap<'a> { +impl<'a> core::ops::BitXorAssign<&Bitmap> for LazyBitmap<'a> { #[inline] fn bitxor_assign(&mut self, other: &Bitmap) { self.xor_inplace(other); @@ -87,7 +87,7 @@ impl Bitmap { /// bitmap2 ^= b; /// } /// assert_eq!(bitmap, bitmap2); - /// assert_eq!(bitmap.to_vec(), [2, 10, 30, 99, 100, 1000, 1001]); + /// assert_eq!(bitmap.iter().collect::>(), [2, 10, 30, 99, 100, 1000, 1001]); /// ``` /// /// The result the passed closure is returned from `lazy_batch` diff --git a/croaring/src/bitmap/mod.rs b/croaring/src/bitmap/mod.rs index c9239a3..6e4aa17 100644 --- a/croaring/src/bitmap/mod.rs +++ b/croaring/src/bitmap/mod.rs @@ -31,7 +31,10 @@ //! rb3.add(5); //! rb3.or_inplace(&rb1); //! +//! # #[cfg(feature = "alloc")] //! let mut rb4 = Bitmap::fast_or(&[&rb1, &rb2, &rb3]); +//! # #[cfg(not(feature = "alloc"))] +//! # let mut rb4 = Bitmap::new(); //! //! rb1.and_inplace(&rb2); //! println!("{:?}", rb1); @@ -44,16 +47,20 @@ //! rb3.add(5); //! rb3.or_inplace(&rb1); //! +//! # #[cfg(feature = "alloc")] //! println!("{:?}", rb3.to_vec()); //! println!("{:?}", rb3); //! println!("{:?}", rb4); //! +//! # #[cfg(feature = "alloc")] +//! # { //! rb4 = Bitmap::fast_or(&[&rb1, &rb2, &rb3]); +//! # } //! //! println!("{:?}", rb4); //! ``` -use std::marker::PhantomData; +use core::marker::PhantomData; /// A compressed bitmap // Must be repr(transparent) and match BitmapView, to allow safe transmute between @@ -91,4 +98,4 @@ mod view; pub use self::iter::{BitmapCursor, BitmapIterator}; pub use self::lazy::LazyBitmap; -pub use self::serialization::{Deserializer, Serializer, ViewDeserializer}; +pub use self::serialization::{Deserializer, Serializer}; diff --git a/croaring/src/bitmap/ops.rs b/croaring/src/bitmap/ops.rs index c7c628d..6d9a1be 100644 --- a/croaring/src/bitmap/ops.rs +++ b/croaring/src/bitmap/ops.rs @@ -1,13 +1,25 @@ use crate::BitmapView; -use std::fmt; -use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; +use core::fmt; +use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; use super::Bitmap; impl fmt::Debug for Bitmap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.cardinality() < 32 { - write!(f, "Bitmap<{:?}>", self.to_vec()) + write!(f, "Bitmap<[")?; + let mut first = true; + for value in self.iter() { + let prefix = if first { + first = false; + "" + } else { + ", " + }; + write!(f, "{prefix}{value}")?; + } + write!(f, "]>")?; + Ok(()) } else { write!( f, diff --git a/croaring/src/bitmap/serialization.rs b/croaring/src/bitmap/serialization.rs index 96e0006..1adf250 100644 --- a/croaring/src/bitmap/serialization.rs +++ b/croaring/src/bitmap/serialization.rs @@ -1,10 +1,14 @@ use super::{Bitmap, BitmapView}; use crate::serialization::{Frozen, Native, Portable}; -use std::ffi::{c_char, c_void}; +use core::ffi::{c_char, c_void}; /// Trait for different formats of bitmap serialization -pub trait Serializer { +pub trait Serializer: crate::sealed::Sealed { + /// The required alignment for the serialized data + #[doc(hidden)] + const REQUIRED_ALIGNMENT: usize = 1; + /// Serialize a bitmap into bytes, using the provided vec buffer to store the serialized data /// /// Note that some serializers ([Frozen]) may require that the bitmap is aligned specially, @@ -14,15 +18,62 @@ pub trait Serializer { /// The contents of the provided vec buffer will not be overwritten: only new data will be /// appended to the end of the buffer. If the buffer has enough capacity, and the current /// end of the buffer is correctly aligned, then no additional allocations will be performed. - fn serialize_into<'a>(bitmap: &Bitmap, dst: &'a mut Vec) -> &'a [u8]; + #[doc(hidden)] + #[cfg(feature = "alloc")] + fn serialize_into_vec<'a>(bitmap: &Bitmap, dst: &'a mut alloc::vec::Vec) -> &'a mut [u8] { + let len = Self::get_serialized_size_in_bytes(bitmap); + let spare_capacity = + crate::serialization::get_aligned_spare_capacity(dst, Self::REQUIRED_ALIGNMENT, len); + let data_start; + unsafe { + Self::raw_serialize(bitmap, spare_capacity.as_mut_ptr().cast::()); + data_start = dst.len(); + let total_len = data_start.checked_add(len).unwrap(); + dst.set_len(total_len); + } + + &mut dst[data_start..] + } + + #[doc(hidden)] + fn try_serialize_into_aligned<'a>(bitmap: &Bitmap, dst: &'a mut [u8]) -> Option<&'a mut [u8]> { + let offset = dst.as_ptr().align_offset(Self::REQUIRED_ALIGNMENT); + let offset_dst = dst.get_mut(offset..)?; + let len = Self::try_serialize_into(bitmap, offset_dst)?; + Some(&mut dst[offset..offset + len]) + } + + /// Serialize a bitmap into bytes, using the provided buffer to store the serialized data + /// + /// This method does not require the buffer to be aligned, and will return `None` if the buffer + /// is not large enough to store the serialized data. + /// + /// This is a niche method, and is not recommended for general use. The + /// [`Bitmap::serialize_into_vec`]/[`Bitmap::try_serialize_into`] methods should usually be used + /// instead of this method. + fn try_serialize_into(bitmap: &Bitmap, dst: &mut [u8]) -> Option { + let required_len = Self::get_serialized_size_in_bytes(bitmap); + if dst.len() < required_len { + return None; + } + unsafe { + Self::raw_serialize(bitmap, dst.as_mut_ptr().cast::()); + } + Some(required_len) + } + /// Get the number of bytes required to serialize this bitmap /// /// This does not include any additional padding which may be required to align the bitmap + #[doc(hidden)] fn get_serialized_size_in_bytes(bitmap: &Bitmap) -> usize; + + #[doc(hidden)] + unsafe fn raw_serialize(bitmap: &Bitmap, dst: *mut c_char); } /// Trait for different formats of bitmap deserialization -pub trait Deserializer { +pub trait Deserializer: crate::sealed::Sealed { /// Try to deserialize a bitmap from the beginning of the provided buffer /// /// The [`Bitmap::try_deserialize`] method should usually be used instead of this method @@ -36,6 +87,7 @@ pub trait Deserializer { /// /// To determine how many bytes were consumed from the buffer, use the /// [`Serializer::get_serialized_size_in_bytes`] method on the returned bitmap. + #[doc(hidden)] fn try_deserialize(buffer: &[u8]) -> Option; /// Deserialize a bitmap from the beginning of the provided buffer @@ -45,11 +97,12 @@ pub trait Deserializer { /// Unlike its safe counterpart ([`Self::try_deserialize`]) this function assumes the data is /// valid, passing data which does not contain/start with a bitmap serialized with this format /// will result in undefined behavior. + #[doc(hidden)] unsafe fn try_deserialize_unchecked(buffer: &[u8]) -> Bitmap; } /// Trait for different formats of bitmap deserialization into a view without copying -pub trait ViewDeserializer { +pub trait ViewDeserializer: crate::sealed::Sealed { /// Create a bitmap view using the passed data /// /// # Safety @@ -58,37 +111,24 @@ pub trait ViewDeserializer { /// * data.len() must be equal exactly to the size of the serialized bitmap. /// /// See [`BitmapView::deserialize`] for examples. + #[doc(hidden)] unsafe fn deserialize_view(data: &[u8]) -> BitmapView<'_>; } +impl crate::sealed::Sealed for Portable {} impl Serializer for Portable { - /// Serializes a bitmap to a slice of bytes in portable format. - /// See [`Bitmap::serialize_into`] for examples. - #[doc(alias = "roaring_bitmap_portable_serialize")] - fn serialize_into<'a>(bitmap: &Bitmap, dst: &'a mut Vec) -> &'a [u8] { - let len = Self::get_serialized_size_in_bytes(bitmap); - - dst.reserve(len); - let offset = dst.len(); - let total_len = offset.checked_add(len).unwrap(); - - unsafe { - ffi::roaring_bitmap_portable_serialize( - &bitmap.bitmap, - dst.spare_capacity_mut().as_mut_ptr().cast::(), - ); - dst.set_len(total_len); - } - - &dst[offset..] - } - /// Computes the serialized size in bytes of the Bitmap in portable format. /// See [`Bitmap::get_serialized_size_in_bytes`] for examples. #[doc(alias = "roaring_bitmap_portable_size_in_bytes")] fn get_serialized_size_in_bytes(bitmap: &Bitmap) -> usize { unsafe { ffi::roaring_bitmap_portable_size_in_bytes(&bitmap.bitmap) } } + + unsafe fn raw_serialize(bitmap: &Bitmap, dst: *mut c_char) { + unsafe { + ffi::roaring_bitmap_portable_serialize(&bitmap.bitmap, dst); + } + } } impl Deserializer for Portable { @@ -145,34 +185,20 @@ impl ViewDeserializer for Portable { } } +impl crate::sealed::Sealed for Native {} impl Serializer for Native { - /// Serializes a bitmap to a slice of bytes in native format. - /// See [`Bitmap::serialize_into`] for examples. - #[doc(alias = "roaring_bitmap_serialize")] - fn serialize_into<'a>(bitmap: &Bitmap, dst: &'a mut Vec) -> &'a [u8] { - let len = Self::get_serialized_size_in_bytes(bitmap); - - dst.reserve(len); - let offset = dst.len(); - let total_len = offset.checked_add(len).unwrap(); - - unsafe { - ffi::roaring_bitmap_serialize( - &bitmap.bitmap, - dst.spare_capacity_mut().as_mut_ptr().cast::(), - ); - dst.set_len(total_len); - } - - &dst[offset..] - } - /// Computes the serialized size in bytes of the Bitmap in native format. /// See [`Bitmap::get_serialized_size_in_bytes`] for examples. #[doc(alias = "roaring_bitmap_size_in_bytes")] fn get_serialized_size_in_bytes(bitmap: &Bitmap) -> usize { unsafe { ffi::roaring_bitmap_size_in_bytes(&bitmap.bitmap) } } + + unsafe fn raw_serialize(bitmap: &Bitmap, dst: *mut c_char) { + unsafe { + ffi::roaring_bitmap_serialize(&bitmap.bitmap, dst); + } + } } impl Deserializer for Native { @@ -205,39 +231,10 @@ impl Deserializer for Native { } } +impl crate::sealed::Sealed for Frozen {} impl Serializer for Frozen { - /// Serializes a bitmap to a slice of bytes in "frozen" format. - /// - /// This has an odd API because it always returns a slice which is aligned to 32 bytes: - /// This means the returned slice may not start exactly at the beginning of the passed `Vec` - /// See [`Bitmap::serialize_into`] for examples. - #[doc(alias = "roaring_bitmap_frozen_serialize")] - fn serialize_into<'a>(bitmap: &Bitmap, dst: &'a mut Vec) -> &'a [u8] { - let len = Self::get_serialized_size_in_bytes(bitmap); - - let mut offset = dst.len(); - if dst.capacity() < dst.len() + len - || Self::required_padding(dst.as_ptr_range().end as usize) != 0 - { - dst.reserve(len.checked_add(Self::MAX_PADDING).unwrap()); - let extra_offset = Self::required_padding(dst.as_ptr_range().end as usize); - offset = offset.checked_add(extra_offset).unwrap(); - // we must initialize up to offset - dst.resize(offset, 0); - } - let total_len = offset.checked_add(len).unwrap(); - debug_assert!(dst.capacity() >= total_len); - - unsafe { - ffi::roaring_bitmap_frozen_serialize( - &bitmap.bitmap, - dst.as_mut_ptr().add(offset).cast::(), - ); - dst.set_len(total_len); - } - - &dst[offset..total_len] - } + // Defer to the innate const on Frozen + const REQUIRED_ALIGNMENT: usize = Self::REQUIRED_ALIGNMENT; /// Computes the serialized size in bytes of the Bitmap in frozen format. /// See [`Bitmap::get_serialized_size_in_bytes`] for examples. @@ -245,6 +242,12 @@ impl Serializer for Frozen { fn get_serialized_size_in_bytes(bitmap: &Bitmap) -> usize { unsafe { ffi::roaring_bitmap_frozen_size_in_bytes(&bitmap.bitmap) } } + + unsafe fn raw_serialize(bitmap: &Bitmap, dst: *mut c_char) { + unsafe { + ffi::roaring_bitmap_frozen_serialize(&bitmap.bitmap, dst); + } + } } impl ViewDeserializer for Frozen { @@ -252,7 +255,7 @@ impl ViewDeserializer for Frozen { /// /// # Safety /// * `data` must be the result of serializing a roaring bitmap in frozen mode - /// (in c with `roaring_bitmap_frozen_serialize`, or via [`Bitmap::serialize_into::`]). + /// (in c with `roaring_bitmap_frozen_serialize`, or via [`Bitmap::try_serialize_into::`]). /// * Its beginning must be aligned by 32 bytes. /// * data.len() must be equal exactly to the size of the frozen bitmap. /// diff --git a/croaring/src/bitmap/view.rs b/croaring/src/bitmap/view.rs index 175cd02..1fa3ff1 100644 --- a/croaring/src/bitmap/view.rs +++ b/croaring/src/bitmap/view.rs @@ -1,9 +1,9 @@ use super::serialization::ViewDeserializer; use super::{Bitmap, BitmapView}; +use core::marker::PhantomData; +use core::ops::Deref; +use core::{fmt, mem}; use ffi::roaring_bitmap_t; -use std::marker::PhantomData; -use std::ops::Deref; -use std::{fmt, mem}; #[inline] const fn original_bitmap_ptr(bitmap: &roaring_bitmap_t) -> *const roaring_bitmap_t { @@ -48,8 +48,9 @@ impl<'a> BitmapView<'a> { /// ``` /// use croaring::{Bitmap, BitmapView, Portable}; /// let orig_bitmap = Bitmap::of(&[1, 2, 3, 4]); - /// let data: Vec = orig_bitmap.serialize::(); - /// let view = unsafe { BitmapView::deserialize::(&data) }; + /// let mut buf = [0; 1024]; + /// let data: &[u8] = orig_bitmap.try_serialize_into::(&mut buf).unwrap(); + /// let view = unsafe { BitmapView::deserialize::(data) }; /// assert!(view.contains_range(1..=4)); /// assert_eq!(orig_bitmap, view); /// ``` @@ -70,8 +71,9 @@ impl<'a> BitmapView<'a> { /// use croaring::{Bitmap, BitmapView, Portable}; /// /// let orig_bitmap = Bitmap::of(&[1, 2, 3, 4]); - /// let data = orig_bitmap.serialize::(); - /// let view: BitmapView = unsafe { BitmapView::deserialize::(&data) }; + /// let mut buf = [0; 1024]; + /// let data: &[u8] = orig_bitmap.try_serialize_into::(&mut buf).unwrap(); + /// let view: BitmapView = unsafe { BitmapView::deserialize::(data) }; /// # assert_eq!(view, orig_bitmap); /// let mut mutable_bitmap: Bitmap = view.to_bitmap(); /// assert_eq!(view, mutable_bitmap); diff --git a/croaring/src/bitmap64/imp.rs b/croaring/src/bitmap64/imp.rs index 9a7e2ee..f12865a 100644 --- a/croaring/src/bitmap64/imp.rs +++ b/croaring/src/bitmap64/imp.rs @@ -1,13 +1,12 @@ use crate::bitmap64::Bitmap64; use crate::bitmap64::{Deserializer, Serializer}; -use crate::callback::CallbackWrapper; -use std::collections::Bound; -use std::ffi::CStr; -use std::mem::MaybeUninit; -use std::ops::{ControlFlow, RangeBounds}; -use std::panic; -use std::ptr; -use std::ptr::NonNull; +use core::mem::MaybeUninit; +use core::ops::{Bound, RangeBounds}; +use core::prelude::v1::*; +use core::ptr::{self, NonNull}; + +#[cfg(feature = "alloc")] +use alloc::vec::Vec; impl Bitmap64 { #[inline] @@ -66,7 +65,7 @@ impl Bitmap64 { /// use std::ops::Bound; /// use croaring::Bitmap64; /// let bitmap = Bitmap64::from_range_with_step(0..10, 3); - /// assert_eq!(bitmap.to_vec(), vec![0, 3, 6, 9]); + /// assert_eq!(bitmap.iter().collect::>(), vec![0, 3, 6, 9]); /// /// // empty ranges /// assert_eq!(Bitmap64::from_range_with_step(0..0, 1), Bitmap64::new()); @@ -83,13 +82,13 @@ impl Bitmap64 { /// /// // Exclusive ranges still step from the start, but do not include it /// let bitmap = Bitmap64::from_range_with_step((Bound::Excluded(10), Bound::Included(30)), 10); - /// assert_eq!(bitmap.to_vec(), vec![20, 30]); + /// assert_eq!(bitmap.iter().collect::>(), vec![20, 30]); /// /// // Ranges including max value /// let bitmap = Bitmap64::from_range_with_step((u64::MAX - 1)..=u64::MAX, 1); - /// assert_eq!(bitmap.to_vec(), vec![u64::MAX - 1, u64::MAX]); + /// assert_eq!(bitmap.iter().collect::>(), vec![u64::MAX - 1, u64::MAX]); /// let bitmap = Bitmap64::from_range_with_step((u64::MAX - 1)..=u64::MAX, 3); - /// assert_eq!(bitmap.to_vec(), vec![u64::MAX - 1]); + /// assert_eq!(bitmap.iter().collect::>(), vec![u64::MAX - 1]); /// ``` #[inline] #[doc(alias = "roaring64_bitmap_from_range")] @@ -274,7 +273,7 @@ impl Bitmap64 { /// use croaring::Bitmap64; /// let mut bitmap = Bitmap64::of(&[1, 2, 3, 4, 5, 6, 7, 8, 9]); /// bitmap.remove_many(&[1, 2, 3, 4, 5, 6, 7, 8]); - /// assert_eq!(bitmap.to_vec(), vec![9]); + /// assert_eq!(bitmap.iter().collect::>(), vec![9]); /// ``` #[inline] #[doc(alias = "roaring64_bitmap_remove_many")] @@ -295,7 +294,7 @@ impl Bitmap64 { /// use croaring::Bitmap64; /// let mut bitmap = Bitmap64::of(&[1, 2, 3, 4, 5, 6, 7, 8, 9]); /// bitmap.remove_all(1..=8); // Remove all values from iterator - /// assert_eq!(bitmap.to_vec(), vec![9]); + /// assert_eq!(bitmap.iter().collect::>(), vec![9]); /// ``` #[inline] #[doc(alias = "roaring64_bitmap_remove_bulk")] @@ -317,10 +316,10 @@ impl Bitmap64 { /// use croaring::Bitmap64; /// let mut bitmap = Bitmap64::new(); /// bitmap.add_range(1..4); - /// assert_eq!(bitmap.to_vec(), vec![1, 2, 3]); + /// assert_eq!(bitmap.iter().collect::>(), vec![1, 2, 3]); /// /// bitmap.remove_range(1..=2); - /// assert_eq!(bitmap.to_vec(), vec![3]); + /// assert_eq!(bitmap.iter().collect::>(), vec![3]); /// ``` #[inline] #[doc(alias = "roaring64_bitmap_remove_range_closed")] @@ -722,7 +721,7 @@ impl Bitmap64 { /// assert!(bitmap2.contains(4)); /// /// let bitmap3 = bitmap1.flip(1..=5); - /// assert_eq!(bitmap3.to_vec(), [1, 2, 3, 5]) + /// assert_eq!(bitmap3.iter().collect::>(), [1, 2, 3, 5]) /// ``` #[inline] #[doc(alias = "roaring64_bitmap_flip")] @@ -757,7 +756,7 @@ impl Bitmap64 { /// assert!(!bitmap1.contains(3)); /// assert!(bitmap1.contains(4)); /// bitmap1.flip_inplace(4..=4); - /// assert_eq!(bitmap1.to_vec(), [1, 2]); + /// assert_eq!(bitmap1.iter().collect::>(), [1, 2]); /// ``` #[inline] #[doc(alias = "roaring64_bitmap_flip_inplace")] @@ -776,13 +775,14 @@ impl Bitmap64 { /// assert_eq!(bitmap.to_vec(), vec![1, 2, 3]); /// ``` #[must_use] + #[cfg(feature = "alloc")] pub fn to_vec(&self) -> Vec { let len = self .cardinality() .try_into() .expect("cardinality must fit in a usize"); - let mut vec = vec![0; len]; + let mut vec = alloc::vec![0; len]; unsafe { ffi::roaring64_bitmap_to_uint64_array(self.raw.as_ptr(), vec.as_mut_ptr()) }; vec } @@ -811,9 +811,11 @@ impl Bitmap64 { /// ``` #[inline] #[must_use] - pub fn serialize(&self) -> Vec { + #[cfg(feature = "alloc")] + pub fn serialize(&self) -> Vec { let mut dst = Vec::new(); - self.serialize_into::(&mut dst); + let res = self.serialize_into_vec::(&mut dst); + debug_assert_eq!(res.as_ptr(), dst.as_ptr()); dst } @@ -833,14 +835,30 @@ impl Bitmap64 { /// let mut data = Vec::new(); /// for bitmap in [original_bitmap_1, original_bitmap_2] { /// data.clear(); - /// bitmap.serialize_into::(&mut data); + /// bitmap.serialize_into_vec::(&mut data); /// // do something with data /// } /// ``` #[inline] #[doc(alias = "roaring64_bitmap_portable_serialize")] - pub fn serialize_into<'a, S: Serializer>(&self, dst: &'a mut Vec) -> &'a [u8] { - S::serialize_into(self, dst) + #[cfg(feature = "alloc")] + pub fn serialize_into_vec<'a, S: Serializer>(&self, dst: &'a mut Vec) -> &'a [u8] { + S::serialize_into_vec(self, dst) + } + + /// Serializes a bitmap to a slice of bytes in format `S` + /// + /// Returns the serialized data if the buffer was large enough, otherwise None. + /// + /// See [`Self::get_serialized_size_in_bytes`] to determine the required buffer size. + /// Note also that some ([`crate::Frozen`]) formats require alignment, so the buffer size may need to + /// be larger than the serialized size. + /// + /// See also [`Self::serialize_into_vec`] for a version that uses a Vec instead, or, for + /// advanced use-cases, see [`Serializer::try_serialize_into`]. + #[inline] + pub fn try_serialize_into<'a, S: Serializer>(&self, dst: &'a mut [u8]) -> Option<&'a mut [u8]> { + S::try_serialize_into_aligned(self, dst) } /// Given a serialized bitmap as slice of bytes in format `S`, returns a `Bitmap64` instance. @@ -854,9 +872,10 @@ impl Bitmap64 { /// use croaring::{Bitmap64, Portable}; /// /// let original_bitmap: Bitmap64 = (1..5).collect(); - /// let serialized_buffer = original_bitmap.serialize::(); + /// let mut buf = [0; 1024]; + /// let serialized_buffer: &[u8] = original_bitmap.try_serialize_into::(&mut buf).unwrap(); /// - /// let deserialized_bitmap = Bitmap64::try_deserialize::(&serialized_buffer); + /// let deserialized_bitmap = Bitmap64::try_deserialize::(serialized_buffer); /// assert_eq!(original_bitmap, deserialized_bitmap.unwrap()); /// /// let invalid_buffer: Vec = vec![3]; @@ -906,18 +925,25 @@ impl Bitmap64 { /// assert_eq!(first_over_50, ControlFlow::Break(100)); /// ``` #[inline] - pub fn for_each(&self, f: F) -> ControlFlow + pub fn for_each(&self, f: F) -> core::ops::ControlFlow where - F: FnMut(u64) -> ControlFlow, + F: FnMut(u64) -> core::ops::ControlFlow, { - let mut callback_wrapper = CallbackWrapper::new(f); - let (callback, context) = callback_wrapper.callback_and_ctx(); - unsafe { - ffi::roaring64_bitmap_iterate(self.raw.as_ptr(), Some(callback), context); + #[cfg(feature = "std")] + { + let mut callback_wrapper = crate::callback::CallbackWrapper::new(f); + let (callback, context) = callback_wrapper.callback_and_ctx(); + unsafe { + ffi::roaring64_bitmap_iterate(self.raw.as_ptr(), Some(callback), context); + } + match callback_wrapper.result() { + Ok(cf) => cf, + Err(e) => std::panic::resume_unwind(e), + } } - match callback_wrapper.result() { - Ok(cf) => cf, - Err(e) => panic::resume_unwind(e), + #[cfg(not(feature = "std"))] + { + self.iter().try_for_each(f) } } @@ -951,8 +977,8 @@ impl Bitmap64 { if error_str.is_null() { return Err("Unknown error"); } - let reason = unsafe { CStr::from_ptr(error_str) }; - Err(reason.to_str().unwrap_or("Invalid UTF-8")) + let reason = unsafe { core::ffi::CStr::from_ptr(error_str) }; + Err(reason.to_str().unwrap_or("Invalid UTF-8 in error message")) } } } @@ -1107,7 +1133,7 @@ impl Bitmap64 { /// let bitmap1 = Bitmap64::of(&[1, 2, 3]); /// let bitmap2 = Bitmap64::of(&[2, 3, 4]); /// let bitmap3 = bitmap1.or(&bitmap2); - /// assert_eq!(bitmap3.to_vec(), vec![1, 2, 3, 4]); + /// assert_eq!(bitmap3.iter().collect::>(), vec![1, 2, 3, 4]); /// ``` #[inline] #[doc(alias = "roaring64_bitmap_or")] @@ -1147,7 +1173,7 @@ impl Bitmap64 { /// let mut bitmap1 = Bitmap64::of(&[1, 2, 3]); /// let bitmap2 = Bitmap64::of(&[2, 3, 4]); /// bitmap1.or_inplace(&bitmap2); - /// assert_eq!(bitmap1.to_vec(), vec![1, 2, 3, 4]); + /// assert_eq!(bitmap1.iter().collect::>(), vec![1, 2, 3, 4]); /// ``` #[inline] #[doc(alias = "roaring64_bitmap_or_inplace")] @@ -1164,7 +1190,7 @@ impl Bitmap64 { /// let bitmap1 = Bitmap64::of(&[1, 2, 3]); /// let bitmap2 = Bitmap64::of(&[2, 3, 4]); /// let bitmap3 = bitmap1.xor(&bitmap2); - /// assert_eq!(bitmap3.to_vec(), vec![1, 4]); + /// assert_eq!(bitmap3.iter().collect::>(), vec![1, 4]); /// ``` #[inline] #[doc(alias = "roaring64_bitmap_xor")] @@ -1204,7 +1230,7 @@ impl Bitmap64 { /// let mut bitmap1 = Bitmap64::of(&[1, 2, 3]); /// let bitmap2 = Bitmap64::of(&[2, 3, 4]); /// bitmap1.xor_inplace(&bitmap2); - /// assert_eq!(bitmap1.to_vec(), vec![1, 4]); + /// assert_eq!(bitmap1.iter().collect::>(), vec![1, 4]); /// ``` #[inline] #[doc(alias = "roaring64_bitmap_xor_inplace")] @@ -1221,7 +1247,7 @@ impl Bitmap64 { /// let bitmap1 = Bitmap64::of(&[1, 2, 3]); /// let bitmap2 = Bitmap64::of(&[2, 3, 4]); /// let bitmap3 = bitmap1.andnot(&bitmap2); - /// assert_eq!(bitmap3.to_vec(), vec![1]); + /// assert_eq!(bitmap3.iter().collect::>(), vec![1]); /// ``` #[inline] #[doc(alias = "roaring64_bitmap_andnot")] @@ -1261,7 +1287,7 @@ impl Bitmap64 { /// let mut bitmap1 = Bitmap64::of(&[1, 2, 3]); /// let bitmap2 = Bitmap64::of(&[2, 3, 4]); /// bitmap1.andnot_inplace(&bitmap2); - /// assert_eq!(bitmap1.to_vec(), vec![1]); + /// assert_eq!(bitmap1.iter().collect::>(), vec![1]); /// ``` #[inline] #[doc(alias = "roaring64_bitmap_andnot_inplace")] diff --git a/croaring/src/bitmap64/iter.rs b/croaring/src/bitmap64/iter.rs index 7ab39d9..037431b 100644 --- a/croaring/src/bitmap64/iter.rs +++ b/croaring/src/bitmap64/iter.rs @@ -1,7 +1,7 @@ use crate::Bitmap64; -use std::marker::PhantomData; -use std::mem::{ManuallyDrop, MaybeUninit}; -use std::ptr::NonNull; +use core::marker::PhantomData; +use core::mem::{ManuallyDrop, MaybeUninit}; +use core::ptr::NonNull; impl FromIterator for Bitmap64 { /// Convenience method for creating bitmap from iterator. diff --git a/croaring/src/bitmap64/mod.rs b/croaring/src/bitmap64/mod.rs index 58d4d9b..0b96ed5 100644 --- a/croaring/src/bitmap64/mod.rs +++ b/croaring/src/bitmap64/mod.rs @@ -11,7 +11,7 @@ pub use self::serialization::{Deserializer, Serializer}; /// A Bitmap which can hold 64-bit integers pub struct Bitmap64 { - raw: std::ptr::NonNull, + raw: core::ptr::NonNull, } unsafe impl Sync for Bitmap64 {} unsafe impl Send for Bitmap64 {} diff --git a/croaring/src/bitmap64/ops.rs b/croaring/src/bitmap64/ops.rs index c49688f..dc60609 100644 --- a/croaring/src/bitmap64/ops.rs +++ b/croaring/src/bitmap64/ops.rs @@ -1,12 +1,24 @@ use crate::Bitmap64; +use core::fmt; +use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; use ffi::roaring64_bitmap_copy; -use std::fmt; -use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; impl fmt::Debug for Bitmap64 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.cardinality() < 32 { - write!(f, "Bitmap64<{:?}>", self.to_vec()) + write!(f, "Bitmap64<[")?; + let mut first = true; + for value in self.iter() { + let prefix = if first { + first = false; + "" + } else { + ", " + }; + write!(f, "{prefix}{value}")?; + } + write!(f, "]>")?; + Ok(()) } else { write!( f, diff --git a/croaring/src/bitmap64/serialization.rs b/croaring/src/bitmap64/serialization.rs index f03188c..701923d 100644 --- a/croaring/src/bitmap64/serialization.rs +++ b/croaring/src/bitmap64/serialization.rs @@ -1,9 +1,13 @@ use crate::{Bitmap64, Portable}; -use std::ffi::c_char; -use std::num::NonZeroUsize; +use core::ffi::c_char; +use core::num::NonZeroUsize; /// Trait for different formats of bitmap64 serialization -pub trait Serializer { +pub trait Serializer: crate::sealed::Sealed { + /// The required alignment for the serialized data + #[doc(hidden)] + const REQUIRED_ALIGNMENT: usize = 1; + /// Serialize a bitmap into bytes, using the provided vec buffer to store the serialized data /// /// Note that some serializers ([Frozen][crate::Frozen]) may require that the @@ -13,15 +17,65 @@ pub trait Serializer { /// The contents of the provided vec buffer will not be overwritten: only new data will be /// appended to the end of the buffer. If the buffer has enough capacity, and the current /// end of the buffer is correctly aligned, then no additional allocations will be performed. - fn serialize_into<'a>(bitmap: &Bitmap64, dst: &'a mut Vec) -> &'a [u8]; + #[doc(hidden)] + #[cfg(feature = "alloc")] + fn serialize_into_vec<'a>(bitmap: &Bitmap64, dst: &'a mut alloc::vec::Vec) -> &'a mut [u8] { + let len = Self::get_serialized_size_in_bytes(bitmap); + let spare_capacity = + crate::serialization::get_aligned_spare_capacity(dst, Self::REQUIRED_ALIGNMENT, len); + let data_start; + unsafe { + Self::raw_serialize(bitmap, spare_capacity.as_mut_ptr().cast::()); + data_start = dst.len(); + let total_len = data_start.checked_add(len).unwrap(); + dst.set_len(total_len); + } + + &mut dst[data_start..] + } + + #[doc(hidden)] + fn try_serialize_into_aligned<'a>( + bitmap: &Bitmap64, + dst: &'a mut [u8], + ) -> Option<&'a mut [u8]> { + let offset = dst.as_ptr().align_offset(Self::REQUIRED_ALIGNMENT); + let offset_dst = dst.get_mut(offset..)?; + let len = Self::try_serialize_into(bitmap, offset_dst)?; + Some(&mut dst[offset..offset + len]) + } + + /// Serialize a bitmap into bytes, using the provided buffer to store the serialized data + /// + /// This method does not require the buffer to be aligned, and will return `None` if the buffer + /// is not large enough to store the serialized data. + /// + /// This is a niche method, and is not recommended for general use. The + /// [`Bitmap64::try_serialize_into`]/[`Bitmap64::serialize_into_vec`] methods should usually be used + /// instead of this method. + fn try_serialize_into(bitmap: &Bitmap64, dst: &mut [u8]) -> Option { + let required_len = Self::get_serialized_size_in_bytes(bitmap); + if dst.len() < required_len { + return None; + } + unsafe { + Self::raw_serialize(bitmap, dst.as_mut_ptr().cast::()); + } + Some(required_len) + } + /// Get the number of bytes required to serialize this bitmap /// /// This does not include any additional padding which may be required to align the bitmap + #[doc(hidden)] fn get_serialized_size_in_bytes(bitmap: &Bitmap64) -> usize; + + #[doc(hidden)] + unsafe fn raw_serialize(bitmap: &Bitmap64, dst: *mut c_char); } /// Trait for different formats of bitmap deserialization -pub trait Deserializer { +pub trait Deserializer: crate::sealed::Sealed { /// Try to deserialize a bitmap from the beginning of the provided buffer /// /// The [`Bitmap64::try_deserialize`] method should usually be used instead of this method @@ -54,33 +108,18 @@ pub trait Deserializer { } impl Serializer for Portable { - /// Serialize a bitmap to a slice of bytes in portable format. - /// - /// See [`Bitmap64::serialize_into`] for more details. - #[doc(alias = "roaring64_bitmap_portable_serialize")] - fn serialize_into<'a>(bitmap: &Bitmap64, dst: &'a mut Vec) -> &'a [u8] { - let len = Self::get_serialized_size_in_bytes(bitmap); - - dst.reserve(len); - let offset = dst.len(); - let total_len = offset.checked_add(len).unwrap(); - - unsafe { - ffi::roaring64_bitmap_portable_serialize( - bitmap.raw.as_ptr(), - dst.spare_capacity_mut().as_mut_ptr().cast::(), - ); - dst.set_len(total_len); - } - &dst[offset..] - } - /// Computes the serialized size in bytes of the Bitmap in portable format. /// See [`Bitmap64::get_serialized_size_in_bytes`] for examples. #[doc(alias = "roaring64_bitmap_portable_size_in_bytes")] fn get_serialized_size_in_bytes(bitmap: &Bitmap64) -> usize { unsafe { ffi::roaring64_bitmap_portable_size_in_bytes(bitmap.raw.as_ptr()) } } + + unsafe fn raw_serialize(bitmap: &Bitmap64, dst: *mut c_char) { + unsafe { + ffi::roaring64_bitmap_portable_serialize(bitmap.raw.as_ptr(), dst); + } + } } impl Deserializer for Portable { diff --git a/croaring/src/bitset/imp.rs b/croaring/src/bitset/imp.rs index 3e3137d..d29a08c 100644 --- a/croaring/src/bitset/imp.rs +++ b/croaring/src/bitset/imp.rs @@ -1,5 +1,5 @@ use super::Bitset; -use std::{mem, ptr}; +use core::{mem, ptr}; impl Bitset { #[inline] @@ -21,7 +21,7 @@ impl Bitset { if self.bitset.arraysize == 0 { &[] } else { - unsafe { std::slice::from_raw_parts(self.bitset.array, self.bitset.arraysize) } + unsafe { core::slice::from_raw_parts(self.bitset.array, self.bitset.arraysize) } } } @@ -31,7 +31,7 @@ impl Bitset { if self.bitset.arraysize == 0 { &mut [] } else { - unsafe { std::slice::from_raw_parts_mut(self.bitset.array, self.bitset.arraysize) } + unsafe { core::slice::from_raw_parts_mut(self.bitset.array, self.bitset.arraysize) } } } diff --git a/croaring/src/bitset/ops.rs b/croaring/src/bitset/ops.rs index e56b0a1..f2625b0 100644 --- a/croaring/src/bitset/ops.rs +++ b/croaring/src/bitset/ops.rs @@ -1,6 +1,6 @@ use super::Bitset; -use std::ffi::c_void; -use std::{fmt, ops}; +use core::ffi::c_void; +use core::{fmt, ops}; impl Default for Bitset { #[inline] diff --git a/croaring/src/callback.rs b/croaring/src/callback.rs index 7ce0434..ec27ba4 100644 --- a/croaring/src/callback.rs +++ b/croaring/src/callback.rs @@ -1,9 +1,12 @@ -use std::any::Any; -use std::ops::ControlFlow; -use std::panic::AssertUnwindSafe; -use std::{panic, ptr}; +#![cfg(feature = "std")] -pub struct CallbackWrapper { +use alloc::boxed::Box; +use core::any::Any; +use core::ops::ControlFlow; +use core::panic::AssertUnwindSafe; +use core::{panic, ptr}; + +pub(crate) struct CallbackWrapper { f: F, result: Result, Box>, } @@ -16,14 +19,15 @@ impl CallbackWrapper { } } - unsafe extern "C" fn raw_callback(value: I, arg: *mut std::ffi::c_void) -> bool + unsafe extern "C" fn raw_callback(value: I, arg: *mut core::ffi::c_void) -> bool where - I: panic::UnwindSafe, F: FnMut(I) -> ControlFlow, + I: panic::UnwindSafe, { let wrapper = &mut *(arg as *mut Self); - let mut f = AssertUnwindSafe(&mut wrapper.f); - let result = panic::catch_unwind(move || f(value)); + let f = &mut wrapper.f; + let f = AssertUnwindSafe(|| f(value)); + let result = std::panic::catch_unwind(f); match result { Ok(ControlFlow::Continue(())) => true, Ok(cf @ ControlFlow::Break(_)) => { @@ -40,8 +44,8 @@ impl CallbackWrapper { pub fn callback_and_ctx( &mut self, ) -> ( - unsafe extern "C" fn(I, *mut std::ffi::c_void) -> bool, - *mut std::ffi::c_void, + unsafe extern "C" fn(I, *mut core::ffi::c_void) -> bool, + *mut core::ffi::c_void, ) where I: panic::UnwindSafe, diff --git a/croaring/src/lib.rs b/croaring/src/lib.rs index 52b6fe1..e43af56 100644 --- a/croaring/src/lib.rs +++ b/croaring/src/lib.rs @@ -1,21 +1,37 @@ +#![no_std] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![deny(missing_docs)] //! Rust wrapper for `CRoaring` (a C/C++ implementation at ) //! //! Provides Compressed Bitmaps, which act like a set of integers in an efficient way. +#[cfg(feature = "alloc")] +extern crate alloc; + +#[cfg(feature = "std")] +extern crate std; + pub mod bitmap; pub mod bitmap64; pub mod bitset; + +#[cfg(feature = "alloc")] pub mod treemap; mod callback; mod serialization; +mod sealed { + pub trait Sealed {} +} + pub use serialization::*; pub use bitmap::Bitmap; pub use bitmap64::Bitmap64; pub use bitset::Bitset; + +#[cfg(feature = "alloc")] pub use treemap::Treemap; pub use bitmap::BitmapView; diff --git a/croaring/src/serialization.rs b/croaring/src/serialization.rs index bcb56b3..0f645d2 100644 --- a/croaring/src/serialization.rs +++ b/croaring/src/serialization.rs @@ -24,22 +24,53 @@ pub enum Frozen {} impl Frozen { /// The frozen format requires bitmaps are aligned to 32 bytes. pub const REQUIRED_ALIGNMENT: usize = 32; +} - // The most padding required to get 32 byte alignment is 31 bytes. - pub(crate) const MAX_PADDING: usize = Self::REQUIRED_ALIGNMENT - 1; +mod private { + use crate::{Native, Portable}; - #[inline] - pub(crate) const fn required_padding(x: usize) -> usize { - match x % Self::REQUIRED_ALIGNMENT { - 0 => 0, - r => Self::REQUIRED_ALIGNMENT - r, - } - } + #[allow(unused)] + pub trait NoAlign: crate::sealed::Sealed {} + impl NoAlign for Native {} + impl NoAlign for Portable {} } +#[allow(unused)] +pub(crate) use private::NoAlign; + /// The `JvmLegacy` format is meant to be compatible with the original Java implementation of `Roaring64NavigableMap` /// /// It is used only for [Treemap][crate::Treemap]s, not bitmaps. /// /// See pub enum JvmLegacy {} + +#[cfg(feature = "alloc")] +pub(crate) fn get_aligned_spare_capacity( + dst: &mut alloc::vec::Vec, + align: usize, + required_len: usize, +) -> &mut [core::mem::MaybeUninit] { + let max_padding = align - 1; + let extra_align_required = + |v: &mut alloc::vec::Vec| v.spare_capacity_mut().as_ptr().align_offset(align); + let mut extra_offset = extra_align_required(dst); + if dst.spare_capacity_mut().len() < required_len + extra_offset { + dst.reserve(required_len.checked_add(max_padding).unwrap()); + // Need to recompute offset after reserve, as the buffer may have been reallocated and + // the end of the buffer may be somewhere else + extra_offset = extra_align_required(dst); + } + let mut data_start = dst.len(); + if extra_offset != 0 { + data_start = data_start.checked_add(extra_offset).unwrap(); + // we must initialize up to offset + dst.resize(data_start, 0); + } + debug_assert_eq!(dst.len(), data_start); + let spare_capacity = dst.spare_capacity_mut(); + debug_assert!(spare_capacity.len() >= required_len); + debug_assert_eq!(spare_capacity.as_ptr().align_offset(align), 0); + + &mut spare_capacity[..required_len] +} diff --git a/croaring/src/treemap/imp.rs b/croaring/src/treemap/imp.rs index a4d9d69..f79c55e 100644 --- a/croaring/src/treemap/imp.rs +++ b/croaring/src/treemap/imp.rs @@ -3,11 +3,12 @@ use crate::Treemap; use super::util; use crate::treemap::{Deserializer, Serializer}; -use std::cmp::Ordering; -use std::collections::btree_map::Entry; -use std::collections::BTreeMap; -use std::ops::{Bound, RangeBounds}; -use std::{io, u64}; +use alloc::collections::btree_map::Entry; +use alloc::collections::BTreeMap; +use alloc::vec::Vec; +use core::cmp::Ordering; +use core::ops::{Bound, RangeBounds}; +use core::prelude::v1::*; impl Treemap { /// Creates an empty `Treemap`. @@ -1080,10 +1081,11 @@ impl Treemap { /// /// assert_eq!(treemap, deserialized_treemap); /// ``` - pub fn serialize_into_writer( + #[cfg(feature = "std")] + pub fn serialize_into_writer( &self, writer: W, - ) -> io::Result { + ) -> std::io::Result { S::serialize_into_writer(self, writer) } diff --git a/croaring/src/treemap/iter.rs b/croaring/src/treemap/iter.rs index 7ea7fe3..3f5717a 100644 --- a/croaring/src/treemap/iter.rs +++ b/croaring/src/treemap/iter.rs @@ -1,8 +1,8 @@ use super::util; use crate::bitmap::BitmapIterator; use crate::{Bitmap, Treemap}; -use std::collections::btree_map; -use std::iter; +use alloc::collections::btree_map; +use core::iter; struct To64Iter<'a> { key: u32, diff --git a/croaring/src/treemap/mod.rs b/croaring/src/treemap/mod.rs index ca2aa53..44e5cf4 100644 --- a/croaring/src/treemap/mod.rs +++ b/croaring/src/treemap/mod.rs @@ -20,7 +20,7 @@ //! assert_eq!(treemap.cardinality(), 3); //! ``` use crate::Bitmap; -use std::collections::BTreeMap; +use alloc::collections::BTreeMap; mod imp; mod iter; diff --git a/croaring/src/treemap/ops.rs b/croaring/src/treemap/ops.rs index fc40048..43144a9 100644 --- a/croaring/src/treemap/ops.rs +++ b/croaring/src/treemap/ops.rs @@ -1,5 +1,5 @@ -use std::fmt; -use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; +use core::fmt; +use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign}; use super::Treemap; diff --git a/croaring/src/treemap/serialization.rs b/croaring/src/treemap/serialization.rs index 71dc0db..cbbd6aa 100644 --- a/croaring/src/treemap/serialization.rs +++ b/croaring/src/treemap/serialization.rs @@ -1,12 +1,11 @@ use crate::serialization::{Frozen, Native, Portable}; use crate::{bitmap, Treemap}; use crate::{Bitmap, JvmLegacy}; -use std::collections::BTreeMap; -use std::io; -use std::io::Write as _; +use alloc::collections::BTreeMap; +use alloc::vec::Vec; +use core::prelude::v1::*; -use byteorder::{BigEndian, NativeEndian, ReadBytesExt, WriteBytesExt}; -use std::mem::size_of; +use core::mem::size_of; /// Trait for different formats of treemap deserialization pub trait Serializer { @@ -18,9 +17,10 @@ pub trait Serializer { /// reading: this method does not perform any extra alignment. See [`Self::serialize_into`] /// for a method which will return a slice of bytes which are guaranteed to be aligned correctly /// in memory - fn serialize_into_writer(treemap: &Treemap, dst: W) -> io::Result + #[cfg(feature = "std")] + fn serialize_into_writer(treemap: &Treemap, dst: W) -> std::io::Result where - W: io::Write; + W: std::io::Write; /// Serialize a treemap into bytes, using the provided vec buffer to store the serialized data /// @@ -58,7 +58,7 @@ pub trait Deserializer { fn serialize_impl<'a, S>(treemap: &Treemap, dst: &'a mut Vec) -> &'a [u8] where - S: bitmap::Serializer, + S: bitmap::Serializer + crate::serialization::NoAlign, { let start_idx = dst.len(); let map_len = u64::try_from(treemap.map.len()).unwrap(); @@ -67,7 +67,7 @@ where treemap.map.iter().for_each(|(&key, bitmap)| { dst.extend_from_slice(&key.to_ne_bytes()); let prev_len = dst.len(); - let serialized_slice = bitmap.serialize_into::(dst); + let serialized_slice = bitmap.serialize_into_vec::(dst); let serialized_len = serialized_slice.len(); let serialized_range = serialized_slice.as_ptr_range(); // Serialization should only append the data, no padding can be allowed for this implementation @@ -77,21 +77,24 @@ where &dst[start_idx..] } -fn serialize_writer_impl(treemap: &Treemap, dst: W) -> io::Result +#[cfg(feature = "std")] +fn serialize_writer_impl(treemap: &Treemap, dst: W) -> std::io::Result where S: bitmap::Serializer, - W: io::Write, + W: std::io::Write, { + use std::io::Write; + let mut dst = OffsetTrackingWriter::new(dst); let map_len = u64::try_from(treemap.map.len()).unwrap(); - dst.write_u64::(map_len)?; + dst.write_all(&map_len.to_ne_bytes())?; let mut buf = Vec::new(); for (&key, bitmap) in &treemap.map { - dst.write_u32::(key)?; + dst.write_all(&key.to_ne_bytes())?; - let bitmap_serialized = bitmap.serialize_into::(&mut buf); + let bitmap_serialized = bitmap.serialize_into_vec::(&mut buf); dst.write_all(bitmap_serialized)?; buf.clear(); } @@ -111,15 +114,18 @@ where overhead + total_sizes } -fn deserialize_impl(mut buffer: &[u8]) -> Option<(Treemap, usize)> +fn deserialize_impl(buffer: &[u8]) -> Option<(Treemap, usize)> where S: bitmap::Serializer + bitmap::Deserializer, { let start_len = buffer.len(); - let map_len = buffer.read_u64::().ok()?; + let (map_len_bytes, mut buffer) = buffer.split_first_chunk()?; + let map_len = u64::from_ne_bytes(*map_len_bytes); let mut map = BTreeMap::new(); for _ in 0..map_len { - let key = buffer.read_u32::().ok()?; + let (key_bytes, rest) = buffer.split_first_chunk()?; + buffer = rest; + let key = u32::from_ne_bytes(*key_bytes); let bitmap = Bitmap::try_deserialize::(buffer)?; buffer = &buffer[bitmap.get_serialized_size_in_bytes::()..]; map.insert(key, bitmap); @@ -130,9 +136,10 @@ where impl Serializer for Portable { /// Serializes a Treemap to a writer in portable format. /// See [`Treemap::serialize_into_writer`] for examples. - fn serialize_into_writer(treemap: &Treemap, dst: W) -> io::Result + #[cfg(feature = "std")] + fn serialize_into_writer(treemap: &Treemap, dst: W) -> std::io::Result where - W: io::Write, + W: std::io::Write, { serialize_writer_impl::(treemap, dst) } @@ -159,9 +166,10 @@ impl Deserializer for Portable { impl Serializer for Native { /// Serializes a Treemap to a writer in native format. /// See [`Treemap::serialize_into_writer`] for examples. - fn serialize_into_writer(treemap: &Treemap, dst: W) -> io::Result + #[cfg(feature = "std")] + fn serialize_into_writer(treemap: &Treemap, dst: W) -> std::io::Result where - W: io::Write, + W: std::io::Write, { serialize_writer_impl::(treemap, dst) } @@ -190,11 +198,15 @@ const FROZEN_BITMAP_METADATA_SIZE: usize = size_of::() + size_of::() impl Serializer for Frozen { /// Serializes a Treemap to a writer in frozen format. /// See [`Treemap::serialize_into_writer`] for examples. - fn serialize_into_writer(treemap: &Treemap, dst: W) -> io::Result + #[cfg(feature = "std")] + fn serialize_into_writer(treemap: &Treemap, dst: W) -> std::io::Result where - W: io::Write, + W: std::io::Write, { - const FULL_PADDING: [u8; Frozen::MAX_PADDING] = [0; Frozen::MAX_PADDING]; + use std::io::Write; + + const FULL_PADDING: [u8; Frozen::REQUIRED_ALIGNMENT - 1] = + [0; Frozen::REQUIRED_ALIGNMENT - 1]; let mut dst = OffsetTrackingWriter::new(dst); @@ -203,9 +215,9 @@ impl Serializer for Frozen { let mut buf = Vec::new(); for (&key, bitmap) in &treemap.map { - let bitmap_serialized = bitmap.serialize_into::(&mut buf); + let bitmap_serialized = bitmap.serialize_into_vec::(&mut buf); let required_padding = - Self::required_padding(dst.bytes_written + FROZEN_BITMAP_METADATA_SIZE); + required_padding(dst.bytes_written + FROZEN_BITMAP_METADATA_SIZE); dst.write_all(&FULL_PADDING[..required_padding])?; dst.write_all(&usize::to_ne_bytes(bitmap_serialized.len()))?; @@ -224,12 +236,22 @@ impl Serializer for Frozen { /// See [`Treemap::serialize_into`] for examples. fn serialize_into<'a>(treemap: &Treemap, dst: &'a mut Vec) -> &'a [u8] { let len = Self::get_serialized_size_in_bytes(treemap); + let max_padding = Self::REQUIRED_ALIGNMENT - 1; + let mut offset = dst.len(); - if dst.capacity() < dst.len() + len - || Self::required_padding(dst.as_ptr() as usize + offset) != 0 - { - dst.reserve(len.checked_add(Self::MAX_PADDING).unwrap()); - let extra_offset = Self::required_padding(dst.as_ptr() as usize + offset); + let extra_align_required = |slice: &[u8]| { + slice + .as_ptr_range() + .end + .align_offset(Self::REQUIRED_ALIGNMENT) + }; + if dst.capacity() < dst.len() + len + extra_align_required(dst) { + dst.reserve(len.checked_add(max_padding).unwrap()); + } + // Need to recompute offset after reserve, as the buffer may have been reallocated and + // the end of the buffer may be somewhere else + let extra_offset = extra_align_required(dst); + if extra_offset != 0 { offset = offset.checked_add(extra_offset).unwrap(); // we must initialize up to offset dst.resize(offset, 0); @@ -242,7 +264,7 @@ impl Serializer for Frozen { treemap.map.iter().for_each(|(&key, bitmap)| { let end_with_metadata = dst.as_ptr_range().end as usize + FROZEN_BITMAP_METADATA_SIZE; - let extra_padding = Self::required_padding(end_with_metadata); + let extra_padding = required_padding(end_with_metadata); dst.resize(dst.len() + extra_padding, 0); let frozen_size_in_bytes: usize = bitmap.get_serialized_size_in_bytes::(); @@ -250,7 +272,7 @@ impl Serializer for Frozen { dst.extend_from_slice(&key.to_ne_bytes()); let before_bitmap_serialize = dst.as_ptr_range().end; - let serialized_slice = bitmap.serialize_into::(dst); + let serialized_slice = bitmap.serialize_into_vec::(dst); // We pre-calculated padding, so there should be no padding added debug_assert_eq!(before_bitmap_serialize, serialized_slice.as_ptr()); debug_assert_eq!(serialized_slice.as_ptr_range().end, dst.as_ptr_range().end); @@ -265,7 +287,7 @@ impl Serializer for Frozen { let mut result = size_of::(); for bitmap in treemap.map.values() { result += FROZEN_BITMAP_METADATA_SIZE; - result += Self::required_padding(result); + result += required_padding(result); result += bitmap.get_serialized_size_in_bytes::(); } result @@ -273,21 +295,24 @@ impl Serializer for Frozen { } impl Serializer for JvmLegacy { - fn serialize_into_writer(treemap: &Treemap, dst: W) -> io::Result + #[cfg(feature = "std")] + fn serialize_into_writer(treemap: &Treemap, dst: W) -> std::io::Result where - W: io::Write, + W: std::io::Write, { + use std::io::Write; + let mut dst = OffsetTrackingWriter::new(dst); // Push a boolean false indicating that the values are not signed - dst.write_u8(0)?; + dst.write_all(&[0])?; let bitmap_count: u32 = treemap.map.len().try_into().unwrap(); - dst.write_u32::(bitmap_count)?; + dst.write_all(&bitmap_count.to_be_bytes())?; let mut buf = Vec::new(); for (&key, bitmap) in &treemap.map { - dst.write_u32::(key)?; - let bitmap_serialized = bitmap.serialize_into::(&mut buf); + dst.write_all(&key.to_be_bytes())?; + let bitmap_serialized = bitmap.serialize_into_vec::(&mut buf); dst.write_all(bitmap_serialized)?; buf.clear(); } @@ -298,13 +323,13 @@ impl Serializer for JvmLegacy { fn serialize_into<'a>(treemap: &Treemap, dst: &'a mut Vec) -> &'a [u8] { let start_idx = dst.len(); // Push a boolean false indicating that the values are not signed - dst.write_u8(0).unwrap(); + dst.push(0); let bitmap_count: u32 = treemap.map.len().try_into().unwrap(); - dst.write_u32::(bitmap_count).unwrap(); + dst.extend_from_slice(&bitmap_count.to_be_bytes()); treemap.map.iter().for_each(|(&key, bitmap)| { - dst.write_u32::(key).unwrap(); - bitmap.serialize_into::(dst); + dst.extend_from_slice(&key.to_be_bytes()); + bitmap.serialize_into_vec::(dst); }); &dst[start_idx..] @@ -322,15 +347,18 @@ impl Serializer for JvmLegacy { } impl Deserializer for JvmLegacy { - fn try_deserialize(mut buffer: &[u8]) -> Option<(Treemap, usize)> { + fn try_deserialize(buffer: &[u8]) -> Option<(Treemap, usize)> { let start_len = buffer.len(); // Ignored, we assume that the values are not signed - let _is_signed = buffer.read_u8().ok()?; + let (_is_signed, buffer) = buffer.split_first()?; - let bitmap_count = buffer.read_u32::().ok()?; + let (bitmap_count_bytes, mut buffer) = buffer.split_first_chunk()?; + let bitmap_count = u32::from_be_bytes(*bitmap_count_bytes); let mut map = BTreeMap::new(); for _ in 0..bitmap_count { - let key = buffer.read_u32::().ok()?; + let (key_bytes, rest) = buffer.split_first_chunk()?; + buffer = rest; + let key = u32::from_be_bytes(*key_bytes); let bitmap = Bitmap::try_deserialize::(buffer)?; buffer = &buffer[bitmap.get_serialized_size_in_bytes::()..]; map.insert(key, bitmap); @@ -340,11 +368,21 @@ impl Deserializer for JvmLegacy { } } +#[inline] +const fn required_padding(x: usize) -> usize { + match x % Frozen::REQUIRED_ALIGNMENT { + 0 => 0, + r => Frozen::REQUIRED_ALIGNMENT - r, + } +} + +#[cfg(feature = "std")] struct OffsetTrackingWriter { writer: W, bytes_written: usize, } +#[cfg(feature = "std")] impl OffsetTrackingWriter { pub fn new(writer: W) -> Self { Self { @@ -354,18 +392,19 @@ impl OffsetTrackingWriter { } } -impl io::Write for OffsetTrackingWriter { - fn write(&mut self, buf: &[u8]) -> io::Result { +#[cfg(feature = "std")] +impl std::io::Write for OffsetTrackingWriter { + fn write(&mut self, buf: &[u8]) -> std::io::Result { let written = self.writer.write(buf)?; self.bytes_written += written; Ok(written) } - fn flush(&mut self) -> io::Result<()> { + fn flush(&mut self) -> std::io::Result<()> { self.writer.flush() } - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> { self.writer.write_all(buf)?; self.bytes_written += buf.len(); Ok(()) @@ -388,12 +427,15 @@ mod tests { let serialized = treemap.serialize_into::(&mut buf); assert_eq!(serialized.len(), expected_len); - let mut writer = Vec::new(); - assert_eq!( - treemap.serialize_into_writer::(&mut writer).unwrap(), - expected_len, - ); - assert_eq!(serialized, writer); + #[cfg(feature = "std")] + { + let mut writer = Vec::new(); + assert_eq!( + treemap.serialize_into_writer::(&mut writer).unwrap(), + expected_len, + ); + assert_eq!(serialized, writer); + } } #[test] diff --git a/croaring/tests/lib.rs b/croaring/tests/lib.rs index f0b8fe9..05f6186 100644 --- a/croaring/tests/lib.rs +++ b/croaring/tests/lib.rs @@ -1,9 +1,11 @@ -use std::collections::BTreeMap; use std::{fs, iter, u32}; -use croaring::{Bitmap, BitmapView, Frozen, JvmLegacy, Native, Portable, Treemap}; +use croaring::{Bitmap, BitmapView, Frozen, Native, Portable}; use proptest::prelude::*; +#[cfg(feature = "alloc")] +use croaring::{JvmLegacy, Treemap}; + // borrowed and adapted from https://github.com/Nemo157/roaring-rs/blob/5089f180ca7e17db25f5c58023f4460d973e747f/tests/lib.rs#L7-L37 #[test] fn smoke1() { @@ -68,8 +70,6 @@ fn smoke2() { rb3.add(5); rb3.or_inplace(&rb1); - let mut rb4 = Bitmap::fast_or(&[&rb1, &rb2, &rb3]); - rb1.and_inplace(&rb2); println!("{:?}", rb1); @@ -81,13 +81,17 @@ fn smoke2() { rb3.add(5); rb3.or_inplace(&rb1); - println!("{:?}", rb3.to_vec()); println!("{:?}", rb3); - println!("{:?}", rb4); - rb4 = Bitmap::fast_or(&[&rb1, &rb2, &rb3]); + #[cfg(feature = "alloc")] + { + println!("{:?}", rb3.to_vec()); + let mut rb4 = Bitmap::fast_or(&[&rb1, &rb2, &rb3]); + println!("{:?}", rb4); - println!("{:?}", rb4); + rb4 = Bitmap::fast_or(&[&rb1, &rb2, &rb3]); + println!("{:?}", rb4); + } } fn expected_serialized_bitmap() -> Bitmap { @@ -163,6 +167,7 @@ fn test_frozen_view() { } #[test] +#[cfg(feature = "alloc")] fn test_treemap_deserialize_cpp() { match fs::read("tests/data/testcpp.bin") { Ok(buffer) => { @@ -180,6 +185,7 @@ fn test_treemap_deserialize_cpp() { } #[test] +#[cfg(feature = "alloc")] fn test_treemap_deserialize_jvm() { match fs::read("tests/data/testjvm.bin") { Ok(buffer) => { @@ -197,6 +203,7 @@ fn test_treemap_deserialize_jvm() { } #[test] +#[cfg(feature = "alloc")] fn test_treemap_max_andnot_empty() { let single_max = Treemap::of(&[std::u64::MAX]); let empty = Treemap::new(); @@ -209,6 +216,7 @@ fn test_treemap_max_andnot_empty() { } #[test] +#[cfg(feature = "alloc")] fn treemap_remove_big_range() { let mut treemap = Treemap::new(); let value = 0xFFFFFFFFFFFF038D; @@ -222,7 +230,10 @@ fn treemap_remove_big_range() { } #[test] +#[cfg(feature = "alloc")] fn treemap_run_optimized() { + use std::collections::BTreeMap; + let mut initial = Bitmap::new(); initial.add(1); initial.add(2); @@ -258,29 +269,85 @@ fn treemap_run_optimized() { } #[test] +#[cfg(feature = "alloc")] fn serialize_into_existing_vec_frozen() { let mut buffer = vec![0; 13]; let bitmap = Bitmap::of(&[1, 2, 3, 4, 5]); - let data = bitmap.serialize_into::(&mut buffer); + let data = bitmap.serialize_into_vec::(&mut buffer); assert_eq!(unsafe { BitmapView::deserialize::(data) }, bitmap); assert!(unsafe { data.as_ptr().offset_from(buffer.as_ptr()) } >= 13); } #[test] +#[cfg(feature = "alloc")] +fn serialize_into_existing_vec_norealloc_frozen() { + let bitmap = Bitmap::of(&[1, 2, 3, 4, 5]); + let mut buffer = Vec::with_capacity( + 13 + Frozen::REQUIRED_ALIGNMENT - 1 + bitmap.get_serialized_size_in_bytes::(), + ); + buffer.resize(13, 1); + let cap_range = buffer.spare_capacity_mut().as_ptr_range(); + let orig_cap = buffer.capacity(); + + let data = bitmap.serialize_into_vec::(&mut buffer); + assert_eq!(unsafe { BitmapView::deserialize::(data) }, bitmap); + assert!(cap_range.contains(&data.as_ptr().cast())); + assert!(unsafe { data.as_ptr().offset_from(cap_range.start.cast()) } < 32); + assert!(buffer[..13].iter().all(|&b| b == 1)); + assert_eq!(buffer.capacity(), orig_cap); + assert!(buffer.len() > 13); +} + +#[test] +fn serialize_into_existing_slice_presized_aligned_frozen() { + const SERIALIZED_SIZE: usize = 19; + + #[repr(align(32))] + struct OverAlign; + + #[repr(C)] + struct AlignedData { + _align: OverAlign, + data: [u8; SERIALIZED_SIZE], + } + + let bitmap = Bitmap::of(&[1, 2, 3, 4, 5]); + let mut buffer = AlignedData { + _align: OverAlign, + data: [0; SERIALIZED_SIZE], + }; + assert_eq!( + buffer + .data + .as_ptr() + .align_offset(Frozen::REQUIRED_ALIGNMENT), + 0 + ); + + let data = bitmap + .try_serialize_into::(&mut buffer.data) + .unwrap(); + assert_eq!(unsafe { BitmapView::deserialize::(data) }, bitmap); + assert_eq!(data.as_ptr_range(), buffer.data.as_ptr_range()); +} + +#[test] +#[cfg(feature = "alloc")] fn serialize_into_existing_vec_portable() { let mut buffer = vec![0; 13]; let bitmap = Bitmap::of(&[1, 2, 3, 4, 5]); - let data = bitmap.serialize_into::(&mut buffer); + let data = bitmap.serialize_into_vec::(&mut buffer); assert_eq!(Bitmap::try_deserialize::(data).unwrap(), bitmap); assert!(unsafe { data.as_ptr().offset_from(buffer.as_ptr()) } >= 13); } #[test] +#[cfg(feature = "alloc")] fn serialize_into_existing_vec_native() { let mut buffer = vec![0; 13]; let bitmap = Bitmap::of(&[1, 2, 3, 4, 5]); - let data = bitmap.serialize_into::(&mut buffer); + let data = bitmap.serialize_into_vec::(&mut buffer); assert_eq!(Bitmap::try_deserialize::(data).unwrap(), bitmap); assert!(unsafe { data.as_ptr().offset_from(buffer.as_ptr()) } >= 13); } @@ -298,6 +365,7 @@ proptest! { } #[test] + #[cfg(feature = "alloc")] fn treemap_cardinality_roundtrip( indices in prop::collection::vec(proptest::num::u64::ANY, 1..3000) ) { @@ -309,6 +377,7 @@ proptest! { } #[test] + #[cfg(feature = "alloc")] fn test_bitmap_serialization_roundtrip( indices in prop::collection::vec(proptest::num::u32::ANY, 1..3000) ) { @@ -322,6 +391,7 @@ proptest! { } #[test] + #[cfg(feature = "alloc")] fn test_treemap_native_serialization_roundtrip( indices in prop::collection::vec(proptest::num::u64::ANY, 1..3000) ) { @@ -335,6 +405,7 @@ proptest! { } #[test] + #[cfg(feature = "alloc")] fn test_treemap_jvm_serialization_roundtrip( indices in prop::collection::vec(proptest::num::u64::ANY, 1..3000) ) { @@ -350,6 +421,7 @@ proptest! { proptest! { #[test] + #[cfg(feature = "alloc")] fn frozen_bitmap_portable_roundtrip( indices in prop::collection::vec(proptest::num::u32::ANY, 0..3000) ) { @@ -363,6 +435,7 @@ proptest! { } #[test] + #[cfg(feature = "alloc")] fn native_bitmap_roundtrip( indices in prop::collection::vec(proptest::num::u32::ANY, 0..3000) ) { @@ -376,6 +449,7 @@ proptest! { } #[test] + #[cfg(feature = "alloc")] fn frozen_bitmap_roundtrip( indices in prop::collection::vec(proptest::num::u32::ANY, 0..3000) ) { @@ -383,7 +457,7 @@ proptest! { let original = Bitmap::of(&indices); let mut buf = Vec::new(); - let serialized: &[u8] = original.serialize_into::(&mut buf); + let serialized: &[u8] = original.serialize_into_vec::(&mut buf); let deserialized = unsafe { BitmapView::deserialize::(serialized) }; assert_eq!(&original, &*deserialized); assert!(original.iter().eq(deserialized.iter())); diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock new file mode 100644 index 0000000..3e41918 --- /dev/null +++ b/fuzz/Cargo.lock @@ -0,0 +1,169 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "croaring" +version = "1.0.1" +dependencies = [ + "byteorder", + "croaring-sys", +] + +[[package]] +name = "croaring-fuzz" +version = "0.0.0" +dependencies = [ + "bitvec", + "croaring", + "libfuzzer-sys", +] + +[[package]] +name = "croaring-sys" +version = "1.1.0" +dependencies = [ + "cc", +] + +[[package]] +name = "derive_arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "libfuzzer-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +]