diff options
Diffstat (limited to 'third_party/rust/ahash')
23 files changed, 6494 insertions, 0 deletions
diff --git a/third_party/rust/ahash/.cargo-checksum.json b/third_party/rust/ahash/.cargo-checksum.json new file mode 100644 index 0000000000..639dfad602 --- /dev/null +++ b/third_party/rust/ahash/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"fb5d1d64108299ae6989a4acdc4e4b6c1ae70d69af68017d16952d928262c638","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"ff8f68cb076caf8cefe7a6430d4ac086ce6af2ca8ce2c4e5a2004d4552ef52a2","README.md":"3799556626a8a3147816593bcfd9ce18b047b54027f8733e75f2e1dbc05dc958","rustfmt.toml":"e090969e99df9360705680cc0097cfaddae10c22dc2e01470592cf3b9787fd36","smhasher/0001-Add-support-for-aHash.patch":"df01a714dd66554cab415afdec1bd634d19a53e564029ba4b84d2e1baffb6104","smhasher/ahashOutput.txt":"e1b1a01abc4d690bed4f2eeefcd63bd2a89d2d5bf3674e8839c8a26f25af4da3","smhasher/clone_smhasher.sh":"510e12ec67052486853f186ce3e18f342fc80da88a47bf9b1aca81c827cb72b7","smhasher/fallbackOutput.txt":"247a408cb8426ed6c0119861d1b06809983cbbff73eafc181fb29910139c1f01","src/aes_hash.rs":"c691bd8dc6d314034a2a085406bab7f21e03c5145b10ac6e8d3e905780d67c62","src/convert.rs":"59e9c20bfd37e8604c80b97339b77e6f6a600c8b177b672cad9ac3600f7f88e0","src/fallback_hash.rs":"01b8006048f810febd5699790389d50787f0cb6ba6035ac8982c57b8ab99b419","src/hash_map.rs":"36bf0b13e334d7cedbf83e4822438098b227e7c7e381abe5e1eeac1ff6caa209","src/hash_quality_test.rs":"bc642c29539a4acc75aa460d409008b7939c0eb8687e07e1a0d47f29fbbc9abb","src/hash_set.rs":"4289672c142e314a0bfc6535b5e8f5e07cc78b60c0c7b308a43fa361eca6ddea","src/lib.rs":"4a0b56b99ba7b941fc3a9412e825af4a9525e003192a894a055b8df4fda1bfbc","src/operations.rs":"82663e2e9d2dac714e84eb0c1daac979d20f7e80a7391027f8d03b0987186804","src/random_state.rs":"ac2aae2cf85d05be97376819291fe094109b85ce6bdcdcbeda26d85e10d2f6b3","src/specialize.rs":"3136ba21f0e9b991f6df589744f724d8e71586e0b48c969183a8b33ce7966c8c","tests/bench.rs":"90cc49473a25184c4d8d21d623a52b103e2d7c7c30e487da000b510c4ba5d944","tests/map_tests.rs":"c1e14ec39c2009d8a081349245e70af317c2d8424d40dc239a6c250c0adfae77","tests/nopanic.rs":"5edbaa43a16f8fc96180c2f3d576436640e6fc3221856df329b0540024625cab"},"package":"0adac150c2dd5a9c864d054e07bda5e6bc010cd10036ea5f17e82a2f5867f735"}
\ No newline at end of file diff --git a/third_party/rust/ahash/Cargo.toml b/third_party/rust/ahash/Cargo.toml new file mode 100644 index 0000000000..c418c0d409 --- /dev/null +++ b/third_party/rust/ahash/Cargo.toml @@ -0,0 +1,91 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "ahash" +version = "0.4.5" +authors = ["Tom Kaitchuck <Tom.Kaitchuck@gmail.com>"] +description = "A non-cryptographic hash function using AES-NI for high performance" +documentation = "https://docs.rs/ahash" +readme = "README.md" +keywords = ["hash", "hashmap", "aes", "aes-ni", "no-std"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/tkaitchuck/ahash" +[package.metadata.docs.rs] +features = ["std"] +rustc-args = ["-C", "target-feature=+aes"] +rustdoc-args = ["-C", "target-feature=+aes"] +[profile.bench] +opt-level = 3 +lto = "fat" +codegen-units = 1 +debug = false +debug-assertions = false + +[profile.release] +opt-level = 3 +lto = "fat" +codegen-units = 1 +debug = false +debug-assertions = false + +[profile.test] +opt-level = 2 +lto = "fat" + +[lib] +name = "ahash" +path = "src/lib.rs" +test = true +doctest = true +bench = true +doc = true + +[[bench]] +name = "ahash" +path = "tests/bench.rs" +harness = false + +[[bench]] +name = "map" +path = "tests/map_tests.rs" +harness = false +[dependencies.const-random] +version = "0.1.6" +optional = true +[dev-dependencies.criterion] +version = "0.3.2" + +[dev-dependencies.fnv] +version = "1.0.5" + +[dev-dependencies.fxhash] +version = "0.2.1" + +[dev-dependencies.hex] +version = "0.3.2" + +[dev-dependencies.no-panic] +version = "0.1.10" + +[dev-dependencies.rand] +version = "0.6.5" + +[dev-dependencies.seahash] +version = "3.0.5" + +[features] +compile-time-rng = ["const-random"] +default = ["compile-time-rng", "std"] +specialize = [] +std = [] diff --git a/third_party/rust/ahash/LICENSE-APACHE b/third_party/rust/ahash/LICENSE-APACHE new file mode 100644 index 0000000000..16fe87b06e --- /dev/null +++ b/third_party/rust/ahash/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/third_party/rust/ahash/LICENSE-MIT b/third_party/rust/ahash/LICENSE-MIT new file mode 100644 index 0000000000..5afc2a7b0a --- /dev/null +++ b/third_party/rust/ahash/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2016 Amanieu d'Antras + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/ahash/README.md b/third_party/rust/ahash/README.md new file mode 100644 index 0000000000..b1bf029d21 --- /dev/null +++ b/third_party/rust/ahash/README.md @@ -0,0 +1,245 @@ +# aHash + +AHash is a high speed keyed hashing algorithm intended for use in in-memory hashmaps. It provides a high quality +64bit hash. AHash is designed for performance and is not cryptographically secure. + +## Goals + +AHash is the fastest DOS resistant hash for use in HashMaps available in the Rust language. +Failing in any of these criteria will be treated as a bug. + +## Design + +AHash is a keyed hash, so two instances initialized with different keys will produce completely different hashes, and the +resulting hashes cannot be predicted without knowing the keys. [This prevents DOS attacks where an attacker sends a large +number of items whose hashes collide that get used as keys in a hashmap.](https://github.com/tkaitchuck/aHash/wiki/How-aHash-is-resists-DOS-attacks) + +AHash takes advantage of specialized hardware instructions whenever possible including the [hardware AES instruction](https://en.wikipedia.org/wiki/AES_instruction_set) +on X86 processors when it is available. If it is not available it falls back on a somewhat slower (but still DOS resistant) +[algorithm based on multiplication](https://github.com/tkaitchuck/aHash/wiki/AHash-fallback-algorithm). + +As such aHash does not have a fixed standard for its output. This is not a problem for Hashmaps, and allows aHash to achieve high performance and improve over time. + +## Non-Goals + +Because different computers or computers on versions of the code will observe different outputs Hash is not recommended +for use other than in-memory maps. Specifically aHash does not intend to be: + +* Used as a MACs or other application requiring a cryptographically secure hash +* Used for distributed applications or ones requiring persisting hashed values + +## Hash quality + +**Both aHash's aes variant and the fallback pass the full [SMHasher test suite](https://github.com/rurban/smhasher)** (the output of the tests is checked into the smhasher subdirectory.) + +At **over 50GB/s** aHash is the fastest algorithm to pass the full test suite by more than a factor of 2. Even the fallback algorithm is in the top 5 in terms of throughput. + +## Speed + +When it is available aHash uses AES rounds using the AES-NI instruction. AES-NI is very fast (on an intel i7-6700 it +is as fast as a 64 bit multiplication.) and handles 16 bytes of input at a time, while being a very strong permutation. + +This is obviously much faster than most standard approaches to hashing, and does a better job of scrambling data than most non-secure hashes. + +On an intel i7-6700 compiled on nightly Rust with flags `-C opt-level=3 -C target-cpu=native -C codegen-units=1`: + +| Input | SipHash 1-3 time | FnvHash time|FxHash time| aHash time| aHash Fallback* | +|----------------|-----------|-----------|-----------|-----------|---------------| +| u8 | 9.3271 ns | 0.808 ns | **0.594 ns** | 0.7704 ns | 0.7664 ns | +| u16 | 9.5139 ns | 0.803 ns | **0.594 ns** | 0.7653 ns | 0.7704 ns | +| u32 | 9.1196 ns | 1.4424 ns | **0.594 ns** | 0.7637 ns | 0.7712 ns | +| u64 | 10.854 ns | 3.0484 ns | **0.628 ns** | 0.7788 ns | 0.7888 ns | +| u128 | 12.465 ns | 7.0728 ns | 0.799 ns | **0.6174 ns** | 0.6250 ns | +| 1 byte string | 11.745 ns | 2.4743 ns | 2.4000 ns | **1.4921 ns** | 1.5861 ns | +| 3 byte string | 12.066 ns | 3.5221 ns | 2.9253 ns | **1.4745 ns** | 1.8518 ns | +| 4 byte string | 11.634 ns | 4.0770 ns | 1.8818 ns | **1.5206 ns** | 1.8924 ns | +| 7 byte string | 14.762 ns | 5.9780 ns | 3.2282 ns | **1.5207 ns** | 1.8933 ns | +| 8 byte string | 13.442 ns | 4.0535 ns | 2.9422 ns | **1.6262 ns** | 1.8929 ns | +| 15 byte string | 16.880 ns | 8.3434 ns | 4.6070 ns | **1.6265 ns** | 1.7965 ns | +| 16 byte string | 15.155 ns | 7.5796 ns | 3.2619 ns | **1.6262 ns** | 1.8011 ns | +| 24 byte string | 16.521 ns | 12.492 ns | 3.5424 ns | **1.6266 ns** | 2.8311 ns | +| 68 byte string | 24.598 ns | 50.715 ns | 5.8312 ns | **4.8282 ns** | 5.4824 ns | +| 132 byte string| 39.224 ns | 119.96 ns | 11.777 ns | **6.5087 ns** | 9.1459 ns | +|1024 byte string| 254.00 ns | 1087.3 ns | 156.41 ns | **25.402 ns** | 54.566 ns | + +* Fallback refers to the algorithm aHash would use if AES instructions are unavailable. +For reference a hash that does nothing (not even reads the input data takes) **0.520 ns**. So that represents the fastest +possible time. + +As you can see above aHash like `FxHash` provides a large speedup over `SipHash-1-3` which is already nearly twice as fast as `SipHash-2-4`. + +Rust's HashMap by default uses `SipHash-1-3` because faster hash functions such as `FxHash` are predictable and vulnerable to denial of +service attacks. While `aHash` has both very strong scrambling and very high performance. + +AHash performs well when dealing with large inputs because aHash reads 8 or 16 bytes at a time. (depending on availability of AES-NI) + +Because of this, and its optimized logic, `aHash` is able to outperform `FxHash` with strings. +It also provides especially good performance dealing with unaligned input. +(Notice the big performance gaps between 3 vs 4, 7 vs 8 and 15 vs 16 in `FxHash` above) + +For more a more representative performance comparison which includes the overhead of using a HashMap, see [HashBrown's benchmarks](https://github.com/rust-lang/hashbrown#performance) +as HashBrown now uses aHash as its hasher by default. + +## Security + +AHash is designed to [prevent an adversary that does not know the key from being able to create hash collisions or partial collisions.](https://github.com/tkaitchuck/aHash/wiki/How-aHash-is-resists-DOS-attacks) + +This achieved by ensuring that: + +* aHash is designed to [resist differential crypto analysis](https://github.com/tkaitchuck/aHash/wiki/How-aHash-is-resists-DOS-attacks#differential-analysis). Meaning it should not be possible to devise a scheme to "cancel" out a modification of the internal state from a block of input via some corresponding change in a subsequent block of input. + * This is achieved by not performing any "premixing" - This reversible mixing gave previous hashes such as murmurhash confidence in their quality, but could be undone by a deliberate attack. + * Before it is used each chunk of input is "masked" such as by xoring it with an unpredictable value. +* aHash obeys the '[strict avalanche criterion](https://en.wikipedia.org/wiki/Avalanche_effect#Strict_avalanche_criterion)': +Each bit of input has the potential to flip every bit of the output. +* Similarly, each bit in the key can affect every bit in the output. +* Input bits never affect just one, or a very few, bits in intermediate state. This is specifically designed to prevent the sort of +[differential attacks launched by the sipHash authors](https://emboss.github.io/blog/2012/12/14/breaking-murmur-hash-flooding-dos-reloaded/) which cancel previous inputs. +* The `finish` call at the end of the hash is designed to not expose individual bits of the internal state. + * For example in the main algorithm 256bits of state and 256bits of keys are reduced to 64 total bits using 3 rounds of AES encryption. +Reversing this is more than non-trivial. Most of the information is by definition gone, and any given bit of the internal state is fully diffused across the output. +* In both aHash and its fallback the internal state is divided into two halves which are updated by two unrelated techniques using the same input. - This means that if there is a way to attack one of them it likely won't be able to attack both of them at the same time. +* It is deliberately difficult to 'chain' collisions. + * To attack Previous attacks on hash functions have relied on the ability + +More details are available on [the wiki](https://github.com/tkaitchuck/aHash/wiki/How-aHash-is-resists-DOS-attacks). + +### aHash is not cryptographically secure + +AHash should not be used for situations where cryptographic security is needed. +It is not intended for this and will likely fail to hold up for several reasons. + +1. aHash relies on random keys which are assumed to not be observable by an attacker. For a cryptographic hash all inputs can be seen and controlled by the attacker. +2. aHash has not yet gone through peer review. +3. Because aHash uses reduced rounds of AES as opposed to the standard of 10. Things like the SQUARE attack apply to part of the internal state. +(These are mitigated by other means to prevent producing collections, but would be a problem in other contexts). +4. Like any cypher based hash, it will show certain statistical deviations from truly random output when comparing a (VERY) large number of hashes. +(By definition cyphers have fewer collisions than truly random data.) + +There are several efforts to build a secure hash function that uses AES-NI for acceleration, but aHash is not one of them. + +## Accelerated CPUs + +Hardware AES instructions are built into Intel processors built after 2010 and AMD processors after 2012. +It is also available on [many other CPUs](https://en.wikipedia.org/wiki/AES_instruction_set) should in eventually +be able to get aHash to work. However, only X86 and X86-64 are the only supported architectures at the moment, as currently +they are the only architectures for which Rust provides an intrinsic. + +aHash also uses `sse2` and `sse3` instructions. X86 processors that have `aesni` also have these instruction sets. + +## Why not use a cryptographic hash in a hashmap. + +Cryptographic hashes are designed to make is nearly impossible to find two items that collide when the attacker has full control +over the input. This has several implications: + +* They are very difficult to construct, and have to go to a lot of effort to ensure that collisions are not possible. +* They have no notion of a 'key'. Rather, they are fully deterministic and provide exactly one hash for a given input. + +For a HashMap the requirements are different. + +* Speed is very important, especially for short inputs. Often the key for a HashMap is a single `u32` or similar, and to be effective +the bucket that it should be hashed to needs to be computed in just a few CPU cycles. +* A hashmap does not need to provide a hard and fast guarantee that no two inputs will ever collide. Hence, hashCodes are not 256bits +but are just 64 or 32 bits in length. Often the first thing done with the hashcode is to truncate it further to compute which among a few buckets should be used for a key. + * Here collisions are expected, and a cheap to deal with provided there is no systematic way to generated huge numbers of values that all +go to the same bucket. + * This also means that unlike a cryptographic hash partial collisions matter. It doesn't do a hashmap any good to produce a unique 256bit hash if +the lower 12 bits are all the same. This means that even a provably irreversible hash would not offer protection from a DOS attack in a hashmap +because an attacker can easily just brute force the bottom N bits. + +From a cryptography point of view, a hashmap needs something closer to a block cypher. +Where the input can be quickly mixed in a way that cannot be reversed without knowing a key. + +# Why use aHash over X + +## SipHash + +For a hashmap: Because aHash nearly **10x** faster. + +SipHash is however useful in other contexts, such as for a HMAC, where aHash would be completely inappropriate. + +*SipHash-2-4* is designed to provide DOS attack resistance, and has no presently known attacks +against this claim that doesn't involve learning bits of the key. + +SipHash is also available in the "1-3" variant which is about twice as fast as the standard version. +The SipHash authors don't recommend using this variation when DOS attacks are a concern, but there are still no known +practical DOS attacks against the algorithm. Rust has opted for the "1-3" version as the default in `std::collections::HashMap`, +because the speed trade off of "2-4" was not worth it. + +As you can see in the table above, aHash is **much** faster than even *SipHash-1-3*, but it also provides DOS resistance, +and any attack against the accelerated form would likely involve a weakness in AES. + +## FxHash + +In terms of performance, aHash is faster than the FXhash for strings and byte arrays but not primitives. +So it might seem like using Fxhash for hashmaps when the key is a primitive is a good idea. This is *not* the case. + +When FX hash is operating on a 4 or 8 byte input such as a u32 or a u64, it reduces to multiplying the input by a fixed +constant. This is a bad hashing algorithm because it means that lower bits can never be influenced by any higher bit. In +the context of a hashmap where the low order bits are used to determine which bucket to put an item in, this isn't +any better than the identity function. Any keys that happen to end in the same bit pattern will all collide. +Some examples of where this is likely to occur are: + +* Strings encoded in base64 +* Null terminated strings (when working with C code) +* Integers that have the lower bits as zeros. (IE any multiple of small power of 2, which isn't a rare pattern in computer programs.) + * For example when taking lengths of data or locations in data it is common for values to +have a multiple of 1024, if these were used as keys in a map they will collide and end up in the same bucket. + +Like any non-keyed hash FxHash can be attacked. But FxHash is so prone to this that you may find yourself doing it accidentally. + +For example, it is possible to [accidentally introduce quadratic behavior by reading from one map in iteration order and writing to another.](https://accidentallyquadratic.tumblr.com/post/153545455987/rust-hash-iteration-reinsertion) + +Fxhash flaws make sense when you understand it for what it is. It is a quick and dirty hash, nothing more. +it was not published and promoted by its creator, it was **found**! + +Because it is error-prone, FxHash should never be used as a default. In specialized instances where the keys are understood +it makes sense, but given that aHash is faster on almost any object, it's probably not worth it. + +## FnvHash + +FnvHash is also a poor default. It only handles one byte at a time, so its performance really suffers with large inputs. +It is also non-keyed so it is still subject to DOS attacks and [accidentally quadratic behavior.](https://accidentallyquadratic.tumblr.com/post/153545455987/rust-hash-iteration-reinsertion) + +## MurmurHash, CityHash, MetroHash, FarmHash, HighwayHash, XXHash, SeaHash + +Murmur, City, Metro, Farm and Highway are all related, and appear to directly replace one another. Sea and XX are independent +and compete. + +They are all fine hashing algorithms, they do a good job of scrambling data, but they are all targeted at a different +usecase. They are intended to work in distributed systems where the hash is expected to be the same over time and from one +computer to the next, efficiently hashing large volumes of data. + +This is quite different from the needs of a Hasher used in a hashmap. In a map the typical value is under 10 bytes. None +of these algorithms scale down to handle that small of data at a competitive time. What's more the restriction that they +provide consistent output prevents them from taking advantage of different hardware capabilities on different CPUs. It makes +sense for a hashmap to work differently on a phone than on a server, or in wasm. + +If you need to persist or transmit a hash of a file, then using one of these is probably a good idea. HighwayHash seems to be the preferred solution du jour. But inside a simple Hashmap, stick with aHash. + +## AquaHash + +AquaHash is structured similarly to aHash. (Though the two were designed completely independently). AquaHash does not scale down nearly as well and +does poorly with for example a single `i32` as input. Its only implementation at this point is in C++. + +## t1ha + +T1ha is fairly fast at large sizes, and the output is of fairly high quality, but it is not clear what usecase it aims for. +It has many different versions and is very complex, and uses hardware tricks, so one might infer it is meant for +hashmaps like aHash. But any hash using it take at least **20ns**, and it doesn't outperform even SipHash until the +input sizes are larger than 128 bytes and is not designed to be DOS resistant. So uses are likely niche. + +# License + +Licensed under either of: + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +## Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any +additional terms or conditions. + diff --git a/third_party/rust/ahash/rustfmt.toml b/third_party/rust/ahash/rustfmt.toml new file mode 100644 index 0000000000..7530651796 --- /dev/null +++ b/third_party/rust/ahash/rustfmt.toml @@ -0,0 +1 @@ +max_width = 120 diff --git a/third_party/rust/ahash/smhasher/0001-Add-support-for-aHash.patch b/third_party/rust/ahash/smhasher/0001-Add-support-for-aHash.patch new file mode 100644 index 0000000000..99a98d380f --- /dev/null +++ b/third_party/rust/ahash/smhasher/0001-Add-support-for-aHash.patch @@ -0,0 +1,135 @@ +From 426384ce34cf410d892eeeeeb7f6046d52bff8e7 Mon Sep 17 00:00:00 2001 +From: Tom Kaitchuck <Tom.Kaitchuck@gmail.com> +Date: Sat, 11 Jul 2020 17:15:56 -0700 +Subject: [PATCH] Add support for ahash + +--- + CMakeLists.txt | 1 + + Hashes.h | 5 +++++ + ahash.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ + main.cpp | 2 +- + 4 files changed, 55 insertions(+), 1 deletion(-) + create mode 100644 ahash.h + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 6ebab1a..9d79e98 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -470,10 +470,11 @@ add_executable( + target_link_libraries( + SMHasher + SMHasherSupport + ${HIGHWAY_LIB} + ${BLAKE3_LIB} ++ libahash_c.a + ${CMAKE_THREAD_LIBS_INIT} + ) + + #add_executable( + # bittest +diff --git a/Hashes.h b/Hashes.h +index 4e111c1..fcd3e38 100644 +--- a/Hashes.h ++++ b/Hashes.h +@@ -19,10 +19,11 @@ + #if defined(__SSE4_2__) && defined(__x86_64__) + #include "metrohash/metrohash64crc.h" + #include "metrohash/metrohash128crc.h" + #endif + ++#include "ahash.h" + #include "fasthash.h" + #include "jody_hash32.h" + #include "jody_hash64.h" + + // objsize: 0-0x113 = 276 +@@ -356,10 +357,14 @@ inline void fasthash32_test ( const void * key, int len, uint32_t seed, void * o + } + #ifdef HAVE_INT64 + inline void fasthash64_test ( const void * key, int len, uint32_t seed, void * out ) { + *(uint64_t*)out = fasthash64(key, (size_t) len, (uint64_t)seed); + } ++inline void ahash64_test ( const void * key, int len, uint32_t seed, void * out ) { ++ *(uint64_t*)out = ahash64(key, (size_t) len, (uint64_t)seed); ++} ++ + #endif + + // objsize 0-778: 1912 + void mum_hash_test(const void * key, int len, uint32_t seed, void * out); + +diff --git a/ahash.h b/ahash.h +new file mode 100644 +index 0000000..6c59caf +--- /dev/null ++++ b/ahash.h +@@ -0,0 +1,48 @@ ++/* The MIT License ++ ++ Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com) ++ ++ Permission is hereby granted, free of charge, to any person ++ obtaining a copy of this software and associated documentation ++ files (the "Software"), to deal in the Software without ++ restriction, including without limitation the rights to use, copy, ++ modify, merge, publish, distribute, sublicense, and/or sell copies ++ of the Software, and to permit persons to whom the Software is ++ furnished to do so, subject to the following conditions: ++ ++ The above copyright notice and this permission notice shall be ++ included in all copies or substantial portions of the Software. ++ ++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ SOFTWARE. ++*/ ++ ++#ifndef _AHASH_H ++#define _AHASH_H ++ ++#include <stdint.h> ++#include <stdio.h> ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/** ++ * Ahash - 64-bit implementation of aHash ++ * @buf: data buffer ++ * @len: data size ++ * @seed: the seed ++ */ ++ uint64_t ahash64(const void *buf, size_t len, uint64_t seed); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +\ No newline at end of file +diff --git a/main.cpp b/main.cpp +index 04060f2..7489aaf 100644 +--- a/main.cpp ++++ b/main.cpp +@@ -263,11 +263,11 @@ HashInfo g_hashes[] = + + { xxh3_test, 64, 0x39CD9E4A, "xxh3", "xxHash v3, 64-bit", GOOD }, + { xxh3low_test, 32, 0xFAE8467B, "xxh3low", "xxHash v3, 64-bit, low 32-bits part", GOOD }, + { xxh128_test, 128, 0xEB61B3A0, "xxh128", "xxHash v3, 128-bit", GOOD }, + { xxh128low_test, 64, 0x54D1CC70, "xxh128low", "xxHash v3, 128-bit, low 64-bits part", GOOD }, +- ++ { ahash64_test, 64, 0x00000000, "ahash64", "ahash 64bit", GOOD }, //Expected value set to zero because aHash does not adhere to a fixed output. + #if __WORDSIZE >= 64 + # define TIFU_VERIF 0x644236D4 + #else + // broken on certain travis + # define TIFU_VERIF 0x0 +-- +2.25.1 + diff --git a/third_party/rust/ahash/smhasher/ahashOutput.txt b/third_party/rust/ahash/smhasher/ahashOutput.txt new file mode 100644 index 0000000000..f618f2cbcf --- /dev/null +++ b/third_party/rust/ahash/smhasher/ahashOutput.txt @@ -0,0 +1,1467 @@ +------------------------------------------------------------------------------- +--- Testing ahash64 "ahash 64bit" GOOD + +[[[ Sanity Tests ]]] + +Verification value 0x64556379 ....... SKIP (self- or unseeded) +Running sanity check 1 .......... PASS +Running AppendedZeroesTest .......... PASS + +[[[ Speed Tests ]]] + +Bulk speed test - 262144-byte keys +Alignment 7 - 19.381 bytes/cycle - 55448.94 MiB/sec @ 3 ghz +Alignment 6 - 19.351 bytes/cycle - 55363.53 MiB/sec @ 3 ghz +Alignment 5 - 19.357 bytes/cycle - 55380.15 MiB/sec @ 3 ghz +Alignment 4 - 19.332 bytes/cycle - 55308.08 MiB/sec @ 3 ghz +Alignment 3 - 19.296 bytes/cycle - 55206.94 MiB/sec @ 3 ghz +Alignment 2 - 19.326 bytes/cycle - 55292.64 MiB/sec @ 3 ghz +Alignment 1 - 19.336 bytes/cycle - 55322.04 MiB/sec @ 3 ghz +Alignment 0 - 20.429 bytes/cycle - 58448.30 MiB/sec @ 3 ghz +Average - 19.476 bytes/cycle - 55721.33 MiB/sec @ 3 ghz + +Small key speed test - 1-byte keys - 23.00 cycles/hash +Small key speed test - 2-byte keys - 23.13 cycles/hash +Small key speed test - 3-byte keys - 24.21 cycles/hash +Small key speed test - 4-byte keys - 24.00 cycles/hash +Small key speed test - 5-byte keys - 25.18 cycles/hash +Small key speed test - 6-byte keys - 25.02 cycles/hash +Small key speed test - 7-byte keys - 25.20 cycles/hash +Small key speed test - 8-byte keys - 27.75 cycles/hash +Small key speed test - 9-byte keys - 24.22 cycles/hash +Small key speed test - 10-byte keys - 24.00 cycles/hash +Small key speed test - 11-byte keys - 24.16 cycles/hash +Small key speed test - 12-byte keys - 24.04 cycles/hash +Small key speed test - 13-byte keys - 24.00 cycles/hash +Small key speed test - 14-byte keys - 24.00 cycles/hash +Small key speed test - 15-byte keys - 24.07 cycles/hash +Small key speed test - 16-byte keys - 24.26 cycles/hash +Small key speed test - 17-byte keys - 26.00 cycles/hash +Small key speed test - 18-byte keys - 26.43 cycles/hash +Small key speed test - 19-byte keys - 26.03 cycles/hash +Small key speed test - 20-byte keys - 26.38 cycles/hash +Small key speed test - 21-byte keys - 26.06 cycles/hash +Small key speed test - 22-byte keys - 26.24 cycles/hash +Small key speed test - 23-byte keys - 26.00 cycles/hash +Small key speed test - 24-byte keys - 25.99 cycles/hash +Small key speed test - 25-byte keys - 26.00 cycles/hash +Small key speed test - 26-byte keys - 25.99 cycles/hash +Small key speed test - 27-byte keys - 26.20 cycles/hash +Small key speed test - 28-byte keys - 25.98 cycles/hash +Small key speed test - 29-byte keys - 26.29 cycles/hash +Small key speed test - 30-byte keys - 25.99 cycles/hash +Small key speed test - 31-byte keys - 26.29 cycles/hash +Average 25.229 cycles/hash + +[[[ 'Hashmap' Speed Tests ]]] + +std::unordered_map +Init std HashMapTest: 289.522 cycles/op (102401 inserts, 1% deletions) +Running std HashMapTest: 122.314 cycles/op (5.1 stdv) + +greg7mdp/parallel-hashmap +Init fast HashMapTest: 110.898 cycles/op (102401 inserts, 1% deletions) +Running fast HashMapTest: 83.840 cycles/op (3.3 stdv) ....... PASS + +[[[ Avalanche Tests ]]] + +Testing 24-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.597333% +Testing 32-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.618667% +Testing 40-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.602667% +Testing 48-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.626667% +Testing 56-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.715333% +Testing 64-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.648667% +Testing 72-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.809333% +Testing 80-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.654000% +Testing 96-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.679333% +Testing 112-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.668000% +Testing 128-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.769333% +Testing 160-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.675333% +Testing 512-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.806667% +Testing 1024-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.826667% + +[[[ Keyset 'Sparse' Tests ]]] + +Keyset 'Sparse' - 16-bit keys with up to 9 bits set - 50643 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 0.6, actual 1 (1.67x) (1) +Testing collisions (high 19-26 bits) - Worst is 21 bits: 619/1222 (0.51x) +Testing collisions (high 12-bit) - Expected 50643.0, actual 46547 (0.92x) +Testing collisions (high 8-bit) - Expected 50643.0, actual 50387 (0.99x) (-256) +Testing collisions (low 32-bit) - Expected 0.6, actual 0 (0.00x) +Testing collisions (low 19-26 bits) - Worst is 20 bits: 1256/2445 (0.51x) +Testing collisions (low 12-bit) - Expected 50643.0, actual 46547 (0.92x) +Testing collisions (low 8-bit) - Expected 50643.0, actual 50387 (0.99x) (-256) +Testing distribution - Worst bias is the 13-bit window at bit 44 - 0.509% + +Keyset 'Sparse' - 24-bit keys with up to 8 bits set - 1271626 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 376.5, actual 169 (0.45x) +Testing collisions (high 24-36 bits) - Worst is 28 bits: 3066/6023 (0.51x) +Testing collisions (high 12-bit) - Expected 1271626.0, actual 1267530 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 1271626.0, actual 1271370 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 376.5, actual 193 (0.51x) +Testing collisions (low 24-36 bits) - Worst is 36 bits: 13/23 (0.55x) +Testing collisions (low 12-bit) - Expected 1271626.0, actual 1267530 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 1271626.0, actual 1271370 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 42 - 0.090% + +Keyset 'Sparse' - 32-bit keys with up to 7 bits set - 4514873 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 4746.0, actual 2349 (0.49x) +Testing collisions (high 26-39 bits) - Worst is 33 bits: 1211/2373 (0.51x) +Testing collisions (high 12-bit) - Expected 4514873.0, actual 4510777 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 4514873.0, actual 4514617 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 4746.0, actual 2291 (0.48x) +Testing collisions (low 26-39 bits) - Worst is 29 bits: 18953/37968 (0.50x) +Testing collisions (low 12-bit) - Expected 4514873.0, actual 4510777 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 4514873.0, actual 4514617 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 58 - 0.042% + +Keyset 'Sparse' - 40-bit keys with up to 6 bits set - 4598479 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 4923.4, actual 2464 (0.50x) +Testing collisions (high 26-39 bits) - Worst is 37 bits: 86/153 (0.56x) +Testing collisions (high 12-bit) - Expected 4598479.0, actual 4594383 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 4598479.0, actual 4598223 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 4923.4, actual 2396 (0.49x) +Testing collisions (low 26-39 bits) - Worst is 39 bits: 24/38 (0.62x) +Testing collisions (low 12-bit) - Expected 4598479.0, actual 4594383 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 4598479.0, actual 4598223 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 13 - 0.035% + +Keyset 'Sparse' - 48-bit keys with up to 6 bits set - 14196869 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 46927.3, actual 23526 (0.50x) +Testing collisions (high 28-43 bits) - Worst is 40 bits: 94/183 (0.51x) +Testing collisions (high 12-bit) - Expected 14196869.0, actual 14192773 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 14196869.0, actual 14196613 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 46927.3, actual 23571 (0.50x) +Testing collisions (low 28-43 bits) - Worst is 43 bits: 13/22 (0.57x) +Testing collisions (low 12-bit) - Expected 14196869.0, actual 14192773 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 14196869.0, actual 14196613 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 24 - 0.021% + +Keyset 'Sparse' - 56-bit keys with up to 5 bits set - 4216423 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 4139.3, actual 2005 (0.48x) +Testing collisions (high 26-39 bits) - Worst is 29 bits: 16547/33114 (0.50x) +Testing collisions (high 12-bit) - Expected 4216423.0, actual 4212327 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 4216423.0, actual 4216167 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 4139.3, actual 2099 (0.51x) +Testing collisions (low 26-39 bits) - Worst is 32 bits: 2099/4139 (0.51x) +Testing collisions (low 12-bit) - Expected 4216423.0, actual 4212327 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 4216423.0, actual 4216167 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 31 - 0.057% + +Keyset 'Sparse' - 64-bit keys with up to 5 bits set - 8303633 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16053.7, actual 7962 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 39 bits: 78/125 (0.62x) +Testing collisions (high 12-bit) - Expected 8303633.0, actual 8299537 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8303633.0, actual 8303377 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16053.7, actual 8118 (0.51x) +Testing collisions (low 27-41 bits) - Worst is 38 bits: 140/250 (0.56x) +Testing collisions (low 12-bit) - Expected 8303633.0, actual 8299537 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8303633.0, actual 8303377 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 7 - 0.037% + +Keyset 'Sparse' - 72-bit keys with up to 5 bits set - 15082603 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 52965.5, actual 26838 (0.51x) +Testing collisions (high 28-43 bits) - Worst is 43 bits: 17/25 (0.66x) +Testing collisions (high 12-bit) - Expected 15082603.0, actual 15078507 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 15082603.0, actual 15082347 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 52965.5, actual 26568 (0.50x) +Testing collisions (low 28-43 bits) - Worst is 36 bits: 1703/3310 (0.51x) +Testing collisions (low 12-bit) - Expected 15082603.0, actual 15078507 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 15082603.0, actual 15082347 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 20 - 0.029% + +Keyset 'Sparse' - 96-bit keys with up to 4 bits set - 3469497 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 2802.7, actual 1368 (0.49x) +Testing collisions (high 26-39 bits) - Worst is 38 bits: 36/43 (0.82x) +Testing collisions (high 12-bit) - Expected 3469497.0, actual 3465401 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 3469497.0, actual 3469241 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 2802.7, actual 1366 (0.49x) +Testing collisions (low 26-39 bits) - Worst is 36 bits: 88/175 (0.50x) +Testing collisions (low 12-bit) - Expected 3469497.0, actual 3465401 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 3469497.0, actual 3469241 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 16 - 0.080% + +Keyset 'Sparse' - 160-bit keys with up to 4 bits set - 26977161 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 169446.5, actual 84423 (0.50x) +Testing collisions (high 29-45 bits) - Worst is 43 bits: 51/82 (0.62x) +Testing collisions (high 12-bit) - Expected 26977161.0, actual 26973065 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 26977161.0, actual 26976905 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 169446.5, actual 84652 (0.50x) +Testing collisions (low 29-45 bits) - Worst is 45 bits: 15/20 (0.73x) +Testing collisions (low 12-bit) - Expected 26977161.0, actual 26973065 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 26977161.0, actual 26976905 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 20 - 0.010% + +Keyset 'Sparse' - 256-bit keys with up to 3 bits set - 2796417 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1820.7, actual 893 (0.49x) +Testing collisions (high 25-38 bits) - Worst is 37 bits: 36/56 (0.63x) +Testing collisions (high 12-bit) - Expected 2796417.0, actual 2792321 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2796417.0, actual 2796161 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1820.7, actual 946 (0.52x) +Testing collisions (low 25-38 bits) - Worst is 37 bits: 32/56 (0.56x) +Testing collisions (low 12-bit) - Expected 2796417.0, actual 2792321 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2796417.0, actual 2796161 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 29 - 0.120% + +Keyset 'Sparse' - 512-bit keys with up to 3 bits set - 22370049 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 116512.9, actual 58551 (0.50x) +Testing collisions (high 28-44 bits) - Worst is 42 bits: 59/113 (0.52x) +Testing collisions (high 12-bit) - Expected 22370049.0, actual 22365953 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 22370049.0, actual 22369793 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 116512.9, actual 58363 (0.50x) +Testing collisions (low 28-44 bits) - Worst is 40 bits: 238/455 (0.52x) +Testing collisions (low 12-bit) - Expected 22370049.0, actual 22365953 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 22370049.0, actual 22369793 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 39 - 0.015% + +Keyset 'Sparse' - 1024-bit keys with up to 2 bits set - 524801 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 64.1, actual 34 (0.53x) +Testing collisions (high 23-33 bits) - Worst is 30 bits: 147/256 (0.57x) +Testing collisions (high 12-bit) - Expected 524801.0, actual 520705 (0.99x) (-4096) +Testing collisions (high 8-bit) - Expected 524801.0, actual 524545 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 64.1, actual 35 (0.55x) +Testing collisions (low 23-33 bits) - Worst is 33 bits: 22/32 (0.69x) +Testing collisions (low 12-bit) - Expected 524801.0, actual 520705 (0.99x) (-4096) +Testing collisions (low 8-bit) - Expected 524801.0, actual 524545 (1.00x) (-256) +Testing distribution - Worst bias is the 16-bit window at bit 29 - 0.187% + +Keyset 'Sparse' - 2048-bit keys with up to 2 bits set - 2098177 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1025.0, actual 487 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 38/64 (0.59x) +Testing collisions (high 12-bit) - Expected 2098177.0, actual 2094081 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2098177.0, actual 2097921 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1025.0, actual 477 (0.47x) +Testing collisions (low 25-37 bits) - Worst is 30 bits: 2058/4100 (0.50x) +Testing collisions (low 12-bit) - Expected 2098177.0, actual 2094081 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2098177.0, actual 2097921 (1.00x) (-256) +Testing distribution - Worst bias is the 18-bit window at bit 59 - 0.078% + + +[[[ Keyset 'Permutation' Tests ]]] + +Combination Lowbits Tests: +Keyset 'Combination' - up to 7 blocks from a set of 8 - 2396744 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1337.5, actual 700 (0.52x) +Testing collisions (high 25-38 bits) - Worst is 38 bits: 15/20 (0.72x) +Testing collisions (high 12-bit) - Expected 2396744.0, actual 2392648 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2396744.0, actual 2396488 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1337.5, actual 695 (0.52x) +Testing collisions (low 25-38 bits) - Worst is 32 bits: 695/1337 (0.52x) +Testing collisions (low 12-bit) - Expected 2396744.0, actual 2392648 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2396744.0, actual 2396488 (1.00x) (-256) +Testing distribution - Worst bias is the 18-bit window at bit 25 - 0.078% + + +Combination Highbits Tests +Keyset 'Combination' - up to 7 blocks from a set of 8 - 2396744 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1337.5, actual 653 (0.49x) +Testing collisions (high 25-38 bits) - Worst is 29 bits: 5394/10699 (0.50x) +Testing collisions (high 12-bit) - Expected 2396744.0, actual 2392648 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2396744.0, actual 2396488 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1337.5, actual 644 (0.48x) +Testing collisions (low 25-38 bits) - Worst is 31 bits: 1325/2674 (0.50x) +Testing collisions (low 12-bit) - Expected 2396744.0, actual 2392648 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2396744.0, actual 2396488 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 18 - 0.038% + + +Combination Hi-Lo Tests: +Keyset 'Combination' - up to 6 blocks from a set of 15 - 12204240 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 34678.6, actual 17516 (0.51x) +Testing collisions (high 27-42 bits) - Worst is 42 bits: 20/33 (0.59x) +Testing collisions (high 12-bit) - Expected 12204240.0, actual 12200144 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 12204240.0, actual 12203984 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 34678.6, actual 17293 (0.50x) +Testing collisions (low 27-42 bits) - Worst is 42 bits: 21/33 (0.62x) +Testing collisions (low 12-bit) - Expected 12204240.0, actual 12200144 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 12204240.0, actual 12203984 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 38 - 0.022% + + +Combination 0x8000000 Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8370 (0.51x) +Testing collisions (high 27-41 bits) - Worst is 40 bits: 43/63 (0.67x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8184 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 40 bits: 37/63 (0.58x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 13 - 0.038% + + +Combination 0x0000001 Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8150 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 34 bits: 2047/4095 (0.50x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8264 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 37 bits: 273/511 (0.53x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 18 - 0.038% + + +Combination 0x800000000000000 Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8130 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 38 bits: 141/255 (0.55x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8166 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 41 bits: 22/31 (0.69x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 31 - 0.026% + + +Combination 0x000000000000001 Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8245 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 39 bits: 78/127 (0.61x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8289 (0.51x) +Testing collisions (low 27-41 bits) - Worst is 37 bits: 274/511 (0.54x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 17 - 0.033% + + +Combination 16-bytes [0-1] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8185 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 41 bits: 28/31 (0.88x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8232 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 38 bits: 152/255 (0.59x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 27 - 0.024% + + +Combination 16-bytes [0-last] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8107 (0.49x) +Testing collisions (high 27-41 bits) - Worst is 34 bits: 2065/4095 (0.50x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8082 (0.49x) +Testing collisions (low 27-41 bits) - Worst is 39 bits: 67/127 (0.52x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 23 - 0.044% + + +Combination 32-bytes [0-1] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8127 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 41 bits: 25/31 (0.78x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8238 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 38 bits: 150/255 (0.59x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 3 - 0.045% + + +Combination 32-bytes [0-last] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8193 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 35 bits: 1079/2047 (0.53x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8201 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 41 bits: 18/31 (0.56x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 26 - 0.036% + + +Combination 64-bytes [0-1] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8169 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 39 bits: 72/127 (0.56x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8101 (0.49x) +Testing collisions (low 27-41 bits) - Worst is 29 bits: 65198/131071 (0.50x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 27 - 0.022% + + +Combination 64-bytes [0-last] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8175 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 40 bits: 39/63 (0.61x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8220 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 39 bits: 83/127 (0.65x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 24 - 0.035% + + +Combination 128-bytes [0-1] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8183 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 36 bits: 532/1023 (0.52x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8309 (0.51x) +Testing collisions (low 27-41 bits) - Worst is 41 bits: 18/31 (0.56x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 33 - 0.040% + + +Combination 128-bytes [0-last] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8280 (0.51x) +Testing collisions (high 27-41 bits) - Worst is 40 bits: 41/63 (0.64x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8222 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 40 bits: 37/63 (0.58x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 27 - 0.052% + + +[[[ Keyset 'Window' Tests ]]] + +Keyset 'Window' - 32-bit key, 25-bit window - 32 tests, 33554432 keys per test +Window at 0 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 1 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 2 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 3 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 4 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 5 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 6 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 7 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 8 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 9 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 10 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 11 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 12 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 13 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 14 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 15 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 16 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 17 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 18 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 19 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 20 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 21 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 22 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 23 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 24 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 25 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 26 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 27 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 28 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 29 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 30 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 31 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 32 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) + +[[[ Keyset 'Cyclic' Tests ]]] + +Keyset 'Cyclic' - 8 cycles of 8 bytes - 1000000 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 232.8, actual 129 (0.55x) +Testing collisions (high 24-35 bits) - Worst is 35 bits: 20/29 (0.69x) +Testing collisions (high 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 232.8, actual 125 (0.54x) +Testing collisions (low 24-35 bits) - Worst is 34 bits: 37/58 (0.64x) +Testing collisions (low 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 22 - 0.076% + +Keyset 'Cyclic' - 8 cycles of 9 bytes - 1000000 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 232.8, actual 106 (0.46x) +Testing collisions (high 24-35 bits) - Worst is 29 bits: 948/1862 (0.51x) +Testing collisions (high 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 232.8, actual 121 (0.52x) +Testing collisions (low 24-35 bits) - Worst is 32 bits: 121/232 (0.52x) +Testing collisions (low 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 6 - 0.088% + +Keyset 'Cyclic' - 8 cycles of 10 bytes - 1000000 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 232.8, actual 115 (0.49x) +Testing collisions (high 24-35 bits) - Worst is 27 bits: 3685/7450 (0.49x) +Testing collisions (high 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 232.8, actual 121 (0.52x) +Testing collisions (low 24-35 bits) - Worst is 35 bits: 19/29 (0.65x) +Testing collisions (low 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 46 - 0.121% + +Keyset 'Cyclic' - 8 cycles of 11 bytes - 1000000 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 232.8, actual 119 (0.51x) +Testing collisions (high 24-35 bits) - Worst is 32 bits: 119/232 (0.51x) +Testing collisions (high 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 232.8, actual 128 (0.55x) +Testing collisions (low 24-35 bits) - Worst is 32 bits: 128/232 (0.55x) +Testing collisions (low 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 17 - 0.118% + +Keyset 'Cyclic' - 8 cycles of 12 bytes - 1000000 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 232.8, actual 102 (0.44x) +Testing collisions (high 24-35 bits) - Worst is 30 bits: 468/931 (0.50x) +Testing collisions (high 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 232.8, actual 134 (0.58x) +Testing collisions (low 24-35 bits) - Worst is 34 bits: 36/58 (0.62x) +Testing collisions (low 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing distribution - Worst bias is the 16-bit window at bit 58 - 0.055% + +Keyset 'Cyclic' - 8 cycles of 16 bytes - 1000000 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 232.8, actual 112 (0.48x) +Testing collisions (high 24-35 bits) - Worst is 34 bits: 32/58 (0.55x) +Testing collisions (high 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 232.8, actual 118 (0.51x) +Testing collisions (low 24-35 bits) - Worst is 35 bits: 18/29 (0.62x) +Testing collisions (low 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 30 - 0.087% + + +[[[ Keyset 'TwoBytes' Tests ]]] + +Keyset 'TwoBytes' - up-to-4-byte keys, 652545 total keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 99.1, actual 45 (0.45x) +Testing collisions (high 23-34 bits) - Worst is 29 bits: 417/793 (0.53x) +Testing collisions (high 12-bit) - Expected 652545.0, actual 648449 (0.99x) (-4096) +Testing collisions (high 8-bit) - Expected 652545.0, actual 652289 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 99.1, actual 47 (0.47x) +Testing collisions (low 23-34 bits) - Worst is 34 bits: 15/24 (0.61x) +Testing collisions (low 12-bit) - Expected 652545.0, actual 648449 (0.99x) (-4096) +Testing collisions (low 8-bit) - Expected 652545.0, actual 652289 (1.00x) (-256) +Testing distribution - Worst bias is the 16-bit window at bit 24 - 0.125% + +Keyset 'TwoBytes' - up-to-8-byte keys, 5471025 total keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 6969.1, actual 3563 (0.51x) +Testing collisions (high 26-40 bits) - Worst is 39 bits: 38/54 (0.70x) +Testing collisions (high 12-bit) - Expected 5471025.0, actual 5466929 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 5471025.0, actual 5470769 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 6969.1, actual 3405 (0.49x) +Testing collisions (low 26-40 bits) - Worst is 40 bits: 17/27 (0.62x) +Testing collisions (low 12-bit) - Expected 5471025.0, actual 5466929 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 5471025.0, actual 5470769 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 36 - 0.047% + +Keyset 'TwoBytes' - up-to-12-byte keys, 18616785 total keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 80695.5, actual 40179 (0.50x) +Testing collisions (high 28-43 bits) - Worst is 42 bits: 43/78 (0.55x) +Testing collisions (high 12-bit) - Expected 18616785.0, actual 18612689 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 18616785.0, actual 18616529 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 80695.5, actual 40091 (0.50x) +Testing collisions (low 28-43 bits) - Worst is 39 bits: 352/630 (0.56x) +Testing collisions (low 12-bit) - Expected 18616785.0, actual 18612689 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 18616785.0, actual 18616529 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 9 - 0.015% + +Keyset 'TwoBytes' - up-to-16-byte keys, 44251425 total keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 455926.3, actual 228151 (0.50x) +Testing collisions (high 29-46 bits) - Worst is 46 bits: 19/27 (0.68x) +Testing collisions (high 12-bit) - Expected 44251425.0, actual 44247329 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 44251425.0, actual 44251169 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 455926.3, actual 227299 (0.50x) +Testing collisions (low 29-46 bits) - Worst is 43 bits: 120/222 (0.54x) +Testing collisions (low 12-bit) - Expected 44251425.0, actual 44247329 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 44251425.0, actual 44251169 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 0 - 0.011% + +Keyset 'TwoBytes' - up-to-20-byte keys, 86536545 total keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1743569.4, actual 866811 (0.50x) +Testing collisions (high 30-48 bits) - Worst is 48 bits: 16/26 (0.60x) +Testing collisions (high 12-bit) - Expected 86536545.0, actual 86532449 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 86536545.0, actual 86536289 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1743569.4, actual 866063 (0.50x) +Testing collisions (low 30-48 bits) - Worst is 48 bits: 16/26 (0.60x) +Testing collisions (low 12-bit) - Expected 86536545.0, actual 86532449 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 86536545.0, actual 86536289 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 33 - 0.003% + + +[[[ Keyset 'Text' Tests ]]] + +Keyset 'Text' - keys of form "Foo[XXXX]Bar" - 14776336 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 50836.3, actual 25425 (0.50x) +Testing collisions (high 28-43 bits) - Worst is 38 bits: 408/794 (0.51x) +Testing collisions (high 12-bit) - Expected 14776336.0, actual 14772240 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 14776336.0, actual 14776080 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 50836.3, actual 25393 (0.50x) +Testing collisions (low 28-43 bits) - Worst is 42 bits: 29/49 (0.58x) +Testing collisions (low 12-bit) - Expected 14776336.0, actual 14772240 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 14776336.0, actual 14776080 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 31 - 0.016% + +Keyset 'Text' - keys of form "FooBar[XXXX]" - 14776336 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 50836.3, actual 25313 (0.50x) +Testing collisions (high 28-43 bits) - Worst is 43 bits: 15/24 (0.60x) +Testing collisions (high 12-bit) - Expected 14776336.0, actual 14772240 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 14776336.0, actual 14776080 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 50836.3, actual 25194 (0.50x) +Testing collisions (low 28-43 bits) - Worst is 43 bits: 14/24 (0.56x) +Testing collisions (low 12-bit) - Expected 14776336.0, actual 14772240 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 14776336.0, actual 14776080 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 35 - 0.030% + +Keyset 'Text' - keys of form "[XXXX]FooBar" - 14776336 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 50836.3, actual 25595 (0.50x) +Testing collisions (high 28-43 bits) - Worst is 43 bits: 15/24 (0.60x) +Testing collisions (high 12-bit) - Expected 14776336.0, actual 14772240 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 14776336.0, actual 14776080 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 50836.3, actual 25449 (0.50x) +Testing collisions (low 28-43 bits) - Worst is 33 bits: 12824/25418 (0.50x) +Testing collisions (low 12-bit) - Expected 14776336.0, actual 14772240 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 14776336.0, actual 14776080 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 50 - 0.016% + + +[[[ Keyset 'Zeroes' Tests ]]] + +Keyset 'Zeroes' - 204800 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 9.8, actual 7 (0.72x) +Testing collisions (high 21-30 bits) - Worst is 30 bits: 26/39 (0.67x) +Testing collisions (high 12-bit) - Expected 204800.0, actual 200704 (0.98x) +Testing collisions (high 8-bit) - Expected 204800.0, actual 204544 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 9.8, actual 5 (0.51x) +Testing collisions (low 21-30 bits) - Worst is 24 bits: 1231/2499 (0.49x) +Testing collisions (low 12-bit) - Expected 204800.0, actual 200704 (0.98x) +Testing collisions (low 8-bit) - Expected 204800.0, actual 204544 (1.00x) (-256) +Testing distribution - Worst bias is the 15-bit window at bit 14 - 0.314% + + +[[[ Keyset 'Seed' Tests ]]] + +Keyset 'Seed' - 5000000 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 5820.8, actual 2941 (0.51x) +Testing collisions (high 26-40 bits) - Worst is 40 bits: 13/22 (0.57x) +Testing collisions (high 12-bit) - Expected 5000000.0, actual 4995904 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 5000000.0, actual 4999744 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 5820.8, actual 2912 (0.50x) +Testing collisions (low 26-40 bits) - Worst is 37 bits: 105/181 (0.58x) +Testing collisions (low 12-bit) - Expected 5000000.0, actual 4995904 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 5000000.0, actual 4999744 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 53 - 0.051% + + +[[[ Keyset 'PerlinNoise' Tests ]]] + +Testing 16777216 coordinates (L2) : +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 65536.0, actual 33050 (0.50x) +Testing collisions (high 28-43 bits) - Worst is 39 bits: 267/511 (0.52x) +Testing collisions (high 12-bit) - Expected 16777216.0, actual 16773120 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 16777216.0, actual 16776960 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 65536.0, actual 32690 (0.50x) +Testing collisions (low 28-43 bits) - Worst is 42 bits: 38/63 (0.59x) +Testing collisions (low 12-bit) - Expected 16777216.0, actual 16773120 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 16777216.0, actual 16776960 (1.00x) (-256) + + +[[[ Diff 'Differential' Tests ]]] + +Testing 8303632 up-to-5-bit differentials in 64-bit keys -> 64 bit hashes. +1000 reps, 8303632000 total tests, expecting 0.00 random collisions.......... +0 total collisions, of which 0 single collisions were ignored + +Testing 11017632 up-to-4-bit differentials in 128-bit keys -> 64 bit hashes. +1000 reps, 11017632000 total tests, expecting 0.00 random collisions.......... +0 total collisions, of which 0 single collisions were ignored + +Testing 2796416 up-to-3-bit differentials in 256-bit keys -> 64 bit hashes. +1000 reps, 2796416000 total tests, expecting 0.00 random collisions.......... +0 total collisions, of which 0 single collisions were ignored + + +[[[ DiffDist 'Differential Distribution' Tests ]]] + +Testing bit 0 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 503 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 33 bits: 259/511 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 520 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 1 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 520 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 38/63 (0.59x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 515 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 33 bits: 261/511 (0.51x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 2 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 484 (0.47x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 504 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 34/63 (0.53x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 3 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 504 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 35 bits: 79/127 (0.62x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 555 (0.54x) +Testing collisions (low 25-37 bits) - Worst is 35 bits: 82/127 (0.64x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 4 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 538 (0.53x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 37/63 (0.58x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 511 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 31 bits: 1077/2047 (0.53x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 5 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 515 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 34 bits: 139/255 (0.54x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 525 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 6 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 519 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 19/31 (0.59x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 572 (0.56x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 42/63 (0.66x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 7 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 535 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 20/31 (0.63x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 518 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 20/31 (0.63x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 8 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 561 (0.55x) +Testing collisions (high 25-37 bits) - Worst is 32 bits: 561/1023 (0.55x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 537 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 35 bits: 68/127 (0.53x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 9 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 520 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 35 bits: 67/127 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 505 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 30 bits: 2119/4095 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 10 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 534 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 45/63 (0.70x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 489 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 28 bits: 8383/16383 (0.51x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 11 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 518 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 546 (0.53x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 12 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 517 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 20/31 (0.63x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 506 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 33/63 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 13 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 549 (0.54x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 38/63 (0.59x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 524 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 34 bits: 153/255 (0.60x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 14 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 516 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 21/31 (0.66x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 516 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 23/31 (0.72x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 15 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 526 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 33 bits: 267/511 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 528 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 32 bits: 528/1023 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 16 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 525 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 34 bits: 141/255 (0.55x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 514 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 40/63 (0.63x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 17 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 520 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 31 bits: 1041/2047 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 511 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 20/31 (0.63x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 18 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 527 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 32 bits: 527/1023 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 573 (0.56x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 30/31 (0.94x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 19 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 502 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 20/31 (0.63x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 489 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 34 bits: 133/255 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 20 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 553 (0.54x) +Testing collisions (high 25-37 bits) - Worst is 32 bits: 553/1023 (0.54x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 527 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 37/63 (0.58x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 21 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 499 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 38/63 (0.59x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 489 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 30 bits: 2085/4095 (0.51x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 22 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 507 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 34 bits: 135/255 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 488 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 29 bits: 4118/8191 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 23 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 501 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 34/63 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 469 (0.46x) +Testing collisions (low 25-37 bits) - Worst is 27 bits: 16619/32767 (0.51x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 24 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 519 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 31 bits: 1050/2047 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 526 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 35 bits: 82/127 (0.64x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 25 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 532 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 34/63 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 516 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 26 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 530 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 31 bits: 1063/2047 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 525 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 29 bits: 4240/8191 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 27 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 529 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 34 bits: 155/255 (0.61x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 496 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 35 bits: 67/127 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 28 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 517 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 31 bits: 1049/2047 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 523 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 24/31 (0.75x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 29 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 522 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 36/63 (0.56x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 545 (0.53x) +Testing collisions (low 25-37 bits) - Worst is 32 bits: 545/1023 (0.53x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 30 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 496 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 26 bits: 32495/65535 (0.50x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 467 (0.46x) +Testing collisions (low 25-37 bits) - Worst is 28 bits: 8269/16383 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 31 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 500 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 22/31 (0.69x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 491 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 22/31 (0.69x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 32 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 501 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 33 bits: 264/511 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 527 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 17/31 (0.53x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 33 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 501 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 34 bits: 142/255 (0.55x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 525 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 36/63 (0.56x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 34 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 488 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 30 bits: 2036/4095 (0.50x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 464 (0.45x) +Testing collisions (low 25-37 bits) - Worst is 26 bits: 32633/65535 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 35 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 533 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 23/31 (0.72x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 517 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 22/31 (0.69x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 36 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 561 (0.55x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 22/31 (0.69x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 512 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 26/31 (0.81x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 37 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 487 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 29 bits: 4102/8191 (0.50x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 522 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 32 bits: 522/1023 (0.51x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 38 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 531 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 38/63 (0.59x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 471 (0.46x) +Testing collisions (low 25-37 bits) - Worst is 34 bits: 138/255 (0.54x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 39 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 486 (0.47x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 16/31 (0.50x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 525 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 40/63 (0.63x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 40 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 490 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 17/31 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 485 (0.47x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 40/63 (0.63x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 41 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 492 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 34/63 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 539 (0.53x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 39/63 (0.61x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 42 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 508 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 484 (0.47x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 22/31 (0.69x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 43 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 494 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 35 bits: 70/127 (0.55x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 558 (0.54x) +Testing collisions (low 25-37 bits) - Worst is 35 bits: 76/127 (0.59x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 44 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 538 (0.53x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 21/31 (0.66x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 491 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 33 bits: 258/511 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 45 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 543 (0.53x) +Testing collisions (high 25-37 bits) - Worst is 32 bits: 543/1023 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 502 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 33 bits: 264/511 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 46 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 510 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 41/63 (0.64x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 488 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 22/31 (0.69x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 47 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 528 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 34 bits: 139/255 (0.54x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 474 (0.46x) +Testing collisions (low 25-37 bits) - Worst is 35 bits: 70/127 (0.55x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 48 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 487 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 27 bits: 16234/32767 (0.50x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 499 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 17/31 (0.53x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 49 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 511 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 33 bits: 267/511 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 530 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 20/31 (0.63x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 50 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 532 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 38/63 (0.59x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 511 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 30 bits: 2111/4095 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 51 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 499 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 31 bits: 1034/2047 (0.50x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 530 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 23/31 (0.72x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 52 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 494 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 31 bits: 1029/2047 (0.50x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 461 (0.45x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 35/63 (0.55x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 53 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 530 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 33 bits: 272/511 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 502 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 54 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 502 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 36/63 (0.56x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 495 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 22/31 (0.69x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 55 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 516 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 29 bits: 4224/8191 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 533 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 24/31 (0.75x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 56 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 489 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 19/31 (0.59x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 521 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 27/31 (0.84x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 57 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 556 (0.54x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 19/31 (0.59x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 481 (0.47x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 42/63 (0.66x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 58 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 507 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 518 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 59 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 530 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 34/63 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 450 (0.44x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 17/31 (0.53x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 60 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 494 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 30 bits: 2077/4095 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 501 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 30 bits: 2058/4095 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 61 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 545 (0.53x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 28/31 (0.88x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 514 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 31 bits: 1062/2047 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 62 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 500 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 35 bits: 67/127 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 521 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 25/31 (0.78x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 63 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 481 (0.47x) +Testing collisions (high 25-37 bits) - Worst is 30 bits: 2051/4095 (0.50x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 457 (0.45x) +Testing collisions (low 25-37 bits) - Worst is 27 bits: 16460/32767 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + + +[[[ MomentChi2 Tests ]]] + +Analyze hashes produced from a serie of linearly increasing numbers of 32-bit, using a step of 3 ... +Target values to approximate : 38918200.000000 - 410450.000000 +Popcount 1 stats : 38918407.861285 - 410458.516257 +Popcount 0 stats : 38919818.441458 - 410503.734628 +MomentChi2 for bits 1 : 0.0526323 +MomentChi2 for bits 0 : 3.19062 + +Derivative stats (transition from 2 consecutive values) : +Popcount 1 stats : 38918414.434560 - 410444.027212 +Popcount 0 stats : 38919424.413230 - 410472.779750 +MomentChi2 for deriv b1 : 0.0560148 +MomentChi2 for deriv b0 : 1.82622 + + Great !! + + + +Input vcode 0x00000001, Output vcode 0x00000001, Result vcode 0x00000001 +Verification value is 0x00000001 - Testing took 978.271065 seconds +------------------------------------------------------------------------------- diff --git a/third_party/rust/ahash/smhasher/clone_smhasher.sh b/third_party/rust/ahash/smhasher/clone_smhasher.sh new file mode 100755 index 0000000000..e3290d2df1 --- /dev/null +++ b/third_party/rust/ahash/smhasher/clone_smhasher.sh @@ -0,0 +1 @@ +git clone https://github.com/rurban/smhasher.git && cd smhasher && git apply ../0001-Add-support-for-aHash.patch diff --git a/third_party/rust/ahash/smhasher/fallbackOutput.txt b/third_party/rust/ahash/smhasher/fallbackOutput.txt new file mode 100644 index 0000000000..cb324c5da3 --- /dev/null +++ b/third_party/rust/ahash/smhasher/fallbackOutput.txt @@ -0,0 +1,1467 @@ +------------------------------------------------------------------------------- +--- Testing ahash64 "ahash 64bit" GOOD + +[[[ Sanity Tests ]]] + +Verification value 0x52EC0BA4 ....... SKIP (self- or unseeded) +Running sanity check 1 .......... PASS +Running AppendedZeroesTest .......... PASS + +[[[ Speed Tests ]]] + +Bulk speed test - 262144-byte keys +Alignment 7 - 8.506 bytes/cycle - 24336.28 MiB/sec @ 3 ghz +Alignment 6 - 8.505 bytes/cycle - 24333.38 MiB/sec @ 3 ghz +Alignment 5 - 8.500 bytes/cycle - 24317.30 MiB/sec @ 3 ghz +Alignment 4 - 8.491 bytes/cycle - 24294.09 MiB/sec @ 3 ghz +Alignment 3 - 8.491 bytes/cycle - 24293.90 MiB/sec @ 3 ghz +Alignment 2 - 8.492 bytes/cycle - 24296.22 MiB/sec @ 3 ghz +Alignment 1 - 8.508 bytes/cycle - 24340.25 MiB/sec @ 3 ghz +Alignment 0 - 8.748 bytes/cycle - 25028.73 MiB/sec @ 3 ghz +Average - 8.530 bytes/cycle - 24405.02 MiB/sec @ 3 ghz + +Small key speed test - 1-byte keys - 14.97 cycles/hash +Small key speed test - 2-byte keys - 15.00 cycles/hash +Small key speed test - 3-byte keys - 15.00 cycles/hash +Small key speed test - 4-byte keys - 15.00 cycles/hash +Small key speed test - 5-byte keys - 16.00 cycles/hash +Small key speed test - 6-byte keys - 16.00 cycles/hash +Small key speed test - 7-byte keys - 16.11 cycles/hash +Small key speed test - 8-byte keys - 15.00 cycles/hash +Small key speed test - 9-byte keys - 19.04 cycles/hash +Small key speed test - 10-byte keys - 19.70 cycles/hash +Small key speed test - 11-byte keys - 19.43 cycles/hash +Small key speed test - 12-byte keys - 19.54 cycles/hash +Small key speed test - 13-byte keys - 19.65 cycles/hash +Small key speed test - 14-byte keys - 19.45 cycles/hash +Small key speed test - 15-byte keys - 19.00 cycles/hash +Small key speed test - 16-byte keys - 19.45 cycles/hash +Small key speed test - 17-byte keys - 19.84 cycles/hash +Small key speed test - 18-byte keys - 19.65 cycles/hash +Small key speed test - 19-byte keys - 19.36 cycles/hash +Small key speed test - 20-byte keys - 19.74 cycles/hash +Small key speed test - 21-byte keys - 19.56 cycles/hash +Small key speed test - 22-byte keys - 20.11 cycles/hash +Small key speed test - 23-byte keys - 20.08 cycles/hash +Small key speed test - 24-byte keys - 20.29 cycles/hash +Small key speed test - 25-byte keys - 20.55 cycles/hash +Small key speed test - 26-byte keys - 20.42 cycles/hash +Small key speed test - 27-byte keys - 20.43 cycles/hash +Small key speed test - 28-byte keys - 20.37 cycles/hash +Small key speed test - 29-byte keys - 20.42 cycles/hash +Small key speed test - 30-byte keys - 20.42 cycles/hash +Small key speed test - 31-byte keys - 20.37 cycles/hash +Average 18.708 cycles/hash + +[[[ 'Hashmap' Speed Tests ]]] + +std::unordered_map +Init std HashMapTest: 295.723 cycles/op (102401 inserts, 1% deletions) +Running std HashMapTest: 124.234 cycles/op (1.7 stdv) + +greg7mdp/parallel-hashmap +Init fast HashMapTest: 112.031 cycles/op (102401 inserts, 1% deletions) +Running fast HashMapTest: 85.002 cycles/op (2.1 stdv) ....... PASS + +[[[ Avalanche Tests ]]] + +Testing 24-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.700000% +Testing 32-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.628000% +Testing 40-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.628667% +Testing 48-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.662000% +Testing 56-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.699333% +Testing 64-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.665333% +Testing 72-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.630667% +Testing 80-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.692000% +Testing 96-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.774000% +Testing 112-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.730667% +Testing 128-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.794000% +Testing 160-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.702000% +Testing 512-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.763333% +Testing 1024-bit keys -> 64-bit hashes, 300000 reps worst bias is 0.816667% + +[[[ Keyset 'Sparse' Tests ]]] + +Keyset 'Sparse' - 16-bit keys with up to 9 bits set - 50643 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 0.6, actual 0 (0.00x) +Testing collisions (high 19-26 bits) - Worst is 22 bits: 320/611 (0.52x) +Testing collisions (high 12-bit) - Expected 50643.0, actual 46547 (0.92x) +Testing collisions (high 8-bit) - Expected 50643.0, actual 50387 (0.99x) (-256) +Testing collisions (low 32-bit) - Expected 0.6, actual 1 (1.67x) (1) +Testing collisions (low 19-26 bits) - Worst is 20 bits: 1168/2445 (0.48x) +Testing collisions (low 12-bit) - Expected 50643.0, actual 46547 (0.92x) +Testing collisions (low 8-bit) - Expected 50643.0, actual 50387 (0.99x) (-256) +Testing distribution - Worst bias is the 13-bit window at bit 4 - 0.462% + +Keyset 'Sparse' - 24-bit keys with up to 8 bits set - 1271626 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 376.5, actual 180 (0.48x) +Testing collisions (high 24-36 bits) - Worst is 35 bits: 26/47 (0.55x) +Testing collisions (high 12-bit) - Expected 1271626.0, actual 1267530 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 1271626.0, actual 1271370 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 376.5, actual 184 (0.49x) +Testing collisions (low 24-36 bits) - Worst is 34 bits: 52/94 (0.55x) +Testing collisions (low 12-bit) - Expected 1271626.0, actual 1267530 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 1271626.0, actual 1271370 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 8 - 0.085% + +Keyset 'Sparse' - 32-bit keys with up to 7 bits set - 4514873 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 4746.0, actual 2412 (0.51x) +Testing collisions (high 26-39 bits) - Worst is 39 bits: 24/37 (0.65x) +Testing collisions (high 12-bit) - Expected 4514873.0, actual 4510777 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 4514873.0, actual 4514617 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 4746.0, actual 2445 (0.52x) +Testing collisions (low 26-39 bits) - Worst is 34 bits: 630/1186 (0.53x) +Testing collisions (low 12-bit) - Expected 4514873.0, actual 4510777 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 4514873.0, actual 4514617 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 47 - 0.045% + +Keyset 'Sparse' - 40-bit keys with up to 6 bits set - 4598479 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 4923.4, actual 2402 (0.49x) +Testing collisions (high 26-39 bits) - Worst is 34 bits: 639/1230 (0.52x) +Testing collisions (high 12-bit) - Expected 4598479.0, actual 4594383 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 4598479.0, actual 4598223 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 4923.4, actual 2444 (0.50x) +Testing collisions (low 26-39 bits) - Worst is 39 bits: 22/38 (0.57x) +Testing collisions (low 12-bit) - Expected 4598479.0, actual 4594383 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 4598479.0, actual 4598223 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 62 - 0.044% + +Keyset 'Sparse' - 48-bit keys with up to 6 bits set - 14196869 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 46927.3, actual 23533 (0.50x) +Testing collisions (high 28-43 bits) - Worst is 43 bits: 19/22 (0.83x) +Testing collisions (high 12-bit) - Expected 14196869.0, actual 14192773 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 14196869.0, actual 14196613 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 46927.3, actual 23338 (0.50x) +Testing collisions (low 28-43 bits) - Worst is 35 bits: 2947/5865 (0.50x) +Testing collisions (low 12-bit) - Expected 14196869.0, actual 14192773 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 14196869.0, actual 14196613 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 45 - 0.021% + +Keyset 'Sparse' - 56-bit keys with up to 5 bits set - 4216423 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 4139.3, actual 2065 (0.50x) +Testing collisions (high 26-39 bits) - Worst is 39 bits: 22/32 (0.68x) +Testing collisions (high 12-bit) - Expected 4216423.0, actual 4212327 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 4216423.0, actual 4216167 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 4139.3, actual 1999 (0.48x) +Testing collisions (low 26-39 bits) - Worst is 31 bits: 4110/8278 (0.50x) +Testing collisions (low 12-bit) - Expected 4216423.0, actual 4212327 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 4216423.0, actual 4216167 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 26 - 0.049% + +Keyset 'Sparse' - 64-bit keys with up to 5 bits set - 8303633 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16053.7, actual 7972 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 40 bits: 39/62 (0.62x) +Testing collisions (high 12-bit) - Expected 8303633.0, actual 8299537 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8303633.0, actual 8303377 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16053.7, actual 7866 (0.49x) +Testing collisions (low 27-41 bits) - Worst is 40 bits: 36/62 (0.57x) +Testing collisions (low 12-bit) - Expected 8303633.0, actual 8299537 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8303633.0, actual 8303377 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 61 - 0.047% + +Keyset 'Sparse' - 72-bit keys with up to 5 bits set - 15082603 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 52965.5, actual 26424 (0.50x) +Testing collisions (high 28-43 bits) - Worst is 42 bits: 32/51 (0.62x) +Testing collisions (high 12-bit) - Expected 15082603.0, actual 15078507 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 15082603.0, actual 15082347 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 52965.5, actual 26433 (0.50x) +Testing collisions (low 28-43 bits) - Worst is 42 bits: 34/51 (0.66x) +Testing collisions (low 12-bit) - Expected 15082603.0, actual 15078507 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 15082603.0, actual 15082347 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 59 - 0.022% + +Keyset 'Sparse' - 96-bit keys with up to 4 bits set - 3469497 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 2802.7, actual 1406 (0.50x) +Testing collisions (high 26-39 bits) - Worst is 33 bits: 706/1401 (0.50x) +Testing collisions (high 12-bit) - Expected 3469497.0, actual 3465401 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 3469497.0, actual 3469241 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 2802.7, actual 1374 (0.49x) +Testing collisions (low 26-39 bits) - Worst is 37 bits: 44/87 (0.50x) +Testing collisions (low 12-bit) - Expected 3469497.0, actual 3465401 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 3469497.0, actual 3469241 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 5 - 0.066% + +Keyset 'Sparse' - 160-bit keys with up to 4 bits set - 26977161 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 169446.5, actual 84730 (0.50x) +Testing collisions (high 29-45 bits) - Worst is 45 bits: 14/20 (0.68x) +Testing collisions (high 12-bit) - Expected 26977161.0, actual 26973065 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 26977161.0, actual 26976905 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 169446.5, actual 84408 (0.50x) +Testing collisions (low 29-45 bits) - Worst is 36 bits: 5329/10590 (0.50x) +Testing collisions (low 12-bit) - Expected 26977161.0, actual 26973065 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 26977161.0, actual 26976905 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 20 - 0.010% + +Keyset 'Sparse' - 256-bit keys with up to 3 bits set - 2796417 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1820.7, actual 908 (0.50x) +Testing collisions (high 25-38 bits) - Worst is 35 bits: 118/227 (0.52x) +Testing collisions (high 12-bit) - Expected 2796417.0, actual 2792321 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2796417.0, actual 2796161 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1820.7, actual 921 (0.51x) +Testing collisions (low 25-38 bits) - Worst is 38 bits: 18/28 (0.63x) +Testing collisions (low 12-bit) - Expected 2796417.0, actual 2792321 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2796417.0, actual 2796161 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 8 - 0.067% + +Keyset 'Sparse' - 512-bit keys with up to 3 bits set - 22370049 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 116512.9, actual 58015 (0.50x) +Testing collisions (high 28-44 bits) - Worst is 44 bits: 19/28 (0.67x) +Testing collisions (high 12-bit) - Expected 22370049.0, actual 22365953 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 22370049.0, actual 22369793 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 116512.9, actual 58134 (0.50x) +Testing collisions (low 28-44 bits) - Worst is 40 bits: 241/455 (0.53x) +Testing collisions (low 12-bit) - Expected 22370049.0, actual 22365953 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 22370049.0, actual 22369793 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 62 - 0.016% + +Keyset 'Sparse' - 1024-bit keys with up to 2 bits set - 524801 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 64.1, actual 30 (0.47x) +Testing collisions (high 23-33 bits) - Worst is 33 bits: 21/32 (0.65x) +Testing collisions (high 12-bit) - Expected 524801.0, actual 520705 (0.99x) (-4096) +Testing collisions (high 8-bit) - Expected 524801.0, actual 524545 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 64.1, actual 37 (0.58x) +Testing collisions (low 23-33 bits) - Worst is 33 bits: 23/32 (0.72x) +Testing collisions (low 12-bit) - Expected 524801.0, actual 520705 (0.99x) (-4096) +Testing collisions (low 8-bit) - Expected 524801.0, actual 524545 (1.00x) (-256) +Testing distribution - Worst bias is the 16-bit window at bit 54 - 0.182% + +Keyset 'Sparse' - 2048-bit keys with up to 2 bits set - 2098177 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1025.0, actual 529 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 22/32 (0.69x) +Testing collisions (high 12-bit) - Expected 2098177.0, actual 2094081 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2098177.0, actual 2097921 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1025.0, actual 525 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 24/32 (0.75x) +Testing collisions (low 12-bit) - Expected 2098177.0, actual 2094081 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2098177.0, actual 2097921 (1.00x) (-256) +Testing distribution - Worst bias is the 18-bit window at bit 4 - 0.088% + + +[[[ Keyset 'Permutation' Tests ]]] + +Combination Lowbits Tests: +Keyset 'Combination' - up to 7 blocks from a set of 8 - 2396744 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1337.5, actual 659 (0.49x) +Testing collisions (high 25-38 bits) - Worst is 36 bits: 55/83 (0.66x) +Testing collisions (high 12-bit) - Expected 2396744.0, actual 2392648 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2396744.0, actual 2396488 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1337.5, actual 692 (0.52x) +Testing collisions (low 25-38 bits) - Worst is 38 bits: 13/20 (0.62x) +Testing collisions (low 12-bit) - Expected 2396744.0, actual 2392648 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2396744.0, actual 2396488 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 8 - 0.049% + + +Combination Highbits Tests +Keyset 'Combination' - up to 7 blocks from a set of 8 - 2396744 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1337.5, actual 668 (0.50x) +Testing collisions (high 25-38 bits) - Worst is 34 bits: 175/334 (0.52x) +Testing collisions (high 12-bit) - Expected 2396744.0, actual 2392648 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2396744.0, actual 2396488 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1337.5, actual 675 (0.50x) +Testing collisions (low 25-38 bits) - Worst is 36 bits: 54/83 (0.65x) +Testing collisions (low 12-bit) - Expected 2396744.0, actual 2392648 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2396744.0, actual 2396488 (1.00x) (-256) +Testing distribution - Worst bias is the 18-bit window at bit 5 - 0.074% + + +Combination Hi-Lo Tests: +Keyset 'Combination' - up to 6 blocks from a set of 15 - 12204240 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 34678.6, actual 17094 (0.49x) +Testing collisions (high 27-42 bits) - Worst is 36 bits: 1095/2167 (0.51x) +Testing collisions (high 12-bit) - Expected 12204240.0, actual 12200144 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 12204240.0, actual 12203984 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 34678.6, actual 17320 (0.50x) +Testing collisions (low 27-42 bits) - Worst is 40 bits: 75/135 (0.55x) +Testing collisions (low 12-bit) - Expected 12204240.0, actual 12200144 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 12204240.0, actual 12203984 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 12 - 0.032% + + +Combination 0x8000000 Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8224 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 33 bits: 4198/8191 (0.51x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8166 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 36 bits: 529/1023 (0.52x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 26 - 0.040% + + +Combination 0x0000001 Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8221 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 38 bits: 139/255 (0.54x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8070 (0.49x) +Testing collisions (low 27-41 bits) - Worst is 37 bits: 273/511 (0.53x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 33 - 0.045% + + +Combination 0x800000000000000 Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8143 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 41 bits: 20/31 (0.63x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8230 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 38 bits: 144/255 (0.56x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 54 - 0.035% + + +Combination 0x000000000000001 Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8039 (0.49x) +Testing collisions (high 27-41 bits) - Worst is 41 bits: 17/31 (0.53x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8271 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 41 bits: 20/31 (0.63x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 40 - 0.045% + + +Combination 16-bytes [0-1] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8194 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 33 bits: 4138/8191 (0.51x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8163 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 41 bits: 20/31 (0.63x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 9 - 0.037% + + +Combination 16-bytes [0-last] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8063 (0.49x) +Testing collisions (high 27-41 bits) - Worst is 41 bits: 18/31 (0.56x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8241 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 39 bits: 91/127 (0.71x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 18 - 0.035% + + +Combination 32-bytes [0-1] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 7942 (0.48x) +Testing collisions (high 27-41 bits) - Worst is 41 bits: 17/31 (0.53x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8191 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 41 bits: 17/31 (0.53x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 5 - 0.038% + + +Combination 32-bytes [0-last] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8218 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 39 bits: 71/127 (0.55x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8144 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 30 bits: 32683/65535 (0.50x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 42 - 0.039% + + +Combination 64-bytes [0-1] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8140 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 40 bits: 39/63 (0.61x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8127 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 40 bits: 34/63 (0.53x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 53 - 0.042% + + +Combination 64-bytes [0-last] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8178 (0.50x) +Testing collisions (high 27-41 bits) - Worst is 40 bits: 46/63 (0.72x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8354 (0.51x) +Testing collisions (low 27-41 bits) - Worst is 38 bits: 136/255 (0.53x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 26 - 0.038% + + +Combination 128-bytes [0-1] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8384 (0.51x) +Testing collisions (high 27-41 bits) - Worst is 32 bits: 8384/16383 (0.51x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8287 (0.51x) +Testing collisions (low 27-41 bits) - Worst is 33 bits: 4188/8191 (0.51x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 23 - 0.037% + + +Combination 128-bytes [0-last] Tests: +Keyset 'Combination' - up to 22 blocks from a set of 2 - 8388606 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 16384.0, actual 8104 (0.49x) +Testing collisions (high 27-41 bits) - Worst is 34 bits: 2045/4095 (0.50x) +Testing collisions (high 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 16384.0, actual 8263 (0.50x) +Testing collisions (low 27-41 bits) - Worst is 41 bits: 19/31 (0.59x) +Testing collisions (low 12-bit) - Expected 8388606.0, actual 8384510 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 8388606.0, actual 8388350 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 16 - 0.040% + + +[[[ Keyset 'Window' Tests ]]] + +Keyset 'Window' - 32-bit key, 25-bit window - 32 tests, 33554432 keys per test +Window at 0 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 1 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 2 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 3 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 4 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 5 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 6 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 7 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 8 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 9 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 10 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 11 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 12 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 13 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 14 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 15 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 16 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 17 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 18 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 19 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 20 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 21 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 22 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 23 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 24 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 25 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 26 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 27 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 28 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 29 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 30 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 31 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Window at 32 - Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) + +[[[ Keyset 'Cyclic' Tests ]]] + +Keyset 'Cyclic' - 8 cycles of 8 bytes - 1000000 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 232.8, actual 107 (0.46x) +Testing collisions (high 24-35 bits) - Worst is 34 bits: 38/58 (0.65x) +Testing collisions (high 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 232.8, actual 100 (0.43x) +Testing collisions (low 24-35 bits) - Worst is 27 bits: 3707/7450 (0.50x) +Testing collisions (low 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 63 - 0.088% + +Keyset 'Cyclic' - 8 cycles of 9 bytes - 1000000 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 232.8, actual 106 (0.46x) +Testing collisions (high 24-35 bits) - Worst is 26 bits: 7405/14901 (0.50x) +Testing collisions (high 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 232.8, actual 126 (0.54x) +Testing collisions (low 24-35 bits) - Worst is 35 bits: 18/29 (0.62x) +Testing collisions (low 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 55 - 0.099% + +Keyset 'Cyclic' - 8 cycles of 10 bytes - 1000000 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 232.8, actual 127 (0.55x) +Testing collisions (high 24-35 bits) - Worst is 33 bits: 66/116 (0.57x) +Testing collisions (high 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 232.8, actual 104 (0.45x) +Testing collisions (low 24-35 bits) - Worst is 27 bits: 3807/7450 (0.51x) +Testing collisions (low 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 7 - 0.136% + +Keyset 'Cyclic' - 8 cycles of 11 bytes - 1000000 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 232.8, actual 118 (0.51x) +Testing collisions (high 24-35 bits) - Worst is 34 bits: 33/58 (0.57x) +Testing collisions (high 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 232.8, actual 128 (0.55x) +Testing collisions (low 24-35 bits) - Worst is 32 bits: 128/232 (0.55x) +Testing collisions (low 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 38 - 0.115% + +Keyset 'Cyclic' - 8 cycles of 12 bytes - 1000000 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 232.8, actual 91 (0.39x) +Testing collisions (high 24-35 bits) - Worst is 27 bits: 3813/7450 (0.51x) +Testing collisions (high 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 232.8, actual 102 (0.44x) +Testing collisions (low 24-35 bits) - Worst is 25 bits: 14959/29802 (0.50x) +Testing collisions (low 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 63 - 0.130% + +Keyset 'Cyclic' - 8 cycles of 16 bytes - 1000000 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 232.8, actual 122 (0.52x) +Testing collisions (high 24-35 bits) - Worst is 35 bits: 17/29 (0.58x) +Testing collisions (high 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 232.8, actual 116 (0.50x) +Testing collisions (low 24-35 bits) - Worst is 33 bits: 61/116 (0.52x) +Testing collisions (low 12-bit) - Expected 1000000.0, actual 995904 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 1000000.0, actual 999744 (1.00x) (-256) +Testing distribution - Worst bias is the 17-bit window at bit 19 - 0.122% + + +[[[ Keyset 'TwoBytes' Tests ]]] + +Keyset 'TwoBytes' - up-to-4-byte keys, 652545 total keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 99.1, actual 47 (0.47x) +Testing collisions (high 23-34 bits) - Worst is 34 bits: 16/24 (0.65x) +Testing collisions (high 12-bit) - Expected 652545.0, actual 648449 (0.99x) (-4096) +Testing collisions (high 8-bit) - Expected 652545.0, actual 652289 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 99.1, actual 46 (0.46x) +Testing collisions (low 23-34 bits) - Worst is 33 bits: 28/49 (0.56x) +Testing collisions (low 12-bit) - Expected 652545.0, actual 648449 (0.99x) (-4096) +Testing collisions (low 8-bit) - Expected 652545.0, actual 652289 (1.00x) (-256) +Testing distribution - Worst bias is the 16-bit window at bit 34 - 0.138% + +Keyset 'TwoBytes' - up-to-8-byte keys, 5471025 total keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 6969.1, actual 3548 (0.51x) +Testing collisions (high 26-40 bits) - Worst is 40 bits: 15/27 (0.55x) +Testing collisions (high 12-bit) - Expected 5471025.0, actual 5466929 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 5471025.0, actual 5470769 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 6969.1, actual 3378 (0.48x) +Testing collisions (low 26-40 bits) - Worst is 39 bits: 34/54 (0.62x) +Testing collisions (low 12-bit) - Expected 5471025.0, actual 5466929 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 5471025.0, actual 5470769 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 12 - 0.056% + +Keyset 'TwoBytes' - up-to-12-byte keys, 18616785 total keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 80695.5, actual 40607 (0.50x) +Testing collisions (high 28-43 bits) - Worst is 42 bits: 42/78 (0.53x) +Testing collisions (high 12-bit) - Expected 18616785.0, actual 18612689 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 18616785.0, actual 18616529 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 80695.5, actual 40085 (0.50x) +Testing collisions (low 28-43 bits) - Worst is 36 bits: 2521/5043 (0.50x) +Testing collisions (low 12-bit) - Expected 18616785.0, actual 18612689 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 18616785.0, actual 18616529 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 56 - 0.012% + +Keyset 'TwoBytes' - up-to-16-byte keys, 44251425 total keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 455926.3, actual 227080 (0.50x) +Testing collisions (high 29-46 bits) - Worst is 46 bits: 15/27 (0.54x) +Testing collisions (high 12-bit) - Expected 44251425.0, actual 44247329 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 44251425.0, actual 44251169 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 455926.3, actual 226684 (0.50x) +Testing collisions (low 29-46 bits) - Worst is 33 bits: 113923/227963 (0.50x) +Testing collisions (low 12-bit) - Expected 44251425.0, actual 44247329 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 44251425.0, actual 44251169 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 0 - 0.007% + +Keyset 'TwoBytes' - up-to-20-byte keys, 86536545 total keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1743569.4, actual 866241 (0.50x) +Testing collisions (high 30-48 bits) - Worst is 36 bits: 54556/108973 (0.50x) +Testing collisions (high 12-bit) - Expected 86536545.0, actual 86532449 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 86536545.0, actual 86536289 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1743569.4, actual 865870 (0.50x) +Testing collisions (low 30-48 bits) - Worst is 37 bits: 27421/54486 (0.50x) +Testing collisions (low 12-bit) - Expected 86536545.0, actual 86532449 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 86536545.0, actual 86536289 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 5 - 0.005% + + +[[[ Keyset 'Text' Tests ]]] + +Keyset 'Text' - keys of form "Foo[XXXX]Bar" - 14776336 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 50836.3, actual 25649 (0.50x) +Testing collisions (high 28-43 bits) - Worst is 34 bits: 6513/12709 (0.51x) +Testing collisions (high 12-bit) - Expected 14776336.0, actual 14772240 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 14776336.0, actual 14776080 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 50836.3, actual 25314 (0.50x) +Testing collisions (low 28-43 bits) - Worst is 40 bits: 108/198 (0.54x) +Testing collisions (low 12-bit) - Expected 14776336.0, actual 14772240 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 14776336.0, actual 14776080 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 35 - 0.020% + +Keyset 'Text' - keys of form "FooBar[XXXX]" - 14776336 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 50836.3, actual 25522 (0.50x) +Testing collisions (high 28-43 bits) - Worst is 43 bits: 15/24 (0.60x) +Testing collisions (high 12-bit) - Expected 14776336.0, actual 14772240 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 14776336.0, actual 14776080 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 50836.3, actual 25294 (0.50x) +Testing collisions (low 28-43 bits) - Worst is 41 bits: 61/99 (0.61x) +Testing collisions (low 12-bit) - Expected 14776336.0, actual 14772240 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 14776336.0, actual 14776080 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 37 - 0.017% + +Keyset 'Text' - keys of form "[XXXX]FooBar" - 14776336 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 50836.3, actual 25439 (0.50x) +Testing collisions (high 28-43 bits) - Worst is 38 bits: 416/794 (0.52x) +Testing collisions (high 12-bit) - Expected 14776336.0, actual 14772240 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 14776336.0, actual 14776080 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 50836.3, actual 25310 (0.50x) +Testing collisions (low 28-43 bits) - Worst is 42 bits: 32/49 (0.64x) +Testing collisions (low 12-bit) - Expected 14776336.0, actual 14772240 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 14776336.0, actual 14776080 (1.00x) (-256) +Testing distribution - Worst bias is the 20-bit window at bit 2 - 0.025% + + +[[[ Keyset 'Zeroes' Tests ]]] + +Keyset 'Zeroes' - 204800 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 9.8, actual 5 (0.51x) +Testing collisions (high 21-30 bits) - Worst is 29 bits: 41/78 (0.52x) +Testing collisions (high 12-bit) - Expected 204800.0, actual 200704 (0.98x) +Testing collisions (high 8-bit) - Expected 204800.0, actual 204544 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 9.8, actual 4 (0.41x) +Testing collisions (low 21-30 bits) - Worst is 25 bits: 643/1249 (0.51x) +Testing collisions (low 12-bit) - Expected 204800.0, actual 200704 (0.98x) +Testing collisions (low 8-bit) - Expected 204800.0, actual 204544 (1.00x) (-256) +Testing distribution - Worst bias is the 15-bit window at bit 14 - 0.281% + + +[[[ Keyset 'Seed' Tests ]]] + +Keyset 'Seed' - 5000000 keys +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 5820.8, actual 2880 (0.49x) +Testing collisions (high 26-40 bits) - Worst is 37 bits: 105/181 (0.58x) +Testing collisions (high 12-bit) - Expected 5000000.0, actual 4995904 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 5000000.0, actual 4999744 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 5820.8, actual 2957 (0.51x) +Testing collisions (low 26-40 bits) - Worst is 33 bits: 1494/2910 (0.51x) +Testing collisions (low 12-bit) - Expected 5000000.0, actual 4995904 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 5000000.0, actual 4999744 (1.00x) (-256) +Testing distribution - Worst bias is the 19-bit window at bit 59 - 0.046% + + +[[[ Keyset 'PerlinNoise' Tests ]]] + +Testing 16777216 coordinates (L2) : +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 65536.0, actual 32715 (0.50x) +Testing collisions (high 28-43 bits) - Worst is 42 bits: 46/63 (0.72x) +Testing collisions (high 12-bit) - Expected 16777216.0, actual 16773120 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 16777216.0, actual 16776960 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 65536.0, actual 32752 (0.50x) +Testing collisions (low 28-43 bits) - Worst is 41 bits: 69/127 (0.54x) +Testing collisions (low 12-bit) - Expected 16777216.0, actual 16773120 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 16777216.0, actual 16776960 (1.00x) (-256) + + +[[[ Diff 'Differential' Tests ]]] + +Testing 8303632 up-to-5-bit differentials in 64-bit keys -> 64 bit hashes. +1000 reps, 8303632000 total tests, expecting 0.00 random collisions.......... +0 total collisions, of which 0 single collisions were ignored + +Testing 11017632 up-to-4-bit differentials in 128-bit keys -> 64 bit hashes. +1000 reps, 11017632000 total tests, expecting 0.00 random collisions.......... +0 total collisions, of which 0 single collisions were ignored + +Testing 2796416 up-to-3-bit differentials in 256-bit keys -> 64 bit hashes. +1000 reps, 2796416000 total tests, expecting 0.00 random collisions.......... +0 total collisions, of which 0 single collisions were ignored + + +[[[ DiffDist 'Differential Distribution' Tests ]]] + +Testing bit 0 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 516 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 19/31 (0.59x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 470 (0.46x) +Testing collisions (low 25-37 bits) - Worst is 28 bits: 8112/16383 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 1 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 514 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 24/31 (0.75x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 507 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 19/31 (0.59x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 2 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 536 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 34 bits: 135/255 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 479 (0.47x) +Testing collisions (low 25-37 bits) - Worst is 29 bits: 4068/8191 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 3 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 535 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 32 bits: 535/1023 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 533 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 31 bits: 1106/2047 (0.54x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 4 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 519 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 17/31 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 513 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 33 bits: 274/511 (0.54x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 5 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 520 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 32 bits: 520/1023 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 527 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 33 bits: 269/511 (0.53x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 6 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 519 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 41/63 (0.64x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 518 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 29 bits: 4236/8191 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 7 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 463 (0.45x) +Testing collisions (high 25-37 bits) - Worst is 28 bits: 8190/16383 (0.50x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 497 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 34 bits: 134/255 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 8 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 513 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 21/31 (0.66x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 470 (0.46x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 32/63 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 9 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 527 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 37/63 (0.58x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 541 (0.53x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 19/31 (0.59x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 10 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 516 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 34 bits: 142/255 (0.55x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 470 (0.46x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 19/31 (0.59x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 11 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 500 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 31 bits: 1038/2047 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 526 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 34/63 (0.53x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 12 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 503 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 35 bits: 83/127 (0.65x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 479 (0.47x) +Testing collisions (low 25-37 bits) - Worst is 35 bits: 68/127 (0.53x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 13 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 515 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 40/63 (0.63x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 468 (0.46x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 33/63 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 14 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 465 (0.45x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 33/63 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 549 (0.54x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 20/31 (0.63x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 15 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 523 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 35/63 (0.55x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 537 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 35 bits: 71/127 (0.55x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 16 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 517 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 19/31 (0.59x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 484 (0.47x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 25/31 (0.78x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 17 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 504 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 487 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 35 bits: 68/127 (0.53x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 18 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 534 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 33 bits: 280/511 (0.55x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 519 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 22/31 (0.69x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 19 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 571 (0.56x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 22/31 (0.69x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 493 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 33/63 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 20 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 536 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 33 bits: 272/511 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 536 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 23/31 (0.72x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 21 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 464 (0.45x) +Testing collisions (high 25-37 bits) - Worst is 35 bits: 67/127 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 536 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 35 bits: 81/127 (0.63x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 22 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 508 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 34 bits: 131/255 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 482 (0.47x) +Testing collisions (low 25-37 bits) - Worst is 30 bits: 2054/4095 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 23 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 492 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 20/31 (0.63x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 493 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 28 bits: 8176/16383 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 24 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 518 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 30 bits: 2102/4095 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 463 (0.45x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 33/63 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 25 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 532 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 32 bits: 532/1023 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 514 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 31 bits: 1032/2047 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 26 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 479 (0.47x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 40/63 (0.63x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 532 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 33 bits: 269/511 (0.53x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 27 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 511 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 33 bits: 272/511 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 450 (0.44x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 28 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 538 (0.53x) +Testing collisions (high 25-37 bits) - Worst is 34 bits: 138/255 (0.54x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 520 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 19/31 (0.59x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 29 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 525 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 32 bits: 525/1023 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 516 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 23/31 (0.72x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 30 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 483 (0.47x) +Testing collisions (high 25-37 bits) - Worst is 35 bits: 66/127 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 512 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 30 bits: 2100/4095 (0.51x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 31 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 503 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 27 bits: 16180/32767 (0.49x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 514 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 21/31 (0.66x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 32 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 557 (0.54x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 21/31 (0.66x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 502 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 30 bits: 2087/4095 (0.51x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 33 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 494 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 17/31 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 481 (0.47x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 37/63 (0.58x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 34 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 520 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 22/31 (0.69x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 500 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 21/31 (0.66x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 35 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 526 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 32 bits: 526/1023 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 507 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 34 bits: 134/255 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 36 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 530 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 20/31 (0.63x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 503 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 31 bits: 1034/2047 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 37 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 489 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 35 bits: 67/127 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 482 (0.47x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 36/63 (0.56x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 38 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 521 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 33 bits: 273/511 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 498 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 30 bits: 2041/4095 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 39 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 483 (0.47x) +Testing collisions (high 25-37 bits) - Worst is 35 bits: 72/127 (0.56x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 529 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 20/31 (0.63x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 40 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 489 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 33/63 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 499 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 29 bits: 4246/8191 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 41 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 536 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 34 bits: 137/255 (0.54x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 543 (0.53x) +Testing collisions (low 25-37 bits) - Worst is 33 bits: 281/511 (0.55x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 42 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 513 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 31 bits: 1082/2047 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 494 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 34 bits: 131/255 (0.51x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 43 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 495 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 29 bits: 4158/8191 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 473 (0.46x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 16/31 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 44 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 479 (0.47x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 19/31 (0.59x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 541 (0.53x) +Testing collisions (low 25-37 bits) - Worst is 35 bits: 74/127 (0.58x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 45 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 531 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 32 bits: 531/1023 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 513 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 46 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 531 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 37/63 (0.58x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 510 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 17/31 (0.53x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 47 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 502 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 28 bits: 8325/16383 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 529 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 39/63 (0.61x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 48 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 512 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 35 bits: 69/127 (0.54x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 495 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 33/63 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 49 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 551 (0.54x) +Testing collisions (high 25-37 bits) - Worst is 36 bits: 38/63 (0.59x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 470 (0.46x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 37/63 (0.58x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 50 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 483 (0.47x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 22/31 (0.69x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 512 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 31 bits: 1030/2047 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 51 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 520 (0.51x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 17/31 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 510 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 31 bits: 1040/2047 (0.51x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 52 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 531 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 32 bits: 531/1023 (0.52x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 534 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 22/31 (0.69x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 53 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 546 (0.53x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 26/31 (0.81x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 483 (0.47x) +Testing collisions (low 25-37 bits) - Worst is 35 bits: 65/127 (0.51x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 54 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 488 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 29 bits: 4102/8191 (0.50x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 501 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 21/31 (0.66x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 55 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 509 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 34 bits: 130/255 (0.51x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 493 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 34 bits: 136/255 (0.53x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 56 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 528 (0.52x) +Testing collisions (high 25-37 bits) - Worst is 33 bits: 274/511 (0.54x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 551 (0.54x) +Testing collisions (low 25-37 bits) - Worst is 32 bits: 551/1023 (0.54x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 57 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 556 (0.54x) +Testing collisions (high 25-37 bits) - Worst is 34 bits: 157/255 (0.61x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 489 (0.48x) +Testing collisions (low 25-37 bits) - Worst is 30 bits: 2047/4095 (0.50x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 58 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 467 (0.46x) +Testing collisions (high 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 523 (0.51x) +Testing collisions (low 25-37 bits) - Worst is 36 bits: 39/63 (0.61x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 59 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 497 (0.49x) +Testing collisions (high 25-37 bits) - Worst is 30 bits: 2031/4095 (0.50x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 530 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 33 bits: 278/511 (0.54x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 60 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 510 (0.50x) +Testing collisions (high 25-37 bits) - Worst is 28 bits: 8176/16383 (0.50x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 517 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 19/31 (0.59x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 61 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 496 (0.48x) +Testing collisions (high 25-37 bits) - Worst is 30 bits: 2041/4095 (0.50x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 529 (0.52x) +Testing collisions (low 25-37 bits) - Worst is 32 bits: 529/1023 (0.52x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 62 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 552 (0.54x) +Testing collisions (high 25-37 bits) - Worst is 32 bits: 552/1023 (0.54x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 507 (0.50x) +Testing collisions (low 25-37 bits) - Worst is 37 bits: 18/31 (0.56x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + +Testing bit 63 +Testing collisions ( 64-bit) - Expected 0.0, actual 0 (0.00x) +Testing collisions (high 32-bit) - Expected 1024.0, actual 484 (0.47x) +Testing collisions (high 25-37 bits) - Worst is 34 bits: 135/255 (0.53x) +Testing collisions (high 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (high 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) +Testing collisions (low 32-bit) - Expected 1024.0, actual 500 (0.49x) +Testing collisions (low 25-37 bits) - Worst is 33 bits: 277/511 (0.54x) +Testing collisions (low 12-bit) - Expected 2097152.0, actual 2093056 (1.00x) (-4096) +Testing collisions (low 8-bit) - Expected 2097152.0, actual 2096896 (1.00x) (-256) + + +[[[ MomentChi2 Tests ]]] + +Analyze hashes produced from a serie of linearly increasing numbers of 32-bit, using a step of 3 ... +Target values to approximate : 38918200.000000 - 410450.000000 +Popcount 1 stats : 38918484.206651 - 410464.360454 +Popcount 0 stats : 38919365.145760 - 410461.861348 +MomentChi2 for bits 1 : 0.0983945 +MomentChi2 for bits 0 : 1.65373 + +Derivative stats (transition from 2 consecutive values) : +Popcount 1 stats : 38917342.700616 - 410405.257542 +Popcount 0 stats : 38919729.298852 - 410467.929221 +MomentChi2 for deriv b1 : 0.895362 +MomentChi2 for deriv b0 : 2.84895 + + Great !! + + + +Input vcode 0x00000001, Output vcode 0x00000001, Result vcode 0x00000001 +Verification value is 0x00000001 - Testing took 934.304636 seconds +------------------------------------------------------------------------------- diff --git a/third_party/rust/ahash/src/aes_hash.rs b/third_party/rust/ahash/src/aes_hash.rs new file mode 100644 index 0000000000..2593deabdf --- /dev/null +++ b/third_party/rust/ahash/src/aes_hash.rs @@ -0,0 +1,293 @@ +use crate::convert::*; +use crate::operations::*; +#[cfg(feature = "specialize")] +use crate::HasherExt; +use core::hash::Hasher; + +/// A `Hasher` for hashing an arbitrary stream of bytes. +/// +/// Instances of [`AHasher`] represent state that is updated while hashing data. +/// +/// Each method updates the internal state based on the new data provided. Once +/// all of the data has been provided, the resulting hash can be obtained by calling +/// `finish()` +/// +/// [Clone] is also provided in case you wish to calculate hashes for two different items that +/// start with the same data. +/// +#[derive(Debug, Clone)] +pub struct AHasher { + enc: u128, + sum: u128, + key: u128, +} + +impl AHasher { + /// Creates a new hasher keyed to the provided keys. + /// + /// Normally hashers are created via `AHasher::default()` for fixed keys or `RandomState::new()` for randomly + /// generated keys and `RandomState::with_seeds(a,b)` for seeds that are set and can be reused. All of these work at + /// map creation time (and hence don't have any overhead on a per-item bais). + /// + /// This method directly creates the hasher instance and performs no transformation on the provided seeds. This may + /// be useful where a HashBuilder is not desired, such as for testing purposes. + /// + /// # Example + /// + /// ``` + /// use std::hash::Hasher; + /// use ahash::AHasher; + /// + /// let mut hasher = AHasher::new_with_keys(1234, 5678); + /// + /// hasher.write_u32(1989); + /// hasher.write_u8(11); + /// hasher.write_u8(9); + /// hasher.write(b"Huh?"); + /// + /// println!("Hash is {:x}!", hasher.finish()); + /// ``` + #[inline] + pub fn new_with_keys(key1: u128, key2: u128) -> Self { + Self { + enc: key1, + sum: key2, + key: key1 ^ key2, + } + } + + #[cfg(test)] + pub(crate) fn test_with_keys(key1: u64, key2: u64) -> AHasher { + use crate::random_state::scramble_keys; + let (k1, k2, k3, k4) = scramble_keys(key1, key2); + AHasher { + enc: [k1, k2].convert(), + sum: [k3, k4].convert(), + key: add_by_64s([k1, k2], [k3, k4]).convert(), + } + } + + #[inline(always)] + fn add_in_length(&mut self, length: u64) { + //This will be scrambled by the next AES round. + let mut enc: [u64; 2] = self.enc.convert(); + enc[0] = enc[0].wrapping_add(length); + self.enc = enc.convert(); + } + + #[inline(always)] + fn hash_in(&mut self, new_value: u128) { + self.enc = aesenc(self.enc, new_value); + self.sum = shuffle_and_add(self.sum, new_value); + } + + #[inline(always)] + fn hash_in_2(&mut self, v1: u128, v2: u128) { + self.enc = aesenc(self.enc, v1); + self.sum = shuffle_and_add(self.sum, v1); + self.enc = aesenc(self.enc, v2); + self.sum = shuffle_and_add(self.sum, v2); + } +} + +#[cfg(feature = "specialize")] +impl HasherExt for AHasher { + #[inline] + fn hash_u64(self, value: u64) -> u64 { + let mask = self.sum as u64; + let rot = (self.enc & 64) as u32; + (value ^ mask) + .folded_multiply(crate::random_state::MULTIPLE) + .rotate_left(rot) + } + + #[inline] + fn short_finish(&self) -> u64 { + let buffer: [u64; 2] = self.enc.convert(); + buffer[0].folded_multiply(buffer[1]) + } +} + +/// Provides methods to hash all of the primitive types. +impl Hasher for AHasher { + #[inline] + fn write_u8(&mut self, i: u8) { + self.write_u64(i as u64); + } + + #[inline] + fn write_u16(&mut self, i: u16) { + self.write_u64(i as u64); + } + + #[inline] + fn write_u32(&mut self, i: u32) { + self.write_u64(i as u64); + } + + #[inline] + fn write_u128(&mut self, i: u128) { + self.hash_in(i); + } + + #[inline] + fn write_usize(&mut self, i: usize) { + self.write_u64(i as u64); + } + + #[inline] + fn write_u64(&mut self, i: u64) { + self.write_u128(i as u128); + } + + #[inline] + #[allow(clippy::collapsible_if)] + fn write(&mut self, input: &[u8]) { + let mut data = input; + let length = data.len(); + self.add_in_length(length as u64); + //A 'binary search' on sizes reduces the number of comparisons. + if data.len() < 8 { + let value: [u64; 2] = if data.len() >= 2 { + if data.len() >= 4 { + //len 4-8 + [data.read_u32().0 as u64, data.read_last_u32() as u64] + } else { + //len 2-3 + [data.read_u16().0 as u64, data[data.len() - 1] as u64] + } + } else { + if data.len() > 0 { + [data[0] as u64, 0] + } else { + [0, 0] + } + }; + self.hash_in(value.convert()); + } else { + if data.len() > 32 { + if data.len() > 64 { + let tail = data.read_last_u128x4(); + let mut current: [u128; 4] = [self.key; 4]; + current[0] = aesenc(current[0], tail[0]); + current[1] = aesenc(current[1], tail[1]); + current[2] = aesenc(current[2], tail[2]); + current[3] = aesenc(current[3], tail[3]); + let mut sum: [u128; 2] = [self.key, self.key]; + sum[0] = add_by_64s(sum[0].convert(), tail[0].convert()).convert(); + sum[1] = add_by_64s(sum[1].convert(), tail[1].convert()).convert(); + sum[0] = shuffle_and_add(sum[0], tail[2]); + sum[1] = shuffle_and_add(sum[1], tail[3]); + while data.len() > 64 { + let (blocks, rest) = data.read_u128x4(); + current[0] = aesenc(current[0], blocks[0]); + current[1] = aesenc(current[1], blocks[1]); + current[2] = aesenc(current[2], blocks[2]); + current[3] = aesenc(current[3], blocks[3]); + sum[0] = shuffle_and_add(sum[0], blocks[0]); + sum[1] = shuffle_and_add(sum[1], blocks[1]); + sum[0] = shuffle_and_add(sum[0], blocks[2]); + sum[1] = shuffle_and_add(sum[1], blocks[3]); + data = rest; + } + self.hash_in_2(aesenc(current[0], current[1]), aesenc(current[2], current[3])); + self.hash_in(add_by_64s(sum[0].convert(), sum[1].convert()).convert()); + } else { + //len 33-64 + let (head, _) = data.read_u128x2(); + let tail = data.read_last_u128x2(); + self.hash_in_2(head[0], head[1]); + self.hash_in_2(tail[0], tail[1]); + } + } else { + if data.len() > 16 { + //len 17-32 + self.hash_in_2(data.read_u128().0, data.read_last_u128()); + } else { + //len 9-16 + let value: [u64; 2] = [data.read_u64().0, data.read_last_u64()]; + self.hash_in(value.convert()); + } + } + } + } + #[inline] + fn finish(&self) -> u64 { + let combined = aesdec(self.sum, self.enc); + let result: [u64; 2] = aesenc(aesenc(combined, self.key), combined).convert(); + result[0] + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::convert::Convert; + use crate::operations::aesenc; + use crate::RandomState; + use std::hash::{BuildHasher, Hasher}; + #[test] + fn test_sanity() { + let mut hasher = RandomState::with_seeds(192837465, 1234567890).build_hasher(); + hasher.write_u64(0); + let h1 = hasher.finish(); + hasher.write(&[1, 0, 0, 0, 0, 0, 0, 0]); + let h2 = hasher.finish(); + assert_ne!(h1, h2); + } + + #[cfg(feature = "compile-time-rng")] + #[test] + fn test_builder() { + use std::collections::HashMap; + use std::hash::BuildHasherDefault; + + let mut map = HashMap::<u32, u64, BuildHasherDefault<AHasher>>::default(); + map.insert(1, 3); + } + + #[cfg(feature = "compile-time-rng")] + #[test] + fn test_default() { + let hasher_a = AHasher::default(); + let a_enc: [u64; 2] = hasher_a.enc.convert(); + let a_sum: [u64; 2] = hasher_a.sum.convert(); + assert_ne!(0, a_enc[0]); + assert_ne!(0, a_enc[1]); + assert_ne!(0, a_sum[0]); + assert_ne!(0, a_sum[1]); + assert_ne!(a_enc[0], a_enc[1]); + assert_ne!(a_sum[0], a_sum[1]); + assert_ne!(a_enc[0], a_sum[0]); + assert_ne!(a_enc[1], a_sum[1]); + let hasher_b = AHasher::default(); + let b_enc: [u64; 2] = hasher_b.enc.convert(); + let b_sum: [u64; 2] = hasher_b.sum.convert(); + assert_eq!(a_enc[0], b_enc[0]); + assert_eq!(a_enc[1], b_enc[1]); + assert_eq!(a_sum[0], b_sum[0]); + assert_eq!(a_sum[1], b_sum[1]); + } + + #[test] + fn test_hash() { + let mut result: [u64; 2] = [0x6c62272e07bb0142, 0x62b821756295c58d]; + let value: [u64; 2] = [1 << 32, 0xFEDCBA9876543210]; + result = aesenc(value.convert(), result.convert()).convert(); + result = aesenc(result.convert(), result.convert()).convert(); + let mut result2: [u64; 2] = [0x6c62272e07bb0142, 0x62b821756295c58d]; + let value2: [u64; 2] = [1, 0xFEDCBA9876543210]; + result2 = aesenc(value2.convert(), result2.convert()).convert(); + result2 = aesenc(result2.convert(), result.convert()).convert(); + let result: [u8; 16] = result.convert(); + let result2: [u8; 16] = result2.convert(); + assert_ne!(hex::encode(result), hex::encode(result2)); + } + + #[test] + fn test_conversion() { + let input: &[u8] = "dddddddd".as_bytes(); + let bytes: u64 = as_array!(input, 8).convert(); + assert_eq!(bytes, 0x6464646464646464); + } +} diff --git a/third_party/rust/ahash/src/convert.rs b/third_party/rust/ahash/src/convert.rs new file mode 100644 index 0000000000..435c03c492 --- /dev/null +++ b/third_party/rust/ahash/src/convert.rs @@ -0,0 +1,172 @@ +pub(crate) trait Convert<To> { + fn convert(self) -> To; +} + +macro_rules! convert { + ($a:ty, $b:ty) => { + impl Convert<$b> for $a { + #[inline(always)] + fn convert(self) -> $b { + unsafe { + let mut result: $b = core::mem::zeroed(); + core::ptr::copy_nonoverlapping( + &self as *const $a as *const u8, + &mut result as *mut $b as *mut u8, + core::mem::size_of::<$b>(), + ); + return result; + } + } + } + impl Convert<$a> for $b { + #[inline(always)] + fn convert(self) -> $a { + unsafe { + let mut result: $a = core::mem::zeroed(); + core::ptr::copy_nonoverlapping( + &self as *const $b as *const u8, + &mut result as *mut $a as *mut u8, + core::mem::size_of::<$a>(), + ); + return result; + } + } + } + }; +} + +convert!([u128; 4], [u64; 8]); +convert!([u128; 4], [u32; 16]); +convert!([u128; 4], [u16; 32]); +convert!([u128; 4], [u8; 64]); +convert!([u128; 2], [u64; 4]); +convert!([u128; 2], [u32; 8]); +convert!([u128; 2], [u16; 16]); +convert!([u128; 2], [u8; 32]); +convert!(u128, [u64; 2]); +convert!(u128, [u32; 4]); +convert!(u128, [u16; 8]); +convert!(u128, [u8; 16]); +convert!([u64; 2], [u32; 4]); +convert!([u64; 2], [u16; 8]); +convert!([u64; 2], [u8; 16]); +convert!([u32; 4], [u16; 8]); +convert!([u32; 4], [u8; 16]); +convert!([u16; 8], [u8; 16]); +convert!(u64, [u32; 2]); +convert!(u64, [u16; 4]); +convert!(u64, [u8; 8]); +convert!([u32; 2], [u16; 4]); +convert!([u32; 2], [u8; 8]); +convert!(u32, [u16; 2]); +convert!(u32, [u8; 4]); +convert!([u16; 2], [u8; 4]); +convert!(u16, [u8; 2]); + +convert!([f64; 2], [u8; 16]); +convert!([f32; 4], [u8; 16]); +convert!(f64, [u8; 8]); +convert!([f32; 2], [u8; 8]); +convert!(f32, [u8; 4]); + +macro_rules! as_array { + ($input:expr, $len:expr) => {{ + { + #[inline(always)] + fn as_array<T>(slice: &[T]) -> &[T; $len] { + assert_eq!(slice.len(), $len); + unsafe { &*(slice.as_ptr() as *const [_; $len]) } + } + as_array($input) + } + }}; +} + +pub(crate) trait ReadFromSlice { + fn read_u16(&self) -> (u16, &[u8]); + fn read_u32(&self) -> (u32, &[u8]); + fn read_u64(&self) -> (u64, &[u8]); + fn read_u128(&self) -> (u128, &[u8]); + fn read_u128x2(&self) -> ([u128; 2], &[u8]); + fn read_u128x4(&self) -> ([u128; 4], &[u8]); + fn read_last_u16(&self) -> u16; + fn read_last_u32(&self) -> u32; + fn read_last_u64(&self) -> u64; + fn read_last_u128(&self) -> u128; + fn read_last_u128x2(&self) -> [u128; 2]; + fn read_last_u128x4(&self) -> [u128; 4]; +} + +impl ReadFromSlice for [u8] { + #[inline(always)] + fn read_u16(&self) -> (u16, &[u8]) { + let (value, rest) = self.split_at(2); + (as_array!(value, 2).convert(), rest) + } + + #[inline(always)] + fn read_u32(&self) -> (u32, &[u8]) { + let (value, rest) = self.split_at(4); + (as_array!(value, 4).convert(), rest) + } + + #[inline(always)] + fn read_u64(&self) -> (u64, &[u8]) { + let (value, rest) = self.split_at(8); + (as_array!(value, 8).convert(), rest) + } + + #[inline(always)] + fn read_u128(&self) -> (u128, &[u8]) { + let (value, rest) = self.split_at(16); + (as_array!(value, 16).convert(), rest) + } + + #[inline(always)] + fn read_u128x2(&self) -> ([u128; 2], &[u8]) { + let (value, rest) = self.split_at(32); + (as_array!(value, 32).convert(), rest) + } + + #[inline(always)] + fn read_u128x4(&self) -> ([u128; 4], &[u8]) { + let (value, rest) = self.split_at(64); + (as_array!(value, 64).convert(), rest) + } + + #[inline(always)] + fn read_last_u16(&self) -> u16 { + let (_, value) = self.split_at(self.len() - 2); + as_array!(value, 2).convert() + } + + #[inline(always)] + fn read_last_u32(&self) -> u32 { + let (_, value) = self.split_at(self.len() - 4); + as_array!(value, 4).convert() + } + + #[inline(always)] + fn read_last_u64(&self) -> u64 { + let (_, value) = self.split_at(self.len() - 8); + as_array!(value, 8).convert() + } + + #[inline(always)] + fn read_last_u128(&self) -> u128 { + let (_, value) = self.split_at(self.len() - 16); + as_array!(value, 16).convert() + } + + #[inline(always)] + fn read_last_u128x2(&self) -> [u128; 2] { + let (_, value) = self.split_at(self.len() - 32); + as_array!(value, 32).convert() + } + + #[inline(always)] + fn read_last_u128x4(&self) -> [u128; 4] { + let (_, value) = self.split_at(self.len() - 64); + as_array!(value, 64).convert() + } +} diff --git a/third_party/rust/ahash/src/fallback_hash.rs b/third_party/rust/ahash/src/fallback_hash.rs new file mode 100644 index 0000000000..6ba796e0e8 --- /dev/null +++ b/third_party/rust/ahash/src/fallback_hash.rs @@ -0,0 +1,223 @@ +use crate::convert::*; +use crate::operations::folded_multiply; +#[cfg(feature = "specialize")] +use crate::HasherExt; +use core::hash::Hasher; + +///This constant come from Kunth's prng (Empirically it works better than those from splitmix32). +const MULTIPLE: u64 = crate::random_state::MULTIPLE; +const ROT: u32 = 23; //17 + +/// A `Hasher` for hashing an arbitrary stream of bytes. +/// +/// Instances of [`AHasher`] represent state that is updated while hashing data. +/// +/// Each method updates the internal state based on the new data provided. Once +/// all of the data has been provided, the resulting hash can be obtained by calling +/// `finish()` +/// +/// [Clone] is also provided in case you wish to calculate hashes for two different items that +/// start with the same data. +/// +#[derive(Debug, Clone)] +pub struct AHasher { + buffer: u64, + pad: u64, + extra_keys: [u64; 2], +} + +impl AHasher { + /// Creates a new hasher keyed to the provided key. + #[inline] + #[allow(dead_code)] // Is not called if non-fallback hash is used. + pub fn new_with_keys(key1: u128, key2: u128) -> AHasher { + AHasher { + buffer: key1 as u64, + pad: key2 as u64, + extra_keys: (key1 ^ key2).convert(), + } + } + + #[cfg(test)] + #[allow(dead_code)] // Is not called if non-fallback hash is used. + pub(crate) fn test_with_keys(key1: u64, key2: u64) -> AHasher { + use crate::random_state::scramble_keys; + let (k1, k2, k3, k4) = scramble_keys(key1, key2); + AHasher { + buffer: k1, + pad: k2, + extra_keys: [k3, k4], + } + } + + /// This update function has the goal of updating the buffer with a single multiply + /// FxHash does this but is vulnerable to attack. To avoid this input needs to be masked to with an + /// unpredictable value. Other hashes such as murmurhash have taken this approach but were found vulnerable + /// to attack. The attack was based on the idea of reversing the pre-mixing (Which is necessarily + /// reversible otherwise bits would be lost) then placing a difference in the highest bit before the + /// multiply used to mix the data. Because a multiply can never affect the bits to the right of it, a + /// subsequent update that also differed in this bit could result in a predictable collision. + /// + /// This version avoids this vulnerability while still only using a single multiply. It takes advantage + /// of the fact that when a 64 bit multiply is performed the upper 64 bits are usually computed and thrown + /// away. Instead it creates two 128 bit values where the upper 64 bits are zeros and multiplies them. + /// (The compiler is smart enough to turn this into a 64 bit multiplication in the assembly) + /// Then the upper bits are xored with the lower bits to produce a single 64 bit result. + /// + /// To understand why this is a good scrambling function it helps to understand multiply-with-carry PRNGs: + /// https://en.wikipedia.org/wiki/Multiply-with-carry_pseudorandom_number_generator + /// If the multiple is chosen well, this creates a long period, decent quality PRNG. + /// Notice that this function is equivalent to this except the `buffer`/`state` is being xored with each + /// new block of data. In the event that data is all zeros, it is exactly equivalent to a MWC PRNG. + /// + /// This is impervious to attack because every bit buffer at the end is dependent on every bit in + /// `new_data ^ buffer`. For example suppose two inputs differed in only the 5th bit. Then when the + /// multiplication is performed the `result` will differ in bits 5-69. More specifically it will differ by + /// 2^5 * MULTIPLE. However in the next step bits 65-128 are turned into a separate 64 bit value. So the + /// differing bits will be in the lower 6 bits of this value. The two intermediate values that differ in + /// bits 5-63 and in bits 0-5 respectively get added together. Producing an output that differs in every + /// bit. The addition carries in the multiplication and at the end additionally mean that the even if an + /// attacker somehow knew part of (but not all) the contents of the buffer before hand, + /// they would not be able to predict any of the bits in the buffer at the end. + #[inline(always)] + fn update(&mut self, new_data: u64) { + self.buffer = folded_multiply(new_data ^ self.buffer, MULTIPLE); + } + + /// Similar to the above this function performs an update using a "folded multiply". + /// However it takes in 128 bits of data instead of 64. Both halves must be masked. + /// + /// This makes it impossible for an attacker to place a single bit difference between + /// two blocks so as to cancel each other. + /// + /// However this is not sufficient. to prevent (a,b) from hashing the same as (b,a) the buffer itself must + /// be updated between calls in a way that does not commute. To achieve this XOR and Rotate are used. + /// Add followed by xor is not the same as xor followed by add, and rotate ensures that the same out bits + /// can't be changed by the same set of input bits. To cancel this sequence with subsequent input would require + /// knowing the keys. + #[inline(always)] + fn large_update(&mut self, new_data: u128) { + let block: [u64; 2] = new_data.convert(); + let combined = folded_multiply(block[0] ^ self.extra_keys[0], block[1] ^ self.extra_keys[1]); + self.buffer = (self.pad.wrapping_add(combined) ^ self.buffer).rotate_left(ROT); + } +} + +#[cfg(feature = "specialize")] +impl HasherExt for AHasher { + #[inline] + fn hash_u64(self, value: u64) -> u64 { + let rot = (self.pad & 64) as u32; + folded_multiply(value ^ self.buffer, MULTIPLE).rotate_left(rot) + } + + #[inline] + fn short_finish(&self) -> u64 { + self.buffer.wrapping_add(self.pad) + } +} + +/// Provides methods to hash all of the primitive types. +impl Hasher for AHasher { + #[inline] + fn write_u8(&mut self, i: u8) { + self.update(i as u64); + } + + #[inline] + fn write_u16(&mut self, i: u16) { + self.update(i as u64); + } + + #[inline] + fn write_u32(&mut self, i: u32) { + self.update(i as u64); + } + + #[inline] + fn write_u64(&mut self, i: u64) { + self.update(i as u64); + } + + #[inline] + fn write_u128(&mut self, i: u128) { + let data: [u64; 2] = i.convert(); + self.update(data[0]); + self.update(data[1]); + } + + #[inline] + fn write_usize(&mut self, i: usize) { + self.write_u64(i as u64); + } + + #[inline] + #[allow(clippy::collapsible_if)] + fn write(&mut self, input: &[u8]) { + let mut data = input; + let length = data.len() as u64; + //Needs to be an add rather than an xor because otherwise it could be canceled with carefully formed input. + self.buffer = self.buffer.wrapping_add(length).wrapping_mul(MULTIPLE); + //A 'binary search' on sizes reduces the number of comparisons. + if data.len() > 8 { + if data.len() > 16 { + let tail = data.read_last_u128(); + self.large_update(tail); + while data.len() > 16 { + let (block, rest) = data.read_u128(); + self.large_update(block); + data = rest; + } + } else { + self.large_update([data.read_u64().0, data.read_last_u64()].convert()); + } + } else { + if data.len() >= 2 { + if data.len() >= 4 { + let block = [data.read_u32().0 as u64, data.read_last_u32() as u64]; + self.large_update(block.convert()); + } else { + let value = [data.read_u16().0 as u32, data[data.len() - 1] as u32]; + self.update(value.convert()); + } + } else { + if data.len() > 0 { + self.update(data[0] as u64); + } + } + } + } + #[inline] + fn finish(&self) -> u64 { + let rot = (self.buffer & 63) as u32; + folded_multiply(self.buffer, self.pad).rotate_left(rot) + } +} + +#[cfg(test)] +mod tests { + use crate::convert::Convert; + use crate::fallback_hash::*; + + #[test] + fn test_hash() { + let mut hasher = AHasher::new_with_keys(0, 0); + let value: u64 = 1 << 32; + hasher.update(value); + let result = hasher.buffer; + let mut hasher = AHasher::new_with_keys(0, 0); + let value2: u64 = 1; + hasher.update(value2); + let result2 = hasher.buffer; + let result: [u8; 8] = result.convert(); + let result2: [u8; 8] = result2.convert(); + assert_ne!(hex::encode(result), hex::encode(result2)); + } + + #[test] + fn test_conversion() { + let input: &[u8] = "dddddddd".as_bytes(); + let bytes: u64 = as_array!(input, 8).convert(); + assert_eq!(bytes, 0x6464646464646464); + } +} diff --git a/third_party/rust/ahash/src/hash_map.rs b/third_party/rust/ahash/src/hash_map.rs new file mode 100644 index 0000000000..362ac8551a --- /dev/null +++ b/third_party/rust/ahash/src/hash_map.rs @@ -0,0 +1,177 @@ +use std::borrow::Borrow; +use std::collections::{hash_map, HashMap}; +use std::fmt::{self, Debug}; +use std::hash::{BuildHasher, Hash}; +use std::iter::FromIterator; +use std::ops::{Deref, DerefMut, Index}; +use std::panic::UnwindSafe; + +/// A [`HashMap`](std::collections::HashMap) using [`RandomState`](crate::RandomState) to hash the items. +/// Requires the `std` feature to be enabled. +#[derive(Clone)] +pub struct AHashMap<K, V, S = crate::RandomState>(HashMap<K, V, S>); + +impl<K, V, S> AHashMap<K, V, S> +where + K: Hash + Eq, + S: BuildHasher + Default, +{ + pub fn new() -> Self { + AHashMap(HashMap::with_hasher(S::default())) + } + + pub fn with_capacity(capacity: usize) -> Self { + AHashMap(HashMap::with_capacity_and_hasher(capacity, S::default())) + } +} + +impl<K, V, S> AHashMap<K, V, S> +where + K: Hash + Eq, + S: BuildHasher, +{ + pub fn with_hasher(hash_builder: S) -> Self { + AHashMap(HashMap::with_hasher(hash_builder)) + } + + pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self { + AHashMap(HashMap::with_capacity_and_hasher(capacity, hash_builder)) + } +} + +impl<K, V, S> Deref for AHashMap<K, V, S> { + type Target = HashMap<K, V, S>; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl<K, V, S> DerefMut for AHashMap<K, V, S> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl<K, V, S> UnwindSafe for AHashMap<K, V, S> +where + K: UnwindSafe, + V: UnwindSafe, +{ +} + +impl<K, V, S> PartialEq for AHashMap<K, V, S> +where + K: Eq + Hash, + V: PartialEq, + S: BuildHasher, +{ + fn eq(&self, other: &AHashMap<K, V, S>) -> bool { + self.0.eq(&other.0) + } +} + +impl<K, V, S> Eq for AHashMap<K, V, S> +where + K: Eq + Hash, + V: Eq, + S: BuildHasher, +{ +} + +impl<K, Q: ?Sized, V, S> Index<&Q> for AHashMap<K, V, S> +where + K: Eq + Hash + Borrow<Q>, + Q: Eq + Hash, + S: BuildHasher, +{ + type Output = V; + + /// Returns a reference to the value corresponding to the supplied key. + /// + /// # Panics + /// + /// Panics if the key is not present in the `HashMap`. + #[inline] + fn index(&self, key: &Q) -> &V { + self.0.index(key) + } +} + +impl<K, V, S> Debug for AHashMap<K, V, S> +where + K: Eq + Hash + Debug, + V: Debug, + S: BuildHasher, +{ + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(fmt) + } +} + +impl<K, V, S> FromIterator<(K, V)> for AHashMap<K, V, S> +where + K: Eq + Hash, + S: BuildHasher + Default, +{ + fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self { + AHashMap(HashMap::from_iter(iter)) + } +} + +impl<'a, K, V, S> IntoIterator for &'a AHashMap<K, V, S> { + type Item = (&'a K, &'a V); + type IntoIter = hash_map::Iter<'a, K, V>; + fn into_iter(self) -> Self::IntoIter { + (&self.0).iter() + } +} + +impl<'a, K, V, S> IntoIterator for &'a mut AHashMap<K, V, S> { + type Item = (&'a K, &'a mut V); + type IntoIter = hash_map::IterMut<'a, K, V>; + fn into_iter(self) -> Self::IntoIter { + (&mut self.0).iter_mut() + } +} + +impl<K, V, S> IntoIterator for AHashMap<K, V, S> { + type Item = (K, V); + type IntoIter = hash_map::IntoIter<K, V>; + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +impl<K, V, S> Extend<(K, V)> for AHashMap<K, V, S> +where + K: Eq + Hash, + S: BuildHasher, +{ + #[inline] + fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) { + self.0.extend(iter) + } +} + +impl<'a, K, V, S> Extend<(&'a K, &'a V)> for AHashMap<K, V, S> +where + K: Eq + Hash + Copy + 'a, + V: Copy + 'a, + S: BuildHasher, +{ + #[inline] + fn extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) { + self.0.extend(iter) + } +} + +impl<K, V, S> Default for AHashMap<K, V, S> +where + K: Eq + Hash, + S: BuildHasher + Default, +{ + #[inline] + fn default() -> AHashMap<K, V, S> { + AHashMap::with_hasher(Default::default()) + } +} diff --git a/third_party/rust/ahash/src/hash_quality_test.rs b/third_party/rust/ahash/src/hash_quality_test.rs new file mode 100644 index 0000000000..1a69562daa --- /dev/null +++ b/third_party/rust/ahash/src/hash_quality_test.rs @@ -0,0 +1,451 @@ +use crate::{CallHasher, HasherExt}; +use core::hash::{Hash, Hasher}; +use std::collections::HashMap; + +fn assert_sufficiently_different(a: u64, b: u64, tolerance: i32) { + let (same_byte_count, same_nibble_count) = count_same_bytes_and_nibbles(a, b); + assert!(same_byte_count <= tolerance, "{:x} vs {:x}: {:}", a, b, same_byte_count); + assert!( + same_nibble_count <= tolerance * 3, + "{:x} vs {:x}: {:}", + a, + b, + same_nibble_count + ); + let flipped_bits = (a ^ b).count_ones(); + assert!( + flipped_bits > 12 && flipped_bits < 52, + "{:x} and {:x}: {:}", + a, + b, + flipped_bits + ); + for rotate in 0..64 { + let flipped_bits2 = (a ^ (b.rotate_left(rotate))).count_ones(); + assert!( + flipped_bits2 > 10 && flipped_bits2 < 54, + "{:x} and {:x}: {:}", + a, + b.rotate_left(rotate), + flipped_bits2 + ); + } +} + +fn count_same_bytes_and_nibbles(a: u64, b: u64) -> (i32, i32) { + let mut same_byte_count = 0; + let mut same_nibble_count = 0; + for byte in 0..8 { + let ba = (a >> (8 * byte)) as u8; + let bb = (b >> (8 * byte)) as u8; + if ba == bb { + same_byte_count += 1; + } + if ba & 0xF0u8 == bb & 0xF0u8 { + same_nibble_count += 1; + } + if ba & 0x0Fu8 == bb & 0x0Fu8 { + same_nibble_count += 1; + } + } + (same_byte_count, same_nibble_count) +} + +fn gen_combinations(options: &[u32; 8], depth: u32, so_far: Vec<u32>, combinations: &mut Vec<Vec<u32>>) { + if depth == 0 { + return; + } + for option in options { + let mut next = so_far.clone(); + next.push(*option); + combinations.push(next.clone()); + gen_combinations(options, depth - 1, next, combinations); + } +} + +fn test_no_full_collisions<T: Hasher>(gen_hash: impl Fn() -> T) { + let options: [u32; 8] = [ + 0x00000000, 0x20000000, 0x40000000, 0x60000000, 0x80000000, 0xA0000000, 0xC0000000, 0xE0000000, + ]; + let mut combinations = Vec::new(); + gen_combinations(&options, 7, Vec::new(), &mut combinations); + let mut map: HashMap<u64, Vec<u8>> = HashMap::new(); + for combination in combinations { + let array = unsafe { + let (begin, middle, end) = combination.align_to::<u8>(); + assert_eq!(0, begin.len()); + assert_eq!(0, end.len()); + middle.to_vec() + }; + let mut hasher = gen_hash(); + hasher.write(&array); + let hash = hasher.finish(); + if let Some(value) = map.get(&hash) { + assert_eq!( + value, &array, + "Found a collision between {:x?} and {:x?}", + value, &array + ); + } else { + map.insert(hash, array); + } + } + assert_eq!(2396744, map.len()); +} + +fn test_keys_change_output<T: HasherExt>(constructor: impl Fn(u64, u64) -> T) { + let mut a = constructor(1, 1); + let mut b = constructor(1, 2); + let mut c = constructor(2, 1); + let mut d = constructor(2, 2); + "test".hash(&mut a); + "test".hash(&mut b); + "test".hash(&mut c); + "test".hash(&mut d); + assert_sufficiently_different(a.finish(), b.finish(), 1); + assert_sufficiently_different(a.finish(), c.finish(), 1); + assert_sufficiently_different(a.finish(), d.finish(), 1); + assert_sufficiently_different(b.finish(), c.finish(), 1); + assert_sufficiently_different(b.finish(), d.finish(), 1); + assert_sufficiently_different(c.finish(), d.finish(), 1); +} + +fn test_input_affect_every_byte<T: HasherExt>(constructor: impl Fn(u64, u64) -> T) { + let base = 0.get_hash(constructor(0, 0)); + for shift in 0..16 { + let mut alternitives = vec![]; + for v in 0..256 { + let input = (v as u128) << (shift * 8); + let hasher = constructor(0, 0); + alternitives.push(input.get_hash(hasher)); + } + assert_each_byte_differs(base, alternitives); + } +} + +///Ensures that for every bit in the output there is some value for each byte in the key that flips it. +fn test_keys_affect_every_byte<H: Hash, T: HasherExt>(item: H, constructor: impl Fn(u64, u64) -> T) { + let base = item.get_hash(constructor(0, 0)); + for shift in 0..8 { + let mut alternitives1 = vec![]; + let mut alternitives2 = vec![]; + for v in 0..256 { + let input = (v as u64) << (shift * 8); + let hasher1 = constructor(input, 0); + let hasher2 = constructor(0, input); + let h1 = item.get_hash(hasher1); + let h2 = item.get_hash(hasher2); + alternitives1.push(h1); + alternitives2.push(h2); + } + assert_each_byte_differs(base, alternitives1); + assert_each_byte_differs(base, alternitives2); + } +} + +fn assert_each_byte_differs(base: u64, alternitives: Vec<u64>) { + let mut changed_bits = 0_u64; + for alternitive in alternitives { + changed_bits |= base ^ alternitive + } + assert_eq!(core::u64::MAX, changed_bits, "Bits changed: {:x}", changed_bits); +} + +fn test_finish_is_consistent<T: Hasher>(constructor: impl Fn(u64, u64) -> T) { + let mut hasher = constructor(1, 2); + "Foo".hash(&mut hasher); + let a = hasher.finish(); + let b = hasher.finish(); + assert_eq!(a, b); +} + +fn test_single_key_bit_flip<T: Hasher>(constructor: impl Fn(u64, u64) -> T) { + for bit in 0..64 { + let mut a = constructor(0, 0); + let mut b = constructor(0, 1 << bit); + let mut c = constructor(1 << bit, 0); + "1234".hash(&mut a); + "1234".hash(&mut b); + "1234".hash(&mut c); + assert_sufficiently_different(a.finish(), b.finish(), 2); + assert_sufficiently_different(a.finish(), c.finish(), 2); + assert_sufficiently_different(b.finish(), c.finish(), 2); + let mut a = constructor(0, 0); + let mut b = constructor(0, 1 << bit); + let mut c = constructor(1 << bit, 0); + "12345678".hash(&mut a); + "12345678".hash(&mut b); + "12345678".hash(&mut c); + assert_sufficiently_different(a.finish(), b.finish(), 2); + assert_sufficiently_different(a.finish(), c.finish(), 2); + assert_sufficiently_different(b.finish(), c.finish(), 2); + let mut a = constructor(0, 0); + let mut b = constructor(0, 1 << bit); + let mut c = constructor(1 << bit, 0); + "1234567812345678".hash(&mut a); + "1234567812345678".hash(&mut b); + "1234567812345678".hash(&mut c); + assert_sufficiently_different(a.finish(), b.finish(), 2); + assert_sufficiently_different(a.finish(), c.finish(), 2); + assert_sufficiently_different(b.finish(), c.finish(), 2); + } +} + +fn test_all_bytes_matter<T: HasherExt>(hasher: impl Fn() -> T) { + let mut item = vec![0; 256]; + let base_hash = hash(&item, &hasher); + for pos in 0..256 { + item[pos] = 255; + let hash = hash(&item, &hasher); + assert_ne!(base_hash, hash, "Position {} did not affect output", pos); + item[pos] = 0; + } +} + +fn test_no_pair_collisions<T: HasherExt>(hasher: impl Fn() -> T) { + let base = [0_u64, 0_u64]; + let base_hash = hash(&base, &hasher); + for bitpos1 in 0..64 { + let a = 1_u64 << bitpos1; + for bitpos2 in 0..bitpos1 { + let b = 1_u64 << bitpos2; + let aa = hash(&[a, a], &hasher); + let ab = hash(&[a, b], &hasher); + let ba = hash(&[b, a], &hasher); + let bb = hash(&[b, b], &hasher); + assert_sufficiently_different(base_hash, aa, 3); + assert_sufficiently_different(base_hash, ab, 3); + assert_sufficiently_different(base_hash, ba, 3); + assert_sufficiently_different(base_hash, bb, 3); + assert_sufficiently_different(aa, ab, 3); + assert_sufficiently_different(ab, ba, 3); + assert_sufficiently_different(ba, bb, 3); + assert_sufficiently_different(aa, ba, 3); + assert_sufficiently_different(ab, bb, 3); + assert_sufficiently_different(aa, bb, 3); + } + } +} + +fn hash<H: Hash, T: HasherExt>(b: &H, hasher: &dyn Fn() -> T) -> u64 { + b.get_hash(hasher()) +} + +fn test_single_bit_flip<T: HasherExt>(hasher: impl Fn() -> T) { + let size = 32; + let compare_value = hash(&0u32, &hasher); + for pos in 0..size { + let test_value = hash(&(1u32 << pos), &hasher); + assert_sufficiently_different(compare_value, test_value, 2); + } + let size = 64; + let compare_value = hash(&0u64, &hasher); + for pos in 0..size { + let test_value = hash(&(1u64 << pos), &hasher); + assert_sufficiently_different(compare_value, test_value, 2); + } + let size = 128; + let compare_value = hash(&0u128, &hasher); + for pos in 0..size { + let test_value = hash(&(1u128 << pos), &hasher); + assert_sufficiently_different(compare_value, test_value, 2); + } +} + +fn test_padding_doesnot_collide<T: Hasher>(hasher: impl Fn() -> T) { + for c in 0..128u8 { + for string in ["", "\0", "\x01", "1234", "12345678", "1234567812345678"].iter() { + let mut short = hasher(); + string.hash(&mut short); + let value = short.finish(); + let mut padded = string.to_string(); + for num in 1..=128 { + let mut long = hasher(); + padded.push(c as char); + padded.hash(&mut long); + let (same_bytes, same_nibbles) = count_same_bytes_and_nibbles(value, long.finish()); + assert!( + same_bytes <= 3, + format!("{} bytes of {} -> {:x} vs {:x}", num, c, value, long.finish()) + ); + assert!( + same_nibbles <= 8, + format!("{} bytes of {} -> {:x} vs {:x}", num, c, value, long.finish()) + ); + let flipped_bits = (value ^ long.finish()).count_ones(); + assert!(flipped_bits > 10); + } + if string.len() > 0 { + let mut padded = string[1..].to_string(); + padded.push(c as char); + for num in 2..=128 { + let mut long = hasher(); + padded.push(c as char); + padded.hash(&mut long); + let (same_bytes, same_nibbles) = count_same_bytes_and_nibbles(value, long.finish()); + assert!( + same_bytes <= 3, + format!( + "string {:?} + {} bytes of {} -> {:x} vs {:x}", + string, + num, + c, + value, + long.finish() + ) + ); + assert!( + same_nibbles <= 8, + format!( + "string {:?} + {} bytes of {} -> {:x} vs {:x}", + string, + num, + c, + value, + long.finish() + ) + ); + let flipped_bits = (value ^ long.finish()).count_ones(); + assert!(flipped_bits > 10); + } + } + } + } +} + +#[cfg(test)] +mod fallback_tests { + use crate::fallback_hash::*; + use crate::hash_quality_test::*; + + #[test] + fn fallback_single_bit_flip() { + test_single_bit_flip(|| AHasher::test_with_keys(0, 0)) + } + + #[test] + fn fallback_single_key_bit_flip() { + test_single_key_bit_flip(AHasher::test_with_keys) + } + + #[test] + fn fallback_all_bytes_matter() { + test_all_bytes_matter(|| AHasher::test_with_keys(0, 0)); + } + + #[test] + fn fallback_test_no_pair_collisions() { + test_no_pair_collisions(|| AHasher::test_with_keys(0, 0)); + } + + #[test] + fn fallback_test_no_full_collisions() { + test_no_full_collisions(|| AHasher::test_with_keys(12345, 67890)); + } + + #[test] + fn fallback_keys_change_output() { + test_keys_change_output(AHasher::test_with_keys); + } + + #[test] + fn fallback_input_affect_every_byte() { + test_input_affect_every_byte(AHasher::test_with_keys); + } + + #[test] + fn fallback_keys_affect_every_byte() { + test_keys_affect_every_byte(0, AHasher::test_with_keys); + test_keys_affect_every_byte("", AHasher::test_with_keys); + test_keys_affect_every_byte((0, 0), AHasher::test_with_keys); + } + + #[test] + fn fallback_finish_is_consistant() { + test_finish_is_consistent(AHasher::test_with_keys) + } + + #[test] + fn fallback_padding_doesnot_collide() { + test_padding_doesnot_collide(|| AHasher::test_with_keys(0, 0)); + test_padding_doesnot_collide(|| AHasher::test_with_keys(0, 1)); + test_padding_doesnot_collide(|| AHasher::test_with_keys(1, 0)); + test_padding_doesnot_collide(|| AHasher::test_with_keys(1, 1)); + } +} + +///Basic sanity tests of the cypto properties of aHash. +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)))] +#[cfg(test)] +mod aes_tests { + use crate::aes_hash::*; + use crate::hash_quality_test::*; + use std::hash::{Hash, Hasher}; + + const BAD_KEY: u64 = 0x5252_5252_5252_5252; //This encrypts to 0. + const BAD_KEY2: u64 = 0x6363_6363_6363_6363; //This decrypts to 0. + + #[test] + fn test_single_bit_in_byte() { + let mut hasher1 = AHasher::new_with_keys(0, 0); + 8_u32.hash(&mut hasher1); + let mut hasher2 = AHasher::new_with_keys(0, 0); + 0_u32.hash(&mut hasher2); + assert_sufficiently_different(hasher1.finish(), hasher2.finish(), 1); + } + + #[test] + fn aes_single_bit_flip() { + test_single_bit_flip(|| AHasher::test_with_keys(BAD_KEY, BAD_KEY)); + test_single_bit_flip(|| AHasher::test_with_keys(BAD_KEY2, BAD_KEY2)); + } + + #[test] + fn aes_single_key_bit_flip() { + test_single_key_bit_flip(|k1, k2| AHasher::test_with_keys(k1, k2)) + } + + #[test] + fn aes_all_bytes_matter() { + test_all_bytes_matter(|| AHasher::test_with_keys(BAD_KEY, BAD_KEY)); + test_all_bytes_matter(|| AHasher::test_with_keys(BAD_KEY2, BAD_KEY2)); + } + + #[test] + fn aes_test_no_pair_collisions() { + test_no_pair_collisions(|| AHasher::test_with_keys(BAD_KEY, BAD_KEY)); + test_no_pair_collisions(|| AHasher::test_with_keys(BAD_KEY2, BAD_KEY2)); + } + + #[test] + fn ase_test_no_full_collisions() { + test_no_full_collisions(|| AHasher::test_with_keys(12345, 67890)); + } + + #[test] + fn aes_keys_change_output() { + test_keys_change_output(AHasher::test_with_keys); + } + + #[test] + fn aes_input_affect_every_byte() { + test_input_affect_every_byte(AHasher::test_with_keys); + } + + #[test] + fn aes_keys_affect_every_byte() { + test_keys_affect_every_byte(0, AHasher::test_with_keys); + test_keys_affect_every_byte("", AHasher::test_with_keys); + test_keys_affect_every_byte((0, 0), AHasher::test_with_keys); + } + #[test] + fn aes_finish_is_consistant() { + test_finish_is_consistent(AHasher::test_with_keys) + } + + #[test] + fn aes_padding_doesnot_collide() { + test_padding_doesnot_collide(|| AHasher::test_with_keys(BAD_KEY, BAD_KEY)); + test_padding_doesnot_collide(|| AHasher::test_with_keys(BAD_KEY2, BAD_KEY2)); + } +} diff --git a/third_party/rust/ahash/src/hash_set.rs b/third_party/rust/ahash/src/hash_set.rs new file mode 100644 index 0000000000..2950ec9282 --- /dev/null +++ b/third_party/rust/ahash/src/hash_set.rs @@ -0,0 +1,267 @@ +use std::collections::{hash_set, HashSet}; +use std::fmt::{self, Debug}; +use std::hash::{BuildHasher, Hash}; +use std::iter::FromIterator; +use std::ops::{BitAnd, BitOr, BitXor, Deref, DerefMut, Sub}; + +/// A [`HashSet`](std::collections::HashSet) using [`RandomState`](crate::RandomState) to hash the items. +/// Requires the `std` feature to be enabled. +#[derive(Clone)] +pub struct AHashSet<T, S = crate::RandomState>(HashSet<T, S>); + +impl<T, S> AHashSet<T, S> +where + T: Hash + Eq, + S: BuildHasher + Default, +{ + pub fn new() -> Self { + AHashSet(HashSet::with_hasher(S::default())) + } + + pub fn with_capacity(capacity: usize) -> Self { + AHashSet(HashSet::with_capacity_and_hasher(capacity, S::default())) + } +} + +impl<T, S> AHashSet<T, S> +where + T: Hash + Eq, + S: BuildHasher, +{ + pub fn with_hasher(hash_builder: S) -> Self { + AHashSet(HashSet::with_hasher(hash_builder)) + } + + pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self { + AHashSet(HashSet::with_capacity_and_hasher(capacity, hash_builder)) + } +} + +impl<T, S> Deref for AHashSet<T, S> { + type Target = HashSet<T, S>; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl<T, S> DerefMut for AHashSet<T, S> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl<T, S> PartialEq for AHashSet<T, S> +where + T: Eq + Hash, + S: BuildHasher, +{ + fn eq(&self, other: &AHashSet<T, S>) -> bool { + self.0.eq(&other.0) + } +} + +impl<T, S> Eq for AHashSet<T, S> +where + T: Eq + Hash, + S: BuildHasher, +{ +} + +impl<T, S> BitOr<&AHashSet<T, S>> for &AHashSet<T, S> +where + T: Eq + Hash + Clone, + S: BuildHasher + Default, +{ + type Output = AHashSet<T, S>; + + /// Returns the union of `self` and `rhs` as a new `AHashSet<T, S>`. + /// + /// # Examples + /// + /// ``` + /// use ahash::AHashSet; + /// + /// let a: AHashSet<_> = vec![1, 2, 3].into_iter().collect(); + /// let b: AHashSet<_> = vec![3, 4, 5].into_iter().collect(); + /// + /// let set = &a | &b; + /// + /// let mut i = 0; + /// let expected = [1, 2, 3, 4, 5]; + /// for x in &set { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn bitor(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> { + AHashSet(self.0.bitor(&rhs.0)) + } +} + +impl<T, S> BitAnd<&AHashSet<T, S>> for &AHashSet<T, S> +where + T: Eq + Hash + Clone, + S: BuildHasher + Default, +{ + type Output = AHashSet<T, S>; + + /// Returns the intersection of `self` and `rhs` as a new `AHashSet<T, S>`. + /// + /// # Examples + /// + /// ``` + /// use ahash::AHashSet; + /// + /// let a: AHashSet<_> = vec![1, 2, 3].into_iter().collect(); + /// let b: AHashSet<_> = vec![2, 3, 4].into_iter().collect(); + /// + /// let set = &a & &b; + /// + /// let mut i = 0; + /// let expected = [2, 3]; + /// for x in &set { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn bitand(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> { + AHashSet(self.0.bitand(&rhs.0)) + } +} + +impl<T, S> BitXor<&AHashSet<T, S>> for &AHashSet<T, S> +where + T: Eq + Hash + Clone, + S: BuildHasher + Default, +{ + type Output = AHashSet<T, S>; + + /// Returns the symmetric difference of `self` and `rhs` as a new `AHashSet<T, S>`. + /// + /// # Examples + /// + /// ``` + /// use ahash::AHashSet; + /// + /// let a: AHashSet<_> = vec![1, 2, 3].into_iter().collect(); + /// let b: AHashSet<_> = vec![3, 4, 5].into_iter().collect(); + /// + /// let set = &a ^ &b; + /// + /// let mut i = 0; + /// let expected = [1, 2, 4, 5]; + /// for x in &set { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn bitxor(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> { + AHashSet(self.0.bitxor(&rhs.0)) + } +} + +impl<T, S> Sub<&AHashSet<T, S>> for &AHashSet<T, S> +where + T: Eq + Hash + Clone, + S: BuildHasher + Default, +{ + type Output = AHashSet<T, S>; + + /// Returns the difference of `self` and `rhs` as a new `AHashSet<T, S>`. + /// + /// # Examples + /// + /// ``` + /// use ahash::AHashSet; + /// + /// let a: AHashSet<_> = vec![1, 2, 3].into_iter().collect(); + /// let b: AHashSet<_> = vec![3, 4, 5].into_iter().collect(); + /// + /// let set = &a - &b; + /// + /// let mut i = 0; + /// let expected = [1, 2]; + /// for x in &set { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn sub(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> { + AHashSet(self.0.sub(&rhs.0)) + } +} + +impl<T, S> Debug for AHashSet<T, S> +where + T: Eq + Hash + Debug, + S: BuildHasher, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(fmt) + } +} + +impl<T, S> FromIterator<T> for AHashSet<T, S> +where + T: Eq + Hash, + S: BuildHasher + Default, +{ + #[inline] + fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> AHashSet<T, S> { + AHashSet(HashSet::from_iter(iter)) + } +} + +impl<'a, T, S> IntoIterator for &'a AHashSet<T, S> { + type Item = &'a T; + type IntoIter = hash_set::Iter<'a, T>; + fn into_iter(self) -> Self::IntoIter { + (&self.0).iter() + } +} + +impl<T, S> IntoIterator for AHashSet<T, S> { + type Item = T; + type IntoIter = hash_set::IntoIter<T>; + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +impl<T, S> Extend<T> for AHashSet<T, S> +where + T: Eq + Hash, + S: BuildHasher, +{ + #[inline] + fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { + self.0.extend(iter) + } +} + +impl<'a, T, S> Extend<&'a T> for AHashSet<T, S> +where + T: 'a + Eq + Hash + Copy, + S: BuildHasher, +{ + #[inline] + fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) { + self.0.extend(iter) + } +} + +impl<T, S> Default for AHashSet<T, S> +where + T: Eq + Hash, + S: BuildHasher + Default, +{ + /// Creates an empty `AHashSet<T, S>` with the `Default` value for the hasher. + #[inline] + fn default() -> AHashSet<T, S> { + AHashSet(HashSet::default()) + } +} diff --git a/third_party/rust/ahash/src/lib.rs b/third_party/rust/ahash/src/lib.rs new file mode 100644 index 0000000000..542fa35e92 --- /dev/null +++ b/third_party/rust/ahash/src/lib.rs @@ -0,0 +1,203 @@ +//! # aHash +//! +//! This hashing algorithm is intended to be a high performance, (hardware specific), keyed hash function. +//! This can be seen as a DOS resistant alternative to `FxHash`, or a fast equivalent to `SipHash`. +//! It provides a high speed hash algorithm, but where the result is not predictable without knowing a Key. +//! This allows it to be used in a `HashMap` without allowing for the possibility that an malicious user can +//! induce a collision. +//! +//! # How aHash works +//! +//! aHash uses the hardware AES instruction on x86 processors to provide a keyed hash function. +//! aHash is not a cryptographically secure hash. +#![deny(clippy::correctness, clippy::complexity, clippy::perf)] +#![allow(clippy::pedantic, clippy::cast_lossless, clippy::unreadable_literal)] +#![cfg_attr(all(not(test), not(feature = "std")), no_std)] +#![cfg_attr(feature = "specialize", feature(specialization))] + +#[macro_use] +mod convert; + +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)))] +mod aes_hash; +mod fallback_hash; +#[cfg(test)] +mod hash_quality_test; + +mod operations; +#[cfg(feature = "std")] +mod hash_map; +#[cfg(feature = "std")] +mod hash_set; +mod random_state; +mod specialize; + +#[cfg(feature = "compile-time-rng")] +use const_random::const_random; + +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)))] +pub use crate::aes_hash::AHasher; + +#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri))))] +pub use crate::fallback_hash::AHasher; +pub use crate::random_state::RandomState; + +pub use crate::specialize::CallHasher; + +#[cfg(feature = "std")] +pub use crate::hash_map::AHashMap; +#[cfg(feature = "std")] +pub use crate::hash_set::AHashSet; +use core::hash::Hasher; + +/// Provides a default [Hasher] compile time generated constants for keys. +/// This is typically used in conjunction with [BuildHasherDefault] to create +/// [AHasher]s in order to hash the keys of the map. +/// +/// Generally it is preferable to use [RandomState] instead, so that different +/// hashmaps will have different keys. However if fixed keys are desireable this +/// may be used instead. +/// +/// # Example +/// ``` +/// use std::hash::BuildHasherDefault; +/// use ahash::{AHasher, RandomState}; +/// use std::collections::HashMap; +/// +/// let mut map: HashMap<i32, i32, BuildHasherDefault<AHasher>> = HashMap::default(); +/// map.insert(12, 34); +/// ``` +/// +/// [BuildHasherDefault]: std::hash::BuildHasherDefault +/// [Hasher]: std::hash::Hasher +/// [HashMap]: std::collections::HashMap +impl Default for AHasher { + + /// Constructs a new [AHasher] with compile time generated constants for keys if the + /// `compile-time-rng`feature is enabled. Otherwise the keys will be fixed constants. + /// This means the keys will be the same from one instance to another, + /// but different from build to the next. So if it is possible for a potential + /// attacker to have access to the compiled binary it would be better + /// to specify keys generated at runtime. + /// + /// # Examples + /// + /// ``` + /// use ahash::AHasher; + /// use std::hash::Hasher; + /// + /// let mut hasher_1 = AHasher::default(); + /// let mut hasher_2 = AHasher::default(); + /// + /// hasher_1.write_u32(1234); + /// hasher_2.write_u32(1234); + /// + /// assert_eq!(hasher_1.finish(), hasher_2.finish()); + /// ``` + #[inline] + #[cfg(feature = "compile-time-rng")] + fn default() -> AHasher { + AHasher::new_with_keys(const_random!(u128), const_random!(u128)) + } + + /// Constructs a new [AHasher] with compile time generated constants for keys if the + /// `compile-time-rng`feature is enabled. Otherwise the keys will be fixed constants. + /// This means the keys will be the same from one instance to another, + /// but different from build to the next. So if it is possible for a potential + /// attacker to have access to the compiled binary it would be better + /// to specify keys generated at runtime. + /// + /// # Examples + /// + /// ``` + /// use ahash::AHasher; + /// use std::hash::Hasher; + /// + /// let mut hasher_1 = AHasher::default(); + /// let mut hasher_2 = AHasher::default(); + /// + /// hasher_1.write_u32(1234); + /// hasher_2.write_u32(1234); + /// + /// assert_eq!(hasher_1.finish(), hasher_2.finish()); + /// ``` + #[inline] + #[cfg(not(feature = "compile-time-rng"))] + fn default() -> AHasher { + const K1: u128 = (random_state::INIT_SEED[0] as u128).wrapping_mul(random_state::MULTIPLE as u128); + const K2: u128 = (random_state::INIT_SEED[1] as u128).wrapping_mul(random_state::MULTIPLE as u128); + AHasher::new_with_keys(K1, K2) + } +} + +/// Used for specialization. (Sealed) +pub(crate) trait HasherExt: Hasher { + #[doc(hidden)] + fn hash_u64(self, value: u64) -> u64; + + #[doc(hidden)] + fn short_finish(&self) -> u64; +} + +impl<T: Hasher> HasherExt for T { + #[inline] + #[cfg(feature = "specialize")] + default fn hash_u64(self, value: u64) -> u64 { + value.get_hash(self) + } + #[inline] + #[cfg(not(feature = "specialize"))] + fn hash_u64(self, value: u64) -> u64 { + value.get_hash(self) + } + #[inline] + #[cfg(feature = "specialize")] + default fn short_finish(&self) -> u64 { + self.finish() + } + #[inline] + #[cfg(not(feature = "specialize"))] + fn short_finish(&self) -> u64 { + self.finish() + } +} + +// #[inline(never)] +// #[doc(hidden)] +// pub fn hash_test(input: &[u8]) -> u64 { +// let a = AHasher::new_with_keys(11111111111_u128, 2222222222_u128); +// input.get_hash(a) +// } + +#[cfg(test)] +mod test { + use crate::convert::Convert; + use crate::*; + use std::collections::HashMap; + + #[cfg(feature = "std")] + #[test] + fn test_default_builder() { + use core::hash::BuildHasherDefault; + + let mut map = HashMap::<u32, u64, BuildHasherDefault<AHasher>>::default(); + map.insert(1, 3); + } + #[test] + fn test_builder() { + let mut map = HashMap::<u32, u64, RandomState>::default(); + map.insert(1, 3); + } + + #[test] + fn test_conversion() { + let input: &[u8] = b"dddddddd"; + let bytes: u64 = as_array!(input, 8).convert(); + assert_eq!(bytes, 0x6464646464646464); + } + + #[test] + fn test_ahasher_construction() { + let _ = AHasher::new_with_keys(1234, 5678); + } +} diff --git a/third_party/rust/ahash/src/operations.rs b/third_party/rust/ahash/src/operations.rs new file mode 100644 index 0000000000..0646c446cd --- /dev/null +++ b/third_party/rust/ahash/src/operations.rs @@ -0,0 +1,277 @@ +use crate::convert::*; + +/// This is a constant with a lot of special properties found by automated search. +/// See the unit tests below. (Below are alternative values) +#[cfg(all(target_feature = "ssse3", not(miri)))] +const SHUFFLE_MASK: u128 = 0x020a0700_0c01030e_050f0d08_06090b04_u128; +//const SHUFFLE_MASK: u128 = 0x000d0702_0a040301_05080f0c_0e0b0609_u128; +//const SHUFFLE_MASK: u128 = 0x040A0700_030E0106_0D050F08_020B0C09_u128; + +pub(crate) const fn folded_multiply(s: u64, by: u64) -> u64 { + let result = (s as u128).wrapping_mul(by as u128); + ((result & 0xffff_ffff_ffff_ffff) as u64) ^ ((result >> 64) as u64) +} + +#[inline(always)] +pub(crate) fn shuffle(a: u128) -> u128 { + #[cfg(all(target_feature = "ssse3", not(miri)))] + { + use core::mem::transmute; + #[cfg(target_arch = "x86")] + use core::arch::x86::*; + #[cfg(target_arch = "x86_64")] + use core::arch::x86_64::*; + unsafe { + transmute(_mm_shuffle_epi8(transmute(a), transmute(SHUFFLE_MASK))) + } + } + #[cfg(not(all(target_feature = "ssse3", not(miri))))] + { + a.swap_bytes() + } +} + +#[allow(unused)] //not used by fallback +#[inline(always)] +pub(crate) fn add_and_shuffle(a: u128, b: u128) -> u128 { + let sum = add_by_64s(a.convert(), b.convert()); + shuffle(sum.convert()) +} + +#[allow(unused)] //not used by fallbac +#[inline(always)] +pub(crate) fn shuffle_and_add(base: u128, to_add: u128) -> u128 { + let shuffled: [u64; 2] = shuffle(base).convert(); + add_by_64s(shuffled, to_add.convert()).convert() +} + +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2", not(miri)))] +#[inline(always)] +pub(crate) fn add_by_64s(a: [u64; 2], b: [u64; 2]) -> [u64; 2] { + use core::mem::transmute; + unsafe { + #[cfg(target_arch = "x86")] + use core::arch::x86::*; + #[cfg(target_arch = "x86_64")] + use core::arch::x86_64::*; + transmute(_mm_add_epi64(transmute(a), transmute(b))) + } +} + +#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2", not(miri))))] +#[inline(always)] +pub(crate) fn add_by_64s(a: [u64; 2], b: [u64; 2]) -> [u64; 2] { + [a[0].wrapping_add(b[0]), a[1].wrapping_add(b[1])] +} + +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)))] +#[allow(unused)] +#[inline(always)] +pub(crate) fn aesenc(value: u128, xor: u128) -> u128 { + #[cfg(target_arch = "x86")] + use core::arch::x86::*; + #[cfg(target_arch = "x86_64")] + use core::arch::x86_64::*; + use core::mem::transmute; + unsafe { + let value = transmute(value); + transmute(_mm_aesenc_si128(value, transmute(xor))) + } +} +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)))] +#[allow(unused)] +#[inline(always)] +pub(crate) fn aesdec(value: u128, xor: u128) -> u128 { + #[cfg(target_arch = "x86")] + use core::arch::x86::*; + #[cfg(target_arch = "x86_64")] + use core::arch::x86_64::*; + use core::mem::transmute; + unsafe { + let value = transmute(value); + transmute(_mm_aesdec_si128(value, transmute(xor))) + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::convert::Convert; + + // This is code to search for the shuffle constant + // + //thread_local! { static MASK: Cell<u128> = Cell::new(0); } + // + // fn shuffle(a: u128) -> u128 { + // use std::intrinsics::transmute; + // #[cfg(target_arch = "x86")] + // use core::arch::x86::*; + // #[cfg(target_arch = "x86_64")] + // use core::arch::x86_64::*; + // MASK.with(|mask| { + // unsafe { transmute(_mm_shuffle_epi8(transmute(a), transmute(mask.get()))) } + // }) + // } + // + // #[test] + // fn find_shuffle() { + // use rand::prelude::*; + // use SliceRandom; + // use std::panic; + // use std::io::Write; + // + // let mut value: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ,13, 14, 15]; + // let mut rand = thread_rng(); + // let mut successful_list = HashMap::new(); + // for _attempt in 0..10000000 { + // rand.shuffle(&mut value); + // let test_val = value.convert(); + // MASK.with(|mask| { + // mask.set(test_val); + // }); + // if let Ok(successful) = panic::catch_unwind(|| { + // test_shuffle_does_not_collide_with_aes(); + // test_shuffle_moves_high_bits(); + // test_shuffle_moves_every_value(); + // //test_shuffle_does_not_loop(); + // value + // }) { + // let successful: u128 = successful.convert(); + // successful_list.insert(successful, iters_before_loop()); + // } + // } + // let write_file = File::create("/tmp/output").unwrap(); + // let mut writer = BufWriter::new(&write_file); + // + // for success in successful_list { + // writeln!(writer, "Found successful: {:x?} - {:?}", success.0, success.1); + // } + // } + // + // fn iters_before_loop() -> u32 { + // let numbered = 0x00112233_44556677_8899AABB_CCDDEEFF; + // let mut shuffled = shuffle(numbered); + // let mut count = 0; + // loop { + // // println!("{:>16x}", shuffled); + // if numbered == shuffled { + // break; + // } + // count += 1; + // shuffled = shuffle(shuffled); + // } + // count + // } + + #[cfg(all( + any(target_arch = "x86", target_arch = "x86_64"), + target_feature = "ssse3", + target_feature = "aes", + not(miri) + ))] + #[test] + fn test_shuffle_does_not_collide_with_aes() { + let mut value: [u8; 16] = [0; 16]; + let zero_mask_enc = aesenc(0, 0); + let zero_mask_dec = aesdec(0, 0); + for index in 0..16 { + value[index] = 1; + let excluded_positions_enc: [u8; 16] = aesenc(value.convert(), zero_mask_enc).convert(); + let excluded_positions_dec: [u8; 16] = aesdec(value.convert(), zero_mask_dec).convert(); + let actual_location: [u8; 16] = shuffle(value.convert()).convert(); + for pos in 0..16 { + if actual_location[pos] != 0 { + assert_eq!( + 0, excluded_positions_enc[pos], + "Forward Overlap between {:?} and {:?} at {}", + excluded_positions_enc, actual_location, index + ); + assert_eq!( + 0, excluded_positions_dec[pos], + "Reverse Overlap between {:?} and {:?} at {}", + excluded_positions_dec, actual_location, index + ); + } + } + value[index] = 0; + } + } + + #[test] + fn test_shuffle_contains_each_value() { + let value: [u8; 16] = 0x00010203_04050607_08090A0B_0C0D0E0F_u128.convert(); + let shuffled: [u8; 16] = shuffle(value.convert()).convert(); + for index in 0..16_u8 { + assert!(shuffled.contains(&index), "Value is missing {}", index); + } + } + + #[test] + fn test_shuffle_moves_every_value() { + let mut value: [u8; 16] = [0; 16]; + for index in 0..16 { + value[index] = 1; + let shuffled: [u8; 16] = shuffle(value.convert()).convert(); + assert_eq!(0, shuffled[index], "Value is not moved {}", index); + value[index] = 0; + } + } + + #[test] + fn test_shuffle_moves_high_bits() { + assert!( + shuffle(1) > (1_u128 << 80), + "Low bits must be moved to other half {:?} -> {:?}", + 0, + shuffle(1) + ); + + assert!( + shuffle(1_u128 << 58) >= (1_u128 << 64), + "High bits must be moved to other half {:?} -> {:?}", + 7, + shuffle(1_u128 << 58) + ); + assert!( + shuffle(1_u128 << 58) < (1_u128 << 112), + "High bits must not remain high {:?} -> {:?}", + 7, + shuffle(1_u128 << 58) + ); + assert!( + shuffle(1_u128 << 64) < (1_u128 << 64), + "Low bits must be moved to other half {:?} -> {:?}", + 8, + shuffle(1_u128 << 64) + ); + assert!( + shuffle(1_u128 << 64) >= (1_u128 << 16), + "Low bits must not remain low {:?} -> {:?}", + 8, + shuffle(1_u128 << 64) + ); + + assert!( + shuffle(1_u128 << 120) < (1_u128 << 50), + "High bits must be moved to low half {:?} -> {:?}", + 15, + shuffle(1_u128 << 120) + ); + } + + #[cfg(all( + any(target_arch = "x86", target_arch = "x86_64"), + target_feature = "ssse3", + not(miri) + ))] + #[test] + fn test_shuffle_does_not_loop() { + let numbered = 0x00112233_44556677_8899AABB_CCDDEEFF; + let mut shuffled = shuffle(numbered); + for count in 0..100 { + // println!("{:>16x}", shuffled); + assert_ne!(numbered, shuffled, "Equal after {} vs {:x}", count, shuffled); + shuffled = shuffle(shuffled); + } + } +} diff --git a/third_party/rust/ahash/src/random_state.rs b/third_party/rust/ahash/src/random_state.rs new file mode 100644 index 0000000000..0936556c38 --- /dev/null +++ b/third_party/rust/ahash/src/random_state.rs @@ -0,0 +1,153 @@ +use crate::convert::Convert; +use crate::AHasher; +use core::fmt; +use core::hash::BuildHasher; +use core::sync::atomic::AtomicUsize; +use core::sync::atomic::Ordering; + +use crate::operations::folded_multiply; +#[cfg(all(feature = "compile-time-rng", not(test)))] +use const_random::const_random; + +///This constant come from Kunth's prng +pub(crate) const MULTIPLE: u64 = 6364136223846793005; +pub(crate) const INCREMENT: u64 = 1442695040888963407; + +// Const random provides randomized starting key with no runtime cost. +#[cfg(all(feature = "compile-time-rng", not(test)))] +pub(crate) const INIT_SEED: [u64; 2] = [const_random!(u64), const_random!(u64)]; + +#[cfg(any(not(feature = "compile-time-rng"), test))] +pub(crate) const INIT_SEED: [u64; 2] = [0x2360_ED05_1FC6_5DA4, 0x4385_DF64_9FCC_F645]; //From PCG-64 + +#[cfg(all(feature = "compile-time-rng", not(test)))] +static SEED: AtomicUsize = AtomicUsize::new(const_random!(u64) as usize); + +#[cfg(any(not(feature = "compile-time-rng"), test))] +static SEED: AtomicUsize = AtomicUsize::new(INCREMENT as usize); + +/// Provides a [Hasher] factory. This is typically used (e.g. by [HashMap]) to create +/// [AHasher]s in order to hash the keys of the map. See `build_hasher` below. +/// +/// [build_hasher]: ahash:: +/// [Hasher]: std::hash::Hasher +/// [BuildHasher]: std::hash::BuildHasher +/// [HashMap]: std::collections::HashMap +#[derive(Clone)] +pub struct RandomState { + pub(crate) k0: u64, + pub(crate) k1: u64, + pub(crate) k2: u64, + pub(crate) k3: u64, +} + +impl fmt::Debug for RandomState { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.pad("RandomState { .. }") + } +} + +impl RandomState { + #[inline] + pub fn new() -> RandomState { + //Using a self pointer. When running with ASLR this is a random value. + let previous = SEED.load(Ordering::Relaxed) as u64; + let stack_mem_loc = &previous as *const _ as u64; + //This is similar to the update function in the fallback. + //only one multiply is needed because memory locations are not under an attackers control. + let current_seed = previous + .wrapping_add(stack_mem_loc) + .wrapping_mul(MULTIPLE) + .rotate_right(31); + SEED.store(current_seed as usize, Ordering::Relaxed); + let (k0, k1, k2, k3) = scramble_keys(&SEED as *const _ as u64, current_seed); + RandomState { k0, k1, k2, k3 } + } + + /// Allows for explicitly setting the seeds to used. + pub const fn with_seeds(k0: u64, k1: u64) -> RandomState { + let (k0, k1, k2, k3) = scramble_keys(k0, k1); + RandomState { k0, k1, k2, k3 } + } +} + +/// This is based on the fallback hasher +#[inline] +pub(crate) const fn scramble_keys(a: u64, b: u64) -> (u64, u64, u64, u64) { + let k1 = folded_multiply(INIT_SEED[0] ^ a, MULTIPLE).wrapping_add(b); + let k2 = folded_multiply(INIT_SEED[0] ^ b, MULTIPLE).wrapping_add(a); + let k3 = folded_multiply(INIT_SEED[1] ^ a, MULTIPLE).wrapping_add(b); + let k4 = folded_multiply(INIT_SEED[1] ^ b, MULTIPLE).wrapping_add(a); + let combined = folded_multiply(a ^ b, MULTIPLE).wrapping_add(INCREMENT); + let rot1 = (combined & 63) as u32; + let rot2 = ((combined >> 16) & 63) as u32; + let rot3 = ((combined >> 32) & 63) as u32; + let rot4 = ((combined >> 48) & 63) as u32; + ( + k1.rotate_left(rot1), + k2.rotate_left(rot2), + k3.rotate_left(rot3), + k4.rotate_left(rot4), + ) +} + +impl Default for RandomState { + #[inline] + fn default() -> Self { + Self::new() + } +} + +impl BuildHasher for RandomState { + type Hasher = AHasher; + + /// Constructs a new [AHasher] with keys based on compile time generated constants** and the location + /// this object was constructed at in memory. This means that two different [BuildHasher]s will will generate + /// [AHasher]s that will return different hashcodes, but [Hasher]s created from the same [BuildHasher] + /// will generate the same hashes for the same input data. + /// + /// ** - only if the `compile-time-rng` feature is enabled. + /// + /// # Examples + /// + /// ``` + /// use ahash::{AHasher, RandomState}; + /// use std::hash::{Hasher, BuildHasher}; + /// + /// let build_hasher = RandomState::new(); + /// let mut hasher_1 = build_hasher.build_hasher(); + /// let mut hasher_2 = build_hasher.build_hasher(); + /// + /// hasher_1.write_u32(1234); + /// hasher_2.write_u32(1234); + /// + /// assert_eq!(hasher_1.finish(), hasher_2.finish()); + /// + /// let other_build_hasher = RandomState::new(); + /// let mut different_hasher = other_build_hasher.build_hasher(); + /// different_hasher.write_u32(1234); + /// assert_ne!(different_hasher.finish(), hasher_1.finish()); + /// ``` + /// [Hasher]: std::hash::Hasher + /// [BuildHasher]: std::hash::BuildHasher + /// [HashMap]: std::collections::HashMap + #[inline] + fn build_hasher(&self) -> AHasher { + AHasher::new_with_keys([self.k0, self.k1].convert(), [self.k2, self.k3].convert()) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_const_rand_disabled() { + assert_eq!(INIT_SEED, [0x2360_ED05_1FC6_5DA4, 0x4385_DF64_9FCC_F645]); + } + + #[test] + fn test_with_seeds_const() { + const _CONST_RANDOM_STATE: RandomState = RandomState::with_seeds(17, 19); + } +} diff --git a/third_party/rust/ahash/src/specialize.rs b/third_party/rust/ahash/src/specialize.rs new file mode 100644 index 0000000000..2c0bc2d8af --- /dev/null +++ b/third_party/rust/ahash/src/specialize.rs @@ -0,0 +1,162 @@ +#[cfg(feature = "specialize")] +use crate::HasherExt; +use core::hash::Hash; +use core::hash::Hasher; + +/// Provides a way to get an optimized hasher for a given data type. +/// Rather than using a Hasher generically which can hash any value, this provides a way to get a specialized hash +/// for a specific type. So this may be faster for primitive types. It does however consume the hasher in the process. +/// #Example +/// ``` +/// use std::hash::BuildHasher; +/// use ahash::RandomState; +/// use ahash::CallHasher; +/// +/// let hash_builder = RandomState::new(); +/// //... +/// let value = 17; +/// let hash = value.get_hash(hash_builder.build_hasher()); +/// ``` +pub trait CallHasher: Hash { + fn get_hash<H: Hasher>(&self, hasher: H) -> u64; +} + +#[cfg(not(feature = "specialize"))] +impl<T> CallHasher for T +where + T: Hash, +{ + #[inline] + fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 { + self.hash(&mut hasher); + hasher.finish() + } +} + +#[cfg(feature = "specialize")] +impl<T> CallHasher for T +where + T: Hash, +{ + #[inline] + default fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 { + self.hash(&mut hasher); + hasher.finish() + } +} + +macro_rules! call_hasher_impl { + ($typ:ty) => { + #[cfg(feature = "specialize")] + impl CallHasher for $typ { + #[inline] + fn get_hash<H: Hasher>(&self, hasher: H) -> u64 { + hasher.hash_u64(*self as u64) + } + } + }; +} +call_hasher_impl!(u8); +call_hasher_impl!(u16); +call_hasher_impl!(u32); +call_hasher_impl!(u64); +call_hasher_impl!(i8); +call_hasher_impl!(i16); +call_hasher_impl!(i32); +call_hasher_impl!(i64); + +#[cfg(feature = "specialize")] +impl CallHasher for u128 { + #[inline] + fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 { + hasher.write_u128(*self); + hasher.short_finish() + } +} + +#[cfg(feature = "specialize")] +impl CallHasher for i128 { + #[inline] + fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 { + hasher.write_u128(*self as u128); + hasher.short_finish() + } +} + +#[cfg(feature = "specialize")] +impl CallHasher for [u8] { + #[inline] + fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 { + hasher.write(self); + hasher.finish() + } +} + +#[cfg(all(feature = "specialize", feature = "std"))] +impl CallHasher for Vec<u8> { + #[inline] + fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 { + hasher.write(self); + hasher.finish() + } +} + +#[cfg(feature = "specialize")] +impl CallHasher for str { + #[inline] + fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 { + hasher.write(self.as_bytes()); + hasher.finish() + } +} + +#[cfg(all(feature = "specialize", feature = "std"))] +impl CallHasher for String { + #[inline] + fn get_hash<H: Hasher>(&self, mut hasher: H) -> u64 { + hasher.write(self.as_bytes()); + hasher.finish() + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::*; + + #[test] + #[cfg(feature = "specialize")] + pub fn test_specialized_invoked() { + let shortened = 0_u64.get_hash(AHasher::new_with_keys(1, 2)); + let mut hasher = AHasher::new_with_keys(1, 2); + 0_u64.hash(&mut hasher); + assert_ne!(hasher.finish(), shortened); + } + + /// Tests that some non-trivial transformation takes place. + #[test] + pub fn test_input_processed() { + let hasher = || AHasher::new_with_keys(3, 2); + assert_ne!(0, 0_u64.get_hash(hasher())); + assert_ne!(1, 0_u64.get_hash(hasher())); + assert_ne!(2, 0_u64.get_hash(hasher())); + assert_ne!(3, 0_u64.get_hash(hasher())); + assert_ne!(4, 0_u64.get_hash(hasher())); + assert_ne!(5, 0_u64.get_hash(hasher())); + + assert_ne!(0, 1_u64.get_hash(hasher())); + assert_ne!(1, 1_u64.get_hash(hasher())); + assert_ne!(2, 1_u64.get_hash(hasher())); + assert_ne!(3, 1_u64.get_hash(hasher())); + assert_ne!(4, 1_u64.get_hash(hasher())); + assert_ne!(5, 1_u64.get_hash(hasher())); + + let xored = 0_u64.get_hash(hasher()) ^ 1_u64.get_hash(hasher()); + assert_ne!(0, xored); + assert_ne!(1, xored); + assert_ne!(2, xored); + assert_ne!(3, xored); + assert_ne!(4, xored); + assert_ne!(5, xored); + } +} diff --git a/third_party/rust/ahash/tests/bench.rs b/third_party/rust/ahash/tests/bench.rs new file mode 100644 index 0000000000..c03a0f56ee --- /dev/null +++ b/third_party/rust/ahash/tests/bench.rs @@ -0,0 +1,224 @@ +use ahash::{AHasher, CallHasher}; +use criterion::*; +use fxhash::FxHasher; +use std::collections::hash_map::DefaultHasher; +use std::hash::{Hash, Hasher}; + +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))] +fn aeshash<H: Hash>(b: &H) -> u64 { + let hasher = AHasher::default(); + b.get_hash(hasher) +} +#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))] +fn aeshash<H: Hash>(_b: &H) -> u64 { + panic!("aes must be enabled") +} + +#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))] +fn fallbackhash<H: Hash>(b: &H) -> u64 { + let hasher = AHasher::default(); + b.get_hash(hasher) +} +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))] +fn fallbackhash<H: Hash>(_b: &H) -> u64 { + panic!("aes must be disabled") +} + +fn fnvhash<H: Hash>(b: &H) -> u64 { + let mut hasher = fnv::FnvHasher::default(); + b.hash(&mut hasher); + hasher.finish() +} + +fn siphash<H: Hash>(b: &H) -> u64 { + let mut hasher = DefaultHasher::default(); + b.hash(&mut hasher); + hasher.finish() +} + +fn fxhash<H: Hash>(b: &H) -> u64 { + let mut hasher = FxHasher::default(); + b.hash(&mut hasher); + hasher.finish() +} + +fn seahash<H: Hash>(b: &H) -> u64 { + let mut hasher = seahash::SeaHasher::default(); + b.hash(&mut hasher); + hasher.finish() +} + +const STRING_LENGTHS: [u32; 12] = [1, 3, 4, 7, 8, 15, 16, 24, 33, 68, 132, 1024]; + +fn gen_strings() -> Vec<String> { + STRING_LENGTHS + .iter() + .map(|len| { + let mut string = String::default(); + for pos in 1..=*len { + let c = (48 + (pos % 10) as u8) as char; + string.push(c); + } + string + }) + .collect() +} + +const U8_VALUES: [u8; 1] = [123]; +const U16_VALUES: [u16; 1] = [1234]; +const U32_VALUES: [u32; 1] = [12345678]; +const U64_VALUES: [u64; 1] = [1234567890123456]; +const U128_VALUES: [u128; 1] = [12345678901234567890123456789012]; + +fn bench_ahash(c: &mut Criterion) { + c.bench( + "aeshash", + ParameterizedBenchmark::new("u8", |b, &s| b.iter(|| black_box(aeshash(s))), &U8_VALUES), + ); + c.bench( + "aeshash", + ParameterizedBenchmark::new("u16", |b, &s| b.iter(|| black_box(aeshash(s))), &U16_VALUES), + ); + c.bench( + "aeshash", + ParameterizedBenchmark::new("u32", |b, &s| b.iter(|| black_box(aeshash(s))), &U32_VALUES), + ); + c.bench( + "aeshash", + ParameterizedBenchmark::new("u64", |b, &s| b.iter(|| black_box(aeshash(s))), &U64_VALUES), + ); + c.bench( + "aeshash", + ParameterizedBenchmark::new("u128", |b, &s| b.iter(|| black_box(aeshash(s))), &U128_VALUES), + ); + c.bench( + "aeshash", + ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(aeshash(s))), gen_strings()), + ); +} + +fn bench_fallback(c: &mut Criterion) { + c.bench( + "fallback", + ParameterizedBenchmark::new("u8", |b, &s| b.iter(|| black_box(fallbackhash(s))), &U8_VALUES), + ); + c.bench( + "fallback", + ParameterizedBenchmark::new("u16", |b, &s| b.iter(|| black_box(fallbackhash(s))), &U16_VALUES), + ); + c.bench( + "fallback", + ParameterizedBenchmark::new("u32", |b, &s| b.iter(|| black_box(fallbackhash(s))), &U32_VALUES), + ); + c.bench( + "fallback", + ParameterizedBenchmark::new("u64", |b, &s| b.iter(|| black_box(fallbackhash(s))), &U64_VALUES), + ); + c.bench( + "fallback", + ParameterizedBenchmark::new("u128", |b, &s| b.iter(|| black_box(fallbackhash(s))), &U128_VALUES), + ); + c.bench( + "fallback", + ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fallbackhash(s))), gen_strings()), + ); +} + +fn bench_fx(c: &mut Criterion) { + c.bench( + "fx", + ParameterizedBenchmark::new("u8", |b, &s| b.iter(|| black_box(fxhash(s))), &U8_VALUES), + ); + c.bench( + "fx", + ParameterizedBenchmark::new("u16", |b, &s| b.iter(|| black_box(fxhash(s))), &U16_VALUES), + ); + c.bench( + "fx", + ParameterizedBenchmark::new("u32", |b, &s| b.iter(|| black_box(fxhash(s))), &U32_VALUES), + ); + c.bench( + "fx", + ParameterizedBenchmark::new("u64", |b, &s| b.iter(|| black_box(fxhash(s))), &U64_VALUES), + ); + c.bench( + "fx", + ParameterizedBenchmark::new("u128", |b, &s| b.iter(|| black_box(fxhash(s))), &U128_VALUES), + ); + c.bench( + "fx", + ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fxhash(s))), gen_strings()), + ); +} + +fn bench_fnv(c: &mut Criterion) { + c.bench( + "fnv", + ParameterizedBenchmark::new("u8", |b, &s| b.iter(|| black_box(fnvhash(s))), &U8_VALUES), + ); + c.bench( + "fnv", + ParameterizedBenchmark::new("u16", |b, &s| b.iter(|| black_box(fnvhash(s))), &U16_VALUES), + ); + c.bench( + "fnv", + ParameterizedBenchmark::new("u32", |b, &s| b.iter(|| black_box(fnvhash(s))), &U32_VALUES), + ); + c.bench( + "fnv", + ParameterizedBenchmark::new("u64", |b, &s| b.iter(|| black_box(fnvhash(s))), &U64_VALUES), + ); + c.bench( + "fnv", + ParameterizedBenchmark::new("u128", |b, &s| b.iter(|| black_box(fnvhash(s))), &U128_VALUES), + ); + c.bench( + "fnv", + ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fnvhash(s))), gen_strings()), + ); +} + +fn bench_sea(c: &mut Criterion) { + c.bench( + "sea", + ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(seahash(s))), gen_strings()), + ); +} + +fn bench_sip(c: &mut Criterion) { + c.bench( + "sip", + ParameterizedBenchmark::new("u8", |b, &s| b.iter(|| black_box(siphash(s))), &U8_VALUES), + ); + c.bench( + "sip", + ParameterizedBenchmark::new("u16", |b, &s| b.iter(|| black_box(siphash(s))), &U16_VALUES), + ); + c.bench( + "sip", + ParameterizedBenchmark::new("u32", |b, &s| b.iter(|| black_box(siphash(s))), &U32_VALUES), + ); + c.bench( + "sip", + ParameterizedBenchmark::new("u64", |b, &s| b.iter(|| black_box(siphash(s))), &U64_VALUES), + ); + c.bench( + "sip", + ParameterizedBenchmark::new("u128", |b, &s| b.iter(|| black_box(siphash(s))), &U128_VALUES), + ); + c.bench( + "sip", + ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(siphash(s))), gen_strings()), + ); +} + +criterion_main!(benches); +criterion_group!( + benches, + bench_ahash, + bench_fallback, + bench_fx, + bench_fnv, + bench_sea, + bench_sip +); diff --git a/third_party/rust/ahash/tests/map_tests.rs b/third_party/rust/ahash/tests/map_tests.rs new file mode 100644 index 0000000000..70e4a86cfd --- /dev/null +++ b/third_party/rust/ahash/tests/map_tests.rs @@ -0,0 +1,204 @@ +use std::hash::{Hash, Hasher}; + +use criterion::*; +use fxhash::FxHasher; + +use ahash::{AHasher, CallHasher}; + +fn gen_word_pairs() -> Vec<String> { + let words: Vec<_> = r#" +a, ability, able, about, above, accept, according, account, across, act, action, +activity, actually, add, address, administration, admit, adult, affect, after, +again, against, age, agency, agent, ago, agree, agreement, ahead, air, all, +allow, almost, alone, along, already, also, although, always, American, among, +amount, analysis, and, animal, another, answer, any, anyone, anything, appear, +apply, approach, area, argue, arm, around, arrive, art, article, artist, as, +ask, assume, at, attack, attention, attorney, audience, author, authority, +available, avoid, away, baby, back, bad, bag, ball, bank, bar, base, be, beat, +beautiful, because, become, bed, before, begin, behavior, behind, believe, +benefit, best, better, between, beyond, big, bill, billion, bit, black, blood, +blue, board, body, book, born, both, box, boy, break, bring, brother, budget, +build, building, business, but, buy, by, call, camera, campaign, can, cancer, +candidate, capital, car, card, care, career, carry, case, catch, cause, cell, +center, central, century, certain, certainly, chair, challenge, chance, change, +character, charge, check, child, choice, choose, church, citizen, city, civil, +claim, class, clear, clearly, close, coach, cold, collection, college, color, +come, commercial, common, community, company, compare, computer, concern, +condition, conference, Congress, consider, consumer, contain, continue, control, +cost, could, country, couple, course, court, cover, create, crime, cultural, +culture, cup, current, customer, cut, dark, data, daughter, day, dead, deal, +death, debate, decade, decide, decision, deep, defense, degree, Democrat, +democratic, describe, design, despite, detail, determine, develop, development, +die, difference, different, difficult, dinner, direction, director, discover, +discuss, discussion, disease, do, doctor, dog, door, down, draw, dream, drive, +drop, drug, during, each, early, east, easy, eat, economic, economy, edge, +education, effect, effort, eight, either, election, else, employee, end, energy, +enjoy, enough, enter, entire, environment, environmental, especially, establish, +even, evening, event, ever, every, everybody, everyone, everything, evidence, +exactly, example, executive, exist, expect, experience, expert, explain, eye, +face, fact, factor, fail, fall, family, far, fast, father, fear, federal, feel, +feeling, few, field, fight, figure, fill, film, final, finally, financial, find, +fine, finger, finish, fire, firm, first, fish, five, floor, fly, focus, follow, +food, foot, for, force, foreign, forget, form, former, forward, four, free, +friend, from, front, full, fund, future, game, garden, gas, general, generation, +get, girl, give, glass, go, goal, good, government, great, green, ground, group, +grow, growth, guess, gun, guy, hair, half, hand, hang, happen, happy, hard, +have, he, head, health, hear, heart, heat, heavy, help, her, here, herself, +high, him, himself, his, history, hit, hold, home, hope, hospital, hot, hotel, +hour, house, how, however, huge, human, hundred, husband, I, idea, identify, if, +image, imagine, impact, important, improve, in, include, including, increase, +indeed, indicate, individual, industry, information, inside, instead, +institution, interest, interesting, international, interview, into, investment, +involve, issue, it, item, its, itself, job, join, just, keep, key, kid, kill, +kind, kitchen, know, knowledge, land, language, large, last, late, later, laugh, +law, lawyer, lay, lead, leader, learn, least, leave, left, leg, legal, less, +let, letter, level, lie, life, light, like, likely, line, list, listen, little, +live, local, long, look, lose, loss, lot, love, low, machine, magazine, main, +maintain, major, majority, make, man, manage, management, manager, many, market, +marriage, material, matter, may, maybe, me, mean, measure, media, medical, meet, +meeting, member, memory, mention, message, method, middle, might, military, +million, mind, minute, miss, mission, model, modern, moment, money, month, more, +morning, most, mother, mouth, move, movement, movie, Mr, Mrs, much, music, must, +my, myself, name, nation, national, natural, nature, near, nearly, necessary, +need, network, never, new, news, newspaper, next, nice, night, no, none, nor, +north, not, note, nothing, notice, now, n't, number, occur, of, off, offer, +office, officer, official, often, oh, oil, ok, old, on, once, one, only, onto, +open, operation, opportunity, option, or, order, organization, other, others, +our, out, outside, over, own, owner, page, pain, painting, paper, parent, part, +participant, particular, particularly, partner, party, pass, past, patient, +pattern, pay, peace, people, per, perform, performance, perhaps, period, person, +personal, phone, physical, pick, picture, piece, place, plan, plant, play, +player, PM, point, police, policy, political, politics, poor, popular, +population, position, positive, possible, power, practice, prepare, present, +president, pressure, pretty, prevent, price, private, probably, problem, +process, produce, product, production, professional, professor, program, +project, property, protect, prove, provide, public, pull, purpose, push, put, +quality, question, quickly, quite, race, radio, raise, range, rate, rather, +reach, read, ready, real, reality, realize, really, reason, receive, recent, +recently, recognize, record, red, reduce, reflect, region, relate, relationship, +religious, remain, remember, remove, report, represent, Republican, require, +research, resource, respond, response, responsibility, rest, result, return, +reveal, rich, right, rise, risk, road, rock, role, room, rule, run, safe, same, +save, say, scene, school, science, scientist, score, sea, season, seat, second, +section, security, see, seek, seem, sell, send, senior, sense, series, serious, +serve, service, set, seven, several, sex, sexual, shake, share, she, shoot, +short, shot, should, shoulder, show, side, sign, significant, similar, simple, +simply, since, sing, single, sister, sit, site, situation, six, size, skill, +skin, small, smile, so, social, society, soldier, some, somebody, someone, +something, sometimes, son, song, soon, sort, sound, source, south, southern, +space, speak, special, specific, speech, spend, sport, spring, staff, stage, +stand, standard, star, start, state, statement, station, stay, step, still, +stock, stop, store, story, strategy, street, strong, structure, student, study, +stuff, style, subject, success, successful, such, suddenly, suffer, suggest, +summer, support, sure, surface, system, table, take, talk, task, tax, teach, +teacher, team, technology, television, tell, ten, tend, term, test, than, thank, +that, the, their, them, themselves, then, theory, there, these, they, thing, +think, third, this, those, though, thought, thousand, threat, three, through, +throughout, throw, thus, time, to, today, together, tonight, too, top, total, +tough, toward, town, trade, traditional, training, travel, treat, treatment, +tree, trial, trip, trouble, true, truth, try, turn, TV, two, type, under, +understand, unit, until, up, upon, us, use, usually, value, various, very, +victim, view, violence, visit, voice, vote, wait, walk, wall, want, war, watch, +water, way, we, weapon, wear, week, weight, well, west, western, what, whatever, +when, where, whether, which, while, white, who, whole, whom, whose, why, wide, +wife, will, win, wind, window, wish, with, within, without, woman, wonder, word, +work, worker, world, worry, would, write, writer, wrong, yard, yeah, year, yes, +yet, you, young, your, yourself"# + .split(',') + .map(|word| word.trim()) + .collect(); + + let mut word_pairs: Vec<_> = Vec::new(); + for word in &words { + for other_word in &words { + word_pairs.push(word.to_string() + " " + other_word); + } + } + assert_eq!(1_000_000, word_pairs.len()); + word_pairs +} + +#[allow(unused)] // False positive +fn test_hash_common_words<T: Hasher>(hasher: impl Fn() -> T) { + let word_pairs: Vec<_> = gen_word_pairs(); + check_for_collisions(&hasher, &word_pairs, 32); +} + +#[allow(unused)] // False positive +fn check_for_collisions<T: Hasher, H: Hash>(hasher: &impl Fn() -> T, items: &[H], bucket_count: usize) { + let mut buckets = vec![0; bucket_count]; + for item in items { + let value = hash(item, &hasher) as usize; + buckets[value % bucket_count] += 1; + } + let mean = items.len() / bucket_count; + let max = *buckets.iter().max().unwrap(); + let min = *buckets.iter().min().unwrap(); + assert!( + (min as f64) > (mean as f64) * 0.95, + "min: {}, max:{}, {:?}", + min, + max, + buckets + ); + assert!( + (max as f64) < (mean as f64) * 1.05, + "min: {}, max:{}, {:?}", + min, + max, + buckets + ); +} + +#[allow(unused)] // False positive +fn hash<T: Hasher>(b: &impl Hash, hasher: &dyn Fn() -> T) -> u64 { + let hasher = hasher(); + b.get_hash(hasher) +} + +#[test] +fn test_bucket_distribution() { + let hasher = || AHasher::new_with_keys(123456789, 987654321); + test_hash_common_words(&hasher); + let sequence: Vec<_> = (0..320000).collect(); + check_for_collisions(&hasher, &sequence, 32); + let sequence: Vec<_> = (0..2560000).collect(); + check_for_collisions(&hasher, &sequence, 256); + let sequence: Vec<_> = (0..320000).map(|i| i * 1024).collect(); + check_for_collisions(&hasher, &sequence, 32); + let sequence: Vec<_> = (0..2560000_u64).map(|i| i * 1024).collect(); + check_for_collisions(&hasher, &sequence, 256); +} + +fn ahash_vec<H: Hash>(b: &Vec<H>) -> u64 { + let mut total: u64 = 0; + for item in b { + let mut hasher = AHasher::new_with_keys(1234, 5678); + item.hash(&mut hasher); + total = total.wrapping_add(hasher.finish()); + } + total +} + +fn fxhash_vec<H: Hash>(b: &Vec<H>) -> u64 { + let mut total: u64 = 0; + for item in b { + let mut hasher = FxHasher::default(); + item.hash(&mut hasher); + total = total.wrapping_add(hasher.finish()); + } + total +} + +fn bench_ahash_words(c: &mut Criterion) { + let words = gen_word_pairs(); + c.bench_function("aes_words", |b| b.iter(|| black_box(ahash_vec(&words)))); +} + +fn bench_fx_words(c: &mut Criterion) { + let words = gen_word_pairs(); + c.bench_function("fx_words", |b| b.iter(|| black_box(fxhash_vec(&words)))); +} + +criterion_main!(benches); +criterion_group!(benches, bench_ahash_words, bench_fx_words,); diff --git a/third_party/rust/ahash/tests/nopanic.rs b/third_party/rust/ahash/tests/nopanic.rs new file mode 100644 index 0000000000..f3d9361d20 --- /dev/null +++ b/third_party/rust/ahash/tests/nopanic.rs @@ -0,0 +1,54 @@ +use ahash::{AHasher, CallHasher, RandomState}; +use std::hash::BuildHasher; + +#[macro_use] +extern crate no_panic; + +#[inline(never)] +#[no_panic] +fn hash_test_final(num: i32, string: &str) -> (u64, u64) { + use core::hash::Hasher; + let mut hasher1 = AHasher::new_with_keys(1, 2); + let mut hasher2 = AHasher::new_with_keys(3, 4); + hasher1.write_i32(num); + hasher2.write(string.as_bytes()); + (hasher1.finish(), hasher2.finish()) +} + +#[inline(never)] +fn hash_test_final_wrapper(num: i32, string: &str) { + hash_test_final(num, string); +} + +#[inline(never)] +#[no_panic] +fn hash_test_specialize(num: i32, string: &str) -> (u64, u64) { + let hasher1 = AHasher::new_with_keys(1, 2); + let hasher2 = AHasher::new_with_keys(1, 2); + (num.get_hash(hasher1), string.as_bytes().get_hash(hasher2)) +} + +#[inline(never)] +fn hash_test_random_wrapper(num: i32, string: &str) { + hash_test_specialize(num, string); +} + +#[inline(never)] +#[no_panic] +fn hash_test_random(num: i32, string: &str) -> (u64, u64) { + let hasher1 = RandomState::with_seeds(1, 2).build_hasher(); + let hasher2 = RandomState::with_seeds(1, 2).build_hasher(); + (num.get_hash(hasher1), string.as_bytes().get_hash(hasher2)) +} + +#[inline(never)] +fn hash_test_specialize_wrapper(num: i32, string: &str) { + hash_test_specialize(num, string); +} + +#[test] +fn test_no_panic() { + hash_test_final_wrapper(2, "Foo"); + hash_test_specialize_wrapper(2, "Bar"); + hash_test_random_wrapper(2, "Baz"); +} |