diff options
author | jbj <devnull@localhost> | 2004-10-16 01:31:54 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 2004-10-16 01:31:54 +0000 |
commit | d03f220fde879509cab2ac1c73b71b7efb52b737 (patch) | |
tree | 1e34bfadac0a6618d0e9a7933bad90063a785acf /db/mod_db4/mm_hash.c | |
parent | 2dc699bfe049b9319ea3719f604d25940ff52004 (diff) | |
download | librpm-tizen-d03f220fde879509cab2ac1c73b71b7efb52b737.tar.gz librpm-tizen-d03f220fde879509cab2ac1c73b71b7efb52b737.tar.bz2 librpm-tizen-d03f220fde879509cab2ac1c73b71b7efb52b737.zip |
... and in with the New ...
CVS patchset: 7471
CVS date: 2004/10/16 01:31:54
Diffstat (limited to 'db/mod_db4/mm_hash.c')
-rw-r--r-- | db/mod_db4/mm_hash.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/db/mod_db4/mm_hash.c b/db/mod_db4/mm_hash.c new file mode 100644 index 000000000..f42409c93 --- /dev/null +++ b/db/mod_db4/mm_hash.c @@ -0,0 +1,137 @@ +/*- + * Copyright (c) 2004 + * Sleepycat Software. All rights reserved. + * + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + * authors: Thies C. Arntzen <thies@php.net> + * Sterling Hughes <sterling@php.net> + * George Schlossnagle <george@omniti.com> + */ + +#include <stdlib.h> +#include <string.h> +#include "mm_hash.h" + +MM_Hash *mm_hash_new(MM *mm, MM_HashDtor dtor) +{ + MM_Hash *table; + + table = mm_calloc(mm, 1, sizeof(MM_Hash)); + table->mm = mm; + table->dtor = dtor; + + return table; +} + +void mm_hash_free(MM_Hash *table) +{ + MM_Bucket *cur; + MM_Bucket *next; + int i; + + for (i = 0; i < MM_HASH_SIZE; i++) { + cur = table->buckets[i]; + while (cur) { + next = cur->next; + + if (table->dtor) table->dtor(cur->data); + mm_free(table->mm, cur->key); + mm_free(table->mm, cur); + + cur = next; + } + } + mm_free(table->mm, table); +} + +static unsigned int hash_hash(const char *key, int length) +{ + unsigned int hash = 0; + + while (--length) + hash = hash * 65599 + *key++; + + return hash; +} + +void *mm_hash_find(MM_Hash *table, const void *key, int length) +{ + MM_Bucket *b; + unsigned int hash = hash_hash(key, length) % MM_HASH_SIZE; + + for (b = table->buckets[ hash ]; b; b = b->next) { + if (hash != b->hash) continue; + if (length != b->length) continue; + if (memcmp(key, b->key, length)) continue; + + return b->data; + } + + return NULL; +} + +void mm_hash_update(MM_Hash *table, char *key, int length, void *data) +{ + MM_Bucket *b, p; + unsigned int hash; + + hash = hash_hash(key, length) % MM_HASH_SIZE; + + for(b = table->buckets[ hash ]; b; b = b->next) { + if (hash != b->hash) continue; + if (length != b->length) continue; + if (memcmp(key, b->key, length)) continue; + if (table->dtor) table->dtor(b->data); + b->data = data; + } + if(!b) { + b = mm_malloc(table->mm, sizeof(MM_Bucket)); + b->key = mm_malloc(table->mm, length + 1); + memcpy(b->key, key, length); + b->key[length] = 0; + b->length = length; + b->hash = hash; + b->data = data; + b->next = table->buckets[ hash ]; + table->buckets[ hash ] = b; + } + table->nElements++; +} + +void mm_hash_delete(MM_Hash *table, char *key, int length) +{ + MM_Bucket *b; + MM_Bucket *prev = NULL; + unsigned int hash; + + hash = hash_hash(key, length) % MM_HASH_SIZE; + for (b = table->buckets[ hash ]; b; b = b->next) { + if (hash != b->hash || length != b->length || memcmp(key, b->key, length)) { + prev = b; + continue; + } + + /* unlink */ + if (prev) { + prev->next = b->next; + } else { + table->buckets[hash] = b->next; + } + + if (table->dtor) table->dtor(b->data); + mm_free(table->mm, b->key); + mm_free(table->mm, b); + + break; + } +} + +/* +Local variables: +tab-width: 4 +c-basic-offset: 4 +End: +vim600: noet sw=4 ts=4 fdm=marker +vim<600: noet sw=4 ts=4 +*/ |