From d707380744721edc55528be568f3c8230cb68c70 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Tue, 27 Dec 2011 12:20:35 -0200 Subject: [PATCH] Copy missing hash functions from kmod-depmod to libkmod --- libkmod/libkmod-hash.c | 44 +++++++++++++++++++++++++++++++++++++++ libkmod/libkmod-private.h | 2 ++ 2 files changed, 46 insertions(+) diff --git a/libkmod/libkmod-hash.c b/libkmod/libkmod-hash.c index 0fd94100..43cbc02f 100644 --- a/libkmod/libkmod-hash.c +++ b/libkmod/libkmod-hash.c @@ -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; +} diff --git a/libkmod/libkmod-private.h b/libkmod/libkmod-private.h index 87c8df49..ee76e70e 100644 --- a/libkmod/libkmod-private.h +++ b/libkmod/libkmod-private.h @@ -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))); -- 2.47.2