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
hash_state_new(CMPH_HASH hashfunc,cmph_uint32 hashsize)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 }
hash(hash_state_t * state,const char * key,cmph_uint32 keylen)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
hash_vector(hash_state_t * state,const char * key,cmph_uint32 keylen,cmph_uint32 * hashes)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
hash_state_dump(hash_state_t * state,char ** buf,cmph_uint32 * buflen)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) {
63 goto cmph_cleanup;
64 }
65 break;
66 default:
67 assert(0);
68 }
69 *buf = (char *)malloc(strlen(cmph_hash_names[state->hashfunc]) + 1 + *buflen);
70 memcpy(*buf, cmph_hash_names[state->hashfunc], strlen(cmph_hash_names[state->hashfunc]) + 1);
71 DEBUGP("Algobuf is %u\n", *(cmph_uint32 *)algobuf);
72 len = *buflen;
73 memcpy(*buf + strlen(cmph_hash_names[state->hashfunc]) + 1, algobuf, len);
74 *buflen = (cmph_uint32)strlen(cmph_hash_names[state->hashfunc]) + 1 + *buflen;
75 cmph_cleanup:
76 free(algobuf);
77 return;
78 }
79
hash_state_copy(hash_state_t * src_state)80 hash_state_t * hash_state_copy(hash_state_t *src_state)
81 {
82 hash_state_t *dest_state = NULL;
83 switch (src_state->hashfunc)
84 {
85 case CMPH_HASH_JENKINS:
86 dest_state = (hash_state_t *)jenkins_state_copy((jenkins_state_t *)src_state);
87 break;
88 default:
89 assert(0);
90 }
91 dest_state->hashfunc = src_state->hashfunc;
92 return dest_state;
93 }
94
hash_state_load(const char * buf,cmph_uint32 buflen)95 hash_state_t *hash_state_load(const char *buf, cmph_uint32 buflen)
96 {
97 cmph_uint32 i;
98 cmph_uint32 offset;
99 CMPH_HASH hashfunc = CMPH_HASH_COUNT;
100 for (i = 0; i < CMPH_HASH_COUNT; ++i)
101 {
102 if (strcmp(buf, cmph_hash_names[i]) == 0)
103 {
104 hashfunc = (CMPH_HASH)(i);
105 break;
106 }
107 }
108 if (hashfunc == CMPH_HASH_COUNT) return NULL;
109 offset = (cmph_uint32)strlen(cmph_hash_names[hashfunc]) + 1;
110 switch (hashfunc)
111 {
112 case CMPH_HASH_JENKINS:
113 return (hash_state_t *)jenkins_state_load(buf + offset, buflen - offset);
114 default:
115 return NULL;
116 }
117 return NULL;
118 }
hash_state_destroy(hash_state_t * state)119 void hash_state_destroy(hash_state_t *state)
120 {
121 switch (state->hashfunc)
122 {
123 case CMPH_HASH_JENKINS:
124 jenkins_state_destroy((jenkins_state_t *)state);
125 break;
126 default:
127 assert(0);
128 }
129 return;
130 }
131
132 /** \fn void hash_state_pack(hash_state_t *state, void *hash_packed)
133 * \brief Support the ability to pack a hash function into a preallocated contiguous memory space pointed by hash_packed.
134 * \param state points to the hash function
135 * \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()
136 *
137 * Support the ability to pack a hash function into a preallocated contiguous memory space pointed by hash_packed.
138 * However, the hash function type must be packed outside.
139 */
hash_state_pack(hash_state_t * state,void * hash_packed)140 void hash_state_pack(hash_state_t *state, void *hash_packed)
141 {
142 switch (state->hashfunc)
143 {
144 case CMPH_HASH_JENKINS:
145 // pack the jenkins hash function
146 jenkins_state_pack((jenkins_state_t *)state, hash_packed);
147 break;
148 default:
149 assert(0);
150 }
151 return;
152 }
153
154 /** \fn cmph_uint32 hash_state_packed_size(CMPH_HASH hashfunc)
155 * \brief Return the amount of space needed to pack a hash function.
156 * \param hashfunc function type
157 * \return the size of the packed function or zero for failures
158 */
hash_state_packed_size(CMPH_HASH hashfunc)159 cmph_uint32 hash_state_packed_size(CMPH_HASH hashfunc)
160 {
161 cmph_uint32 size = 0;
162 switch (hashfunc)
163 {
164 case CMPH_HASH_JENKINS:
165 size += jenkins_state_packed_size();
166 break;
167 default:
168 assert(0);
169 }
170 return size;
171 }
172
173 /** \fn cmph_uint32 hash_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen)
174 * \param hash_packed is a pointer to a contiguous memory area
175 * \param hashfunc is the type of the hash function packed in hash_packed
176 * \param key is a pointer to a key
177 * \param keylen is the key length
178 * \return an integer that represents a hash value of 32 bits.
179 */
hash_packed(void * hash_packed,CMPH_HASH hashfunc,const char * k,cmph_uint32 keylen)180 cmph_uint32 hash_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen)
181 {
182 switch (hashfunc)
183 {
184 case CMPH_HASH_JENKINS:
185 return jenkins_hash_packed(hash_packed, k, keylen);
186 default:
187 assert(0);
188 }
189 assert(0);
190 return 0;
191 }
192
193 /** \fn hash_vector_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes)
194 * \param hash_packed is a pointer to a contiguous memory area
195 * \param key is a pointer to a key
196 * \param keylen is the key length
197 * \param hashes is a pointer to a memory large enough to fit three 32-bit integers.
198 */
hash_vector_packed(void * hash_packed,CMPH_HASH hashfunc,const char * k,cmph_uint32 keylen,cmph_uint32 * hashes)199 void hash_vector_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes)
200 {
201 switch (hashfunc)
202 {
203 case CMPH_HASH_JENKINS:
204 jenkins_hash_vector_packed(hash_packed, k, keylen, hashes);
205 break;
206 default:
207 assert(0);
208 }
209 }
210
211
212 /** \fn CMPH_HASH hash_get_type(hash_state_t *state);
213 * \param state is a pointer to a hash_state_t structure
214 * \return the hash function type pointed by state
215 */
hash_get_type(hash_state_t * state)216 CMPH_HASH hash_get_type(hash_state_t *state)
217 {
218 return state->hashfunc;
219 }
220