X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=util.c;h=73c5335e08e49a3d87929a75351bdfd5d3315ad5;hp=3740429f369803c66b9d1d112b882c2dc74c0518;hb=b47e3ebccf562b26671247c2e99f4a0f6bc8e969;hpb=46752af74b8553b4a0a6d8928a823289308c6f8a diff --git a/util.c b/util.c index 3740429..73c5335 100644 --- a/util.c +++ b/util.c @@ -670,146 +670,6 @@ void util_htdel(hash_table_t *ht) { util_htrem(ht, NULL); } -/* - * A basic implementation of a hash-set. Unlike a hashtable, a hash - * set doesn't maintain key-value pairs. It simply maintains a key - * that can be set, removed, and checked for. - * - * See EXPOSED interface comment below - */ -#define GMQCC_HASHSET_PRIME0 0x0049 -#define GMQCC_HASHSET_PRIME1 0x1391 - -static int util_hsput(hash_set_t *set, void *item) { - size_t hash = (size_t)item; /* shouldn't drop the bits */ - size_t iter; - - /* a == 0 || a == 1 */ - if (hash >> 1) - return -1; - - iter = set->mask & (GMQCC_HASHSET_PRIME0 * hash); - - /* while (set->items[iter] != 0 && set->items[iter] != 1) */ - while (!(set->items[iter] >> 1)) { - if (set->items[iter] == hash) - return 0; - - iter = set->mask & (iter + GMQCC_HASHSET_PRIME1); - } - - set->total ++; - set->items[iter] = hash; - - return 1; -} - -static void util_hsupdate(hash_set_t *set) { - size_t *old; - size_t end; - size_t itr; - - /* time to rehash? */ - if ((float)set->total >= (size_t)((double)set->capacity * 0.85)) { - old = set->items; - end = set->capacity; - - set->bits ++; - set->capacity = (size_t)(1 << set->bits); - set->mask = set->capacity - 1; - set->items = (size_t*)mem_a(set->capacity * sizeof(size_t)); - set->total = 0; - - /*assert(set->items);*/ - - /* - * this shouldn't be slow? if so unroll it a little perhaps - * (shouldn't be though) - */ - for (itr = 0; itr < end; itr++) - util_hsput(set, (void*)old[itr]); - - mem_d(old); - } -} - -/* - * EXPOSED interface: all of these functions are exposed to the outside - * for use. The stuff above is static because it's the "internal" mechanics - * for syncronizing the set for updating, and putting data into the set. - */ -int util_hsadd(hash_set_t *set, void *item) { - int run = util_hsput(set, item); /* inlined */ - util_hsupdate(set); - - return run; -} - -/* remove item in set */ -int util_hsrem(hash_set_t *set, void *item) { - size_t hash = (size_t)item; - size_t iter = set->mask & (GMQCC_HASHSET_PRIME0 * hash); - - while (set->items[iter]) { - if (set->items[iter] == hash) { - set->items[iter] = 1; - set->total --; - - return 1; - } - iter = set->mask & (iter + GMQCC_HASHSET_PRIME1); - } - - return 0; -} - -/* check if item is set */ -int util_hshas(hash_set_t *set, void *item) { - size_t hash = (size_t)item; - size_t iter = set->mask & (GMQCC_HASHSET_PRIME0 * hash); - - while (set->items[iter]) { - if (set->items[iter] == hash) - return 1; - - iter = set->mask & (iter + GMQCC_HASHSET_PRIME1); - } - - return 0; -} - -hash_set_t *util_hsnew(void) { - hash_set_t *set; - - if (!(set = (hash_set_t*)mem_a(sizeof(hash_set_t)))) - return NULL; - - set->bits = 3; - set->total = 0; - set->capacity = (size_t)(1 << set->bits); - set->mask = set->capacity - 1; - set->items = (size_t*)mem_a(set->capacity * sizeof(size_t)); - - if (!set->items) { - util_hsdel(set); - return NULL; - } - - return set; -} - -void util_hsdel(hash_set_t *set) { - if (!set) return; - - if (set->items) - mem_d(set->items); - - mem_d(set); -} -#undef GMQCC_HASHSET_PRIME0 -#undef GMQCC_HASHSET_PRIME1 - - /* * Portable implementation of vasprintf/asprintf. Assumes vsnprintf * exists, otherwise compiler error.