1 ! Copyright (C) 2018 John Benediktsson.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien.c-types alien.data byte-arrays checksums
4 combinators endian grouping kernel locals math math.bitwise
5 sequences specialized-arrays ;
6 SPECIALIZED-ARRAY: uint64_t
7 SPECIALIZED-ARRAY: uint32_t
8 SPECIALIZED-ARRAY: uint16_t
10 IN: checksums.metrohash
12 TUPLE: metrohash-64 seed ;
14 C: <metrohash-64> metrohash-64
18 :: native-mapper ( from to bytes c-type -- seq )
20 bytes byte-array? alien.data:little-endian? and
22 [ c-type heap-size <groups> [ le> ] map ] if ; inline
26 M:: metrohash-64 checksum-bytes ( bytes checksum -- value )
32 checksum seed>> :> seed
35 len dup 32 mod - :> len/32
36 len dup 16 mod - :> len/16
37 len dup 8 mod - :> len/8
38 len dup 4 mod - :> len/4
39 len dup 2 mod - :> len/2
43 h h h h :> ( v0! v1! v2! v3! )
46 0 len/32 bytes uint64_t native-mapper 4 <groups> [
48 [ k0 W* v0 W+ -29 bitroll-64 v2 W+ v0! ]
49 [ k1 W* v1 W+ -29 bitroll-64 v3 W+ v1! ]
50 [ k2 W* v2 W+ -29 bitroll-64 v0 W+ v2! ]
51 [ k3 W* v3 W+ -29 bitroll-64 v1 W+ v3! ]
55 v0 v3 W+ k0 W* v1 W+ -37 bitroll-64 k1 W* v2 bitxor v2!
56 v1 v2 W+ k1 W* v0 W+ -37 bitroll-64 k0 W* v3 bitxor v3!
57 v0 v2 W+ k0 W* v3 W+ -37 bitroll-64 k1 W* v0 bitxor v0!
58 v1 v3 W+ k1 W* v2 W+ -37 bitroll-64 k0 W* v1 bitxor v1!
63 len/32 len/16 bytes uint64_t native-mapper [
65 [ k2 W* v0 W+ -29 bitroll-64 k3 W* v1! ]
66 [ k2 W* v0 W+ -29 bitroll-64 k3 W* v2! ] bi*
67 v1 k0 W* -21 bitroll-64 v2 W+ v1 bitxor v1!
68 v2 k3 W* -21 bitroll-64 v1 W+ v2 bitxor v2!
72 len/16 len/8 bytes uint64_t native-mapper [
74 v0 -55 bitroll-64 k1 W* v0 bitxor v0!
77 len/8 len/4 bytes uint32_t native-mapper [
79 v0 -26 bitroll-64 k1 W* v0 bitxor v0!
82 len/4 len/2 bytes uint16_t native-mapper [
84 v0 -48 bitroll-64 k1 W* v0 bitxor v0!
87 bytes len/2 tail-slice [
89 v0 -37 bitroll-64 k1 W* v0 bitxor v0!
92 v0 -28 bitroll-64 v0 bitxor v0!
94 v0 -29 bitroll-64 v0 bitxor v0!
97 INSTANCE: metrohash-64 checksum
99 TUPLE: metrohash-128 seed ;
101 C: <metrohash-128> metrohash-128
103 M:: metrohash-128 checksum-bytes ( bytes checksum -- value )
109 checksum seed>> :> seed
112 len dup 32 mod - :> len/32
113 len dup 16 mod - :> len/16
114 len dup 8 mod - :> len/8
115 len dup 4 mod - :> len/4
116 len dup 2 mod - :> len/2
118 seed k0 W- k3 W* :> v0!
119 seed k1 W+ k2 W* :> v1!
120 seed k0 W+ k2 W* :> v2!
121 seed k1 W- k3 W* :> v3!
124 0 len/32 bytes uint64_t native-mapper 4 <groups> [
126 [ k0 W* v0 W+ -29 bitroll-64 v2 W+ v0! ]
127 [ k1 W* v1 W+ -29 bitroll-64 v3 W+ v1! ]
128 [ k2 W* v2 W+ -29 bitroll-64 v0 W+ v2! ]
129 [ k3 W* v3 W+ -29 bitroll-64 v1 W+ v3! ]
133 v0 v3 W+ k0 W* v1 W+ -21 bitroll-64 k1 W* v2 bitxor v2!
134 v1 v2 W+ k1 W* v0 W+ -21 bitroll-64 k0 W* v3 bitxor v3!
135 v0 v2 W+ k0 W* v3 W+ -21 bitroll-64 k1 W* v0 bitxor v0!
136 v1 v3 W+ k1 W* v2 W+ -21 bitroll-64 k0 W* v1 bitxor v1!
139 len/32 len/16 bytes uint64_t native-mapper [
141 [ k2 W* v0 W+ -33 bitroll-64 k3 W* v0! ]
142 [ k2 W* v1 W+ -33 bitroll-64 k3 W* v1! ] bi*
143 v0 k2 W* v1 W+ -45 bitroll-64 k1 W* v0 bitxor v0!
144 v1 k3 W* v0 W+ -45 bitroll-64 k0 W* v1 bitxor v1!
147 len/16 len/8 bytes uint64_t native-mapper [
148 first k2 W* v0 W+ -33 bitroll-64 k3 W* v0!
149 v0 k2 W* v1 W+ -27 bitroll-64 k1 W* v0 bitxor v0!
152 len/8 len/4 bytes uint32_t native-mapper [
153 first k2 W* v1 W+ -33 bitroll-64 k3 W* v1!
154 v1 k3 W* v0 W+ -46 bitroll-64 k0 W* v1 bitxor v1!
157 len/4 len/2 bytes uint16_t native-mapper [
158 first k2 W* v0 W+ -33 bitroll-64 k3 W* v0!
159 v0 k2 W* v1 W+ -22 bitroll-64 k1 W* v0 bitxor v0!
162 bytes len/2 tail-slice [
163 first k2 W* v1 W+ -33 bitroll-64 k3 W* v1!
164 v1 k3 W* v0 W+ -58 bitroll-64 k0 W* v1 bitxor v1!
167 v0 k0 W* v1 W+ -13 bitroll-64 v0 W+ v0!
168 v1 k1 W* v0 W+ -37 bitroll-64 v1 W+ v1!
169 v0 k2 W* v1 W+ -13 bitroll-64 v0 W+ v0!
170 v1 k3 W* v0 W+ -37 bitroll-64 v1 W+ v1!
174 INSTANCE: metrohash-128 checksum