1 #include "hash_state.h"
2 #include <stdlib.h>
3 #include <assert.h>
4 #include <limits.h>
5 #include <string.h>
6
7 //#define DEBUG
8 #include "debug.h"
9
10 const char *cmph_hash_names[] = { "jenkins", NULL };
11
12 hash_state_t *hash_state_new(CMPH_HASH hashfunc, cmph_uint32 hashsize)
13 {
14 hash_state_t *state = NULL;
15 switch (hashfunc)
16 {
17 case CMPH_HASH_JENKINS:
18 DEBUGP("Jenkins function - %u\n", hashsize);
19 state = (hash_state_t *)jenkins_state_new(hashsize);
20 DEBUGP("Jenkins function created\n");
21 break;
22 default:
23 assert(0);
24 }
25 state->hashfunc = hashfunc;
26 return state;
27 }
28 cmph_uint32 hash(hash_state_t *state, const char *key, cmph_uint32 keylen)
29 {
30 switch (state->hashfunc)
31 {
32 case CMPH_HASH_JENKINS:
33 return jenkins_hash((jenkins_state_t *)state, key, keylen);
34 default:
35 assert(0);
36 }
37 assert(0);
38 return 0;
39 }
40
41 void hash_vector(hash_state_t *state, const char *key, cmph_uint32 keylen, cmph_uint32 * hashes)
42 {
43 switch (state->hashfunc)
44 {
45 case CMPH_HASH_JENKINS:
46 jenkins_hash_vector_((jenkins_state_t *)state, key, keylen, hashes);
47 break;
48 default:
49 assert(0);
50 }
51 }
52
53
54 void hash_state_dump(hash_state_t *state, char **buf, cmph_uint32 *buflen)
55 {
56 char *algobuf;
57 size_t len;
58 switch (state->hashfunc)
59 {
60 case CMPH_HASH_JENKINS:
61 jenkins_state_dump((jenkins_state_t *)state, &algobuf, buflen);
62 if (*buflen == UINT_MAX) return;
63 break;
64 default:
65 assert(0);
66 }
67 *buf = (char *)malloc(strlen(cmph_hash_names[state->hashfunc]) + 1 + *buflen);
68 memcpy(*buf, cmph_hash_names[state->hashfunc], strlen(cmph_hash_names[state->hashfunc]) + 1);
69 DEBUGP("Algobuf is %u\n", *(cmph_uint32 *)algobuf);
70 len = *buflen;
71 memcpy(*buf + strlen(cmph_hash_names[state->hashfunc]) + 1, algobuf, len);
72 *buflen = (cmph_uint32)strlen(cmph_hash_names[state->hashfunc]) + 1 + *buflen;
73 free(algobuf);
74 return;
75 }
76
77 hash_state_t * hash_state_copy(hash_state_t *src_state)
78 {
79 hash_state_t *dest_state = NULL;
80 switch (src_state->hashfunc)
81 {
82 case CMPH_HASH_JENKINS:
83 dest_state = (hash_state_t *)jenkins_state_copy((jenkins_state_t *)src_state);
84 break;
85 default:
86 assert(0);
87 }
88 dest_state->hashfunc = src_state->hashfunc;
89 return dest_state;
90 }
91
92 hash_state_t *hash_state_load(const char *buf, cmph_uint32 buflen)
93 {
94 cmph_uint32 i;
95 cmph_uint32 offset;
96 CMPH_HASH hashfunc = CMPH_HASH_COUNT;
97 for (i = 0; i < CMPH_HASH_COUNT; ++i)
98 {
99 if (strcmp(buf, cmph_hash_names[i]) == 0)
100 {
101 hashfunc = i;
102 break;
103 }
104 }
105 if (hashfunc == CMPH_HASH_COUNT) return NULL;
106 offset = (cmph_uint32)strlen(cmph_hash_names[hashfunc]) + 1;
107 switch (hashfunc)
108 {
109 case CMPH_HASH_JENKINS:
110 return (hash_state_t *)jenkins_state_load(buf + offset, buflen - offset);
111 default:
112 return NULL;
113 }
114 return NULL;
115 }
116 void hash_state_destroy(hash_state_t *state)
117 {
118 switch (state->hashfunc)
119 {
120 case CMPH_HASH_JENKINS:
121 jenkins_state_destroy((jenkins_state_t *)state);
122 break;
123 default:
124 assert(0);
125 }
126 return;
127 }
128
129 /** \fn void hash_state_pack(hash_state_t *state, void *hash_packed)
130 * \brief Support the ability to pack a hash function into a preallocated contiguous memory space pointed by hash_packed.
131 * \param state points to the hash function
132 * \param hash_packed pointer to the contiguous memory area used to store the hash function. The size of hash_packed must be at least hash_state_packed_size()
133 *
134 * Support the ability to pack a hash function into a preallocated contiguous memory space pointed by hash_packed.
135 * However, the hash function type must be packed outside.
136 */
137 void hash_state_pack(hash_state_t *state, void *hash_packed)
138 {
139 switch (state->hashfunc)
140 {
141 case CMPH_HASH_JENKINS:
142 // pack the jenkins hash function
143 jenkins_state_pack((jenkins_state_t *)state, hash_packed);
144 break;
145 default:
146 assert(0);
147 }
148 return;
149 }
150
151 /** \fn cmph_uint32 hash_state_packed_size(CMPH_HASH hashfunc)
152 * \brief Return the amount of space needed to pack a hash function.
153 * \param hashfunc function type
154 * \return the size of the packed function or zero for failures
155 */
156 cmph_uint32 hash_state_packed_size(CMPH_HASH hashfunc)
157 {
158 cmph_uint32 size = 0;
159 switch (hashfunc)
160 {
161 case CMPH_HASH_JENKINS:
162 size += jenkins_state_packed_size();
163 break;
164 default:
165 assert(0);
166 }
167 return size;
168 }
169
170 /** \fn cmph_uint32 hash_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen)
171 * \param hash_packed is a pointer to a contiguous memory area
172 * \param hashfunc is the type of the hash function packed in hash_packed
173 * \param key is a pointer to a key
174 * \param keylen is the key length
175 * \return an integer that represents a hash value of 32 bits.
176 */
177 cmph_uint32 hash_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen)
178 {
179 switch (hashfunc)
180 {
181 case CMPH_HASH_JENKINS:
182 return jenkins_hash_packed(hash_packed, k, keylen);
183 default:
184 assert(0);
185 }
186 assert(0);
187 return 0;
188 }
189
190 /** \fn hash_vector_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes)
191 * \param hash_packed is a pointer to a contiguous memory area
192 * \param key is a pointer to a key
193 * \param keylen is the key length
194 * \param hashes is a pointer to a memory large enough to fit three 32-bit integers.
195 */
196 void hash_vector_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes)
197 {
198 switch (hashfunc)
199 {
200 case CMPH_HASH_JENKINS:
201 jenkins_hash_vector_packed(hash_packed, k, keylen, hashes);
202 break;
203 default:
204 assert(0);
205 }
206 }
207
208
209 /** \fn CMPH_HASH hash_get_type(hash_state_t *state);
210 * \param state is a pointer to a hash_state_t structure
211 * \return the hash function type pointed by state
212 */
213 CMPH_HASH hash_get_type(hash_state_t *state)
214 {
215 return state->hashfunc;
216 }