nfs-ganesha 1.4

HashTable.h

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Copyright CEA/DAM/DIF  (2008)
00005  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00006  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
00007  *
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 3 of the License, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00022  * 02110-1301 USA
00023  *
00024  * ---------------------------------------
00025  */
00026 
00035 #ifndef _HASHTABLE_H
00036 #define _HASHTABLE_H
00037 
00038 #include <rbt_node.h>
00039 #include <rbt_tree.h>
00040 #include <pthread.h>
00041 #include "HashData.h"
00042 #include "log.h"
00043 #include "lookup3.h"
00044 #include "abstract_mem.h"
00045 
00046 #ifndef TRUE
00047 #define TRUE 1
00048 #endif
00049 
00050 #ifndef FALSE
00051 #define FALSE 0
00052 #endif
00053 
00059 /* Forward declaration */
00060 
00061 typedef struct hash_param hash_parameter_t;
00062 
00063 typedef uint32_t (*index_function_t)(struct hash_param *,
00064                                      struct hash_buff *);
00065 typedef uint64_t (*rbthash_function_t)(struct hash_param *,
00066                                        struct hash_buff *);
00067 typedef int (*both_function_t)(struct hash_param *,
00068                                struct hash_buff *,
00069                                uint32_t *,
00070                                uint64_t *);
00071 typedef int (*hash_buff_comparator_t)(struct hash_buff *,
00072                                        struct hash_buff *);
00073 typedef int (*key_display_function_t)(struct hash_buff *,
00074                                        char *);
00075 typedef int (*val_display_function_t)(struct hash_buff*,
00076                                        char *);
00077 
00078 
00084 #define HT_FLAG_NONE 0x0000
00085 #define HT_FLAG_CACHE 0x0001
00086 
00087 struct hash_param
00088 {
00089      uint32_t flags; /*< Create flags */
00090      uint32_t cache_entry_count; /*< 2^10 <= Power of 2 <= 2^15 */
00091      uint32_t index_size; /*< Number of partition trees, this MUST be a
00092                               prime number. */
00093      uint32_t alphabet_length; /*< Size of the input alphabet for
00094                                    the template (and other polynomial
00095                                    style) hash functions. */
00096      index_function_t hash_func_key; /*< Partition function, returns an
00097                                          integer from 0 to (index_size
00098                                          - 1).  This should be
00099                                          something fairly simple and
00100                                          fast with a uniform
00101                                          distribution. */
00102      rbthash_function_t hash_func_rbt; /*< The actual hash value,
00103                                            termining location within
00104                                            the partition tree. This
00105                                            should be a high quality
00106                                            hash function such as
00107                                            64 bit Lookup3 or Murmur. */
00108      both_function_t hash_func_both; /*< Index and partition calcualtor.
00109                                          Returns false on
00110                                          failure. A single function
00111                                          may replace the partition
00112                                          and hash funcions. */
00113      hash_buff_comparator_t compare_key; /*< Function to compare two
00114                                              keys.  This function
00115                                              returns 0 on equality. */
00116      key_display_function_t key_to_str; /*< Function to convert a key
00117                                             to a string. */
00118      val_display_function_t val_to_str; /*< Function to convert a
00119                                             value to a string. */
00120      char *ht_name; /*< Name of this hash table. */
00121      log_components_t ht_log_component; /*< Log component to use for this
00122                                             hash table */
00123 };
00124 
00125 typedef struct hash_stat
00126 {
00127      size_t entries; /*< Number of entries in the hash table */
00128      size_t min_rbt_num_node; /*< Minimum size (in number of
00129                                   nodes) of the rbt used. */
00130      size_t max_rbt_num_node; /*< Maximum size (in number of
00131                                   nodes) of the rbt used. */
00132      size_t average_rbt_num_node;  /*< Average size (in number
00133                                        of nodes) of the rbt used. */
00134 } hash_stat_t;
00135 
00143 struct hash_partition
00144 {
00145      size_t count; /*< Numer of entries in this partition */
00146      struct rbt_head rbt; /*< The red-black tree */
00147      pthread_rwlock_t lock; /*< Lock for this partition */
00148      struct rbt_node** cache; /*< expected entry cache */
00149 };
00150 
00151 typedef struct hash_table
00152 {
00153      struct hash_param parameter; /*< Definitive parameter for the
00154                                       HashTable */
00155      pool_t *node_pool; /*< Pool of RBT nodes */
00156      pool_t *data_pool; /*< Pool of buffer pairs */
00157      struct hash_partition partitions[]; /*< Parameter.index_size partitions of
00158                                              the hash table. */
00159 } hash_table_t;
00160 
00161 struct hash_latch {
00162      uint32_t index; /*< Saved partition index */
00163      uint64_t rbt_hash; /*< Saved red-black hash */
00164      struct rbt_node *locator; /*< Saved location in the tree */
00165 };
00166 
00167 typedef enum hash_set_how {
00168      HASHTABLE_SET_HOW_TEST_ONLY = 1,
00169      HASHTABLE_SET_HOW_SET_OVERWRITE = 2,
00170      HASHTABLE_SET_HOW_SET_NO_OVERWRITE = 3
00171 } hash_set_how_t;
00172 
00173 /* @} */
00174 
00175 /* How many character used to display a key or value */
00176 static const size_t HASHTABLE_DISPLAY_STRLEN = 8192;
00177 
00178 /* Possible errors */
00179 typedef enum hash_error {
00180      HASHTABLE_SUCCESS = 0,
00181      HASHTABLE_UNKNOWN_HASH_TYPE = 1,
00182      HASHTABLE_INSERT_MALLOC_ERROR = 2,
00183      HASHTABLE_ERROR_NO_SUCH_KEY = 3,
00184      HASHTABLE_ERROR_KEY_ALREADY_EXISTS = 4,
00185      HASHTABLE_ERROR_INVALID_ARGUMENT = 5,
00186      HASHTABLE_ERROR_DELALL_FAIL = 6,
00187      HASHTABLE_NOT_DELETED = 7,
00188      HASHTABLE_OVERWRITTEN = 8
00189 } hash_error_t;
00190 
00191 const char *hash_table_err_to_str(hash_error_t err);
00192 
00193 /* These are the primitives of the hash table */
00194 
00195 struct hash_table *HashTable_Init(struct hash_param *hparam);
00196 hash_error_t HashTable_Destroy(struct hash_table *ht,
00197                                int (*free_func)(struct hash_buff,
00198                                                 struct hash_buff));
00199 hash_error_t HashTable_GetLatch(struct hash_table *ht,
00200                                 struct hash_buff *key,
00201                                 struct hash_buff *val,
00202                                 int may_write,
00203                                 struct hash_latch *latch);
00204 void HashTable_ReleaseLatched(struct hash_table *ht,
00205                               struct hash_latch *latch);
00206 hash_error_t HashTable_SetLatched(struct hash_table *ht,
00207                                   struct hash_buff *key,
00208                                   struct hash_buff *val,
00209                                   struct hash_latch *latch,
00210                                   int overwrite,
00211                                   struct hash_buff *stored_key,
00212                                   struct hash_buff *stored_val);
00213 hash_error_t HashTable_DeleteLatched(struct hash_table *ht,
00214                                      struct hash_buff *key,
00215                                      struct hash_latch *latch,
00216                                      struct hash_buff *stored_key,
00217                                      struct hash_buff *stored_val);
00218 hash_error_t HashTable_Delall(struct hash_table *ht,
00219                               int (*free_func)(struct hash_buff,
00220                                                struct hash_buff));
00221 
00222 void HashTable_GetStats(struct hash_table *ht,
00223                         struct hash_stat *hstat);
00224 size_t HashTable_GetSize(struct hash_table *ht);
00225 void HashTable_Log(log_components_t component, struct hash_table *ht);
00226 
00227 /* These are very simple wrappers around the primitives */
00228 
00243 static inline hash_error_t
00244 HashTable_Get(struct hash_table *ht,
00245               struct hash_buff *key,
00246               struct hash_buff *val)
00247 {
00248      return HashTable_GetLatch(ht, key, val, FALSE, NULL);
00249 } /* HashTable_Get */
00250 
00268 static inline hash_error_t
00269 HashTable_Set(struct hash_table *ht,
00270               struct hash_buff *key,
00271               struct hash_buff *val)
00272 {
00273      /* structure to hold retained state */
00274      struct hash_latch latch;
00275      /* Stored return code */
00276      hash_error_t rc = HASHTABLE_SUCCESS;
00277 
00278      rc = HashTable_GetLatch(ht, key, NULL,
00279                              TRUE,
00280                              &latch);
00281 
00282      if ((rc != HASHTABLE_SUCCESS) &&
00283          (rc != HASHTABLE_ERROR_NO_SUCH_KEY)) {
00284           return rc;
00285      }
00286 
00287      rc = HashTable_SetLatched(ht,
00288                                key,
00289                                val,
00290                                &latch,
00291                                FALSE,
00292                                NULL,
00293                                NULL);
00294 
00295      return rc;
00296 } /* HashTable_Set */
00297 
00298 
00313 static inline hash_error_t
00314 HashTable_Del(struct hash_table *ht,
00315               struct hash_buff *key,
00316               struct hash_buff *stored_key,
00317               struct hash_buff *stored_val)
00318 {
00319      /* Structure to hold retained state */
00320      struct hash_latch latch;
00321      /* Stored return code */
00322      hash_error_t rc = HASHTABLE_SUCCESS;
00323 
00324      rc = HashTable_GetLatch(ht, key, NULL,
00325                              TRUE, &latch);
00326 
00327      switch (rc) {
00328      case HASHTABLE_SUCCESS:
00329           return HashTable_DeleteLatched(ht,
00330                                          key,
00331                                          &latch,
00332                                          stored_key,
00333                                          stored_val);
00334 
00335      case HASHTABLE_ERROR_NO_SUCH_KEY:
00336           HashTable_ReleaseLatched(ht, &latch);
00337      default:
00338           return rc;
00339      }
00340 }
00341 
00342 /* These are the prototypes for large wrappers implementing more
00343    complex semantics on top of the primitives. */
00344 
00345 hash_error_t HashTable_Test_And_Set(struct hash_table *ht,
00346                                     struct hash_buff *key,
00347                                     struct hash_buff *val,
00348                                     enum hash_set_how how);
00349 hash_error_t HashTable_GetRef(struct hash_table *ht,
00350                               struct hash_buff *key,
00351                               struct hash_buff *val,
00352                               void (*get_ref)(struct hash_buff *));
00353 
00354 hash_error_t HashTable_Get_and_Del(struct hash_table  *ht,
00355                                    struct hash_buff *key,
00356                                    struct hash_buff *val,
00357                                    struct hash_buff *stored_key);
00358 hash_error_t HashTable_DelRef(struct hash_table *ht,
00359                               struct hash_buff *key,
00360                               struct hash_buff *stored_key,
00361                               struct hash_buff *stored_val,
00362                               int (*put_ref)(struct hash_buff *));
00363 hash_error_t HashTable_DelSafe(hash_table_t *ht,
00364                                hash_buffer_t *key,
00365                                hash_buffer_t *val);
00366 
00367 #endif                          /* _HASHTABLE_H */