summaryrefslogtreecommitdiff
path: root/common/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/hash.c')
-rw-r--r--common/hash.c112
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;