Branch data Line data Source code
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 : 13 : hash_state_t *hash_state_new(CMPH_HASH hashfunc, cmph_uint32 hashsize)
13 : : {
14 : 13 : hash_state_t *state = NULL;
15 : 13 : switch (hashfunc)
16 : : {
17 : 13 : case CMPH_HASH_JENKINS:
18 : : DEBUGP("Jenkins function - %u\n", hashsize);
19 : 13 : state = (hash_state_t *)jenkins_state_new(hashsize);
20 : : DEBUGP("Jenkins function created\n");
21 : 13 : break;
22 : 0 : default:
23 : 0 : assert(0);
24 : : }
25 : 13 : state->hashfunc = hashfunc;
26 : 13 : return state;
27 : : }
28 : 0 : cmph_uint32 hash(hash_state_t *state, const char *key, cmph_uint32 keylen)
29 : : {
30 : 0 : switch (state->hashfunc)
31 : : {
32 : 0 : case CMPH_HASH_JENKINS:
33 : 0 : return jenkins_hash((jenkins_state_t *)state, key, keylen);
34 : 0 : default:
35 : 0 : assert(0);
36 : : }
37 : : assert(0);
38 : : return 0;
39 : : }
40 : :
41 : 2645 : void hash_vector(hash_state_t *state, const char *key, cmph_uint32 keylen, cmph_uint32 * hashes)
42 : : {
43 : 2645 : switch (state->hashfunc)
44 : : {
45 : 2645 : case CMPH_HASH_JENKINS:
46 : 2645 : jenkins_hash_vector_((jenkins_state_t *)state, key, keylen, hashes);
47 : 2645 : break;
48 : 0 : default:
49 : 0 : assert(0);
50 : : }
51 : 2645 : }
52 : :
53 : :
54 : 0 : void hash_state_dump(hash_state_t *state, char **buf, cmph_uint32 *buflen)
55 : : {
56 : : char *algobuf;
57 : : size_t len;
58 : 0 : switch (state->hashfunc)
59 : : {
60 : 0 : case CMPH_HASH_JENKINS:
61 : 0 : jenkins_state_dump((jenkins_state_t *)state, &algobuf, buflen);
62 : 0 : if (*buflen == UINT_MAX) return;
63 : 0 : break;
64 : 0 : default:
65 : 0 : assert(0);
66 : : }
67 : 0 : *buf = (char *)malloc(strlen(cmph_hash_names[state->hashfunc]) + 1 + *buflen);
68 : 0 : memcpy(*buf, cmph_hash_names[state->hashfunc], strlen(cmph_hash_names[state->hashfunc]) + 1);
69 : : DEBUGP("Algobuf is %u\n", *(cmph_uint32 *)algobuf);
70 : 0 : len = *buflen;
71 : 0 : memcpy(*buf + strlen(cmph_hash_names[state->hashfunc]) + 1, algobuf, len);
72 : 0 : *buflen = (cmph_uint32)strlen(cmph_hash_names[state->hashfunc]) + 1 + *buflen;
73 : 0 : free(algobuf);
74 : 0 : return;
75 : : }
76 : :
77 : 0 : hash_state_t * hash_state_copy(hash_state_t *src_state)
78 : : {
79 : 0 : hash_state_t *dest_state = NULL;
80 : 0 : switch (src_state->hashfunc)
81 : : {
82 : 0 : case CMPH_HASH_JENKINS:
83 : 0 : dest_state = (hash_state_t *)jenkins_state_copy((jenkins_state_t *)src_state);
84 : 0 : break;
85 : 0 : default:
86 : 0 : assert(0);
87 : : }
88 : 0 : dest_state->hashfunc = src_state->hashfunc;
89 : 0 : return dest_state;
90 : : }
91 : :
92 : 0 : hash_state_t *hash_state_load(const char *buf, cmph_uint32 buflen)
93 : : {
94 : : cmph_uint32 i;
95 : : cmph_uint32 offset;
96 : 0 : CMPH_HASH hashfunc = CMPH_HASH_COUNT;
97 : 0 : for (i = 0; i < CMPH_HASH_COUNT; ++i)
98 : : {
99 : 0 : if (strcmp(buf, cmph_hash_names[i]) == 0)
100 : : {
101 : 0 : hashfunc = i;
102 : 0 : break;
103 : : }
104 : : }
105 : 0 : if (hashfunc == CMPH_HASH_COUNT) return NULL;
106 : 0 : offset = (cmph_uint32)strlen(cmph_hash_names[hashfunc]) + 1;
107 : 0 : switch (hashfunc)
108 : : {
109 : 0 : case CMPH_HASH_JENKINS:
110 : 0 : return (hash_state_t *)jenkins_state_load(buf + offset, buflen - offset);
111 : 0 : default:
112 : 0 : return NULL;
113 : : }
114 : : return NULL;
115 : : }
116 : 13 : void hash_state_destroy(hash_state_t *state)
117 : : {
118 : 13 : switch (state->hashfunc)
119 : : {
120 : 13 : case CMPH_HASH_JENKINS:
121 : 13 : jenkins_state_destroy((jenkins_state_t *)state);
122 : 13 : break;
123 : 0 : default:
124 : 0 : assert(0);
125 : : }
126 : 13 : 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 : 9 : void hash_state_pack(hash_state_t *state, void *hash_packed)
138 : : {
139 : 9 : switch (state->hashfunc)
140 : : {
141 : 9 : case CMPH_HASH_JENKINS:
142 : : // pack the jenkins hash function
143 : 9 : jenkins_state_pack((jenkins_state_t *)state, hash_packed);
144 : 9 : break;
145 : 0 : default:
146 : 0 : assert(0);
147 : : }
148 : 9 : 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 : 2311 : cmph_uint32 hash_state_packed_size(CMPH_HASH hashfunc)
157 : : {
158 : 2311 : cmph_uint32 size = 0;
159 : 2311 : switch (hashfunc)
160 : : {
161 : 2311 : case CMPH_HASH_JENKINS:
162 : 2311 : size += jenkins_state_packed_size();
163 : 2311 : break;
164 : 0 : default:
165 : 0 : assert(0);
166 : : }
167 : 2311 : 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 : 0 : cmph_uint32 hash_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen)
178 : : {
179 : 0 : switch (hashfunc)
180 : : {
181 : 0 : case CMPH_HASH_JENKINS:
182 : 0 : return jenkins_hash_packed(hash_packed, k, keylen);
183 : 0 : default:
184 : 0 : 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 : 2293 : void hash_vector_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes)
197 : : {
198 : 2293 : switch (hashfunc)
199 : : {
200 : 2293 : case CMPH_HASH_JENKINS:
201 : 2293 : jenkins_hash_vector_packed(hash_packed, k, keylen, hashes);
202 : 2293 : break;
203 : 0 : default:
204 : 0 : assert(0);
205 : : }
206 : 2293 : }
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 : 18 : CMPH_HASH hash_get_type(hash_state_t *state)
214 : : {
215 : 18 : return state->hashfunc;
216 : : }
|