EFL 1.7 svn doobies
[profile/ivi/eina.git] / src / include / eina_inline_hash.x
1 /* EINA - EFL data type library
2  * Copyright (C) 2002-2008 Carsten Haitzler
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library;
16  * if not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #ifndef EINA_INLINE_HASH_X_
20 #define EINA_INLINE_HASH_X_
21
22 /*
23   djb2 hash algorithm was first reported by dan bernstein, and was the old
24   default hash function for evas.
25  */
26 static inline int
27 eina_hash_djb2(const char *key, int len)
28 {
29    unsigned int hash_num = 5381;
30    const unsigned char *ptr;
31
32    if (!key) return 0;
33    for (ptr = (unsigned char *)key; len; ptr++, len--)
34      hash_num = ((hash_num << 5) + hash_num) ^ *ptr; /* hash * 33 ^ c */
35
36    return (int)hash_num;
37 }
38
39 static inline int
40 eina_hash_djb2_len(const char *key, int *plen)
41 {
42    unsigned int hash_num = 5381;
43    int len = 0;
44    const unsigned char *ptr;
45
46    if (!key) return 0;
47
48    for (ptr = (unsigned char *)key; *ptr; ptr++, len++)
49      hash_num = ((hash_num << 5) + hash_num) ^ *ptr; /* hash * 33 ^ c */
50
51    *plen = len + 1;
52
53    return (int)hash_num;
54 }
55
56 static inline int
57 eina_hash_int32(const unsigned int *pkey, int len)
58 {
59    unsigned int key = *pkey;
60
61    (void) len;
62
63    key  = ~key + (key << 15);
64    key ^= key >> 12;
65    key += key << 2;
66    key ^= key >> 4;
67    key *= 2057;
68    key ^= key >> 16;
69    return key;
70 }
71
72 static inline int
73 eina_hash_int64(const unsigned long int *pkey, int len)
74 {
75    unsigned long int key = *pkey;
76
77    (void) len;
78
79    key  = ~key + (key << 18);
80    key ^= key >> 31;
81    key *= 21;
82    key ^= key >> 11;
83    key += key << 6;
84    key ^= key >> 22;
85    return (int) key;
86 }
87
88 static inline unsigned int _rotl32(unsigned int x, char r)
89 {
90    return (x << r) | (x >> (32 - r));
91 }
92
93 static inline unsigned int _fmix32(unsigned int h)
94 {
95    h ^= h >> 16;
96    h *= 0x85ebca6b;
97    h ^= h >> 13;
98    h *= 0xc2b2ae35;
99    h ^= h >> 16;
100
101    return h;
102 }
103
104 static inline int
105 eina_hash_murmur3(const char *key, int len)
106 {
107    const unsigned char * data = (const unsigned char*)key;
108    const int nblocks = len / 4;
109    unsigned int h1 = 0, k1;
110    unsigned int c1 = 0xcc9e2d51;
111    unsigned int c2 = 0x1b873593;
112    const unsigned int * blocks = (const unsigned int *)(data + nblocks*4);
113    int i;
114    const unsigned char *tail;
115
116    for(i = -nblocks; i; i++)
117      {
118         k1 = blocks[i];
119
120         k1 *= c1;
121         k1 = _rotl32(k1, 15);
122         k1 *= c2;
123
124         h1 ^= k1;
125         h1 = _rotl32(h1, 13);
126         h1 = h1*5+0xe6546b64;
127      }
128
129    tail = (const unsigned char*)(data + nblocks*4);
130
131    k1 = 0;
132
133    switch(len & 3)
134      {
135       case 3:
136          k1 ^= tail[2] << 16;
137       case 2:
138          k1 ^= tail[1] << 8;
139       case 1:
140          k1 ^= tail[0];
141          k1 *= c1;
142          k1 = _rotl32(k1, 16);
143          k1 *= c2;
144          h1 ^= k1;
145      }
146
147    h1 ^= len;
148
149    return _fmix32(h1);
150 }
151 #endif