aboutsummaryrefslogtreecommitdiffhomepage
path: root/mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'mem.c')
-rw-r--r--mem.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/mem.c b/mem.c
index 3efe1b6..2532234 100644
--- a/mem.c
+++ b/mem.c
@@ -249,17 +249,20 @@ pmap_init_(struct pmapbase *m, void **v, uint vsiz, uint N)
m->N = N;
}
-int pmap_get_(struct pmapbase *m, const void *k)
+int
+pmap_get_(struct pmapbase *m, const void *k)
{
assert(k && "null key");
if (!m->N) return -1;
- for (int i = ptrhash(k);; ++i) {
+ for (size_t i = ptrhash(k);; ++i) {
i &= m->N - 1;
if (m->k[i] == k) return i;
if (!m->k[i]) return -1;
}
}
+char pmap_tombstone_[1];
+
static void
pmap_rehash(struct pmapbase *m, void **v, uint vsiz)
{
@@ -275,7 +278,7 @@ pmap_rehash(struct pmapbase *m, void **v, uint vsiz)
newk = xcalloc(sizk + sizv);
newv = (char *)newk + sizk;
for (i = 0; i < m->N; ++i) {
- if (!m->k[i])
+ if (!m->k[i] || m->k[i] == pmap_tombstone_)
continue;
j = ptrhash(k = m->k[i]);
for (;; ++j) {
@@ -293,18 +296,19 @@ pmap_rehash(struct pmapbase *m, void **v, uint vsiz)
m->N = N2;
}
-int pmap_set_(struct pmapbase *m, void **v, uint vsiz, const void *k)
+int
+pmap_set_(struct pmapbase *m, void **v, uint vsiz, const void *k)
{
assert(k && "null key");
if (m->n >= m->N/4*3 /*load factor 75%*/) {
pmap_rehash(m, v, vsiz);
assert(m->n < m->N);
}
- for (int i = ptrhash(k);; ++i) {
+ for (size_t i = ptrhash(k);; ++i) {
i &= m->N - 1;
if (m->k[i] == k)
return i;
- if (!m->k[i]) {
+ if (!m->k[i] || m->k[i] == pmap_tombstone_) {
m->k[i] = (void *)k;
++m->n;
return i;
@@ -312,4 +316,19 @@ int pmap_set_(struct pmapbase *m, void **v, uint vsiz, const void *k)
}
}
+void
+pmap_del_(struct pmapbase *m, const void *k)
+{
+ assert(k && "null key");
+ for (size_t i = ptrhash(k);; ++i) {
+ i &= m->N - 1;
+ if (m->k[i] == k) {
+ m->k[i] = pmap_tombstone_;
+ --m->n;
+ return;
+ } else if (!m->k[i])
+ return;
+ }
+}
+
/* vim:set ts=3 sw=3 expandtab: */