stable_hash/fast/address.rs
1use crate::prelude::*;
2
3impl FieldAddress for u128 {
4 fn root() -> Self {
5 17
6 }
7 #[inline]
8 fn child(&self, number: u64) -> Self {
9 profile_method!(child);
10
11 self.wrapping_mul(486_187_739).wrapping_add(number as u128)
12 }
13 #[inline]
14 fn unordered(&self) -> (Self, Self) {
15 (Self::root(), *self)
16 }
17}
18
19#[cfg(test)]
20mod test {
21 use super::FieldAddress;
22
23 use std::collections::HashSet;
24
25 fn recurse(field_address: u128, depth: usize, length: usize, collector: &mut HashSet<u128>) {
26 // Struct/Recursion check
27 for i in 0..6 {
28 let child = field_address.child(i);
29 assert!(collector.insert(child));
30 if depth != 0 {
31 recurse(child, depth - 1, length, collector);
32 }
33 }
34 // Vec check (not recursive)
35 // Tests larger vecs closer to the root, where larger vecs are more likely
36 for i in 0..(length * depth * depth) {
37 let child = field_address.child((i as u64) + 6);
38 assert!(collector.insert(child));
39 }
40 }
41
42 /// This test demonstrates that our choice of primes and algorithm is a good
43 /// one for our use case of common structures to be digested by trying every
44 /// permutation of all structs several deep and long Vecs for children and
45 /// asserting 0 collisions on over 11 million common <u64>
46 /// paths. Just for kicks I ran it on over 1 billion paths before committing, but
47 /// this test did not complete in a reasonable enough amount of time to be committed.
48 ///
49 /// The actual number of struct and vec prototypes verified by this test is
50 /// astronomical, because any valid combinatorial sequence of paths made of
51 /// these unique values composes a unique stream.
52 #[test]
53 fn no_collisions_for_common_prototypes_64() {
54 let mut collector = HashSet::new();
55 let root = u128::root();
56 collector.insert(root);
57 recurse(root, 4, 50, &mut collector);
58 assert_eq!(30831, collector.len());
59 }
60}