summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas De Marchi <lucas.demarchi@intel.com>2013-09-20 15:12:43 -0500
committerLucas De Marchi <lucas.demarchi@intel.com>2013-09-25 02:04:20 -0300
commitf758b1f92ad3c8f2699344f2b47566b26d6e7497 (patch)
treecc4902b9104d05e9b52ca79cfc1e14fd632b8c0a
parentd88090ed6da733a9e7feee1d7ae74a4fffb13749 (diff)
downloadkmod-f758b1f92ad3c8f2699344f2b47566b26d6e7497.tar.gz
use hashval in each item
-rw-r--r--libkmod/libkmod-hash.c75
1 files changed, 30 insertions, 45 deletions
diff --git a/libkmod/libkmod-hash.c b/libkmod/libkmod-hash.c
index cdb8965..5bf2077 100644
--- a/libkmod/libkmod-hash.c
+++ b/libkmod/libkmod-hash.c
@@ -47,6 +47,7 @@ static inline unsigned long long get_cycles(unsigned long long last)
struct hash_entry {
const char *key;
const void *value;
+ unsigned int hashval;
};
struct hash_bucket {
@@ -315,21 +316,17 @@ static _always_inline_ int _hash_add(struct hash *hash, const char *key, const v
entry = bucket->entries;
entry_end = entry + bucket->used;
for (; entry < entry_end; entry++) {
- int c = strcmp(key, entry->key);
- if (c == 0) {
- if (hash->free_value)
- hash->free_value((void *)entry->value);
- entry->value = value;
- return 0;
- } else if (c < 0) {
- memmove(entry + 1, entry,
- (entry_end - entry) * sizeof(struct hash_entry));
- break;
- }
+ if (hashval != entry->hashval || !streq(key, entry->key))
+ continue;
+ if (hash->free_value)
+ hash->free_value((void *)entry->value);
+ entry->value = value;
+ return 0;
}
entry->key = key;
entry->value = value;
+ entry->hashval = hashval;
bucket->used++;
hash->count++;
return 0;
@@ -406,18 +403,13 @@ static _always_inline_ int _hash_add_unique(struct hash *hash, const char *key,
entry = bucket->entries;
entry_end = entry + bucket->used;
for (; entry < entry_end; entry++) {
- int c = strcmp(key, entry->key);
- if (c == 0)
+ if (hashval == entry->hashval && streq(key, entry->key))
return -EEXIST;
- else if (c < 0) {
- memmove(entry + 1, entry,
- (entry_end - entry) * sizeof(struct hash_entry));
- break;
- }
}
entry->key = key;
entry->value = value;
+ entry->hashval = hashval;
bucket->used++;
hash->count++;
return 0;
@@ -436,53 +428,46 @@ int hash_add_unique(struct hash *hash, const char *key, const void *value)
return ret;
}
-static int hash_entry_cmp(const void *pa, const void *pb)
-{
- const struct hash_entry *a = pa;
- const struct hash_entry *b = pb;
- return strcmp(a->key, b->key);
-}
-
void *hash_find(const struct hash *hash, const char *key)
{
unsigned int keylen = strlen(key);
unsigned int hashval = hashfunc(key, keylen);
unsigned int pos = hashval & (hash->n_buckets - 1);
const struct hash_bucket *bucket = hash->buckets + pos;
- const struct hash_entry se = {
- .key = key,
- .value = NULL
- };
- const struct hash_entry *entry = bsearch(
- &se, bucket->entries, bucket->used,
- sizeof(struct hash_entry), hash_entry_cmp);
- if (entry == NULL)
- return NULL;
- return (void *)entry->value;
+ const struct hash_entry *entry, *entry_end;
+
+ entry = bucket->entries;
+ entry_end = entry + bucket->used;
+ for (; entry < entry_end; entry++) {
+ if (hashval == entry->hashval && streq(key, entry->key))
+ return (void *) entry->value;
+ }
+
+ return NULL;
}
int hash_del(struct hash *hash, const char *key)
{
unsigned int keylen = strlen(key);
- int hashval = hashfunc(key, keylen);
+ unsigned int hashval = hashfunc(key, keylen);
unsigned int pos = hashval & (hash->n_buckets - 1);
unsigned int steps_used, steps_total;
struct hash_bucket *bucket = hash->buckets + pos;
struct hash_entry *entry, *entry_end;
- const struct hash_entry se = {
- .key = key,
- .value = NULL
- };
-
- entry = bsearch(&se, bucket->entries, bucket->used,
- sizeof(struct hash_entry), hash_entry_cmp);
- if (entry == NULL)
+
+ entry = bucket->entries;
+ entry_end = entry + bucket->used;
+ for (; entry < entry_end; entry++) {
+ if (hashval == entry->hashval && streq(key, entry->key))
+ break;
+ }
+
+ if (entry > entry_end)
return -ENOENT;
if (hash->free_value)
hash->free_value((void *)entry->value);
- entry_end = bucket->entries + bucket->used;
memmove(entry, entry + 1,
(entry_end - entry) * sizeof(struct hash_entry));