mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-01 12:51:24 +02:00
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:
parent
c824c7e29f
commit
f80e782a6b
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user