poldek: trurlib/libtrurl.sym, trurlib/n_hash_get.c, trurlib/n_hash...

mis mis at pld-linux.org
Thu Jul 12 22:46:31 CEST 2007


Author: mis                          Date: Thu Jul 12 20:46:31 2007 GMT
Module: poldek                        Tag: HEAD
---- Log message:
- _ex() functions and cleanups

---- Files affected:
poldek/trurlib:
   libtrurl.sym (1.3 -> 1.4) , n_hash_get.c (1.3 -> 1.4) , n_hash_int.h (1.9 -> 1.10) , n_hash_put.c (1.7 -> 1.8) , n_hash_stats.c (1.3 -> 1.4) , n_hash_new.c (1.12 -> 1.13) 
poldek/trurlib/include/trurl:
   nhash.h (1.13 -> 1.14) 

---- Diffs:

================================================================
Index: poldek/trurlib/libtrurl.sym
diff -u poldek/trurlib/libtrurl.sym:1.3 poldek/trurlib/libtrurl.sym:1.4
--- poldek/trurlib/libtrurl.sym:1.3	Sun Aug 20 16:08:17 2006
+++ poldek/trurlib/libtrurl.sym	Thu Jul 12 22:46:26 2007
@@ -73,10 +73,12 @@
 n_hash_dump
 n_hash_dup
 n_hash_exists
+n_hash_exists_ex
 n_hash_free
 n_hash_get
-n_hash_get_bucket
+n_hash_get_ex
 n_hash_insert
+n_hash_insert_ex
 n_hash_keys
 n_hash_keys_ext
 n_hash_map

================================================================
Index: poldek/trurlib/n_hash_get.c
diff -u poldek/trurlib/n_hash_get.c:1.3 poldek/trurlib/n_hash_get.c:1.4
--- poldek/trurlib/n_hash_get.c:1.3	Wed Jun 23 20:11:26 2004
+++ poldek/trurlib/n_hash_get.c	Thu Jul 12 22:46:26 2007
@@ -2,49 +2,15 @@
 
 #include "n_hash_int.h"
 
-#if 0
-void *n_hash_get_ll(const tn_hash *ht, const char *key)
-{
-    unsigned val = n_hash_dohash(ht, key, NULL);
-    struct hash_bucket *ptr;
-
-    if (ht->table[val] == NULL)
-        return NULL;
-
-    for (ptr = ht->table[val]; ptr != NULL; ptr = ptr->next) {
-        if (strcmp(key, ptr->key) == 0)
-            return ptr->data;
-    }
-
-    return NULL;
-}
-
-int n_hash_exists_ll(const tn_hash *ht, const char *key) 
-{
-    unsigned val = n_hash_dohash(ht, key, NULL);
-    struct hash_bucket *ptr;
-
-    if (NULL == ht->table[val])
-        return 0;
-
-    for (ptr = ht->table[val]; NULL != ptr; ptr = ptr->next) {
-        if (0 == strcmp(key, ptr->key))
-            return 1;
-    }
-    
-    return 0;
-}
-#endif
-
 static inline
 struct hash_bucket *get_bucket_ll(struct hash_bucket **tbl,
-                                         const char *key, unsigned val)
+                                         const char *key, unsigned khash)
 {
     struct hash_bucket *ptr;
 
-    n_assert (tbl[val] != NULL);
+    n_assert (tbl[khash] != NULL);
     
-    for (ptr = tbl[val]; ptr != NULL; ptr = ptr->next) {
+    for (ptr = tbl[khash]; ptr != NULL; ptr = ptr->next) {
         if (strcmp(key, ptr->key) == 0)
             return ptr;
     }
@@ -53,41 +19,55 @@
 
 
 struct hash_bucket *n_hash_get_bucket(const tn_hash *ht,
-                                      const char *key, int klen, unsigned val)
+                                      const char *key, int klen, unsigned khash)
 {
     struct hash_bucket **tbl, *ptr = NULL;
     tbl = ht->table;
     
-    if (tbl[val] != NULL)
-        ptr = get_bucket_ll(tbl, key, val);
+    if (tbl[khash] != NULL)
+        ptr = get_bucket_ll(tbl, key, khash);
 
     if (ptr == NULL) {
-        val += n_hash_nextslotv(key, klen);
-        if (val < ht->size && tbl[val])
-            ptr = get_bucket_ll(tbl, key, val);
+        khash += n_hash_nextslotv(key, klen);
+        if (khash < ht->size && tbl[khash])
+            ptr = get_bucket_ll(tbl, key, khash);
     }
 
     return ptr;
 }
 
-void *n_hash_get(const tn_hash *ht, const char *key) 
+void *n_hash_get_ex(const tn_hash *ht,
+                    const char *key, int *klen, unsigned *khash)
 {
     struct hash_bucket *ptr;
-    unsigned val;
-    int klen;
     
-    val = n_hash_dohash(ht, key, &klen);
-    ptr = n_hash_get_bucket(ht, key, klen, val);
+    *khash = n_hash_dohash(ht, key, klen);
+    ptr = n_hash_get_bucket(ht, key, *klen, *khash);
     return ptr ? ptr->data : NULL;
 }
 
+
+void *n_hash_get(const tn_hash *ht, const char *key) 
+{
+    unsigned khash;
+    int klen;
+
+    return n_hash_get_ex(ht, key, &klen, &khash);
+}
+
+int n_hash_exists_ex(const tn_hash *ht, const char *key, int *klen,
+                     unsigned *khash)
+{
+    *khash = n_hash_dohash(ht, key, klen);
+    return n_hash_get_bucket(ht, key, *klen, *khash) != NULL;
+}
+
 int n_hash_exists(const tn_hash *ht, const char *key) 
 {
-    unsigned val;
     int klen;
+    unsigned khash;
     
-    val = n_hash_dohash(ht, key, &klen);
-    return n_hash_get_bucket(ht, key, klen, val) != NULL;
+    return n_hash_exists_ex(ht, key, &klen, &khash);
 }
 
     

================================================================
Index: poldek/trurlib/n_hash_int.h
diff -u poldek/trurlib/n_hash_int.h:1.9 poldek/trurlib/n_hash_int.h:1.10
--- poldek/trurlib/n_hash_int.h:1.9	Sat Aug 19 19:34:19 2006
+++ poldek/trurlib/n_hash_int.h	Thu Jul 12 22:46:26 2007
@@ -62,3 +62,6 @@
 
 struct hash_bucket *n_hash_get_bucket(const tn_hash *ht,
                                       const char *key, int klen, unsigned val);
+
+int n_hash_exists_ex(const tn_hash *ht, const char *key, int *klen,
+                     unsigned *khash);

================================================================
Index: poldek/trurlib/n_hash_put.c
diff -u poldek/trurlib/n_hash_put.c:1.7 poldek/trurlib/n_hash_put.c:1.8
--- poldek/trurlib/n_hash_put.c:1.7	Wed Jul 14 20:48:44 2004
+++ poldek/trurlib/n_hash_put.c	Thu Jul 12 22:46:26 2007
@@ -153,19 +153,19 @@
 #endif
 
 static
-tn_hash *n_hash_put(tn_hash *ht, const char *key, const void *data, int replace)
+tn_hash *n_hash_put(tn_hash *ht, const char *key, int klen, unsigned khash,
+                    const void *data, int replace)
 {
     struct hash_bucket *ptr;
-    unsigned val;
-    int klen;
     
     if ((ht->flags & TN_HASH_REHASH) && ht->size - ht->items <= ht->size / 3)
         n_hash_rehash(ht);
 
-    val = n_hash_dohash(ht, key, &klen);
+    if (!khash)
+        khash = n_hash_dohash(ht, key, &klen);
 
     if ((ht->flags & TN_HASH_NOREPLACE) == 0) {
-        ptr = n_hash_get_bucket(ht, key, klen, val);
+        ptr = n_hash_get_bucket(ht, key, klen, khash);
         if (ptr) {
             if (!replace) {
                 trurl_die("n_hash_insert: key '%s' %s already in table\n",
@@ -180,13 +180,13 @@
         }
     }
 
-    ptr = ht->table[val];
+    ptr = ht->table[khash];
     if (ptr != NULL && ptr->next) {
-        unsigned nextval = val + n_hash_nextslotv(key, klen);
+        unsigned nextval = khash + n_hash_nextslotv(key, klen);
         if (nextval < ht->size) {
             if ((ptr = ht->table[nextval]) == NULL) {
-                DBGF("%d. nextmove(%d) %s[%d]\n", moves++, val, key, klen);
-                val = nextval;
+                DBGF("%d. nextmove(%d) %s[%d]\n", moves++, khash, key, klen);
+                khash = nextval;
             }
         }
     }
@@ -196,13 +196,13 @@
         ptr = new_bucket(ht, key, klen);
         ptr->next = NULL;
         ptr->data = (void *) data;
-        ht->table[val] = ptr;
+        ht->table[khash] = ptr;
         ht->items++;
         return ht;
     }
 
     DBGF("INUSE %s, ", key);
-    for (ptr = ht->table[val]; NULL != ptr; ptr = ptr->next) {
+    for (ptr = ht->table[khash]; NULL != ptr; ptr = ptr->next) {
         DBGF("%s, ", ptr->key);
         if (strcmp(key, ptr->key) == 0) {
             trurl_die("n_hash_insert: key '%s' %s already in table\n",
@@ -213,8 +213,8 @@
 
     ptr = new_bucket(ht, key, klen);
     ptr->data = (void *) data;
-    ptr->next = ht->table[val];
-    ht->table[val] = ptr;
+    ptr->next = ht->table[khash];
+    ht->table[khash] = ptr;
     ht->items++;
     
     return ht;
@@ -222,9 +222,10 @@
 
 tn_hash *n_hash_insert(tn_hash *ht, const char *key, const void *data)
 {
-    return n_hash_put(ht, key, data, 0);
+    return n_hash_put(ht, key, 0, 0, data, 0);
 }
 
+
 tn_hash *n_hash_replace(tn_hash *ht, const char *key, const void *data)
 {
     if (ht->flags & TN_HASH_NOREPLACE) {
@@ -232,5 +233,12 @@
                   " \"non-replace\" hash table");
         return NULL;
     }
-    return n_hash_put(ht, key, data, 1);
+    return n_hash_put(ht, key, 0, 0, data, 1);
+}
+
+
+tn_hash *n_hash_insert_ex(tn_hash *ht, const char *key, int klen, unsigned khash,
+                          const void *data)
+{
+    return n_hash_put(ht, key, klen, khash, data, 0);
 }

================================================================
Index: poldek/trurlib/n_hash_stats.c
diff -u poldek/trurlib/n_hash_stats.c:1.3 poldek/trurlib/n_hash_stats.c:1.4
--- poldek/trurlib/n_hash_stats.c:1.3	Tue Jun 22 20:57:31 2004
+++ poldek/trurlib/n_hash_stats.c	Thu Jul 12 22:46:26 2007
@@ -31,8 +31,15 @@
         
         
         deep = 1;
-        for (tmp = ht->table[i]->next; tmp != NULL; tmp = tmp->next) 
+        //if (ht->table[i]->next)
+        //    printf("coll %s, ", ht->table[i]->key);
+        
+        for (tmp = ht->table[i]->next; tmp != NULL; tmp = tmp->next) {
+            //printf("%s, ", tmp->key);
             deep++;
+        }
+        //if (ht->table[i]->next)
+        //    printf("\n");
         
         if (deep > 1) {
             ncolls++;

================================================================
Index: poldek/trurlib/n_hash_new.c
diff -u poldek/trurlib/n_hash_new.c:1.12 poldek/trurlib/n_hash_new.c:1.13
--- poldek/trurlib/n_hash_new.c:1.12	Sat Aug 19 19:34:19 2006
+++ poldek/trurlib/n_hash_new.c	Thu Jul 12 22:46:26 2007
@@ -67,30 +67,52 @@
     return n_hash_new2(na, size, freefn);
 }
 
+/* djb hash */
 # define CDB_HASHSTART 5381
 int n_hash_dohash(const tn_hash *ht, const char *s, int *slen)
 {
-    register unsigned int v, n;
-
+    register unsigned int v;
+    const char *ss = s;
+    
     if (ht->hash_fn)
         return ht->hash_fn(s) % ht->size;
-        
-    
+
     v = CDB_HASHSTART;
-    n = 0;
     while (*s) {
         v += (v << 5);
-        v ^= *s;
+        v ^= (unsigned)*s;
         s++;
-        n++;
     }
+
     if (slen)
-        *slen = n;
-    //v += n;
+        *slen = s - ss;
+
     return v & (ht->size - 1);
 }
 
+#if 0                           /* disabled */
+/*
+  FNV hash (see http://www.isthe.com/chongo/tech/comp/fnv)
+  A bit slower and gives a bit lower collision rate than djb's
+*/
+int n_hash_dohash(const tn_hash *ht, const char *s, int *slen)
+{
+    register unsigned v = 0;
+    const char *ss = s;
+    
+    while (*s) {
+        /* xor the bottom with the current octet */
+        v ^= (unsigned)*s++;
+        // v += (v<<1) + (v<<4) + (v<<7) + (v<<8) + (v<<24);
+        v *= 0x01000193;
+    }
+    
+    if (slen)
+        *slen = s - ss;
 
+    return v & (ht->size - 1);
+}
+#endif
 
 int n_hash_size(const tn_hash *ht) 
 {

================================================================
Index: poldek/trurlib/include/trurl/nhash.h
diff -u poldek/trurlib/include/trurl/nhash.h:1.13 poldek/trurlib/include/trurl/nhash.h:1.14
--- poldek/trurlib/include/trurl/nhash.h:1.13	Fri Jul 23 18:15:54 2004
+++ poldek/trurlib/include/trurl/nhash.h	Thu Jul 12 22:46:26 2007
@@ -35,37 +35,47 @@
                                         if filled more than 80%  */
 #define TN_HASH_NOREPLACE  (1 << 3)  /* don't check for duplicate keys
                                         while inserting; use with care! */
-int n_hash_ctl(tn_hash *ht, unsigned int flags);
-
-//int n_hash_ctl_bktallocfn(tn_hash *ht, );
 
+int n_hash_ctl(tn_hash *ht, unsigned int flags);
 
 /* Removes all entries */
 void n_hash_clean(tn_hash *ht);
 
 
 /*
-** Inserts a pointer to 'data' in the table, with a copy of 'key' 
-** (if TN_HASH_NOCPKEY not set) as its key.  Note that this makes 
-** a copy of the key, but NOT of the associated data.
+  Inserts a pointer to 'data' in the table, with a copy of 'key' 
+  (if TN_HASH_NOCPKEY not set) as its key.  Note that this makes 
+  a copy of the key, but NOT of the associated data.
 */
 
 tn_hash *n_hash_insert(tn_hash *ht, const char *key, const void *data);
+
 tn_hash *n_hash_replace(tn_hash *ht, const char *key, const void *data);
 
+
 /*
-** Returns a pointer to the data associated with a key.
+  Returns a pointer to the data associated with a key.
 */
-
 void *n_hash_get(const tn_hash *ht, const char *key);
 
 
+int n_hash_exists(const tn_hash *ht, const char *key);
+
+
 /*
-** If the key has not been inserted in the table, returns 0,
-** otherwise returns 1.
-*/
+  lower level insert / exists pair to avoid double computation of key hash
+ */
+void *n_hash_get_ex(const tn_hash *ht,
+                    const char *key, int *klen, unsigned *khash);
+
+int n_hash_exists_ex(const tn_hash *ht,
+                     const char *key, int *klen, unsigned *khash);
+
+tn_hash *n_hash_insert_ex(tn_hash *ht,
+                          const char *key, int klen, unsigned khash,
+                          const void *data);
+
 
-int n_hash_exists(const tn_hash *ht, const char *key);
 
 /*
 ** Deletes an entry from the table.  Returns a pointer to the data that
================================================================

---- CVS-web:
    http://cvs.pld-linux.org/poldek/trurlib/libtrurl.sym?r1=1.3&r2=1.4&f=u
    http://cvs.pld-linux.org/poldek/trurlib/n_hash_get.c?r1=1.3&r2=1.4&f=u
    http://cvs.pld-linux.org/poldek/trurlib/n_hash_int.h?r1=1.9&r2=1.10&f=u
    http://cvs.pld-linux.org/poldek/trurlib/n_hash_put.c?r1=1.7&r2=1.8&f=u
    http://cvs.pld-linux.org/poldek/trurlib/n_hash_stats.c?r1=1.3&r2=1.4&f=u
    http://cvs.pld-linux.org/poldek/trurlib/n_hash_new.c?r1=1.12&r2=1.13&f=u
    http://cvs.pld-linux.org/poldek/trurlib/include/trurl/nhash.h?r1=1.13&r2=1.14&f=u



More information about the pld-cvs-commit mailing list