blob: 890aeb01a694a21e800e8a23f325af4df998dd0d [file] [log] [blame]
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00001#include "Hashes.h"
2
3#include "Random.h"
4
tanjent@gmail.combabb5532011-02-28 06:03:12 +00005
6#include <stdlib.h>
7//#include <stdint.h>
8#include <assert.h>
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +00009//#include <emmintrin.h>
10//#include <xmmintrin.h>
tanjent@gmail.combabb5532011-02-28 06:03:12 +000011
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000012//----------------------------------------------------------------------------
13// fake / bad hashes
14
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000015void BadHash ( const void * key, int len, uint32_t seed, void * out )
16{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000017 uint32_t h = seed;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000018
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000019 const uint8_t * data = (const uint8_t*)key;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000020
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000021 for(int i = 0; i < len; i++)
22 {
23 h ^= h >> 3;
24 h ^= h << 5;
25 h ^= data[i];
26 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000027
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000028 *(uint32_t*)out = h;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000029}
30
31void sumhash ( const void * key, int len, uint32_t seed, void * out )
32{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000033 uint32_t h = seed;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000034
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000035 const uint8_t * data = (const uint8_t*)key;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000036
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000037 for(int i = 0; i < len; i++)
38 {
39 h += data[i];
40 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000041
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000042 *(uint32_t*)out = h;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000043}
44
tanjent@gmail.combabb5532011-02-28 06:03:12 +000045void sumhash32 ( const void * key, int len, uint32_t seed, void * out )
46{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000047 uint32_t h = seed;
tanjent@gmail.combabb5532011-02-28 06:03:12 +000048
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000049 const uint32_t * data = (const uint32_t*)key;
tanjent@gmail.combabb5532011-02-28 06:03:12 +000050
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000051 for(int i = 0; i < len/4; i++)
52 {
53 h += data[i];
54 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +000055
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000056 *(uint32_t*)out = h;
tanjent@gmail.combabb5532011-02-28 06:03:12 +000057}
58
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000059void DoNothingHash ( const void *, int, uint32_t, void * )
60{
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000061}
62
63//-----------------------------------------------------------------------------
64// One-byte-at-a-time hash based on Murmur's mix
65
tanjent@gmail.combabb5532011-02-28 06:03:12 +000066void MurmurOAAT ( const void * key, int len, uint32_t seed, void * out )
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000067{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000068 const uint8_t * data = (const uint8_t*)key;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000069
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000070 uint32_t h = seed ^ len;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000071
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000072 for(int i = 0; i < len; i++)
73 {
74 h ^= data[i];
75 h *= 0x5bd1e995;
76 h ^= h >> 15;
77 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000078
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000079 h *= 0x5bd1e995;
80 h ^= h >> 15;
tanjent@gmail.combabb5532011-02-28 06:03:12 +000081
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000082 *(uint32_t*)out = h;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000083}
84
85//----------------------------------------------------------------------------
86
87void FNV ( const void * key, int len, uint32_t seed, void * out )
88{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000089 unsigned int h = seed;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000090
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000091 const uint8_t * data = (const uint8_t*)key;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000092
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000093 h ^= BIG_CONSTANT(2166136261);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000094
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000095 for(int i = 0; i < len; i++)
96 {
97 h ^= data[i];
98 h *= 16777619;
99 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000100
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000101 *(uint32_t*)out = h;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000102}
103
104//-----------------------------------------------------------------------------
105
106uint32_t x17 ( const void * key, int len, uint32_t h )
107{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000108 const uint8_t * data = (const uint8_t*)key;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000109
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000110 for(int i = 0; i < len; ++i)
111 {
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000112 h = 17 * h + (data[i] - ' ');
113 }
114
115 return h ^ (h >> 16);
116}
117
118//-----------------------------------------------------------------------------
119
120uint32_t Bernstein ( const void * key, int len, uint32_t h )
121{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000122 const uint8_t * data = (const uint8_t*)key;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000123
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000124 for(int i = 0; i < len; ++i)
125 {
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000126 h = 33 * h + data[i];
127 }
128
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000129 return h;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000130}
131
132//-----------------------------------------------------------------------------