00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 extern "C"
00012 {
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include "mm_hash.h"
00016 }
00017
00018 MM_Hash *mm_hash_new(MM *mm, MM_HashDtor dtor)
00019 {
00020 MM_Hash *table;
00021
00022 table = (MM_Hash *) mm_calloc(mm, 1, sizeof(MM_Hash));
00023 table->mm = mm;
00024 table->dtor = dtor;
00025
00026 return table;
00027 }
00028
00029 void mm_hash_free(MM_Hash *table)
00030 {
00031 MM_Bucket *cur;
00032 MM_Bucket *next;
00033 int i;
00034
00035 for (i = 0; i < MM_HASH_SIZE; i++) {
00036 cur = table->buckets[i];
00037 while (cur) {
00038 next = cur->next;
00039
00040 if (table->dtor) table->dtor(cur->data);
00041 mm_free(table->mm, cur->key);
00042 mm_free(table->mm, cur);
00043
00044 cur = next;
00045 }
00046 }
00047 mm_free(table->mm, table);
00048 }
00049
00050 static unsigned int hash_hash(const char *key, int length)
00051 {
00052 unsigned int hash = 0;
00053
00054 while (--length)
00055 hash = hash * 65599 + *key++;
00056
00057 return hash;
00058 }
00059
00060 void *mm_hash_find(MM_Hash *table, const void *key, int length)
00061 {
00062 MM_Bucket *b;
00063 unsigned int hash = hash_hash((const char *)key, length) % MM_HASH_SIZE;
00064
00065 for (b = table->buckets[ hash ]; b; b = b->next) {
00066 if (hash != b->hash) continue;
00067 if (length != b->length) continue;
00068 if (memcmp(key, b->key, length)) continue;
00069
00070 return b->data;
00071 }
00072
00073 return NULL;
00074 }
00075
00076 void mm_hash_update(MM_Hash *table, char *key, int length, void *data)
00077 {
00078 MM_Bucket *b, p;
00079 unsigned int hash;
00080
00081 hash = hash_hash(key, length) % MM_HASH_SIZE;
00082
00083 for(b = table->buckets[ hash ]; b; b = b->next) {
00084 if (hash != b->hash) continue;
00085 if (length != b->length) continue;
00086 if (memcmp(key, b->key, length)) continue;
00087 if (table->dtor) table->dtor(b->data);
00088 b->data = data;
00089 }
00090 if(!b) {
00091 b = (MM_Bucket *) mm_malloc(table->mm, sizeof(MM_Bucket));
00092 b->key = (char *) mm_malloc(table->mm, length + 1);
00093 memcpy(b->key, key, length);
00094 b->key[length] = 0;
00095 b->length = length;
00096 b->hash = hash;
00097 b->data = data;
00098 b->next = table->buckets[ hash ];
00099 table->buckets[ hash ] = b;
00100 }
00101 table->nElements++;
00102 }
00103
00104 void mm_hash_delete(MM_Hash *table, char *key, int length)
00105 {
00106 MM_Bucket *b;
00107 MM_Bucket *prev = NULL;
00108 unsigned int hash;
00109
00110 hash = hash_hash(key, length) % MM_HASH_SIZE;
00111 for (b = table->buckets[ hash ]; b; b = b->next) {
00112 if (hash != b->hash || length != b->length || memcmp(key, b->key, length)) {
00113 prev = b;
00114 continue;
00115 }
00116
00117
00118 if (prev) {
00119 prev->next = b->next;
00120 } else {
00121 table->buckets[hash] = b->next;
00122 }
00123
00124 if (table->dtor) table->dtor(b->data);
00125 mm_free(table->mm, b->key);
00126 mm_free(table->mm, b);
00127
00128 break;
00129 }
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139