ref: ff6e3444ff9cb3f8877f9d4c2653236609bae4f2
parent: 1252169ce7027d50158d5a12bad0a2a1b92ce3f7
author: Ori Bernstein <[email protected]>
date: Thu Sep 5 09:00:19 EDT 2013
Add deletion functions to hash table.
--- a/parse/htab.c
+++ b/parse/htab.c
@@ -24,6 +24,7 @@
ht->keys = zalloc(Initsz*sizeof(void*));
ht->vals = zalloc(Initsz*sizeof(void*));
ht->hashes = zalloc(Initsz*sizeof(void*));
+ ht->dead = zalloc(Initsz*sizeof(char));
return ht;
}
@@ -37,6 +38,7 @@
free(ht->keys);
free(ht->vals);
free(ht->hashes);
+ free(ht->dead);
free(ht);
}
@@ -60,6 +62,7 @@
void **oldk;
void **oldv;
ulong *oldh;
+ char *oldd;
int oldsz;
int i;
@@ -66,6 +69,7 @@
oldk = ht->keys;
oldv = ht->vals;
oldh = ht->hashes;
+ oldd = ht->dead;
oldsz = ht->sz;
ht->nelt = 0;
@@ -73,13 +77,15 @@
ht->keys = zalloc(sz*sizeof(void*));
ht->vals = zalloc(sz*sizeof(void*));
ht->hashes = zalloc(sz*sizeof(void*));
+ ht->dead = zalloc(sz*sizeof(void*));
for (i = 0; i < oldsz; i++)
- if (oldh[i])
+ if (oldh[i] && !oldd[i])
htput(ht, oldk[i], oldv[i]);
free(oldh);
free(oldk);
free(oldv);
+ free(oldd);
}
/* Inserts 'k' into the hash table, possibly
@@ -94,9 +100,10 @@
di = 0;
h = hash(ht, k);
i = h & (ht->sz - 1);
- while (ht->hashes[i]) {
- /* second insertion overwrites first */
- if (ht->hashes[i] == h && ht->cmp(ht->keys[i], k))
+ while (ht->hashes[i] && !ht->dead[i]) {
+ /* second insertion overwrites first. nb, we shouldn't touch the
+ * keys for dead values */
+ if (ht->hashes[i] == h && (ht->dead[i] || ht->cmp(ht->keys[i], k)))
break;
di++;
i = (h + di) & (ht->sz - 1);
@@ -104,6 +111,7 @@
ht->hashes[i] = h;
ht->keys[i] = k;
ht->vals[i] = v;
+ ht->dead[i] = 0;
ht->nelt++;
if (ht->sz < ht->nelt*2)
grow(ht, ht->sz*2);
@@ -121,12 +129,12 @@
di = 0;
h = hash(ht, k);
i = h & (ht->sz - 1);
- while (ht->hashes[i] && ht->hashes[i] != h) {
+ while (ht->hashes[i] && !ht->dead[i] && ht->hashes[i] != h) {
searchmore:
di++;
i = (h + di) & (ht->sz - 1);
}
- if (!ht->hashes[i])
+ if (!ht->hashes[i] || ht->dead[i])
return -1;
if (!ht->cmp(ht->keys[i], k))
goto searchmore; /* collision */
@@ -149,6 +157,17 @@
return ht->vals[i];
}
+void htdel(Htab *ht, void *k)
+{
+ ssize_t i;
+
+ i = htidx(ht, k);
+ if (i < 0)
+ return;
+ ht->dead[i] = 1;
+}
+
+
/* Tests for 'k's presence in 'ht' */
int hthas(Htab *ht, void *k)
{
@@ -168,7 +187,7 @@
j = 0;
k = xalloc(sizeof(void*)*ht->nelt);
for (i = 0; i < ht->sz; i++)
- if (ht->hashes[i])
+ if (ht->hashes[i] && !ht->dead[i])
k[j++] = ht->keys[i];
*nkeys = ht->nelt;
return k;
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -75,6 +75,7 @@
void **keys;
void **vals;
ulong *hashes;
+ char *dead;
};
struct Tok {
@@ -296,6 +297,7 @@
Htab *mkht(ulong (*hash)(void *key), int (*cmp)(void *k1, void *k2));
void htfree(Htab *ht);
int htput(Htab *ht, void *k, void *v);
+void htdel(Htab *ht, void *k);
void *htget(Htab *ht, void *k);
int hthas(Htab *ht, void *k);
void **htkeys(Htab *ht, size_t *nkeys);