X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;ds=sidebyside;f=libhashkit%2Fhashkit.c;h=64158f989f671f1b003b79c1b92cd9478b6de07c;hb=98d4dea6ae8869b6fe5e37a2908d66ff062b8f39;hp=54033132cb8e23c03fa6a52a99797dd85faffb1a;hpb=1fefa980a1f3a88df3eb1db02e2319d754aebe75;p=awesomized%2Flibmemcached diff --git a/libhashkit/hashkit.c b/libhashkit/hashkit.c index 54033132..64158f98 100644 --- a/libhashkit/hashkit.c +++ b/libhashkit/hashkit.c @@ -8,74 +8,44 @@ #include "common.h" -inline static bool _is_allocated(const hashkit_st *hashk) -{ - return hashk->options.is_allocated == true; -} - -inline static bool _is_initialized(const hashkit_st *hashk) -{ - return hashk->options.is_initialized == true; -} +static const hashkit_st global_default_hash= { + .base_hash= { + .function= hashkit_one_at_a_time, + .context= NULL + }, +}; /** @note We make no assumptions that "hashk" has been, or not been allocated from heap/stack. We just know we didn't do it. */ -hashkit_st *hashkit_create(hashkit_st *hashk) +hashkit_st *hashkit_create(hashkit_st *self) { - if (hashk == NULL) + if (self == NULL) { - hashk= (hashkit_st *)malloc(sizeof(hashkit_st)); - if (hashk == NULL) + self= (hashkit_st *)malloc(sizeof(hashkit_st)); + if (self == NULL) { return NULL; } - hashk->options.is_allocated= true; + self->options.is_allocated= true; } else { - hashk->options.is_allocated= false; + self->options.is_allocated= false; } - hashk->options.is_initialized= true; - - hashk->distribution= HASHKIT_DISTRIBUTION_MODULA; - hashk->continuum_count= 0; - hashk->continuum_points_count= 0; - hashk->list_size= 0; - hashk->context_size= 0; - hashk->continuum= NULL; - hashk->hash_fn= NULL; - hashk->active_fn= NULL; - hashk->continuum_hash_fn= NULL; - hashk->continuum_key_fn= NULL; - hashk->sort_fn= NULL; - hashk->weight_fn= NULL; - hashk->list= NULL; - - return hashk; + self->base_hash= global_default_hash.base_hash; + + return self; } -void hashkit_free(hashkit_st *hashk) +void hashkit_free(hashkit_st *self) { - assert(_is_initialized(hashk) == true); - - if (hashk->continuum != NULL) + if (hashkit_is_allocated(self)) { - free(hashk->continuum); - } - - /** - We don't know if hashk is pointing to something else, - so we go on and set is_initialized. - */ - hashk->options.is_initialized= false; - - if (_is_allocated(hashk)) - { - free(hashk); + free(self); } } @@ -84,138 +54,99 @@ void hashkit_free(hashkit_st *hashk) */ hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *source) { - hashkit_st *new_clone; - if (source == NULL) { return hashkit_create(destination); } - else - { - assert(_is_initialized(source) == true); - } /* new_clone will be a pointer to destination */ - new_clone= hashkit_create(destination); - assert((destination ? ((_is_allocated(new_clone) == false)) : (_is_allocated(new_clone) == true))); + destination= hashkit_create(destination); // Should only happen on allocation failure. - if (new_clone == NULL) + if (destination == NULL) { return NULL; } - // For the moment we will not clone this. - new_clone->continuum= NULL; - - new_clone->distribution= source->distribution; - new_clone->continuum_count= source->continuum_count; - new_clone->continuum_points_count= source->continuum_points_count; - new_clone->list_size= source->list_size; - new_clone->context_size= source->context_size; - + destination->base_hash= source->base_hash; - new_clone->hash_fn= source->hash_fn; - new_clone->active_fn= source->active_fn; - new_clone->continuum_hash_fn= source->continuum_hash_fn; - new_clone->continuum_key_fn= source->continuum_key_fn; - new_clone->sort_fn= source->sort_fn; - new_clone->weight_fn= source->weight_fn; - new_clone->list= source->list; - - return new_clone; -} - - -#if 0 -void hashkit_set_list(hashkit_st *hashkit, void *list, size_t list_size, size_t context_size) -{ - hashkit->list= list; - hashkit->list_size= list_size; - hashkit->context_size= context_size; + return destination; } -uint32_t hashkit_value(hashkit_st *hashkit, const char *key, size_t key_length) +uint32_t hashkit_generate_value(const hashkit_st *self, const char *key, size_t key_length) { - if (hashkit->hash_fn == NULL) - return hashkit_default(key, key_length); - - return hashkit->hash_fn(key, key_length); + return self->base_hash.function(key, key_length); } - -uint32_t hashkit_index(hashkit_st *hashkit, uint32_t hash_value) +hashkit_return_t hashkit_set_base_function(hashkit_st *self, hashkit_hash_algorithm_t hash_algorithm) { - if (hashkit->list_size == 1) - return 0; - - switch (hashkit->distribution) - { - case HASHKIT_DISTRIBUTION_MODULA: - return hash_value % (uint32_t)hashkit->list_size; - - case HASHKIT_DISTRIBUTION_RANDOM: - return (uint32_t)random() % (uint32_t)hashkit->list_size; - - case HASHKIT_DISTRIBUTION_KETAMA: + switch (hash_algorithm) { - hashkit_continuum_point_st *begin, *end, *left, *right, *middle; - begin= left= hashkit->continuum; - end= right= hashkit->continuum + hashkit->continuum_points_count; - - while (left < right) - { - middle= left + (right - left) / 2; - if (middle->value < hash_value) - left= middle + 1; - else - right= middle; - } - if (right == end) - right= begin; - return right->index; - } - - case HASHKIT_DISTRIBUTION_MAX: + case HASHKIT_HASH_DEFAULT: + self->base_hash.function= hashkit_one_at_a_time; + break; + case HASHKIT_HASH_MD5: + self->base_hash.function= hashkit_md5; + break; + case HASHKIT_HASH_CRC: + self->base_hash.function= hashkit_crc32; + break; + case HASHKIT_HASH_FNV1_64: + self->base_hash.function= hashkit_fnv1_64; + break; + case HASHKIT_HASH_FNV1A_64: + self->base_hash.function= hashkit_fnv1a_64; + break; + case HASHKIT_HASH_FNV1_32: + self->base_hash.function= hashkit_fnv1_32; + break; + case HASHKIT_HASH_FNV1A_32: + self->base_hash.function= hashkit_fnv1a_32; + break; + case HASHKIT_HASH_HSIEH: +#ifdef HAVE_HSIEH_HASH + self->base_hash.function= hashkit_hsieh; + break; +#else + return HASHKIT_FAILURE; +#endif + case HASHKIT_HASH_MURMUR: + self->base_hash.function= hashkit_murmur; + break; + case HASHKIT_HASH_JENKINS: + self->base_hash.function= hashkit_jenkins; + break; + case HASHKIT_HASH_MAX: default: - /* We have added a distribution without extending the logic */ - return hash_value % (uint32_t)hashkit->list_size; + return HASHKIT_FAILURE; + break; } - /* NOTREACHED */ -} + self->base_hash.context= NULL; + return HASHKIT_SUCCESS; +} -int hashkit_run_distribution(hashkit_st *hashkit) +hashkit_return_t hashkit_set_base_function_custom(hashkit_st *self, hashkit_hash_fn function, void *context) { - switch (hashkit->distribution) + if (function) { - case HASHKIT_DISTRIBUTION_MODULA: - if (hashkit->sort_fn != NULL && hashkit->list_size > 1) - hashkit->sort_fn(hashkit->list, hashkit->list_size); - break; - case HASHKIT_DISTRIBUTION_RANDOM: - break; - case HASHKIT_DISTRIBUTION_KETAMA: - return update_continuum(hashkit); - case HASHKIT_DISTRIBUTION_MAX: - default: - /* We have added a distribution without extending the logic */ - break; + self->base_hash.function= function; + self->base_hash.context= context; + + return HASHKIT_SUCCESS; } - return 0; + return HASHKIT_FAILURE; } -#endif - -uint32_t hashkit_generate_value(const char *key, size_t key_length, hashkit_hash_algorithm_t hash_algorithm) +uint32_t libhashkit_generate_value(const char *key, size_t key_length, hashkit_hash_algorithm_t hash_algorithm) { switch (hash_algorithm) { case HASHKIT_HASH_DEFAULT: - return hashkit_default(key, key_length); + return hashkit_one_at_a_time(key, key_length); case HASHKIT_HASH_MD5: return hashkit_md5(key, key_length); case HASHKIT_HASH_CRC: @@ -241,7 +172,7 @@ uint32_t hashkit_generate_value(const char *key, size_t key_length, hashkit_hash case HASHKIT_HASH_MAX: default: #ifdef HAVE_DEBUG - fprintf(stderr, "hashkit_hash_t was extended but hashkit_generate_value was not updated\n"); + fprintf(stderr, "hashkit_hash_t was extended but libhashkit_generate_value was not updated\n"); fflush(stderr); assert(0); #endif