Thinko: of course, invalid CHashPtrs can also be delete-marked.
authorRobert Haas <[email protected]>
Fri, 27 Jul 2012 16:34:50 +0000 (16:34 +0000)
committerRobert Haas <[email protected]>
Fri, 27 Jul 2012 16:34:50 +0000 (16:34 +0000)
src/backend/utils/hash/chash.c

index cfef6d57459261e5214dd3f53dcc5f8aa5b0fdc5..a076da07c25c57622ce018d708632066d04284ea 100644 (file)
  */
 typedef uint32 CHashPtr;
 #define InvalidCHashPtr                                ((uint32) -2)
+#define CHashPtrIsInvalid(x)           ((x) >= InvalidCHashPtr)
 #define CHashPtrIsMarked(x)                    ((x) & 1)
 #define CHashPtrGetOffset(x)           ((x) >> 1)
 #define CHashPtrMark(x)                                ((x) | 1)
@@ -160,7 +161,7 @@ typedef struct CHashTableData
        (AssertMacro((offset) < (table)->arena_limit), \
         (CHashNode *) ((table)->arena + (table)->arena_stride * (offset)))
 #define CHashTableGetNode(table, ptr) \
-       (AssertMacro((ptr) != InvalidCHashPtr), \
+       (AssertMacro(!CHashPtrIsInvalid(ptr)), \
         CHashTableGetRaw((table), CHashPtrGetOffset((ptr))))
 
 /*
@@ -580,7 +581,7 @@ retry:
                 * If we've reached the end of the bucket chain, stop; otherwise,
                 * figure out the actual address of the next item.
                 */
-               if (target == InvalidCHashPtr)
+               if (CHashPtrIsInvalid(target))
                {
                        res->found = false;
                        break;
@@ -748,7 +749,7 @@ CHashAllocate(CHashTable table)
                /* Try to pop a buffer from a freelist using compare-and-swap. */
                b = &table->freelist[f_current];
                new = *b;
-               if (new != InvalidCHashPtr)
+               if (!CHashPtrIsInvalid(new))
                {
                        CHashNode  *n = CHashTableGetNode(table, new);
 
@@ -766,7 +767,7 @@ CHashAllocate(CHashTable table)
                table->gc_next = (table->gc_next + 1) % table->ngarbage;
                b = &table->garbage[table->gc_next];
                garbage = *b;
-               if (garbage != InvalidCHashPtr &&
+               if (!CHashPtrIsInvalid(garbage) &&
                        __sync_bool_compare_and_swap(b, garbage, InvalidCHashPtr))
                {
                        uint64          chash_bucket;
@@ -801,7 +802,7 @@ CHashAllocate(CHashTable table)
                        fhead = n->un.gcnext;
 
                        /* Put any remaining elements back on the free list. */
-                       if (fhead != InvalidCHashPtr)
+                       if (!CHashPtrIsInvalid(fhead))
                        {
                                CHashPtr        fcurrent;
                                CHashPtr        fnext;
@@ -813,7 +814,7 @@ CHashAllocate(CHashTable table)
                                {
                                        n = CHashTableGetNode(table, fcurrent);
                                        fnext = n->un.gcnext;
-                                       if (fnext == InvalidCHashPtr)
+                                       if (CHashPtrIsInvalid(fnext))
                                                break;
                                        fcurrent = fnext;
                                }
@@ -922,7 +923,7 @@ retry:
                 * If we've reached the end of the bucket chain, stop; otherwise,
                 * figure out the actual address of the next item.
                 */
-               if (target == InvalidCHashPtr)
+               if (CHashPtrIsInvalid(target))
                        break;
                target_node = CHashTableGetNode(table, target);