]> sourceware.org Git - lvm2.git/commitdiff
Extend hash functions to handle non-null-terminated data.
authorAlasdair Kergon <agk@redhat.com>
Fri, 18 Jun 2004 15:08:22 +0000 (15:08 +0000)
committerAlasdair Kergon <agk@redhat.com>
Fri, 18 Jun 2004 15:08:22 +0000 (15:08 +0000)
WHATS_NEW
lib/datastruct/hash.c
lib/datastruct/hash.h

index 5b3ff48cdc60783be14aba423a15e490589fbc97..0f2d87c08b561440171e2dab6411ec4f7cef772e 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.00.17 -
 =============================
+  Extend hash functions to handle non-null-terminated data.
   Add local activation support.
   Tidy relative paths in makefile includes.
   fsadm support for fsck and resizing - needs testing.
index 7b42b1d9b293d6b607b31ed2ad67632655942b1c..a745c0fed9d7c4d6d222f6ed7f9bc34e3a504757 100644 (file)
@@ -19,7 +19,8 @@
 struct hash_node {
        struct hash_node *next;
        void *data;
-       char key[1];
+       int keylen;
+       char key[0];
 };
 
 struct hash_table {
@@ -56,22 +57,23 @@ static unsigned char _nums[] = {
        209
 };
 
-static struct hash_node *_create_node(const char *str)
+static struct hash_node *_create_node(const char *str, int len)
 {
-       /* remember sizeof(n) includes an extra char from key[1],
-          so not adding 1 to the strlen as you would expect */
-       struct hash_node *n = dbg_malloc(sizeof(*n) + strlen(str));
+       struct hash_node *n = dbg_malloc(sizeof(*n) + len);
 
-       if (n)
-               strcpy(n->key, str);
+       if (n) {
+               memcpy(n->key, str, len);
+               n->keylen = len;
+       }
 
        return n;
 }
 
-static unsigned _hash(const char *str)
+static unsigned _hash(const char *str, uint32_t len)
 {
-       unsigned long h = 0, g;
-       while (*str) {
+       unsigned long h = 0, g, i;
+
+       for (i = 0; i < len; i++) {
                h <<= 4;
                h += _nums[(int) *str++];
                g = h & ((unsigned long) 0xf << 16u);
@@ -80,6 +82,7 @@ static unsigned _hash(const char *str)
                        h ^= g >> 5u;
                }
        }
+
        return h;
 }
 
@@ -134,32 +137,35 @@ void hash_destroy(struct hash_table *t)
        dbg_free(t);
 }
 
-static struct hash_node **_find(struct hash_table *t, const char *key)
+static inline struct hash_node **_find(struct hash_table *t, const char *key,
+                                      uint32_t len)
 {
-       unsigned h = _hash(key) & (t->num_slots - 1);
+       unsigned h = _hash(key, len) & (t->num_slots - 1);
        struct hash_node **c;
 
        for (c = &t->slots[h]; *c; c = &((*c)->next))
-               if (!strcmp(key, (*c)->key))
+               if (!memcmp(key, (*c)->key, len))
                        break;
 
        return c;
 }
 
-void *hash_lookup(struct hash_table *t, const char *key)
+void *hash_lookup_binary(struct hash_table *t, const char *key,
+                        uint32_t len)
 {
-       struct hash_node **c = _find(t, key);
+       struct hash_node **c = _find(t, key, len);
        return *c ? (*c)->data : 0;
 }
 
-int hash_insert(struct hash_table *t, const char *key, void *data)
+int hash_insert_binary(struct hash_table *t, const char *key,
+                      uint32_t len, void *data)
 {
-       struct hash_node **c = _find(t, key);
+       struct hash_node **c = _find(t, key, len);
 
        if (*c)
                (*c)->data = data;
        else {
-               struct hash_node *n = _create_node(key);
+               struct hash_node *n = _create_node(key, len);
 
                if (!n)
                        return 0;
@@ -173,9 +179,10 @@ int hash_insert(struct hash_table *t, const char *key, void *data)
        return 1;
 }
 
-void hash_remove(struct hash_table *t, const char *key)
+void hash_remove_binary(struct hash_table *t, const char *key,
+                       uint32_t len)
 {
-       struct hash_node **c = _find(t, key);
+       struct hash_node **c = _find(t, key, len);
 
        if (*c) {
                struct hash_node *old = *c;
@@ -185,6 +192,21 @@ void hash_remove(struct hash_table *t, const char *key)
        }
 }
 
+void *hash_lookup(struct hash_table *t, const char *key)
+{
+       return hash_lookup_binary(t, key, strlen(key) + 1);
+}
+
+int hash_insert(struct hash_table *t, const char *key, void *data)
+{
+       return hash_insert_binary(t, key, strlen(key) + 1, data);
+}
+
+void hash_remove(struct hash_table *t, const char *key)
+{
+       hash_remove_binary(t, key, strlen(key) + 1);
+}
+
 unsigned hash_get_num_entries(struct hash_table *t)
 {
        return t->num_nodes;
@@ -235,6 +257,6 @@ struct hash_node *hash_get_first(struct hash_table *t)
 
 struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n)
 {
-       unsigned h = _hash(n->key) & (t->num_slots - 1);
+       unsigned h = _hash(n->key, n->keylen) & (t->num_slots - 1);
        return n->next ? n->next : _next_slot(t, h + 1);
 }
index de9f423b7f6d8338f30374415263d96e86370e92..2640071231660184357365546abc735b89ab245e 100644 (file)
@@ -26,10 +26,14 @@ void hash_destroy(struct hash_table *t);
 void hash_wipe(struct hash_table *t);
 
 void *hash_lookup(struct hash_table *t, const char *key);
-void *hash_lookup_fixed(struct hash_table *t, const char *key, uint32_t len);
 int hash_insert(struct hash_table *t, const char *key, void *data);
 void hash_remove(struct hash_table *t, const char *key);
 
+void *hash_lookup_binary(struct hash_table *t, const char *key, uint32_t len);
+int hash_insert_binary(struct hash_table *t, const char *key, uint32_t len,
+                      void *data);
+void hash_remove_binary(struct hash_table *t, const char *key, uint32_t len);
+
 unsigned hash_get_num_entries(struct hash_table *t);
 void hash_iter(struct hash_table *t, iterate_fn f);
 
This page took 0.048303 seconds and 5 git commands to generate.