2
* Copyright (C) 2006-2009 Brian Aker
5
* Use and distribution licensed under the BSD license. See
6
* the COPYING file in the parent directory for full text.
11
inline static bool _is_allocated(const hashkit_st *hashk)
13
return hashk->options.is_allocated == true;
16
inline static bool _is_initialized(const hashkit_st *hashk)
18
return hashk->options.is_initialized == true;
22
@note We make no assumptions that "hashk" has been, or not been allocated from heap/stack. We just know we didn't do it.
24
hashkit_st *hashkit_create(hashkit_st *hashk)
28
hashk= (hashkit_st *)malloc(sizeof(hashkit_st));
34
hashk->options.is_allocated= true;
38
hashk->options.is_allocated= false;
41
hashk->options.is_initialized= true;
43
hashk->distribution= HASHKIT_DISTRIBUTION_MODULA;
44
hashk->continuum_count= 0;
45
hashk->continuum_points_count= 0;
47
hashk->context_size= 0;
48
hashk->continuum= NULL;
50
hashk->active_fn= NULL;
51
hashk->continuum_hash_fn= NULL;
52
hashk->continuum_key_fn= NULL;
54
hashk->weight_fn= NULL;
61
void hashkit_free(hashkit_st *hashk)
63
assert(_is_initialized(hashk) == true);
65
if (hashk->continuum != NULL)
67
free(hashk->continuum);
71
We don't know if hashk is pointing to something else,
72
so we go on and set is_initialized.
74
hashk->options.is_initialized= false;
76
if (_is_allocated(hashk))
83
@note We do assume source is valid. If source does not exist, we allocate.
85
hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *source)
87
hashkit_st *new_clone;
91
return hashkit_create(destination);
95
assert(_is_initialized(source) == true);
98
/* new_clone will be a pointer to destination */
99
new_clone= hashkit_create(destination);
100
assert((destination ? ((_is_allocated(new_clone) == false)) : (_is_allocated(new_clone) == true)));
102
// Should only happen on allocation failure.
103
if (new_clone == NULL)
108
// For the moment we will not clone this.
109
new_clone->continuum= NULL;
111
new_clone->distribution= source->distribution;
112
new_clone->continuum_count= source->continuum_count;
113
new_clone->continuum_points_count= source->continuum_points_count;
114
new_clone->list_size= source->list_size;
115
new_clone->context_size= source->context_size;
118
new_clone->hash_fn= source->hash_fn;
119
new_clone->active_fn= source->active_fn;
120
new_clone->continuum_hash_fn= source->continuum_hash_fn;
121
new_clone->continuum_key_fn= source->continuum_key_fn;
122
new_clone->sort_fn= source->sort_fn;
123
new_clone->weight_fn= source->weight_fn;
124
new_clone->list= source->list;
131
void hashkit_set_list(hashkit_st *hashkit, void *list, size_t list_size, size_t context_size)
134
hashkit->list_size= list_size;
135
hashkit->context_size= context_size;
139
uint32_t hashkit_value(hashkit_st *hashkit, const char *key, size_t key_length)
141
if (hashkit->hash_fn == NULL)
142
return hashkit_default(key, key_length);
144
return hashkit->hash_fn(key, key_length);
148
uint32_t hashkit_index(hashkit_st *hashkit, uint32_t hash_value)
150
if (hashkit->list_size == 1)
153
switch (hashkit->distribution)
155
case HASHKIT_DISTRIBUTION_MODULA:
156
return hash_value % (uint32_t)hashkit->list_size;
158
case HASHKIT_DISTRIBUTION_RANDOM:
159
return (uint32_t)random() % (uint32_t)hashkit->list_size;
161
case HASHKIT_DISTRIBUTION_KETAMA:
163
hashkit_continuum_point_st *begin, *end, *left, *right, *middle;
164
begin= left= hashkit->continuum;
165
end= right= hashkit->continuum + hashkit->continuum_points_count;
169
middle= left + (right - left) / 2;
170
if (middle->value < hash_value)
180
case HASHKIT_DISTRIBUTION_MAX:
182
/* We have added a distribution without extending the logic */
183
return hash_value % (uint32_t)hashkit->list_size;
190
int hashkit_run_distribution(hashkit_st *hashkit)
192
switch (hashkit->distribution)
194
case HASHKIT_DISTRIBUTION_MODULA:
195
if (hashkit->sort_fn != NULL && hashkit->list_size > 1)
196
hashkit->sort_fn(hashkit->list, hashkit->list_size);
198
case HASHKIT_DISTRIBUTION_RANDOM:
200
case HASHKIT_DISTRIBUTION_KETAMA:
201
return update_continuum(hashkit);
202
case HASHKIT_DISTRIBUTION_MAX:
204
/* We have added a distribution without extending the logic */
213
uint32_t hashkit_generate_value(const char *key, size_t key_length, hashkit_hash_algorithm_t hash_algorithm)
215
switch (hash_algorithm)
217
case HASHKIT_HASH_DEFAULT:
218
return hashkit_default(key, key_length);
219
case HASHKIT_HASH_MD5:
220
return hashkit_md5(key, key_length);
221
case HASHKIT_HASH_CRC:
222
return hashkit_crc32(key, key_length);
223
case HASHKIT_HASH_FNV1_64:
224
return hashkit_fnv1_64(key, key_length);
225
case HASHKIT_HASH_FNV1A_64:
226
return hashkit_fnv1a_64(key, key_length);
227
case HASHKIT_HASH_FNV1_32:
228
return hashkit_fnv1_32(key, key_length);
229
case HASHKIT_HASH_FNV1A_32:
230
return hashkit_fnv1a_32(key, key_length);
231
case HASHKIT_HASH_HSIEH:
232
#ifdef HAVE_HSIEH_HASH
233
return hashkit_hsieh(key, key_length);
237
case HASHKIT_HASH_MURMUR:
238
return hashkit_murmur(key, key_length);
239
case HASHKIT_HASH_JENKINS:
240
return hashkit_jenkins(key, key_length);
241
case HASHKIT_HASH_MAX:
244
fprintf(stderr, "hashkit_hash_t was extended but hashkit_generate_value was not updated\n");