From: Brian Aker Date: Tue, 19 Jan 2010 23:18:01 +0000 (-0800) Subject: Updated for custom hash functions/setting functions. X-Git-Tag: 0.40~78 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=98d4dea6ae8869b6fe5e37a2908d66ff062b8f39;p=m6w6%2Flibmemcached Updated for custom hash functions/setting functions. --- diff --git a/libhashkit/hashkit.c b/libhashkit/hashkit.c index a87e712b..64158f98 100644 --- a/libhashkit/hashkit.c +++ b/libhashkit/hashkit.c @@ -10,7 +10,6 @@ static const hashkit_st global_default_hash= { .base_hash= { - .type= HASHKIT_HASH_DEFAULT, .function= hashkit_one_at_a_time, .context= NULL }, @@ -80,6 +79,68 @@ uint32_t hashkit_generate_value(const hashkit_st *self, const char *key, size_t return self->base_hash.function(key, key_length); } +hashkit_return_t hashkit_set_base_function(hashkit_st *self, hashkit_hash_algorithm_t hash_algorithm) +{ + switch (hash_algorithm) + { + 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: + return HASHKIT_FAILURE; + break; + } + + self->base_hash.context= NULL; + + return HASHKIT_SUCCESS; +} + +hashkit_return_t hashkit_set_base_function_custom(hashkit_st *self, hashkit_hash_fn function, void *context) +{ + if (function) + { + self->base_hash.function= function; + self->base_hash.context= context; + + return HASHKIT_SUCCESS; + } + + return HASHKIT_FAILURE; +} + uint32_t libhashkit_generate_value(const char *key, size_t key_length, hashkit_hash_algorithm_t hash_algorithm) { switch (hash_algorithm) diff --git a/libhashkit/hashkit.h b/libhashkit/hashkit.h index 173f4d9c..68709358 100644 --- a/libhashkit/hashkit.h +++ b/libhashkit/hashkit.h @@ -27,7 +27,6 @@ extern "C" { struct hashkit_st { struct { - hashkit_hash_algorithm_t type; hashkit_hash_fn function; void *context; } base_hash; @@ -49,6 +48,12 @@ void hashkit_free(hashkit_st *hash); HASHKIT_API uint32_t hashkit_generate_value(const hashkit_st *self, const char *key, size_t key_length); +HASHKIT_API +hashkit_return_t hashkit_set_base_function(hashkit_st *hash, hashkit_hash_algorithm_t hash_algorithm); + +HASHKIT_API +hashkit_return_t hashkit_set_base_function_custom(hashkit_st *hash, hashkit_hash_fn function, void *context); + HASHKIT_API uint32_t libhashkit_generate_value(const char *key, size_t key_length, hashkit_hash_algorithm_t hash_algorithm); diff --git a/libhashkit/strerror.h b/libhashkit/strerror.h index 4cb91972..f78a4838 100644 --- a/libhashkit/strerror.h +++ b/libhashkit/strerror.h @@ -13,7 +13,8 @@ extern "C" { #endif -const char *hashkit_strerror(hashkit_st *ptr __attribute__((unused)), hashkit_return_t rc); +HASHKIT_API + const char *hashkit_strerror(hashkit_st *ptr __attribute__((unused)), hashkit_return_t rc); #ifdef __cplusplus } diff --git a/tests/hashkit_functions.c b/tests/hashkit_functions.c index 16cd2c74..0e4a894d 100644 --- a/tests/hashkit_functions.c +++ b/tests/hashkit_functions.c @@ -305,8 +305,99 @@ static test_return_t hashkit_generate_value_test(hashkit_st *hashk) return TEST_SUCCESS; } +static test_return_t hashkit_set_base_function_test(hashkit_st *hashk) +{ + for (hashkit_hash_algorithm_t algo = HASHKIT_HASH_DEFAULT; algo < HASHKIT_HASH_MAX; algo++) + { + hashkit_return_t rc; + uint32_t x; + const char **ptr; + uint32_t *list; + + rc= hashkit_set_base_function(hashk, algo); + + /* Hsieh is disabled most of the time for patent issues */ + if (rc == HASHKIT_FAILURE && algo == HASHKIT_HASH_HSIEH) + continue; + + test_true(rc == HASHKIT_SUCCESS); + + switch (algo) + { + case HASHKIT_HASH_DEFAULT: + list= one_at_a_time_values; + break; + case HASHKIT_HASH_MD5: + list= md5_values; + break; + case HASHKIT_HASH_CRC: + list= crc_values; + break; + case HASHKIT_HASH_FNV1_64: + list= fnv1_64_values; + break; + case HASHKIT_HASH_FNV1A_64: + list= fnv1a_64_values; + break; + case HASHKIT_HASH_FNV1_32: + list= fnv1_32_values; + break; + case HASHKIT_HASH_FNV1A_32: + list= fnv1a_32_values; + break; + case HASHKIT_HASH_HSIEH: + list= hsieh_values; + break; + case HASHKIT_HASH_MURMUR: + list= murmur_values; + break; + case HASHKIT_HASH_JENKINS: + list= jenkins_values; + break; + case HASHKIT_HASH_MAX: + default: + list= NULL; + test_fail("We ended up on a non-existent hash"); + } + + // Now we make sure we did set the hash correctly. + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) + { + uint32_t hash_val; + + hash_val= hashkit_generate_value(hashk, *ptr, strlen(*ptr)); + test_true(list[x] == hash_val); + } + } + + return TEST_SUCCESS; +} + +static test_return_t hashkit_set_base_function_custom_test(hashkit_st *hashk) +{ + hashkit_return_t rc; + uint32_t x; + const char **ptr; + + + rc= hashkit_set_base_function_custom(hashk, hashkit_md5, NULL); + test_true(rc == HASHKIT_SUCCESS); + + for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) + { + uint32_t hash_val; + + hash_val= hashkit_generate_value(hashk, *ptr, strlen(*ptr)); + test_true(md5_values[x] == hash_val); + } + + return TEST_SUCCESS; +} + test_st hashkit_st_functions[] ={ {"hashkit_generate_value", 0, (test_callback_fn)hashkit_generate_value_test}, + {"hashkit_set_base_function", 0, (test_callback_fn)hashkit_set_base_function_test}, + {"hashkit_set_base_function_custom", 0, (test_callback_fn)hashkit_set_base_function_custom_test}, {0, 0, 0} };