3 * https://sites.google.com/site/murmurhash/
5 * Public Domain hash functions by Austin Appleby.
7 * Trivially adapted for use with Ruby TDB by Eric Wong.
11 * 'm' and 'r' are mixing constants generated offline.
12 * They're not really 'magic', they just happen to work well.
15 static const unsigned int m
= 0x5bd1e995;
16 static const int r
= 24;
17 static const unsigned int seed
;
19 unsigned int rbtdb_murmur2(TDB_DATA
* key
)
21 const unsigned char *data
= key
->dptr
;
22 int len
= (int)key
->dsize
;
23 /* Initialize the hash to a 'random' value */
24 unsigned int h
= seed
^ len
;
27 unsigned int k
= *(const unsigned int *)data
;
40 /* Handle the last few bytes of the input array */
52 * Do a few final mixes of the hash to ensure the last few
53 * bytes are well-incorporated.
64 * This is a variant of MurmurHash2 modified to use the Merkle-Damgard
65 * construction. Bulk speed should be identical to Murmur2, small-key speed
66 * will be 10%-20% slower due to the added overhead at the end of the hash.
68 * This variant fixes a minor issue where null keys were more likely to
69 * collide with each other than expected, and also makes the algorithm
70 * more amenable to incremental implementations. All other caveats from
71 * MurmurHash2 still apply.
74 #define mmix(h,k) do { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; } while (0)
76 unsigned int rbtdb_murmur2a(TDB_DATA
* key
)
78 const unsigned char *data
= key
->dptr
;
79 int len
= (int)key
->dsize
;
80 unsigned int l
= (unsigned int)len
;
81 unsigned int h
= seed
;
85 unsigned int k
= *(const unsigned int *)data
;
113 * Same algorithm as MurmurHash2, but only does aligned reads - should be safer
114 * on certain platforms
116 * Performance will be lower than MurmurHash2
119 #define MIX(h,k,m) do { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; } while (0)
121 unsigned int rbtdb_murmur2_aligned(TDB_DATA
* key
)
123 const unsigned char *data
= key
->dptr
;
124 int len
= (int)key
->dsize
;
125 unsigned int h
= seed
^ len
;
126 union { const unsigned char *byte
; int integer
; } cast
= { data
};
127 int align
= cast
.integer
& 3;
129 if (align
&& (len
>= 4)) {
130 /* Pre-load the temp registers */
131 unsigned int t
= 0, d
= 0;
148 sl
= 8 * (4 - align
);
155 d
= *(const unsigned int *)data
;
156 t
= (t
>> sr
) | (d
<< sl
);
168 /* Handle leftover data in temp registers */
182 k
= (t
>> sr
) | (d
<< sl
);
188 /* Handle tail bytes */
207 h
^= (t
>> sr
) | (d
<< sl
);
219 unsigned int k
= *(const unsigned int *)data
;
227 /* Handle tail bytes */
247 * Same as MurmurHash2, but endian- and alignment-neutral.
248 * Half the speed though, alas.
250 unsigned int rbtdb_murmur2_neutral(TDB_DATA
* key
)
252 const unsigned char *data
= key
->dptr
;
253 int len
= (int)key
->dsize
;
254 unsigned int h
= seed
^ len
;