From 7093b464ca6a1637a22e21bf4ac1af273eb78086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Tue, 31 Dec 2013 12:31:11 +0100 Subject: [PATCH] Simplified rebalancing code extracting common operations to a local variable --- .../boost/intrusive/avltree_algorithms.hpp | 47 ++++++++++--------- include/boost/intrusive/rbtree_algorithms.hpp | 41 ++++------------ 2 files changed, 35 insertions(+), 53 deletions(-) diff --git a/include/boost/intrusive/avltree_algorithms.hpp b/include/boost/intrusive/avltree_algorithms.hpp index 526649a..54f9fe0 100644 --- a/include/boost/intrusive/avltree_algorithms.hpp +++ b/include/boost/intrusive/avltree_algorithms.hpp @@ -364,13 +364,14 @@ class avltree_algorithms node_ptr x(xnode), x_parent(xnode_parent); for (node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)) { const balance x_parent_balance = NodeTraits::get_balance(x_parent); + node_ptr const x_parent_left(NodeTraits::get_left(x_parent)); if(x_parent_balance == NodeTraits::zero()){ - NodeTraits::set_balance(x_parent, - (x == NodeTraits::get_right(x_parent) ? NodeTraits::negative() : NodeTraits::positive())); + NodeTraits::set_balance( x_parent + , x == x_parent_left ? NodeTraits::positive() : NodeTraits::negative() ); break; // the height didn't change, let's stop here } else if(x_parent_balance == NodeTraits::negative()){ - if (x == NodeTraits::get_left(x_parent)) { + if (x == x_parent_left) { NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced x = x_parent; x_parent = NodeTraits::get_parent(x_parent); @@ -378,7 +379,7 @@ class avltree_algorithms else { // x is right child // a is left child - node_ptr a = NodeTraits::get_left(x_parent); + node_ptr a = x_parent_left; BOOST_INTRUSIVE_INVARIANT_ASSERT(a); if (NodeTraits::get_balance(a) == NodeTraits::positive()) { // a MUST have a right child @@ -441,38 +442,38 @@ class avltree_algorithms NodeTraits::set_balance(x, NodeTraits::zero()); // Rebalance. for(node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)){ - const balance x_parent_balance = NodeTraits::get_balance(NodeTraits::get_parent(x)); - + node_ptr const x_parent(NodeTraits::get_parent(x)); + node_ptr const x_parent_left(NodeTraits::get_left(x_parent)); + const balance x_parent_balance = NodeTraits::get_balance(x_parent); if(x_parent_balance == NodeTraits::zero()){ // if x is left, parent will have parent->bal_factor = negative // else, parent->bal_factor = NodeTraits::positive() - NodeTraits::set_balance( NodeTraits::get_parent(x) - , x == NodeTraits::get_left(NodeTraits::get_parent(x)) - ? NodeTraits::negative() : NodeTraits::positive() ); - x = NodeTraits::get_parent(x); + NodeTraits::set_balance( x_parent, x == x_parent_left + ? NodeTraits::negative() : NodeTraits::positive() ); + x = x_parent; } else if(x_parent_balance == NodeTraits::positive()){ // if x is a left child, parent->bal_factor = zero - if (x == NodeTraits::get_left(NodeTraits::get_parent(x))) - NodeTraits::set_balance(NodeTraits::get_parent(x), NodeTraits::zero()); + if (x == x_parent_left) + NodeTraits::set_balance(x_parent, NodeTraits::zero()); else{ // x is a right child, needs rebalancing if (NodeTraits::get_balance(x) == NodeTraits::negative()) - rotate_right_left(NodeTraits::get_parent(x), header); + rotate_right_left(x_parent, header); else - rotate_left(NodeTraits::get_parent(x), header); + rotate_left(x_parent, header); } break; } else if(x_parent_balance == NodeTraits::negative()){ // if x is a left child, needs rebalancing - if (x == NodeTraits::get_left(NodeTraits::get_parent(x))) { + if (x == x_parent_left) { if (NodeTraits::get_balance(x) == NodeTraits::positive()) - rotate_left_right(NodeTraits::get_parent(x), header); + rotate_left_right(x_parent, header); else - rotate_right(NodeTraits::get_parent(x), header); + rotate_right(x_parent, header); } else - NodeTraits::set_balance(NodeTraits::get_parent(x), NodeTraits::zero()); + NodeTraits::set_balance(x_parent, NodeTraits::zero()); break; } else{ @@ -486,18 +487,20 @@ class avltree_algorithms // balancing... const balance c_balance = NodeTraits::get_balance(c); const balance zero_balance = NodeTraits::zero(); + const balance posi_balance = NodeTraits::positive(); + const balance nega_balance = NodeTraits::negative(); NodeTraits::set_balance(c, zero_balance); - if(c_balance == NodeTraits::negative()){ - NodeTraits::set_balance(a, NodeTraits::positive()); + if(c_balance == nega_balance){ + NodeTraits::set_balance(a, posi_balance); NodeTraits::set_balance(b, zero_balance); } else if(c_balance == zero_balance){ NodeTraits::set_balance(a, zero_balance); NodeTraits::set_balance(b, zero_balance); } - else if(c_balance == NodeTraits::positive()){ + else if(c_balance == posi_balance){ NodeTraits::set_balance(a, zero_balance); - NodeTraits::set_balance(b, NodeTraits::negative()); + NodeTraits::set_balance(b, nega_balance); } else{ BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached diff --git a/include/boost/intrusive/rbtree_algorithms.hpp b/include/boost/intrusive/rbtree_algorithms.hpp index 529ef90..e20b4d8 100644 --- a/include/boost/intrusive/rbtree_algorithms.hpp +++ b/include/boost/intrusive/rbtree_algorithms.hpp @@ -10,31 +10,6 @@ // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// -// The internal implementation of red-black trees is based on that of SGI STL -// stl_tree.h file: -// -// Copyright (c) 1996,1997 -// Silicon Graphics Computer Systems, Inc. -// -// Permission to use, copy, modify, distribute and sell this software -// and its documentation for any purpose is hereby granted without fee, -// provided that the above copyright notice appear in all copies and -// that both that copyright notice and this permission notice appear -// in supporting documentation. Silicon Graphics makes no -// representations about the suitability of this software for any -// purpose. It is provided "as is" without express or implied warranty. -// -// -// Copyright (c) 1994 -// Hewlett-Packard Company -// -// Permission to use, copy, modify, distribute and sell this software -// and its documentation for any purpose is hereby granted without fee, -// provided that the above copyright notice appear in all copies and -// that both that copyright notice and this permission notice appear -// in supporting documentation. Hewlett-Packard Company makes no -// representations about the suitability of this software for any -// purpose. It is provided "as is" without express or implied warranty. // // The tree destruction algorithm is based on Julienne Walker and The EC Team code: // @@ -421,14 +396,16 @@ class rbtree_algorithms bstree_algo::rotate_left(x_parent, header); w = NodeTraits::get_right(x_parent); } - if((!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()) && - (!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black())){ + node_ptr const w_left (NodeTraits::get_left(w)); + node_ptr const w_right(NodeTraits::get_right(w)); + if((!w_left || NodeTraits::get_color(w_left) == NodeTraits::black()) && + (!w_right || NodeTraits::get_color(w_right) == NodeTraits::black())){ NodeTraits::set_color(w, NodeTraits::red()); x = x_parent; x_parent = NodeTraits::get_parent(x_parent); } else { - if(!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()){ + if(!w_right || NodeTraits::get_color(w_right) == NodeTraits::black()){ NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black()); NodeTraits::set_color(w, NodeTraits::red()); bstree_algo::rotate_right(w, header); @@ -451,14 +428,16 @@ class rbtree_algorithms bstree_algo::rotate_right(x_parent, header); w = NodeTraits::get_left(x_parent); } - if((!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()) && - (!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black())){ + node_ptr const w_left (NodeTraits::get_left(w)); + node_ptr const w_right(NodeTraits::get_right(w)); + if((!w_right || NodeTraits::get_color(w_right) == NodeTraits::black()) && + (!w_left || NodeTraits::get_color(w_left) == NodeTraits::black())){ NodeTraits::set_color(w, NodeTraits::red()); x = x_parent; x_parent = NodeTraits::get_parent(x_parent); } else { - if(!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()){ + if(!w_left || NodeTraits::get_color(w_left) == NodeTraits::black()){ NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black()); NodeTraits::set_color(w, NodeTraits::red()); bstree_algo::rotate_left(w, header);