From: Robert Haas Date: Wed, 25 Jul 2012 14:02:53 +0000 (-0400) Subject: More bug fixing. X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=15a2ab292eef636687d618ad0e52b21791cf9c4d;p=users%2Frhaas%2Fpostgres.git More bug fixing. --- diff --git a/src/backend/utils/hash/chash.c b/src/backend/utils/hash/chash.c index 4fc4e143f3..2c003c7225 100644 --- a/src/backend/utils/hash/chash.c +++ b/src/backend/utils/hash/chash.c @@ -157,9 +157,12 @@ typedef struct CHashTableData 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 @@ -342,10 +345,10 @@ CHashInitialize(CHashTable table, CHashDescriptor *desc) 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); } /* @@ -387,7 +390,7 @@ CHashSearch(CHashTable table, void *entry) 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); @@ -427,7 +430,8 @@ CHashSearch(CHashTable table, void *entry) } } - /* Return result to caller. */ + /* We're done. */ + CHashTableUnsuppressGC(); return found; } @@ -485,7 +489,7 @@ retry: 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); @@ -542,6 +546,12 @@ retry: /* 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; } @@ -591,7 +601,7 @@ CHashAllocate(CHashTable table) 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; } @@ -655,7 +665,7 @@ CHashAllocate(CHashTable table) /* 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. */ @@ -666,7 +676,7 @@ CHashAllocate(CHashTable table) fcurrent = fhead; for (;;) { - n = CHashTableGetNode(table, CHashPtrGetOffset(fcurrent)); + n = CHashTableGetNode(table, fcurrent); fnext = n->un.gcnext; if (fnext == InvalidCHashPtr) break; @@ -719,7 +729,7 @@ CHashRemoveMarked(CHashTable table, uint32 bucket, CHashPtr *cp, pg_read_barrier_depends(); /* Read next-pointer of deleted node. */ - n = CHashTableGetNode(table, CHashPtrGetOffset(c)); + n = CHashTableGetNode(table, c); cc = n->next; /*