diff options
Diffstat (limited to 'common/hash.c')
-rw-r--r-- | common/hash.c | 112 |
1 files changed, 80 insertions, 32 deletions
diff --git a/common/hash.c b/common/hash.c index 6471803..9bbe8ac 100644 --- a/common/hash.c +++ b/common/hash.c @@ -89,38 +89,90 @@ struct hash_t unsigned int klen; #endif #ifdef HASH_CALLBACKS - hash_free_val_t f_free; - void* arg; + hash_table_calls_t calls; #endif }; #define INITIAL_MAX 15 /* tunable == 2^n - 1 */ +#ifdef HASH_CALLBACKS + +/* A copy of the memory call table we've been set to */ +static hash_memory_calls_t g_memory_calls_cpy; + +/* Pointer to above. This indicates when we actually are set */ +static hash_memory_calls_t* g_memory_calls = NULL; + +static void* int_malloc(size_t len) +{ + if(g_memory_calls) + return (g_memory_calls->f_alloc)(g_memory_calls->arg, len); + else + return malloc(len); +} + +static void* int_calloc(size_t len) +{ + void* p = int_malloc(len); + memset(p, 0, len); + return p; +} + +static void int_free(void* ptr) +{ + if(g_memory_calls) + { + /* We allow for gc type memory allocation with a null free */ + if(g_memory_calls->f_free) + (g_memory_calls->f_free)(g_memory_calls->arg, ptr); + } + else + free(ptr); +} + +void hash_set_memory_calls(hash_memory_calls_t* hmc) +{ + if(hmc == NULL) + { + g_memory_calls = NULL; + } + else + { + memcpy(&g_memory_calls_cpy, hmc, sizeof(g_memory_calls_cpy)); + g_memory_calls = &g_memory_calls_cpy; + } +} + +void hash_set_table_calls(hash_t* ht, hash_table_calls_t* htc) +{ + memcpy(&(ht->calls), htc, sizeof(ht->calls)); +} + +#else + +#define int_malloc malloc +#define int_free free + +#endif + + /* * Hash creation functions. */ static hash_entry_t** alloc_array(hash_t* ht, unsigned int max) { - return malloc(sizeof(*(ht->array)) * (max + 1)); + return int_malloc(sizeof(*(ht->array)) * (max + 1)); } -#ifdef HASH_CALLBACKS - #ifdef HASH_COPYKEYS -hash_t* hash_create(size_t klen, hash_free_val_t f_free, void* arg) - #else -hash_t* hash_create(hash_free_val_t f_free, void* arg) - #endif -#else - #ifdef HASH_COPYKEYS +#ifdef HASH_COPYKEYS hash_t* hash_create(size_t klen) - #else +#else hash_t* hash_create() - #endif #endif { - hash_t* ht = malloc(sizeof(hash_t)); + hash_t* ht = int_malloc(sizeof(hash_t)); if(ht) { ht->count = 0; @@ -129,13 +181,9 @@ hash_t* hash_create() #ifdef HASH_COPYKEYS ht->klen = klen; #endif -#ifdef HASH_CALLBACKS - ht->f_free = f_free; - ht->arg = arg; -#endif if(!ht->array) { - free(ht); + int_free(ht); return NULL; } } @@ -149,16 +197,16 @@ void hash_free(hash_t* ht) for(hi = hash_first(ht); hi; hi = hash_next(hi)) { #ifdef HASH_CALLBACKS - if(hi->ths->val && ht->f_free) - ht->f_free(ht->arg, (void*)hi->ths->val); + if(hi->ths->val && ht->calls.f_freeval) + (ht->calls.f_freeval)(ht->calls.arg, (void*)hi->ths->val); #endif - free(hi->ths); + int_free(hi->ths); } if(ht->array) - free(ht->array); + int_free(ht->array); - free(ht); + int_free(ht); } /* @@ -335,9 +383,9 @@ static hash_entry_t** find_entry(hash_t* ht, const void* key, size_t klen, const /* add a new entry for non-NULL val */ #ifdef HASH_COPYKEYS - he = malloc(sizeof(*he) + klen); + he = int_malloc(sizeof(*he) + klen); #else - he = malloc(sizeof(*he)); + he = int_malloc(sizeof(*he)); #endif if(he) @@ -395,8 +443,8 @@ int hash_set(hash_t* ht, const void* key, size_t klen, void* val) if(hep && *hep) { #ifdef HASH_CALLBACKS - if((*hep)->val && (*hep)->val != val && ht->f_free) - ht->f_free(ht->arg, (void*)((*hep)->val)); + if((*hep)->val && (*hep)->val != val && ht->calls.f_freeval) + (ht->calls.f_freeval)(ht->calls.arg, (void*)((*hep)->val)); #endif /* replace entry */ @@ -467,8 +515,8 @@ int hash_purge(hash_t* ht, time_t stamp) #endif #ifdef HASH_CALLBACKS - if(val && ht->f_free) - (ht->f_free)(ht->arg, val); + if(val && ht->calls.f_freeval) + (ht->calls.f_freeval)(ht->calls.arg, val); #endif r++; @@ -523,8 +571,8 @@ int hash_bump(hash_t* ht) #endif #ifdef HASH_CALLBACKS - if(val && ht->f_free) - (ht->f_free)(ht->arg, (void*)val); + if(val && ht->calls.f_freeval) + (ht->calls.f_freeval)(ht->calls.arg, (void*)val); #endif return 1; |