Remove pre-order and post-order traversal logic for red-black trees.

This code isn't used, and there's no clear reason why anybody would ever
want to use it.  These traversal mechanisms don't yield a visitation order
that is semantically meaningful for any external purpose, nor are they
any faster or simpler than the left-to-right or right-to-left traversals.
(In fact, some rough testing suggests they are slower :-(.)  Moreover,
these mechanisms are impossible to test in any arm's-length fashion; doing
so requires knowledge of the red-black tree's internal implementation.
Hence, let's just jettison them.

Discussion: https://postgr.es/m/17735.1505003111@sss.pgh.pa.us
This commit is contained in:
Tom Lane 2017-09-10 13:19:11 -04:00
parent c824c7e29f
commit f80e782a6b
2 changed files with 3 additions and 131 deletions

View File

@ -62,17 +62,6 @@ struct RBTree
static RBNode sentinel = {RBBLACK, RBNIL, RBNIL, NULL}; static RBNode sentinel = {RBBLACK, RBNIL, RBNIL, NULL};
/*
* Values used in the RBTreeIterator.next_state field, with an
* InvertedWalk iterator.
*/
typedef enum InvertedWalkNextStep
{
NextStepBegin,
NextStepUp,
NextStepLeft,
NextStepRight
} InvertedWalkNextStep;
/* /*
* rb_create: create an empty RBTree * rb_create: create an empty RBTree
@ -567,6 +556,7 @@ rb_delete_node(RBTree *rb, RBNode *z)
RBNode *x, RBNode *x,
*y; *y;
/* This is just paranoia: we should only get called on a valid node */
if (!z || z == RBNIL) if (!z || z == RBNIL)
return; return;
@ -730,114 +720,6 @@ rb_right_left_iterator(RBTreeIterator *iter)
return iter->last_visited; return iter->last_visited;
} }
static RBNode *
rb_direct_iterator(RBTreeIterator *iter)
{
if (iter->last_visited == NULL)
{
iter->last_visited = iter->rb->root;
return iter->last_visited;
}
if (iter->last_visited->left != RBNIL)
{
iter->last_visited = iter->last_visited->left;
return iter->last_visited;
}
do
{
if (iter->last_visited->right != RBNIL)
{
iter->last_visited = iter->last_visited->right;
break;
}
/* go up and one step right */
for (;;)
{
RBNode *came_from = iter->last_visited;
iter->last_visited = iter->last_visited->parent;
if (iter->last_visited == NULL)
{
iter->is_over = true;
break;
}
if ((iter->last_visited->right != came_from) && (iter->last_visited->right != RBNIL))
{
iter->last_visited = iter->last_visited->right;
return iter->last_visited;
}
}
}
while (iter->last_visited != NULL);
return iter->last_visited;
}
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:
current = iter->rb->root;
iter->next_step = NextStepLeft;
goto loop;
case NextStepLeft:
while (current->left != RBNIL)
current = current->left;
iter->next_step = NextStepRight;
goto loop;
case NextStepRight:
if (current->right != RBNIL)
{
current = current->right;
iter->next_step = NextStepLeft;
goto loop;
}
else /* not moved - return current, then go up */
iter->next_step = NextStepUp;
break;
case NextStepUp:
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
{
/* otherwise we came from the left */
Assert(came_from == current->left);
iter->next_step = NextStepRight;
goto loop;
}
}
iter->last_visited = current;
return current;
}
/* /*
* rb_begin_iterate: prepare to traverse the tree in any of several orders * rb_begin_iterate: prepare to traverse the tree in any of several orders
* *
@ -849,7 +731,7 @@ loop:
* tree are allowed. * tree are allowed.
* *
* The iterator state is stored in the 'iter' struct. The caller should * The iterator state is stored in the 'iter' struct. The caller should
* treat it as opaque struct. * treat it as an opaque struct.
*/ */
void void
rb_begin_iterate(RBTree *rb, RBOrderControl ctrl, RBTreeIterator *iter) rb_begin_iterate(RBTree *rb, RBOrderControl ctrl, RBTreeIterator *iter)
@ -867,13 +749,6 @@ rb_begin_iterate(RBTree *rb, RBOrderControl ctrl, RBTreeIterator *iter)
case RightLeftWalk: /* visit right, then self, then left */ case RightLeftWalk: /* visit right, then self, then left */
iter->iterate = rb_right_left_iterator; iter->iterate = rb_right_left_iterator;
break; break;
case DirectWalk: /* visit self, then left, then right */
iter->iterate = rb_direct_iterator;
break;
case InvertedWalk: /* visit left, then right, then self */
iter->iterate = rb_inverted_iterator;
iter->next_step = NextStepBegin;
break;
default: default:
elog(ERROR, "unrecognized rbtree iteration order: %d", ctrl); elog(ERROR, "unrecognized rbtree iteration order: %d", ctrl);
} }

View File

@ -35,9 +35,7 @@ typedef struct RBTree RBTree;
typedef enum RBOrderControl typedef enum RBOrderControl
{ {
LeftRightWalk, /* inorder: left child, node, right child */ LeftRightWalk, /* inorder: left child, node, right child */
RightLeftWalk, /* reverse inorder: right, node, left */ RightLeftWalk /* reverse inorder: right, node, left */
DirectWalk, /* preorder: node, left child, right child */
InvertedWalk /* postorder: left child, right child, node */
} RBOrderControl; } RBOrderControl;
/* /*
@ -52,7 +50,6 @@ struct RBTreeIterator
RBTree *rb; RBTree *rb;
RBNode *(*iterate) (RBTreeIterator *iter); RBNode *(*iterate) (RBTreeIterator *iter);
RBNode *last_visited; RBNode *last_visited;
char next_step;
bool is_over; bool is_over;
}; };