Some micro-optimization and code beautification.
authorRobert Haas <[email protected]>
Wed, 25 Jul 2012 16:18:31 +0000 (12:18 -0400)
committerRobert Haas <[email protected]>
Wed, 25 Jul 2012 16:18:31 +0000 (12:18 -0400)
src/backend/utils/hash/chash.c

index aa9005ca3ad0ea8b0b67a03ac6e0049daf9a9796..513521851417a8825a584f408c40ad3ba464273b 100644 (file)
@@ -376,20 +376,15 @@ CHashSearch(CHashTable table, void *entry)
        CHashPtr        c;
        volatile CHashNode  *n;
        bool    found = false;
+       int             cmp = 1;
 
        /* Suppress garbage collection for target bucket. */
        CHashTableSuppressGC(table, bucket);
 
        /* Scan bucket. */
        c = table->bucket[bucket].head;
-       for (;;)
+       while (c != InvalidCHashPtr)
        {
-               int             cmp;
-
-               /* If we've reached the end of the bucket chain, stop. */
-               if (c == InvalidCHashPtr)
-                       break;
-
                /* Compare current node by hashcode, then by memcmp. */
                n = CHashTableGetNode(table, c);
                pg_read_barrier_depends();
@@ -401,34 +396,31 @@ CHashSearch(CHashTable table, void *entry)
                        cmp = -1;
 
                /* Stop if we've passed the list position where the entry should be. */
-               if (cmp > 0)
+               if (cmp >= 0)
                        break;
 
                /* Fetch next-pointer. */
                c = n->next;
+       }
 
-               /* Is it the item we're looking for? */
-               if (cmp == 0)
-               {
-                       /*
-                        * If the pointer is marked, it will be followed (if at all) by
-                        * a node which is "later" than this one in terms of either
-                        * hashcode or memcmp ordering; we won't find a duplicate of the
-                        * current key.  This is because a marked CHashPtr is never
-                        * further updated (or at least, not until after garbage
-                        * collection, which we've already prevented for this bucket),
-                        * so the successor element must have been present before this
-                        * one was deleted.
-                        */
-                       if (!CHashPtrIsMarked(c))
-                       {
-                               memcpy(((char *) entry) + table->desc.key_size,
-                                          CHashNodeGetItem(n) + table->desc.key_size,
-                                          table->desc.element_size - table->desc.key_size);
-                               found = true;
-                       }
-                       break;
-               }
+       /*
+        * Is it the item we're looking for?
+        * 
+        * If the pointer is marked, it will be followed (if at all) by
+        * a node which is "later" than this one in terms of either
+        * hashcode or memcmp ordering; we won't find a duplicate of the
+        * current key.  This is because a marked CHashPtr is never
+        * further updated (or at least, not until after garbage
+        * collection, which we've already prevented for this bucket),
+        * so the successor element must have been present before this
+        * one was deleted.
+        */
+       if (cmp == 0 && !CHashPtrIsMarked(n->next))
+       {
+               memcpy(((char *) entry) + table->desc.key_size,
+                          CHashNodeGetItem(n) + table->desc.key_size,
+                          table->desc.element_size - table->desc.key_size);
+               found = true;
        }
 
        /* We're done. */
@@ -472,23 +464,10 @@ CHashInsert(CHashTable table, void *entry)
 retry:
        p = &table->bucket[bucket].head;
        c = *p;
-       for (;;)
+       while (c != InvalidCHashPtr)
        {
                int             cmp;
 
-               /*
-                * We can't safely update a delete-marked pointer, so remove any
-                * such pointers we find from the bucket chain.  Sometimes, concurrent
-                * activity may force us to restart the whole scan, but that should
-                * be rare.
-                */
-               if (CHashPtrIsMarked(c) && CHashRemoveMarked(table, bucket, &c, p))
-                       goto retry;
-
-               /* If we reach the end of the bucket chain, stop. */
-               if (c == InvalidCHashPtr)
-                       break;
-
                /* Compare current node by hashcode, then by memcmp. */
                n = CHashTableGetNode(table, c);
                pg_read_barrier_depends();
@@ -509,6 +488,15 @@ retry:
                /* Move to next node. */
                p = &n->next;
                c = *p;
+
+               /*
+                * We can't safely update a delete-marked pointer, so remove any
+                * such pointers we find from the bucket chain.  Sometimes, concurrent
+                * activity may force us to restart the whole scan, but that should
+                * be rare.
+                */
+               if (CHashPtrIsMarked(c) && CHashRemoveMarked(table, bucket, &c, p))
+                       goto retry;
        }
 
        if (!found)