Updates to libhashkit.
authorBrian Aker <brian@gaz>
Tue, 19 Jan 2010 22:37:09 +0000 (14:37 -0800)
committerBrian Aker <brian@gaz>
Tue, 19 Jan 2010 22:37:09 +0000 (14:37 -0800)
13 files changed:
libhashkit/algorithm.h
libhashkit/behavior.c
libhashkit/behavior.h
libhashkit/default.c [deleted file]
libhashkit/hashkit.c
libhashkit/hashkit.h
libhashkit/include.am
libhashkit/ketama.c
libhashkit/one_at_a_time.c [new file with mode: 0644]
libhashkit/types.h
tests/hash_results.h
tests/hashkit_functions.c
tests/mem_functions.c

index d3f576c394b7c230b43f9f3b7c28839bca96a01e..f575222e09e5245229ee1c181d0edeeac5186f91 100644 (file)
@@ -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
index 19f08b1b61bb707e701e82b3e5bb4a802867481e..683798ea5de72df0d40a1b580d00703e8b351873 100644 (file)
@@ -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;
-}
index 126a7c97d25697012362b71d5c64a0518e924e22..0ded644ca1b06963cfabd11f81128742c1b1db77 100644 (file)
  */
 
 #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 (file)
index bc0d452..0000000
+++ /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;
-}
index 54033132cb8e23c03fa6a52a99797dd85faffb1a..a87e712b19f57c482fe0e3f099e34d3198fb401e 100644 (file)
@@ -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
index 6dd08f43faa87ae39e38c94390bf5422be844a46..173f4d9ce3c095aa435947b206fdc4edd6b55852 100644 (file)
@@ -6,11 +6,6 @@
  * the COPYING file in the parent directory for full text.
  */
 
-/**
- * @file
- * @brief HashKit Header
- */
-
 #ifndef HASHKIT_H
 #define HASHKIT_H
 
 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)
index dd941f9672533f0894fad3885ae4ba92f15f8a8a..f8aa79f58d9bead690a25f8be5946fb4c5b3b1e9 100644 (file)
@@ -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
index 83b47552a1a8853f88f4863e20a49630ae49e808..a510e57ab1ea802026d185cfcde3693c1fec7633 100644 (file)
@@ -9,6 +9,7 @@
 #include "common.h"
 #include <math.h>
 
+#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 (file)
index 0000000..ab106f1
--- /dev/null
@@ -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;
+}
index a06be2fbadf368ba0c1a9f4f0c17d6fc1ce77928..fadb4d939322704d3955830c019951466afe056b 100644 (file)
@@ -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
 
 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
 }
index da00e872ef6b149f0255a0acbd7f6d0f3e62c6ba..26f1ed8531a7bf8d206ba04c18fa834ee7e27617 100644 (file)
@@ -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,
index aa4e82f07fc060dccd8315598cdeeef01f03f8b0..16cd2c746f5f29ee3d0cfeb6e1db1ffe8a3dc557 100644 (file)
@@ -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);
 
index 14550dcbf8e7445814779939aaae1a63ed28b114..4c1b56b5327816e1da01b1e64c9968c0ed5fd2f1 100644 (file)
@@ -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 },