char *arena; /* arena */
} CHashTableData;
-#define CHashTableGetNode(table, offset) \
+#define CHashTableGetRaw(table, offset) \
(AssertMacro((offset) < (table)->arena_limit), \
(CHashNode *) ((table)->arena + (table)->arena_stride * (offset)))
+#define CHashTableGetNode(table, ptr) \
+ (AssertMacro((ptr) != InvalidCHashPtr), \
+ CHashTableGetRaw((table), CHashPtrGetOffset((ptr))))
/*
* We need a memory barrier to make sure that our bucket advertisement is
for (i = 0; i < table->arena_limit; ++i)
{
CHashBucket *f = &table->freelist[i % table->nfreelists];
- CHashNode *n = CHashTableGetNode(table, i);
+ CHashNode *n = CHashTableGetRaw(table, i);
n->un.gcnext = f->head;
- f->head = i;
+ f->head = MakeCHashPtr(i);
}
/*
break;
/* Compare current node by hashcode, then by memcmp. */
- n = CHashTableGetNode(table, CHashPtrGetOffset(c));
+ n = CHashTableGetNode(table, c);
pg_read_barrier_depends();
if (n->un.hashcode == hashcode)
cmp = memcmp(CHashNodeGetItem(n), entry, table->desc.key_size);
}
}
- /* Return result to caller. */
+ /* We're done. */
+ CHashTableUnsuppressGC();
return found;
}
break;
/* Compare current node by hashcode, then by memcmp. */
- n = CHashTableGetNode(table, CHashPtrGetOffset(c));
+ n = CHashTableGetNode(table, c);
pg_read_barrier_depends();
if (n->un.hashcode == hashcode)
cmp = memcmp(CHashNodeGetItem(n), entry, table->desc.key_size);
/* Done scanning bucket. */
CHashTableUnsuppressGC();
+ /* If the insert failed, free the entry we allocated. */
+ if (found)
+ {
+ /* XXX Need some code here! */
+ }
+
/* The insert succeeded if and only if no duplicate was found. */
return !found;
}
if (new != InvalidCHashPtr)
{
CHashNode *n = CHashTableGetNode(table, new);
- vtable->freelist[f_current].head = n->next;
+ vtable->freelist[f_current].head = n->un.gcnext;
SpinLockRelease(&vtable->freelist[f_current].mutex);
return new;
}
/* Remove one item from list to satisfy current allocation. */
new = garbage;
- n = CHashTableGetNode(table, CHashPtrGetOffset(new));
+ n = CHashTableGetNode(table, new);
fhead = n->un.gcnext;
/* If that's all there was, we're done. */
fcurrent = fhead;
for (;;)
{
- n = CHashTableGetNode(table, CHashPtrGetOffset(fcurrent));
+ n = CHashTableGetNode(table, fcurrent);
fnext = n->un.gcnext;
if (fnext == InvalidCHashPtr)
break;
pg_read_barrier_depends();
/* Read next-pointer of deleted node. */
- n = CHashTableGetNode(table, CHashPtrGetOffset(c));
+ n = CHashTableGetNode(table, c);
cc = n->next;
/*