More bug fixing.
authorRobert Haas <rhaas@postgresql.org>
Wed, 25 Jul 2012 14:02:53 +0000 (10:02 -0400)
committerRobert Haas <rhaas@postgresql.org>
Tue, 27 Jan 2015 02:24:21 +0000 (02:24 +0000)
src/backend/utils/hash/chash.c

index 4fc4e143f3ffb2d7681862646139004d0d55d0b4..2c003c72257035fef7915ddf11d5b797a3552e51 100644 (file)
@@ -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;
 
                /*