More string and buffer functions.
[apps/madmutt.git] / lib-lib / hash.c
index 2bfc65a..c703def 100644 (file)
 
 int hash_string(const unsigned char *s, int n)
 {
-    int h = 0;
+    unsigned h = 0;
 
     while (*s) {
         h += (h << 7) + *s++;
     }
-    h = (h * SOMEPRIME) % n;
-    h = (h >= 0) ? h : h + n;
 
-    return (h % n);
+    return (h * SOMEPRIME) % n;
 }
 
-HASH *hash_create(int nelem, int allow_dup)
+hash_t *hash_init(hash_t *table, int nelem, int allow_dup)
 {
-    HASH *table = p_new(HASH, 1);
-
     table->dupes    = allow_dup;
-    table->nelem    = MIN(nelem, 2);
+    table->nelem    = MAX(nelem, 2);
     table->curnelem = 0;
     table->table    = p_new(struct hash_elem *, table->nelem);
-
     return table;
 }
 
-void hash_resize(HASH *ptr, int nelem)
+/* ptr         pointer to the hash table to be freed
+ * destroy()   function to call to free the ->data member (optional) 
+ */
+void hash_wipe(hash_t *h, void (*dtor)(void *))
+{
+    int i;
+
+    for (i = 0; i < h->nelem; i++) {
+        struct hash_elem *elem, *tmp;
+
+        for (elem = h->table[i]; elem;) {
+            tmp = elem;
+            elem = elem->next;
+            if (dtor)
+                dtor(tmp->data);
+            p_delete(&tmp);
+        }
+    }
+    p_delete(&h->table);
+}
+
+void hash_resize(hash_t *ptr, int nelem)
 {
-    HASH *table;
-    struct hash_elem *elem, *tmp;
+    hash_t table;
     int i;
 
     /* XXX hack: we know the has was correct, no dupe checks is fater */
-    table = hash_create(nelem, 1);
+    hash_init(&table, nelem, 1);
 
     for (i = 0; i < ptr->nelem; i++) {
+        struct hash_elem *elem, *tmp;
         for (elem = ptr->table[i]; elem;) {
             tmp = elem;
             elem = elem->next;
-            hash_insert(table, tmp->key, tmp->data);
+            hash_insert(&table, tmp->key, tmp->data);
             p_delete(&tmp);
         }
     }
 
     p_delete(&ptr->table);
-    ptr->nelem = table->nelem;
-    ptr->table = table->table;
-    p_delete(&table);
+    ptr->nelem = table.nelem;
+    ptr->table = table.table;
 }
 
 /* table        hash table to update
@@ -80,7 +95,7 @@ void hash_resize(HASH *ptr, int nelem)
  * data         data to associate with `key'
  * allow_dup    if nonzero, duplicate keys are allowed in the table 
  */
-int hash_insert(HASH *table, const char *key, void *data)
+int hash_insert(hash_t *table, const char *key, void *data)
 {
     struct hash_elem *ptr;
     int h;
@@ -102,7 +117,7 @@ int hash_insert(HASH *table, const char *key, void *data)
 
             if (r == 0) {
                 p_delete(&ptr);
-                return (-1);
+                return -1;
             }
             if (r > 0)
                 break;
@@ -114,20 +129,22 @@ int hash_insert(HASH *table, const char *key, void *data)
     return h;
 }
 
-void *hash_find_hash(const HASH *table, int hash, const char *key)
+void *hash_find(const hash_t *table, const char *key)
 {
+    int hash = hash_string((unsigned char*)key, table->nelem);
     struct hash_elem *ptr;
 
     for (ptr = table->table[hash]; ptr; ptr = ptr->next) {
         if (m_strcmp(key, ptr->key) == 0)
-            return (ptr->data);
+            return ptr->data;
     }
     return NULL;
 }
 
-void hash_delete_hash(HASH *table, int hash, const char *key, const void *data,
-                      void (*destroy)(void *))
+void hash_remove(hash_t *table, const char *key, const void *data,
+                 void (*destroy)(void *))
 {
+    int hash = hash_string((unsigned char*)key, table->nelem);
     struct hash_elem *ptr   = table->table[hash];
     struct hash_elem **last = &table->table[hash];
 
@@ -146,29 +163,7 @@ void hash_delete_hash(HASH *table, int hash, const char *key, const void *data,
     }
 }
 
-/* ptr         pointer to the hash table to be freed
- * destroy()   function to call to free the ->data member (optional) 
- */
-void hash_destroy(HASH **ptr, void (*destroy)(void *))
-{
-    int i;
-    HASH *pptr = *ptr;
-    struct hash_elem *elem, *tmp;
-
-    for (i = 0; i < pptr->nelem; i++) {
-        for (elem = pptr->table[i]; elem;) {
-            tmp = elem;
-            elem = elem->next;
-            if (destroy)
-                destroy (tmp->data);
-            p_delete(&tmp);
-        }
-    }
-    p_delete(&pptr->table);
-    p_delete(ptr);
-}
-
-void hash_map(HASH *table,
+void hash_map(hash_t *table,
               void (*mapfunc)(const char* key, void* data, unsigned long more),
               unsigned long more)
 {