From 4752550f80206d7ab15daefb68532374f1b5a527 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 23 Jul 2014 13:19:09 +0200 Subject: rbtree: Simplify _RBTree_Rotate() Add and use _RBTree_Direction(). --- cpukit/score/include/rtems/score/rbtreeimpl.h | 78 +++++++++++++++++++++------ testsuites/sptests/sprbtree01/init.c | 1 - 2 files changed, 61 insertions(+), 18 deletions(-) diff --git a/cpukit/score/include/rtems/score/rbtreeimpl.h b/cpukit/score/include/rtems/score/rbtreeimpl.h index 451b5f453a..5f5e78367a 100644 --- a/cpukit/score/include/rtems/score/rbtreeimpl.h +++ b/cpukit/score/include/rtems/score/rbtreeimpl.h @@ -76,6 +76,21 @@ RTEMS_INLINE_ROUTINE RBTree_Direction _RBTree_Opposite_direction( return (RBTree_Direction) !((int) the_dir); } +/** + * @brief Returns the direction of the node. + * + * @param[in] the_node The node of interest. + * @param[in] parent The parent of the node. The parent must exist, thus it is + * invalid to use this function for the root node. + */ +RTEMS_INLINE_ROUTINE RBTree_Direction _RBTree_Direction( + const RBTree_Node *the_node, + const RBTree_Node *parent +) +{ + return (RBTree_Direction) ( the_node != parent->child[ 0 ] ); +} + /** * @brief Is this node red. * @@ -166,32 +181,61 @@ RTEMS_INLINE_ROUTINE bool _RBTree_Is_lesser( } /** - * @brief Rotate the_node in the direction passed as second argument. + * @brief Rotates the node in the specified direction. * - * This routine rotates @a the_node to the direction @a dir, swapping - * @a the_node with its child\[@a dir\]. + * The node is swapped with its child in the opposite direction if it exists. + * + * Sub-tree before rotation: + * @dot + * digraph state { + * parent -> the_node; + * the_node -> sibling [label="dir"]; + * the_node -> child [label="opp_dir"]; + * child -> grandchild [label="dir"]; + * child -> grandchildsibling [label="opp_dir"]; + * } + * @enddot + * + * Sub-tree after rotation: + * @dot + * digraph state { + * parent -> child; + * the_node -> sibling [label="dir"]; + * the_node -> grandchild [label="opp_dir"]; + * child -> the_node [label="dir"]; + * child -> grandchildsibling [label="opp_dir"]; + * } + * @enddot + * + * @param[in] the_node The node to rotate. + * @param[in] dir The rotation direction. */ RTEMS_INLINE_ROUTINE void _RBTree_Rotate( - RBTree_Node *the_node, - RBTree_Direction dir - ) + RBTree_Node *the_node, + RBTree_Direction dir +) { - RBTree_Node *c; - if (the_node == NULL) return; - if (the_node->child[_RBTree_Opposite_direction(dir)] == NULL) return; + RBTree_Direction opp_dir = _RBTree_Opposite_direction( dir ); + RBTree_Node *child = the_node->child[ opp_dir ]; + RBTree_Node *grandchild; + RBTree_Node *parent; + + if ( child == NULL) + return; - c = the_node->child[_RBTree_Opposite_direction(dir)]; - the_node->child[_RBTree_Opposite_direction(dir)] = c->child[dir]; + grandchild = child->child[ dir ]; + the_node->child[ opp_dir ] = grandchild; - if (c->child[dir]) - c->child[dir]->parent = the_node; + if ( grandchild != NULL ) + grandchild->parent = the_node; - c->child[dir] = the_node; + child->child[ dir ] = the_node; - the_node->parent->child[the_node != the_node->parent->child[0]] = c; + parent = _RBTree_Parent( the_node ); + parent->child[ _RBTree_Direction( the_node, parent ) ] = child; - c->parent = the_node->parent; - the_node->parent = c; + child->parent = parent; + the_node->parent = child; } /** @} */ diff --git a/testsuites/sptests/sprbtree01/init.c b/testsuites/sptests/sprbtree01/init.c index ffb91b103f..734530e6bd 100644 --- a/testsuites/sptests/sprbtree01/init.c +++ b/testsuites/sptests/sprbtree01/init.c @@ -858,7 +858,6 @@ rtems_task Init( rtems_task_argument ignored ) rtems_test_assert( !rtems_rbtree_is_node_off_tree( &node1.Node ) ); - _RBTree_Rotate(NULL, RBT_LEFT); i = (node1.Node.parent == &node2.Node); _RBTree_Rotate( &node1.Node, !node1.Node.child[RBT_LEFT] ? RBT_RIGHT : RBT_LEFT -- cgit v1.2.3