From: Brian Aker Date: Tue, 19 Jan 2010 22:37:09 +0000 (-0800) Subject: Updates to libhashkit. X-Git-Tag: 0.40~79 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=a81bddebd55105aefa57af7cc87adbda3d1a022e;p=m6w6%2Flibmemcached Updates to libhashkit. --- diff --git a/libhashkit/algorithm.h b/libhashkit/algorithm.h index d3f576c3..f575222e 100644 --- a/libhashkit/algorithm.h +++ b/libhashkit/algorithm.h @@ -19,7 +19,7 @@ extern "C" { #endif HASHKIT_API -uint32_t hashkit_default(const char *key, size_t key_length); +uint32_t hashkit_one_at_a_time(const char *key, size_t key_length); HASHKIT_API uint32_t hashkit_fnv1_64(const char *key, size_t key_length); HASHKIT_API diff --git a/libhashkit/behavior.c b/libhashkit/behavior.c index 19f08b1b..683798ea 100644 --- a/libhashkit/behavior.c +++ b/libhashkit/behavior.c @@ -7,141 +7,3 @@ */ #include "common.h" - -static hashkit_fn *fetch_hash_fn(hashkit_hash_algorithm_t hash_algorithm) -{ - switch (hash_algorithm) - { - case HASHKIT_HASH_DEFAULT: - return hashkit_default; - case HASHKIT_HASH_MD5: - return hashkit_md5; - case HASHKIT_HASH_CRC: - return hashkit_crc32; - case HASHKIT_HASH_FNV1_64: - return hashkit_fnv1_64; - case HASHKIT_HASH_FNV1A_64: - return hashkit_fnv1a_64; - case HASHKIT_HASH_FNV1_32: - return hashkit_fnv1_32; - case HASHKIT_HASH_FNV1A_32: - return hashkit_fnv1a_32; - case HASHKIT_HASH_HSIEH: -#ifdef HAVE_HSIEH_HASH - return hashkit_hsieh; -#else - return NULL; -#endif - case HASHKIT_HASH_MURMUR: - return hashkit_murmur; - case HASHKIT_HASH_JENKINS: - return hashkit_jenkins; - case HASHKIT_HASH_MAX: - default: -#ifdef HAVE_DEBUG - fprintf(stderr, "hashkit_hash_t was extended but hashkit_generate_value was not updated\n"); - fflush(stderr); - assert(0); -#endif - break; - } - - return NULL; -} - -hashkit_return_t hashkit_behavior_set_distribution(hashkit_st *hashkit, hashkit_distribution_t distribution) -{ - hashkit->distribution= distribution; - - return HASHKIT_SUCCESS; -} - - -hashkit_distribution_t hashkit_behavior_get_distribution(hashkit_st *hashkit) -{ - return hashkit->distribution; -} - - -/** - @note For the moment we will not allow the user to set the distribution hash type. -*/ -hashkit_return_t hashkit_behavior_set_key_hash_algorithm(hashkit_st *hashkit, hashkit_hash_algorithm_t hash_algorithm) -{ - hashkit_fn *hash_fn= fetch_hash_fn(hash_algorithm); - - if (hash_fn == NULL) - return HASHKIT_FAILURE; - - hashkit->hash_fn= hash_fn; - hashkit->for_key= hash_algorithm; - hashkit->for_distribution= hash_algorithm; - - return HASHKIT_SUCCESS; -} - - -hashkit_hash_algorithm_t hashkit_behavior_get_key_hash_algorithm(hashkit_st *hashkit) -{ - return hashkit->for_key; -} - - -void hashkit_behavior_set_active_fn(hashkit_st *hashkit, hashkit_active_fn *function) -{ - hashkit->active_fn= function; -} - - -hashkit_active_fn * hashkit_behavior_get_active_fn(hashkit_st *hashkit) -{ - return hashkit->active_fn; -} - - -void hashkit_behavior_set_continuum_hash_fn(hashkit_st *hashkit, hashkit_fn *function) -{ - hashkit->continuum_hash_fn= function; -} - - -hashkit_fn * hashkit_behavior_get_continuum_hash_fn(hashkit_st *hashkit) -{ - return hashkit->continuum_hash_fn; -} - - -void hashkit_behavior_set_continuum_key_fn(hashkit_st *hashkit, hashkit_key_fn *function) -{ - hashkit->continuum_key_fn= function; -} - - -hashkit_key_fn * hashkit_behavior_get_continuum_key_fn(hashkit_st *hashkit) -{ - return hashkit->continuum_key_fn; -} - - -void hashkit_behavior_set_sort_fn(hashkit_st *hashkit, hashkit_sort_fn *function) -{ - hashkit->sort_fn= function; -} - - -hashkit_sort_fn * hashkit_behavior_get_sort_fn(hashkit_st *hashkit) -{ - return hashkit->sort_fn; -} - - -void hashkit_behavior_set_weight_fn(hashkit_st *hashkit, hashkit_weight_fn *function) -{ - hashkit->weight_fn= function; -} - - -hashkit_weight_fn * hashkit_behavior_get_weight_fn(hashkit_st *hashkit) -{ - return hashkit->weight_fn; -} diff --git a/libhashkit/behavior.h b/libhashkit/behavior.h index 126a7c97..0ded644c 100644 --- a/libhashkit/behavior.h +++ b/libhashkit/behavior.h @@ -12,55 +12,13 @@ */ #ifndef HASHKIT_BEHAVIOR_H -#define HASHKIT_BEHAVIORH +#define HASHKIT_BEHAVIOR_H #ifdef __cplusplus extern "C" { #endif -HASHKIT_API -hashkit_return_t hashkit_behavior_set_distribution(hashkit_st *hashkit, hashkit_distribution_t distribution); - -HASHKIT_API -hashkit_distribution_t hashkit_behavior_get_distribution(hashkit_st *hashkit); - -HASHKIT_API -hashkit_return_t hashkit_behavior_set_key_hash_algorithm(hashkit_st *hashkit, hashkit_hash_algorithm_t hash_algorithm); - -HASHKIT_API -hashkit_hash_algorithm_t hashkit_behavior_get_key_hash_algorithm(hashkit_st *hashkit); - -HASHKIT_API -void hashkit_behavior_set_active_fn(hashkit_st *hash, hashkit_active_fn *function); - -HASHKIT_API -hashkit_active_fn * hashkit_behavior_get_active_fn(hashkit_st *hash); - -HASHKIT_API -void hashkit_behavior_set_continuum_hash_fn(hashkit_st *hash, hashkit_fn *function); - -HASHKIT_API -hashkit_fn * hashkit_behavior_get_continuum_hash_fn(hashkit_st *hash); - -HASHKIT_API -void hashkit_behavior_set_continuum_key_fn(hashkit_st *hash, hashkit_key_fn *function); - -HASHKIT_API -hashkit_key_fn * hashkit_behavior_get_continuum_key_fn(hashkit_st *hash); - -HASHKIT_API -void hashkit_behavior_set_sort_fn(hashkit_st *hash, hashkit_sort_fn *function); - -HASHKIT_API -hashkit_sort_fn * hashkit_behavior_get_sort_fn(hashkit_st *hash); - -HASHKIT_API -void hashkit_behavior_set_weight_fn(hashkit_st *hash, hashkit_weight_fn *function); - -HASHKIT_API -hashkit_weight_fn * hashkit_behavior_get_weight_fn(hashkit_st *hash); - #ifdef __cplusplus } #endif diff --git a/libhashkit/default.c b/libhashkit/default.c deleted file mode 100644 index bc0d4529..00000000 --- a/libhashkit/default.c +++ /dev/null @@ -1,28 +0,0 @@ -/* HashKit - * Copyright (C) 2009 Brian Aker - * All rights reserved. - * - * Use and distribution licensed under the BSD license. See - * the COPYING file in the parent directory for full text. - */ - -#include "common.h" - -uint32_t hashkit_default(const char *key, size_t key_length) -{ - const char *ptr= key; - uint32_t value= 0; - - while (key_length--) - { - uint32_t val= (uint32_t) *ptr++; - value += val; - value += (value << 10); - value ^= (value >> 6); - } - value += (value << 3); - value ^= (value >> 11); - value += (value << 15); - - return value; -} diff --git a/libhashkit/hashkit.c b/libhashkit/hashkit.c index 54033132..a87e712b 100644 --- a/libhashkit/hashkit.c +++ b/libhashkit/hashkit.c @@ -8,74 +8,45 @@ #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= { + .type= HASHKIT_HASH_DEFAULT, + .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 +55,37 @@ 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; - - - 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; + destination->base_hash= source->base_hash; - return new_clone; + return destination; } -#if 0 -void hashkit_set_list(hashkit_st *hashkit, void *list, size_t list_size, size_t context_size) +uint32_t hashkit_generate_value(const hashkit_st *self, const char *key, size_t key_length) { - hashkit->list= list; - hashkit->list_size= list_size; - hashkit->context_size= context_size; + return self->base_hash.function(key, key_length); } - -uint32_t hashkit_value(hashkit_st *hashkit, 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); -} - - -uint32_t hashkit_index(hashkit_st *hashkit, uint32_t hash_value) -{ - 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: - { - 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: - default: - /* We have added a distribution without extending the logic */ - return hash_value % (uint32_t)hashkit->list_size; - } - - /* NOTREACHED */ -} - - -int hashkit_run_distribution(hashkit_st *hashkit) -{ - switch (hashkit->distribution) - { - 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; - } - - return 0; -} -#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 +111,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 diff --git a/libhashkit/hashkit.h b/libhashkit/hashkit.h index 6dd08f43..173f4d9c 100644 --- a/libhashkit/hashkit.h +++ b/libhashkit/hashkit.h @@ -6,11 +6,6 @@ * the COPYING file in the parent directory for full text. */ -/** - * @file - * @brief HashKit Header - */ - #ifndef HASHKIT_H #define HASHKIT_H @@ -29,65 +24,19 @@ extern "C" { #endif -/** - * @addtogroup hashkit_constants Constants - * @ingroup hashkit - * @{ - */ - -/* Defines. */ -#define HASHKIT_MAX_KEY 251 -#define HASHKIT_POINTS_PER_NODE 100 -#define HASHKIT_POINTS_PER_NODE_WEIGHTED 160 -#define HASHKIT_CONTINUUM_ADDITION 10 -#define HASHKIT_CONTINUUM_KEY_SIZE 86 - -/** @} */ - -/** - * @ingroup hashkit - */ struct hashkit_st { - hashkit_options_st options; - hashkit_distribution_t distribution; - uint32_t continuum_count; - uint32_t continuum_points_count; - size_t list_size; - size_t context_size; - - /** - @note There are two places we use hashing, one is for when we have a key - and we want to find out what server it should be placed on. The second is - for when we are placing a value into the continuum. - */ - hashkit_hash_algorithm_t for_key; - hashkit_hash_algorithm_t for_distribution; - - hashkit_continuum_point_st *continuum; - hashkit_fn *hash_fn; - hashkit_active_fn *active_fn; - hashkit_fn *continuum_hash_fn; - hashkit_key_fn *continuum_key_fn; - hashkit_sort_fn *sort_fn; - hashkit_weight_fn *weight_fn; - void *list; -}; - -/** - * @ingroup hashkit - */ -struct hashkit_continuum_point_st -{ - uint32_t index; - uint32_t value; + struct { + hashkit_hash_algorithm_t type; + hashkit_hash_fn function; + void *context; + } base_hash; + + struct { + bool is_allocated:1; + } options; }; -/** - * @addtogroup hashkit Pandora Hash Declarations - * @{ - */ - HASHKIT_API hashkit_st *hashkit_create(hashkit_st *hash); @@ -98,7 +47,10 @@ HASHKIT_API void hashkit_free(hashkit_st *hash); HASHKIT_API -uint32_t hashkit_generate_value(const char *key, size_t key_length, hashkit_hash_algorithm_t hash_algorithm); +uint32_t hashkit_generate_value(const hashkit_st *self, const char *key, size_t key_length); + +HASHKIT_API +uint32_t libhashkit_generate_value(const char *key, size_t key_length, hashkit_hash_algorithm_t hash_algorithm); #define hashkit_is_allocated(__object) ((__object)->options.is_allocated) #define hashkit_is_initialized(__object) ((__object)->options.is_initialized) diff --git a/libhashkit/include.am b/libhashkit/include.am index dd941f96..f8aa79f5 100644 --- a/libhashkit/include.am +++ b/libhashkit/include.am @@ -25,13 +25,13 @@ noinst_HEADERS+= \ libhashkit_libhashkit_la_SOURCES= \ libhashkit/crc32.c \ libhashkit/behavior.c \ - libhashkit/default.c \ libhashkit/fnv.c \ libhashkit/hashkit.c \ libhashkit/jenkins.c \ libhashkit/ketama.c \ libhashkit/md5.c \ libhashkit/murmur.c \ + libhashkit/one_at_a_time.c \ libhashkit/strerror.c if INCLUDE_HSIEH_SRC diff --git a/libhashkit/ketama.c b/libhashkit/ketama.c index 83b47552..a510e57a 100644 --- a/libhashkit/ketama.c +++ b/libhashkit/ketama.c @@ -9,6 +9,7 @@ #include "common.h" #include +#if 0 static uint32_t ketama_server_hash(const char *key, unsigned int key_length, int alignment) { unsigned char results[16]; @@ -160,3 +161,4 @@ int update_continuum(hashkit_st *hashkit) return 0; } +#endif diff --git a/libhashkit/one_at_a_time.c b/libhashkit/one_at_a_time.c new file mode 100644 index 00000000..ab106f1d --- /dev/null +++ b/libhashkit/one_at_a_time.c @@ -0,0 +1,33 @@ +/* HashKit + * Copyright (C) 2009 Brian Aker + * All rights reserved. + * + * Use and distribution licensed under the BSD license. See + * the COPYING file in the parent directory for full text. + */ + +/* + This has is Jenkin's "One at A time Hash". +http://en.wikipedia.org/wiki/Jenkins_hash_function +*/ + +#include "common.h" + +uint32_t hashkit_one_at_a_time(const char *key, size_t key_length) +{ + const char *ptr= key; + uint32_t value= 0; + + while (key_length--) + { + uint32_t val= (uint32_t) *ptr++; + value += val; + value += (value << 10); + value ^= (value >> 6); + } + value += (value << 3); + value ^= (value >> 11); + value += (value << 15); + + return value; +} diff --git a/libhashkit/types.h b/libhashkit/types.h index a06be2fb..fadb4d93 100644 --- a/libhashkit/types.h +++ b/libhashkit/types.h @@ -7,11 +7,6 @@ * the COPYING file in the parent directory for full text. */ -/** - * @file - * @brief HashKit Header - */ - #ifndef HASHKIT_TYPES_H #define HASHKIT_TYPES_H @@ -19,12 +14,6 @@ extern "C" { #endif -/** - * @addtogroup hashkit_types Types - * @ingroup hashkit - * @{ - */ - typedef enum { HASHKIT_SUCCESS, HASHKIT_FAILURE, @@ -32,24 +21,8 @@ typedef enum { HASHKIT_MAXIMUM_RETURN /* Always add new error code before */ } hashkit_return_t; -/** - @todo hashkit_options_t is for future use, currently we do not define any user options. - */ - -typedef enum -{ - HASHKIT_OPTION_MAX -} hashkit_options_t; - -typedef struct -{ - /* We use the following for internal book keeping. */ - bool is_initialized:1; - bool is_allocated:1; -} hashkit_options_st; - typedef enum { - HASHKIT_HASH_DEFAULT= 0, + HASHKIT_HASH_DEFAULT= 0, // hashkit_one_at_a_time() HASHKIT_HASH_MD5, HASHKIT_HASH_CRC, HASHKIT_HASH_FNV1_64, @@ -75,15 +48,7 @@ typedef enum typedef struct hashkit_st hashkit_st; -typedef struct hashkit_continuum_point_st hashkit_continuum_point_st; -typedef bool (hashkit_active_fn)(void *context); -typedef uint32_t (hashkit_fn)(const char *key, size_t key_length); -typedef size_t (hashkit_key_fn)(char *key, size_t key_length, uint32_t point_index, void *context); -typedef void (hashkit_sort_fn)(void *context, size_t count); -typedef uint32_t (hashkit_weight_fn)(void *context); - -/** @} */ - +typedef uint32_t (*hashkit_hash_fn)(const char *key, size_t key_length); #ifdef __cplusplus } diff --git a/tests/hash_results.h b/tests/hash_results.h index da00e872..26f1ed85 100644 --- a/tests/hash_results.h +++ b/tests/hash_results.h @@ -42,6 +42,14 @@ static const char *list_to_hash[]= NULL }; +static uint32_t one_at_a_time_values[]= { 2297466611U, 3902465932U, 469785835U, 1937308741U, + 261917617U, 3785641677U, 1439605128U, 1649152283U, + 1493851484U, 1246520657U, 2221159044U, 1973511823U, + 384136800U, 214358653U, 2379473940U, 4269788650U, + 2864377005U, 2638630052U, 427683330U, 990491717U, + 1747111141U, 792127364U, 2599214128U, 2553037199U, + 2509838425U }; + static uint32_t md5_values[]= { 3195025439U, 2556848621U, 3724893440U, 3332385401U, 245758794U, 2550894432U, 121710495U, 3053817768U, 1250994555U, 1862072655U, 2631955953U, 2951528551U, diff --git a/tests/hashkit_functions.c b/tests/hashkit_functions.c index aa4e82f0..16cd2c74 100644 --- a/tests/hashkit_functions.c +++ b/tests/hashkit_functions.c @@ -37,13 +37,10 @@ static test_return_t init_test(void *not_used __attribute__((unused))) hashk_ptr= hashkit_create(&hashk); test_true(hashk_ptr); test_true(hashk_ptr == &hashk); - test_true(hashkit_is_initialized(&hashk) == true); test_true(hashkit_is_allocated(hashk_ptr) == false); hashkit_free(hashk_ptr); - test_true(hashkit_is_initialized(&hashk) == false); - return TEST_SUCCESS; } @@ -54,7 +51,6 @@ static test_return_t allocation_test(void *not_used __attribute__((unused))) hashk_ptr= hashkit_create(NULL); test_true(hashk_ptr); test_true(hashkit_is_allocated(hashk_ptr) == true); - test_true(hashkit_is_initialized(hashk_ptr) == true); hashkit_free(hashk_ptr); return TEST_SUCCESS; @@ -66,15 +62,13 @@ static test_return_t clone_test(hashkit_st *hashk) assert(&global_hashk == hashk); // Second we test if hashk is even valid - test_true(hashkit_is_initialized(hashk) == true); /* All null? */ { hashkit_st *hashk_ptr; hashk_ptr= hashkit_clone(NULL, NULL); test_true(hashk_ptr); - test_true(hashkit_is_allocated(hashk_ptr) == true); - test_true(hashkit_is_initialized(hashk_ptr) == true); + test_true(hashkit_is_allocated(hashk_ptr)); hashkit_free(hashk_ptr); } @@ -85,22 +79,7 @@ static test_return_t clone_test(hashkit_st *hashk) hashk_ptr= hashkit_clone(NULL, hashk); test_true(hashk_ptr); - test_true(hashkit_is_allocated(hashk_ptr) == true); - test_true(hashkit_is_initialized(hashk_ptr) == true); - - test_true(hashk_ptr->distribution == hashk->distribution); - test_true(hashk_ptr->continuum_count == hashk->continuum_count); - test_true(hashk_ptr->continuum_points_count == hashk->continuum_points_count); - test_true(hashk_ptr->list_size == hashk->list_size); - test_true(hashk_ptr->context_size == hashk->context_size); - test_true(hashk_ptr->continuum == NULL); - test_true(hashk_ptr->hash_fn == hashk->hash_fn); - test_true(hashk_ptr->active_fn == hashk->active_fn); - test_true(hashk_ptr->continuum_hash_fn == hashk->continuum_hash_fn); - test_true(hashk_ptr->continuum_key_fn == hashk->continuum_key_fn); - test_true(hashk_ptr->sort_fn == hashk->sort_fn); - test_true(hashk_ptr->weight_fn == hashk->weight_fn); - test_true(hashk_ptr->list == hashk->list); + test_true(hashkit_is_allocated(hashk_ptr)); hashkit_free(hashk_ptr); } @@ -112,6 +91,8 @@ static test_return_t clone_test(hashkit_st *hashk) hash_clone= hashkit_clone(&declared_clone, NULL); test_true(hash_clone); + test_true(hash_clone == &declared_clone); + test_false(hashkit_is_allocated(hash_clone)); hashkit_free(hash_clone); } @@ -120,15 +101,33 @@ static test_return_t clone_test(hashkit_st *hashk) { hashkit_st declared_clone; hashkit_st *hash_clone; - memset(&declared_clone, 0 , sizeof(hashkit_st)); + hash_clone= hashkit_clone(&declared_clone, hashk); test_true(hash_clone); + test_true(hash_clone == &declared_clone); + test_false(hashkit_is_allocated(hash_clone)); + hashkit_free(hash_clone); } return TEST_SUCCESS; } +static test_return_t one_at_a_time_run (hashkit_st *hashk __attribute__((unused))) +{ + uint32_t x; + const char **ptr; + + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) + { + uint32_t hash_val; + + hash_val= hashkit_one_at_a_time(*ptr, strlen(*ptr)); + test_true(one_at_a_time_values[x] == hash_val); + } + + return TEST_SUCCESS; +} static test_return_t md5_run (hashkit_st *hashk __attribute__((unused))) { @@ -298,7 +297,37 @@ test_st allocation[]= { {0, 0, 0} }; +static test_return_t hashkit_generate_value_test(hashkit_st *hashk) +{ + uint32_t value; + value= hashkit_generate_value(hashk, "a", sizeof("a")); + + return TEST_SUCCESS; +} + +test_st hashkit_st_functions[] ={ + {"hashkit_generate_value", 0, (test_callback_fn)hashkit_generate_value_test}, + {0, 0, 0} +}; + +static test_return_t libhashkit_generate_value_test(hashkit_st *hashk) +{ + uint32_t value; + + (void)hashk; + + value= libhashkit_generate_value("a", sizeof("a"), HASHKIT_HASH_DEFAULT); + + return TEST_SUCCESS; +} + +test_st library_functions[] ={ + {"libhashkit_generate_value", 0, (test_callback_fn)libhashkit_generate_value_test}, + {0, 0, 0} +}; + test_st hash_tests[] ={ + {"one_at_a_time", 0, (test_callback_fn)one_at_a_time_run }, {"md5", 0, (test_callback_fn)md5_run }, {"crc", 0, (test_callback_fn)crc_run }, {"fnv1_64", 0, (test_callback_fn)fnv1_64_run }, @@ -323,8 +352,10 @@ test_st regression[]= { collection_st collection[] ={ {"allocation", 0, 0, allocation}, - {"regression", 0, 0, regression}, + {"hashkit_st_functions", 0, 0, hashkit_st_functions}, + {"library_functions", 0, 0, library_functions}, {"hashing", 0, 0, hash_tests}, + {"regression", 0, 0, regression}, {0, 0, 0, 0} }; @@ -344,25 +375,12 @@ void *world_create(test_return_t *error) return NULL; } - // First we test if hashk is even valid - if (hashkit_is_initialized(hashk_ptr) == false) - { - *error= TEST_FAILURE; - return NULL; - } - if (hashkit_is_allocated(hashk_ptr) == true) { *error= TEST_FAILURE; return NULL; } - if (hashk_ptr->continuum != NULL) - { - *error= TEST_FAILURE; - return NULL; - } - *error= TEST_SUCCESS; return hashk_ptr; @@ -372,7 +390,6 @@ void *world_create(test_return_t *error) test_return_t world_destroy(hashkit_st *hashk) { // Did we get back what we expected? - assert(hashkit_is_initialized(hashk) == true); assert(hashkit_is_allocated(hashk) == false); hashkit_free(&global_hashk); diff --git a/tests/mem_functions.c b/tests/mem_functions.c index 14550dcb..4c1b56b5 100644 --- a/tests/mem_functions.c +++ b/tests/mem_functions.c @@ -4911,6 +4911,22 @@ static test_return_t hsieh_avaibility_test (memcached_st *memc) return TEST_SUCCESS; } +static test_return_t one_at_a_time_run (memcached_st *memc __attribute__((unused))) +{ + uint32_t x; + const char **ptr; + + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) + { + uint32_t hash_val; + + hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_DEFAULT); + test_true(one_at_a_time_values[x] == hash_val); + } + + return TEST_SUCCESS; +} + static test_return_t md5_run (memcached_st *memc __attribute__((unused))) { uint32_t x; @@ -5978,6 +5994,7 @@ test_st ketama_auto_eject_hosts[] ={ }; test_st hash_tests[] ={ + {"one_at_a_time_run", 0, (test_callback_fn)one_at_a_time_run }, {"md5", 0, (test_callback_fn)md5_run }, {"crc", 0, (test_callback_fn)crc_run }, {"fnv1_64", 0, (test_callback_fn)fnv1_64_run },