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}