X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fhash.c;h=101ec1214a30aae2faddd478c24f53321d401832;hb=1fd06503004016a245257a08748473d749559586;hp=c7f4d73939a5668a5e6b3b3c259086401df40015;hpb=b641818c787e48bbf03ce2a0cd5b542c4c21e523;p=rocksndiamonds.git diff --git a/src/libgame/hash.c b/src/libgame/hash.c index c7f4d739..101ec121 100644 --- a/src/libgame/hash.c +++ b/src/libgame/hash.c @@ -41,9 +41,11 @@ /*****************************************************************************/ struct hashtable * -create_hashtable(unsigned int minsize, float maxloadfactor, - unsigned int (*hashf) (void*), - int (*eqf) (void*,void*)) +create_hashtable_ext(unsigned int minsize, float maxloadfactor, + unsigned int (*hashf) (void*), + int (*eqf) (void*, void*), + void (*freekfn) (void*), + void (*freevfn) (void*)) { struct hashtable *h; unsigned int i, size = 1u; @@ -70,7 +72,7 @@ create_hashtable(unsigned int minsize, float maxloadfactor, return NULL; } - for (i=0; i < size; i++) + for (i = 0; i < size; i++) h->table[i] = NULL; h->tablelength = size; @@ -78,10 +80,21 @@ create_hashtable(unsigned int minsize, float maxloadfactor, h->hashfn = hashf; h->eqfn = eqf; h->loadlimit = (unsigned int) ((float)size * maxloadfactor); + h->freekfn = freekfn; + h->freevfn = freevfn; return h; } +struct hashtable * +create_hashtable(unsigned int (*hashf) (void*), + int (*eqf) (void*, void*), + void (*freekfn) (void*), + void (*freevfn) (void*)) +{ + return create_hashtable_ext(16, 0.75, hashf, eqf, freekfn, freevfn); +} + /*****************************************************************************/ static unsigned int hash(struct hashtable *h, void *k) @@ -134,7 +147,7 @@ hashtable_expand(struct hashtable *h) while ((e = h->table[i]) != NULL) { h->table[i] = e->next; - index = indexFor(newsize,e->h); + index = indexFor(newsize, e->h); e->next = newtable[index]; newtable[index] = e; } @@ -160,7 +173,7 @@ hashtable_expand(struct hashtable *h) { for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) { - index = indexFor(newsize,e->h); + index = indexFor(newsize, e->h); if (index == i) { @@ -216,8 +229,8 @@ hashtable_insert(struct hashtable *h, void *k, void *v) return 0; } - e->h = hash(h,k); - index = indexFor(h->tablelength,e->h); + e->h = hash(h, k); + index = indexFor(h->tablelength, e->h); e->k = k; e->v = v; e->next = h->table[index]; @@ -233,8 +246,8 @@ hashtable_change(struct hashtable *h, void *k, void *v) struct entry *e; unsigned int hashvalue, index; - hashvalue = hash(h,k); - index = indexFor(h->tablelength,hashvalue); + hashvalue = hash(h, k); + index = indexFor(h->tablelength, hashvalue); e = h->table[index]; while (e != NULL) @@ -242,7 +255,8 @@ hashtable_change(struct hashtable *h, void *k, void *v) /* Check hash value to short circuit heavier comparison */ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) { - free(e->v); + if (h->freevfn != NULL) + h->freevfn(e->v); e->v = v; return -1; @@ -261,8 +275,8 @@ hashtable_search(struct hashtable *h, void *k) struct entry *e; unsigned int hashvalue, index; - hashvalue = hash(h,k); - index = indexFor(h->tablelength,hashvalue); + hashvalue = hash(h, k); + index = indexFor(h->tablelength, hashvalue); e = h->table[index]; while (e != NULL) @@ -287,7 +301,7 @@ hashtable_remove(struct hashtable *h, void *k) struct entry *e; struct entry **pE; void *v; - unsigned int index = indexFor(h->tablelength,hash(h,k)); + unsigned int index = indexFor(h->tablelength, hash(h, k)); pE = &(h->table[index]); e = *pE; @@ -298,8 +312,13 @@ hashtable_remove(struct hashtable *h, void *k) { *pE = e->next; h->entrycount--; - v = e->v; - free(e->k); + v = NULL; + if (h->freekfn != NULL) + h->freekfn(e->k); + if (h->freevfn != NULL) + h->freevfn(e->v); + else + v = e->v; free(e); return v; @@ -315,7 +334,7 @@ hashtable_remove(struct hashtable *h, void *k) /*****************************************************************************/ /* destroy */ void -hashtable_destroy(struct hashtable *h, int free_values) +hashtable_destroy(struct hashtable *h) { unsigned int i; struct entry *e, *f; @@ -329,10 +348,10 @@ hashtable_destroy(struct hashtable *h, int free_values) { f = e; e = e->next; - free(f->k); - - if (free_values) - free(f->v); + if (h->freekfn != NULL) + h->freekfn(f->k); + if (h->freevfn != NULL) + h->freevfn(f->v); free(f); } @@ -342,7 +361,6 @@ hashtable_destroy(struct hashtable *h, int free_values) free(h); } - /*****************************************************************************/ /* hashtable_iterator - iterator constructor */ @@ -379,7 +397,7 @@ hashtable_iterator(struct hashtable *h) } /*****************************************************************************/ -/* key - return the key of the (key,value) pair at the current position */ +/* key - return the key of the (key, value) pair at the current position */ void * hashtable_iterator_key(struct hashtable_itr *i) @@ -388,7 +406,7 @@ hashtable_iterator_key(struct hashtable_itr *i) } /*****************************************************************************/ -/* value - return the value of the (key,value) pair at the current position */ +/* value - return the value of the (key, value) pair at the current position */ void * hashtable_iterator_value(struct hashtable_itr *i) @@ -403,7 +421,7 @@ hashtable_iterator_value(struct hashtable_itr *i) int hashtable_iterator_advance(struct hashtable_itr *itr) { - unsigned int j,tablelength; + unsigned int j, tablelength; struct entry **table; struct entry *next;