X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=util.c;h=712a9eaa40db597b81e33935a202c0685e9ecf72;hp=92f8e5e4405c0698d29171826826bf07910fe7ee;hb=0b0b6423bae15eae22685f9efc41d6efe70e8ae4;hpb=f2b21158d801e96b5f8d7c9491186267dc75a4dc diff --git a/util.c b/util.c index 92f8e5e..712a9ea 100644 --- a/util.c +++ b/util.c @@ -192,8 +192,8 @@ void util_meminfo() { Total peak memory: %f (MB)\n\ Total leaked memory: %f (MB) in %llu allocations\n", mem_at, - (float)(mem_dt) / 1048576.0f, - mem_ab, + mem_dt, + (float)(mem_ab) / 1048576.0f, (float)(mem_db) / 1048576.0f, (float)(mem_pk) / 1048576.0f, (float)(mem_ab - mem_db) / 1048576.0f, @@ -601,7 +601,7 @@ void *code_util_str_htgeth(hash_table_t *ht, const char *key, size_t bin) { * Free all allocated data in a hashtable, this is quite the amount * of work. */ -void util_htdel(hash_table_t *ht) { +void util_htrem(hash_table_t *ht, void (*callback)(void *data)) { size_t i = 0; for (; i < ht->size; i++) { hash_node_t *n = ht->table[i]; @@ -611,6 +611,8 @@ void util_htdel(hash_table_t *ht) { while (n) { if (n->key) mem_d(n->key); + if (callback) + callback(n->value); p = n; n = n->next; mem_d(p); @@ -622,6 +624,33 @@ void util_htdel(hash_table_t *ht) { mem_d(ht); } +void util_htrmh(hash_table_t *ht, const char *key, size_t bin, void (*cb)(void*)) { + hash_node_t **pair = &ht->table[bin]; + hash_node_t *tmp; + + while (*pair && (*pair)->key && strcmp(key, (*pair)->key) > 0) + pair = &(*pair)->next; + + tmp = *pair; + if (!tmp || !tmp->key || strcmp(key, tmp->key) != 0) + return; + + if (cb) + (*cb)(tmp->value); + + *pair = tmp->next; + mem_d(tmp->key); + mem_d(tmp); +} + +void util_htrm(hash_table_t *ht, const char *key, void (*cb)(void*)) { + util_htrmh(ht, key, util_hthash(ht, key), cb); +} + +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