summaryrefslogtreecommitdiffstats
path: root/third_party/rust/ahash
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/ahash')
-rw-r--r--third_party/rust/ahash/.cargo-checksum.json1
-rw-r--r--third_party/rust/ahash/Cargo.toml91
-rw-r--r--third_party/rust/ahash/LICENSE-APACHE201
-rw-r--r--third_party/rust/ahash/LICENSE-MIT25
-rw-r--r--third_party/rust/ahash/README.md245
-rw-r--r--third_party/rust/ahash/rustfmt.toml1
-rw-r--r--third_party/rust/ahash/smhasher/0001-Add-support-for-aHash.patch135
-rw-r--r--third_party/rust/ahash/smhasher/ahashOutput.txt1467
-rwxr-xr-xthird_party/rust/ahash/smhasher/clone_smhasher.sh1
-rw-r--r--third_party/rust/ahash/smhasher/fallbackOutput.txt1467
-rw-r--r--third_party/rust/ahash/src/aes_hash.rs293
-rw-r--r--third_party/rust/ahash/src/convert.rs172
-rw-r--r--third_party/rust/ahash/src/fallback_hash.rs223
-rw-r--r--third_party/rust/ahash/src/hash_map.rs177
-rw-r--r--third_party/rust/ahash/src/hash_quality_test.rs451
-rw-r--r--third_party/rust/ahash/src/hash_set.rs267
-rw-r--r--third_party/rust/ahash/src/lib.rs203
-rw-r--r--third_party/rust/ahash/src/operations.rs277
-rw-r--r--third_party/rust/ahash/src/random_state.rs153
-rw-r--r--third_party/rust/ahash/src/specialize.rs162
-rw-r--r--third_party/rust/ahash/tests/bench.rs224
-rw-r--r--third_party/rust/ahash/tests/map_tests.rs204
-rw-r--r--third_party/rust/ahash/tests/nopanic.rs54
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");
+}