Browse Source

remove object pool use auto_ptr to handle exception

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac397focused@3776 e5f2f494-b856-4b98-b285-d166d9295462
Han Feng 14 years ago
parent
commit
402c223760
1 changed files with 47 additions and 43 deletions
  1. 47 43
      src/lib/datasrc/rbtree.h

+ 47 - 43
src/lib/datasrc/rbtree.h

@@ -17,7 +17,6 @@
 
 
 #include <dns/name.h>
 #include <dns/name.h>
 #include <boost/utility.hpp>
 #include <boost/utility.hpp>
-#include <boost/pool/object_pool.hpp>
 #include <exception>
 #include <exception>
 #include <ostream>
 #include <ostream>
 #include <algorithm>
 #include <algorithm>
@@ -334,21 +333,20 @@ private:
     /// \name Helper functions
     /// \name Helper functions
     //@{
     //@{
     /// Each public function has related recursive helper function
     /// Each public function has related recursive helper function
+    /// \brief tree with node as its root
+    void deleteHelper(RBNode<T> *node);
+    /// \brief find the node with name
+    /// \param name is the target, up will points to the base domain of 
+    /// the tree which name resides, node will point to the target node
+    /// if we has exact same name or partical name in current tree.
+    /// so for example, in zone a, we has 
+    /// b.a, c.b.a and d.b.a search c.b.a, up will points to b.a. 
+    /// and node will points to c.b.a
     Result findHelper(const isc::dns::Name& name, RBNode<T>** up,
     Result findHelper(const isc::dns::Name& name, RBNode<T>** up,
                       RBNode<T>** node) const;
                       RBNode<T>** node) const;
     void dumpTreeHelper(std::ostream& os, const RBNode<T>* node,
     void dumpTreeHelper(std::ostream& os, const RBNode<T>* node,
                         unsigned int depth) const;
                         unsigned int depth) const;
 
 
-    /// \brief get one node from the node pool, if no memory left return NULL
-    /// without throw exception
-    /// 
-    /// \note For node memory management, it maybe useful let the node
-    /// allocation as a template parameter, just like std::map, by default it
-    /// use std::allocator. And in this way, developer can handle the memory 
-    /// management in his own way. 
-    RBNode<T>* createNode();
-    RBNode<T>* createNode(const isc::dns::Name& name);
-
     /// Split one node into two nodes, keep the old node and create one new
     /// Split one node into two nodes, keep the old node and create one new
     /// node, old node will hold the base name, new node will be the down node
     /// node, old node will hold the base name, new node will be the down node
     /// of old node, new node will hold the sub_name, the data
     /// of old node, new node will hold the sub_name, the data
@@ -364,8 +362,6 @@ private:
     unsigned int node_count_;
     unsigned int node_count_;
     /// the count of real name user inserted into the domain tree
     /// the count of real name user inserted into the domain tree
     unsigned int name_count_;
     unsigned int name_count_;
-    /// use mem pool to manage rbnode to accelerate node creation and destruction
-    boost::object_pool<RBNode<T> > node_pool_;
 };
 };
 
 
 template <typename T>
 template <typename T>
@@ -378,19 +374,34 @@ RBTree<T>::RBTree() {
 
 
 template <typename T>
 template <typename T>
 RBTree<T>::~RBTree() {
 RBTree<T>::~RBTree() {
-    assert(root_ != NULL);
+    deleteHelper(root_);
 }
 }
 
 
 template <typename T>
 template <typename T>
-RBNode<T>*
-RBTree<T>::createNode() {
-    return node_pool_.construct();
-}
+void RBTree<T> ::deleteHelper(RBNode<T> *root) {
+    if (root == NULLNODE) {
+        return;
+    }
+    
+    RBNode<T> *node = root;
+    while (root->left_ != NULLNODE || root->right_ != NULLNODE) {
+        while (node->left_ != NULLNODE || node->right_ != NULLNODE) {
+            node = (node->left_ != NULLNODE) ? node->left_ : node->right_;
+        }
 
 
-template <typename T>
-RBNode<T>*
-RBTree<T>::createNode(const isc::dns::Name& name) {
-    return node_pool_.construct(name);
+        RBNode<T> *parent = node->parent_;
+        if (parent->left_ == node) {
+            parent->left_ = NULLNODE;
+        } else {
+            parent->right_ = NULLNODE;
+        }
+
+        if (node->down_) {
+            deleteHelper(node->down_);
+        }
+        delete node;
+        node = parent;
+    }
 }
 }
 
 
 template <typename T>
 template <typename T>
@@ -503,18 +514,16 @@ RBTree<T>::insert(const isc::dns::Name& target_name, RBNode<T>** new_node) {
                 // insert sub domain to sub tree
                 // insert sub domain to sub tree
                 if (relation == isc::dns::NameComparisonResult::SUBDOMAIN) {
                 if (relation == isc::dns::NameComparisonResult::SUBDOMAIN) {
                     if (current->down_ == NULL) {
                     if (current->down_ == NULL) {
-                        RBNode<T>* node = createNode(name - current->name_);
-                        if (node == NULL) {
-                            return (NOMEM);
-                        }
+                        std::auto_ptr<RBNode<T> > node(new RBNode<T>(name - current->name_));
                         //root node of sub tree, the initial color is BLACK
                         //root node of sub tree, the initial color is BLACK
                         node->color_ = BLACK;
                         node->color_ = BLACK;
-                        current->down_ = node;
+                        current->down_ = node.get();
                         if (new_node != NULL) {
                         if (new_node != NULL) {
-                            *new_node = node;
+                            *new_node = node.get();
                         }
                         }
                         ++node_count_;
                         ++node_count_;
                         ++name_count_;
                         ++name_count_;
+                        node.release();
                         return (SUCCEED);
                         return (SUCCEED);
                     } else {
                     } else {
                         up_node = current;
                         up_node = current;
@@ -539,26 +548,23 @@ RBTree<T>::insert(const isc::dns::Name& target_name, RBNode<T>** new_node) {
     }
     }
 
 
     RBNode<T>** current_root = up_node ? &(up_node->down_) : &root_;
     RBNode<T>** current_root = up_node ? &(up_node->down_) : &root_;
-    RBNode<T>* node = createNode(name);
-    if (node == NULL) {
-        return (NOMEM);
-    }
-
+    std::auto_ptr<RBNode<T> > node(new RBNode<T>(name));
     node->parent_ = parent;
     node->parent_ = parent;
     if (parent == NULLNODE) {
     if (parent == NULLNODE) {
-        *current_root = node;
+        *current_root = node.get();
     } else if (order < 0) {
     } else if (order < 0) {
-        parent->left_ = node;
+        parent->left_ = node.get();
     } else {
     } else {
-        parent->right_ = node;
+        parent->right_ = node.get();
     }
     }
-    insertRebalance(current_root, node);
+    insertRebalance(current_root, node.get());
     if (new_node != NULL) {
     if (new_node != NULL) {
-        *new_node = node;
+        *new_node = node.get();
     }
     }
 
 
     ++node_count_;
     ++node_count_;
     ++name_count_;
     ++name_count_;
+    node.release();
     return (SUCCEED);
     return (SUCCEED);
 }
 }
 
 
@@ -568,18 +574,16 @@ typename RBTree<T>::Result
 RBTree<T>::nodeFission(RBNode<T>& node, const isc::dns::Name& base_name) {
 RBTree<T>::nodeFission(RBNode<T>& node, const isc::dns::Name& base_name) {
     using namespace helper;
     using namespace helper;
     const isc::dns::Name sub_name = node.name_ - base_name;
     const isc::dns::Name sub_name = node.name_ - base_name;
-    RBNode<T>* down_node = createNode(node.name_ - base_name);
-    if (down_node == NULL) {
-        return (NOMEM);
-    }
+    std::auto_ptr<RBNode<T> > down_node(new RBNode<T>(node.name_ - base_name));
 
 
     node.swap(*down_node);
     node.swap(*down_node);
     node.name_ = base_name;
     node.name_ = base_name;
-    node.down_ = down_node;
+    node.down_ = down_node.get();
     down_node->name_ = sub_name;
     down_node->name_ = sub_name;
     //root node of sub tree, the initial color is BLACK
     //root node of sub tree, the initial color is BLACK
     down_node->color_ = BLACK;
     down_node->color_ = BLACK;
     ++node_count_;
     ++node_count_;
+    down_node.release();
     return (SUCCEED);
     return (SUCCEED);
 }
 }