The compiler almost certainly knows better.
[oweals/opkg-lede.git] / libopkg / hash_table.c
index c0c0530372d2e22317426a77ccc7d97d2e8a4da8..713ecff605889eb349222319a9087002da5b7cdd 100644 (file)
@@ -85,6 +85,7 @@ void hash_table_deinit(hash_table_t *hash)
     /* free the reminaing entries */
     for (i = 0; i < hash->n_entries; i++) {
        hash_entry_t *hash_entry = (hash->entries + i);
+       free (hash_entry->key);
        /* skip the first entry as this is part of the array */
        hash_entry = hash_entry->next;
         while (hash_entry)
@@ -138,9 +139,14 @@ int hash_table_insert(hash_table_t *hash, const char *key, void *value)
                * before we can hook up the value
                */
                if (0) opkg_message(NULL, OPKG_DEBUG2, "Function: %s. Value already in hash by collision for '%s' \n", __FUNCTION__, key);
-              while (hash_entry->next)
+              while (hash_entry->next) {
                    hash_entry = hash_entry->next;
-              hash_entry->next = (hash_entry_t *)malloc(sizeof(hash_entry_t));
+                    if (strcmp(hash_entry->key, key) == 0) {
+                        hash_entry->data = value;
+                        return 0;
+                    }
+               }
+              hash_entry->next = (hash_entry_t *)calloc(1, sizeof(hash_entry_t));
               if (!hash_entry->next) {
                    return -ENOMEM;
               }
@@ -155,6 +161,37 @@ int hash_table_insert(hash_table_t *hash, const char *key, void *value)
      return 0;
 }
 
+int hash_table_remove(hash_table_t *hash, const char *key)
+{
+    int ndx= hash_index(hash, key);
+    hash_entry_t *hash_entry = hash->entries + ndx;
+    hash_entry_t *next_entry=NULL, *last_entry=NULL;
+    while (hash_entry) 
+    {
+        if (hash_entry->key) 
+        {
+            if (strcmp(key, hash_entry->key) == 0) {
+                free(hash_entry->key);
+                if (last_entry) {
+                    last_entry->next = hash_entry->next;
+                    free(hash_entry);
+                } else {
+                    next_entry = hash_entry->next;
+                    if (next_entry) {
+                        memmove(hash_entry, next_entry, sizeof(hash_entry_t));
+                        free(next_entry);
+                    } else {
+                        memset(hash_entry, 0 , sizeof(hash_entry_t));
+                    }
+                }
+                return 1;
+            }
+        }
+        last_entry = hash_entry;
+        hash_entry = hash_entry->next;
+    }
+    return 0;
+}
 
 void hash_table_foreach(hash_table_t *hash, void (*f)(const char *key, void *entry, void *data), void *data)
 {