Clarify the new Red-Black post-order traversal code a bit.
authorHeikki Linnakangas <[email protected]>
Sun, 4 Sep 2016 12:02:06 +0000 (15:02 +0300)
committerHeikki Linnakangas <[email protected]>
Sun, 4 Sep 2016 12:02:06 +0000 (15:02 +0300)
Coverity complained about the for(;;) loop, because it never actually
iterated. It was used just to be able to use "break" to exit it early. I
agree with Coverity, that's a bit confusing, so refactor the code to
use if-else instead.

While we're at it, use a local variable to hold the "current" node. That's
shorter and clearer than referring to "iter->last_visited" all the time.

src/backend/lib/rbtree.c

index 242e9803ccc54245046474671c174a3bb0e7937b..7fb7e55f716b24116dd99b4992aab5597479d1b4 100644 (file)
@@ -781,27 +781,30 @@ static RBNode *
 rb_inverted_iterator(RBTreeIterator *iter)
 {
        RBNode     *came_from;
+       RBNode     *current;
+
+       current = iter->last_visited;
 
 loop:
        switch ((InvertedWalkNextStep) iter->next_step)
        {
                        /* First call, begin from root */
                case NextStepBegin:
-                       iter->last_visited = iter->rb->root;
+                       current = iter->rb->root;
                        iter->next_step = NextStepLeft;
                        goto loop;
 
                case NextStepLeft:
-                       while (iter->last_visited->left != RBNIL)
-                               iter->last_visited = iter->last_visited->left;
+                       while (current->left != RBNIL)
+                               current = current->left;
 
                        iter->next_step = NextStepRight;
                        goto loop;
 
                case NextStepRight:
-                       if (iter->last_visited->right != RBNIL)
+                       if (current->right != RBNIL)
                        {
-                               iter->last_visited = iter->last_visited->right;
+                               current = current->right;
                                iter->next_step = NextStepLeft;
                                goto loop;
                        }
@@ -810,30 +813,29 @@ loop:
                        break;
 
                case NextStepUp:
-                       for (;;)
+                       came_from = current;
+                       current = current->parent;
+                       if (current == NULL)
+                       {
+                               iter->is_over = true;
+                               break;          /* end of iteration */
+                       }
+                       else if (came_from == current->right)
+                       {
+                               /* return current, then continue to go up */
+                               break;
+                       }
+                       else
                        {
-                               came_from = iter->last_visited;
-                               iter->last_visited = iter->last_visited->parent;
-                               if (iter->last_visited == NULL)
-                               {
-                                       iter->is_over = true;
-                                       break;          /* end of iteration */
-                               }
-
-                               if (came_from == iter->last_visited->right)
-                               {
-                                       /* return current, then continue to go up */
-                                       break;
-                               }
-
                                /* otherwise we came from the left */
+                               Assert(came_from == current->left);
                                iter->next_step = NextStepRight;
                                goto loop;
                        }
-                       break;
        }
 
-       return iter->last_visited;
+       iter->last_visited = current;
+       return current;
 }
 
 /*