]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
Copy missing hash functions from kmod-depmod to libkmod
authorLucas De Marchi <lucas.demarchi@profusion.mobi>
Tue, 27 Dec 2011 14:20:35 +0000 (12:20 -0200)
committerLucas De Marchi <lucas.demarchi@profusion.mobi>
Tue, 27 Dec 2011 20:11:58 +0000 (18:11 -0200)
libkmod/libkmod-hash.c
libkmod/libkmod-private.h

index 0fd94100fcb253bf4e843d943439db33e1efb03b..43cbc02f89a167996cae63201daf7b37d2245a85 100644 (file)
@@ -177,6 +177,45 @@ int hash_add(struct hash *hash, const char *key, const void *value)
        return 0;
 }
 
+/* similar to hash_add(), but fails if key already exists */
+int hash_add_unique(struct hash *hash, const char *key, const void *value)
+{
+       unsigned int keylen = strlen(key);
+       unsigned int hashval = hash_superfast(key, keylen);
+       unsigned int pos = hashval % hash->n_buckets;
+       struct hash_bucket *bucket = hash->buckets + pos;
+       struct hash_entry *entry, *entry_end;
+
+       if (bucket->used + 1 >= bucket->total) {
+               unsigned new_total = bucket->total + hash->step;
+               size_t size = new_total * sizeof(struct hash_entry);
+               struct hash_entry *tmp = realloc(bucket->entries, size);
+               if (tmp == NULL)
+                       return -errno;
+               bucket->entries = tmp;
+               bucket->total = new_total;
+       }
+
+       entry = bucket->entries;
+       entry_end = entry + bucket->used;
+       for (; entry < entry_end; entry++) {
+               int c = strcmp(key, entry->key);
+               if (c == 0)
+                       return -EEXIST;
+               else if (c < 0) {
+                       memmove(entry + 1, entry,
+                               (entry_end - entry) * sizeof(struct hash_entry));
+                       break;
+               }
+       }
+
+       entry->key = key;
+       entry->value = value;
+       bucket->used++;
+       hash->count++;
+       return 0;
+}
+
 static int hash_entry_cmp(const void *pa, const void *pb)
 {
        const struct hash_entry *a = pa;
@@ -241,3 +280,8 @@ int hash_del(struct hash *hash, const char *key)
 
        return 0;
 }
+
+unsigned int hash_get_count(const struct hash *hash)
+{
+       return hash->count;
+}
index 87c8df4928007f41953e7e7b3bd808ea8f55f546..ee76e70e299a9fcb8d99f130e7cfefacd61a7155 100644 (file)
@@ -133,8 +133,10 @@ struct hash;
 struct hash *hash_new(unsigned int n_buckets, void (*free_value)(void *value));
 void hash_free(struct hash *hash);
 int hash_add(struct hash *hash, const char *key, const void *value);
+int hash_add_unique(struct hash *hash, const char *key, const void *value);
 int hash_del(struct hash *hash, const char *key);
 void *hash_find(const struct hash *hash, const char *key);
+unsigned int hash_get_count(const struct hash *hash);
 
 /* libkmod-file.c */
 struct kmod_file *kmod_file_open(const char *filename) __must_check __attribute__((nonnull(1)));