From: Lucas De Marchi Date: Tue, 27 Dec 2011 14:20:35 +0000 (-0200) Subject: Copy missing hash functions from kmod-depmod to libkmod X-Git-Tag: v3~50 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d707380744721edc55528be568f3c8230cb68c70;p=thirdparty%2Fkmod.git Copy missing hash functions from kmod-depmod to libkmod --- 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)));