diff options
author | Stef Walter <stef@memberwebs.com> | 2004-04-24 22:38:50 +0000 |
---|---|---|
committer | Stef Walter <stef@memberwebs.com> | 2004-04-24 22:38:50 +0000 |
commit | cbbe71752d7f9c6204ab0f16600fe7f10490f203 (patch) | |
tree | 365e6e472d239d117b5f849c45f3c08fc6617c0a /common/hash.c | |
parent | ff76efc3e5e1b0e4ca3b10b7402406f619509bba (diff) |
Completed implementation of ldap/ntlm/simple handlers
Diffstat (limited to 'common/hash.c')
-rw-r--r-- | common/hash.c | 130 |
1 files changed, 102 insertions, 28 deletions
diff --git a/common/hash.c b/common/hash.c index 7d67e53..6471803 100644 --- a/common/hash.c +++ b/common/hash.c @@ -88,10 +88,14 @@ struct hash_t #ifdef HASH_COPYKEYS unsigned int klen; #endif +#ifdef HASH_CALLBACKS + hash_free_val_t f_free; + void* arg; +#endif }; -#define INITIAL_MAX 15 /* tunable == 2^n - 1 */ +#define INITIAL_MAX 15 /* tunable == 2^n - 1 */ /* * Hash creation functions. @@ -102,10 +106,18 @@ static hash_entry_t** alloc_array(hash_t* ht, unsigned int max) return malloc(sizeof(*(ht->array)) * (max + 1)); } -#ifdef HASH_COPYKEYS -hash_t* hash_create(size_t klen) +#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 +hash_t* hash_create(size_t klen) + #else hash_t* hash_create() + #endif #endif { hash_t* ht = malloc(sizeof(hash_t)); @@ -117,7 +129,10 @@ 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); @@ -132,7 +147,13 @@ void hash_free(hash_t* ht) hash_index_t* hi; 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); +#endif free(hi->ths); + } if(ht->array) free(ht->array); @@ -362,58 +383,64 @@ void* hash_get(hash_t* ht, const void *key, size_t klen) } #ifdef HASH_COPYKEYS -int hash_set(hash_t* ht, const void* key, const void* val) +int hash_set(hash_t* ht, const void* key, void* val) { hash_entry_t** hep = find_entry(ht, key, val); #else -int hash_set(hash_t* ht, const void* key, size_t klen, const void* val) +int hash_set(hash_t* ht, const void* key, size_t klen, void* val) { hash_entry_t** hep = find_entry(ht, key, klen, val); #endif if(hep && *hep) { - if(val) - { - /* replace entry */ - (*hep)->val = val; +#ifdef HASH_CALLBACKS + if((*hep)->val && (*hep)->val != val && ht->f_free) + ht->f_free(ht->arg, (void*)((*hep)->val)); +#endif + + /* replace entry */ + (*hep)->val = val; #ifdef HASH_TIMESTAMP - /* Update or set the timestamp */ - (*hep)->stamp = time(NULL); + /* Update or set the timestamp */ + (*hep)->stamp = time(NULL); #endif - /* check that the collision rate isn't too high */ - if(ht->count > ht->max) - { - if(!expand_array(ht)) - return 0; - } - - return 1; + /* check that the collision rate isn't too high */ + if(ht->count > ht->max) + { + if(!expand_array(ht)) + return 0; } + + return 1; } return 0; } #ifdef HASH_COPYKEYS -void hash_rem(hash_t* ht, const void* key) +void* hash_rem(hash_t* ht, const void* key) { hash_entry_t** hep = find_entry(ht, key, NULL); #else -void hash_rem(hash_t* ht, const void* key, size_t klen) +void* hash_rem(hash_t* ht, const void* key, size_t klen) { hash_entry_t** hep = find_entry(ht, key, klen, NULL); #endif + void* val = NULL; if(hep && *hep) { hash_entry_t* old = *hep; *hep = (*hep)->next; --ht->count; + val = (void*)old->val; free(old); } + + return val; } unsigned int hash_count(hash_t* ht) @@ -426,6 +453,7 @@ int hash_purge(hash_t* ht, time_t stamp) { hash_index_t* hi; int r = 0; + void* val; for(hi = hash_first(ht); hi; hi = hash_next(hi)) { @@ -433,9 +461,14 @@ int hash_purge(hash_t* ht, time_t stamp) { /* No need to check for errors as we're deleting */ #ifdef HASH_COPYKEYS - hash_rem(ht, KEY_DATA(hi->ths)); + val = hash_rem(ht, KEY_DATA(hi->ths)); #else - hash_rem(ht, hi->ths->key, hi->ths->klen); + val = hash_rem(ht, hi->ths->key, hi->ths->klen); +#endif + +#ifdef HASH_CALLBACKS + if(val && ht->f_free) + (ht->f_free)(ht->arg, val); #endif r++; @@ -446,17 +479,58 @@ int hash_purge(hash_t* ht, time_t stamp) } #ifdef HASH_COPYKEYS -void* hash_touch(hash_index_t* hi, const void** key); +void hash_touch(hash_t* ht, const void* key) { hash_entry_t** hep = find_entry(ht, key, NULL); #else -void* hash_touch(hash_index_t* hi, const void** key, size_t* klen); +void hash_touch(hash_t* ht, const void* key, size_t* klen) { hash_entry_t** hep = find_entry(ht, key, klen, NULL); #endif - if(he && *he) - ((*he)->stamp) = time(NULL); + if(hep && *hep) + ((*hep)->stamp) = time(NULL); +} + +int hash_bump(hash_t* ht) +{ + hash_index_t* hi; + void* key = NULL; + void* val = NULL; + time_t least = 0; +#ifndef HASH_COPYKEYS + size_t klen = 0; +#endif + + for(hi = hash_first(ht); hi; hi = hash_next(hi)) + { + if(least == 0 || hi->ths->stamp < least) + { + least = hi->ths->stamp; + key = KEY_DATA(hi->ths); +#ifndef HASH_COPYKEYS + klen = hi->this->klen; +#endif + } + } + + if(key) + { +#ifdef HASH_COPYKEYS + val = hash_rem(ht, key); +#else + val = hash_rem(ht, key, klen); +#endif + +#ifdef HASH_CALLBACKS + if(val && ht->f_free) + (ht->f_free)(ht->arg, (void*)val); +#endif + + return 1; + } + + return 0; } #endif /* HASH_TIMESTAMP */ |