Parcourir la source

made a more focused branch based on trac397:
- limit the scope to mandatory features for this sprint
also made a couple of suggested cleanups
- move the files to the datasrc lib
- update file names


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac397focused@3737 e5f2f494-b856-4b98-b285-d166d9295462

JINMEI Tatuya il y a 14 ans
Parent
commit
af9d49f3d6

+ 0 - 1
src/bin/auth/Makefile.am

@@ -51,7 +51,6 @@ libasio_link_a_CPPFLAGS = $(AM_CPPFLAGS)
 BUILT_SOURCES = spec_config.h 
 pkglibexec_PROGRAMS = b10-auth
 b10_auth_SOURCES = auth_srv.cc auth_srv.h
-b10_auth_SOURCES += rbt_datasrc.h
 b10_auth_SOURCES += change_user.cc change_user.h
 b10_auth_SOURCES += common.h
 b10_auth_SOURCES += main.cc

+ 0 - 1
src/bin/auth/tests/Makefile.am

@@ -25,7 +25,6 @@ run_unittests_SOURCES += ../rbt_datasrc.h
 run_unittests_SOURCES += auth_srv_unittest.cc
 run_unittests_SOURCES += change_user_unittest.cc
 run_unittests_SOURCES += asio_link_unittest.cc
-run_unittests_SOURCES += rbt_datasrc_unittest.cc
 run_unittests_SOURCES += run_unittests.cc
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 482
src/bin/auth/tests/rbt_datasrc_unittest.cc


+ 1 - 0
src/lib/datasrc/Makefile.am

@@ -14,3 +14,4 @@ libdatasrc_la_SOURCES += static_datasrc.h static_datasrc.cc
 libdatasrc_la_SOURCES += sqlite3_datasrc.h sqlite3_datasrc.cc
 libdatasrc_la_SOURCES += query.h query.cc
 libdatasrc_la_SOURCES += cache.h cache.cc
+libdatasrc_la_SOURCES += rbtree.h

+ 3 - 391
src/bin/auth/rbt_datasrc.h

@@ -17,17 +17,14 @@
 
 #include <dns/name.h>
 #include <boost/utility.hpp>
-#include <boost/shared_ptr.hpp>
 #include <boost/pool/object_pool.hpp>
 #include <exception>
-#include <iostream>
-#include <iterator>
-#include <stack>
+#include <ostream>
 
 namespace isc {
 namespace datasrc {
 
-namespace helper{
+namespace helper {
 /// helper function to remove the base domain from super domain
 /// the precondition of this function is the super_name contains the
 /// sub_name
@@ -72,7 +69,7 @@ class RBNode : public boost::noncopyable {
 public:
     /// only \c RBTree can create and destroy \c RBNode
     friend class RBTree<T>;
-    friend class RBTree<T>::Iterator;
+
     /// \name Test functions
     //@{
     /// \brief return the name of current node, it's relative to its parents
@@ -82,10 +79,6 @@ public:
 
     /// \brief return the data store in this node
     T& getData() { return (data_); }
-
-    /// \brief return the next node which is bigger than current node
-    /// in the same tree
-    RBNode<T>* successor()const;
     //@}
 
     /// \name Modify functions
@@ -174,32 +167,6 @@ RBNode<T>::RBNode(const isc::dns::Name& name) :
 {
 }
 
-
-template <typename T>
-RBNode<T>*
-RBNode<T>::successor()const {
-    RBNode<T>* current = const_cast<RBNode<T>*>(this);
-    // If it has right node, the successor is the left-most node of the right
-    // subtree.
-    if (right_ != NULL_NODE()) {
-        current = right_;
-        while (current->left_ != NULL_NODE()) {
-            current = current->left_;
-        }
-        return (current);
-    }
-
-    // Otherwise go up until we find the first left branch on our path to
-    // root.  If found, the parent of the branch is the successor.
-    // Otherwise, we return the null node.
-    RBNode<T>* parent = current->parent_;
-    while (parent != NULL_NODE() && current == parent->right_) {
-        current = parent;
-        parent = parent->parent_;
-    }
-    return (parent);
-}
-
 template <typename T>
 void
 RBNode<T>::copyContent(RBNode<T>& node) {
@@ -223,8 +190,6 @@ template <typename T>
 class RBTree : public boost::noncopyable {
     friend class RBNode<T>;
 public:
-    /// the max count of labels in a name
-    enum {MAX_PATH_LEN_TO_ROOT = 254};
     /// \brief The return value for the \c find() insert() and erase() method
     enum Result {
         SUCCEED, //insert or erase succeed
@@ -288,74 +253,11 @@ public:
     /// already exists, it is better to call \c insert and then call the
     /// RBNode interface instead of calling \c find().
     Result insert(const isc::dns::Name& name, RBNode<T>** inserted_node);
-
-    /// \brief Erase the node with the domain name
-    /// \return NOTEXSIT means no node with given name
-    /// otherwise return SUCCEED
-    Result erase(const isc::dns::Name& name);
-    //@}
-
-
-
-    /// \brief iterator of domain tree, mainly used to walk throught the whole tree
-    /// in ascending order according to domain name
-    /// \todo make find and insert in domain tree return iterator not rbnode pointer,
-    /// \note the iterator should know the node it points to and the tree the node 
-    /// belongs to, since the tree can only search from up to down, the up nodes 
-    /// has travelled has to be stored, the iterator has similar functionality as 
-    /// dns_rbtnodechain in bind9. Keep the constuction and deconstruction private is
-    /// becuase there is no default iterator.
-    class Iterator : public std::iterator<std::input_iterator_tag, RBNode<T> >
-    {
-        friend class RBTree<T>;
-        public:
-            /// copy and assign constructor 
-            /// \name
-            //@{
-            Iterator(const Iterator& itr);
-            Iterator& operator=(const Iterator& itr);
-            //@}
-
-            const RBNode<T>& operator*() const { return (*node_);}
-            RBNode<T>& operator*()             { return (*node_);}
-
-            const RBNode<T>* operator->() const { return (node_);}
-            RBNode<T>* operator->() { return (node_);}
-
-            Iterator& operator++() { node_ = nextVisibleSuccessor(node_); return (*this);}
-            Iterator  operator++(int) { Iterator old = *this; node_ = nextVisibleSuccessor(node_); return (old);}
-
-            bool operator==(const Iterator &itr) const { return (itr.node_ == node_);}
-            bool operator!=(const Iterator &itr) const { return !(*this == itr); }
-
-        private:
-            /// constructor
-            Iterator(RBNode<T> *node, RBTree<T> *tree, RBNode<T> **nodes_to_root_path = NULL, int path_len = 0);
-            /// the difference between \c successor and \c nextVisibleSuccessor is that, \c nextVisibleSuccessor will
-            /// travel in the whole tree including the down trees, and also it will return non-shadow node
-            RBNode<T> *nextVisibleSuccessor(RBNode<T> *node);
-
-            RBNode<T>* node_;
-            RBTree<T>* tree_;
-            RBNode<T>* up_node_path_[RBTree<T>::MAX_PATH_LEN_TO_ROOT];
-            int path_len_;
-    };
-
-    friend class Iterator;
-    /// \name iterator related functions
-    //@{
-    /// \brief begin point to the smallest visible node in the tree
-    Iterator begin() const;
-    const Iterator begin();
-
-    Iterator end()  const{ return (Iterator(NULLNODE, const_cast<RBTree<T>*>(this)));}
-    const Iterator end() { return (Iterator(NULLNODE, this));}
     //@}
 
 private:
     /// \name RBTree balance functions
     //@{
-    void deleteRebalance(RBNode<T>** root, RBNode<T>* node);
     void insertRebalance(RBNode<T>** root, RBNode<T>* node);
     RBNode<T>* rightRotate(RBNode<T>** root, RBNode<T>* node);
     RBNode<T>* leftRotate(RBNode<T>** root, RBNode<T>* node);
@@ -364,7 +266,6 @@ private:
     /// \name Helper functions
     //@{
     /// Each public function has related recursive helper function
-    void eraseNode(RBNode<T>** root, RBNode<T>* node);
     Result findHelper(const isc::dns::Name& name, RBNode<T>** up,
                       RBNode<T>** node) const;
     void dumpTreeHelper(std::ostream& os, const RBNode<T>* node,
@@ -374,9 +275,6 @@ private:
     /// without throw exception
     RBNode<T>* createNode();
     RBNode<T>* createNode(const isc::dns::Name& name);
-    /// return the node to node pool
-    void  freeNode(RBNode<T>* node);
-
 
     /// 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
@@ -385,16 +283,6 @@ private:
     /// \return NOMEM: means no memory to create new node
     /// otherwise return SUCCEED
     Result nodeFission(RBNode<T>& node, const isc::dns::Name& sub_name);
-
-    /// Merge node with its down node, down node will be deleted and the data of
-    /// down node will move to up node.
-    /// \note the precondition of this function is that, the down tree of node
-    /// has only one node and current node is shadow
-    void nodeFussion(RBNode<T>& node);
-
-    /// return the node with smallest name, according to DNS domain name order
-    /// normally it's the most left node
-    RBNode<T>* smallestNodeInTree(const RBNode<T>* root) const;
     //@}
 
     RBNode<T>*  root_;
@@ -463,15 +351,6 @@ RBTree<T>::createNode(const isc::dns::Name& name) {
 }
 
 template <typename T>
-void
-RBTree<T>::freeNode(RBNode<T>* node) {
-    // NULLNODE isn't alloc in heap
-    assert(node != NULLNODE);
-    node_pool_.destroy(node);
-}
-
-
-template <typename T>
 typename RBTree<T>::Result
 RBTree<T>::find(const isc::dns::Name& name, RBNode<T>** node) const {
     RBNode<T>* up_node = NULL;
@@ -545,36 +424,6 @@ RBTree<T>::findHelper(const isc::dns::Name& target_name, RBNode<T>** up_node,
 }
 
 template <typename T>
-typename RBTree<T>::Iterator
-RBTree<T>::begin() const {
-    Iterator beg(smallestNodeInTree(root_), const_cast<RBTree<T>*>(this));
-    if (beg->is_shadow_) {
-        ++beg;
-    }
-    return (beg);
-}
-
-template <typename T>
-const typename RBTree<T>::Iterator
-RBTree<T>::begin() {
-    Iterator beg(smallestNodeInTree(root_), this);
-    if (beg->is_shadow_) {
-        ++beg;
-    }
-    return (beg);
-}
-
-template <typename T>
-RBNode<T> *
-RBTree<T>::smallestNodeInTree(const RBNode<T>* root) const {
-    const RBNode<T>* left_most = root;
-    while (left_most->left_ != NULLNODE) {
-        left_most = left_most->left_;
-    }
-    return (const_cast<RBNode<T>*>(left_most));
-}
-
-template <typename T>
 typename RBTree<T>::Result
 RBTree<T>::insert(const isc::dns::Name& target_name, RBNode<T>** new_node) {
     using namespace helper;
@@ -789,173 +638,6 @@ RBTree<T>::rightRotate(RBNode<T>** root, RBNode<T>* node) {
     return (node);
 }
 
-
-template <typename T>
-typename RBTree<T>::Result
-RBTree<T>::erase(const isc::dns::Name& name) {
-    RBNode<T>* node = NULLNODE;
-    RBNode<T>* up_node = NULL;
-    if (findHelper(name, &up_node, &node) != RBTree<T>::EXACTMATCH) {
-        return (NOTFOUND);
-    }
-    --name_count_;
-
-    // For node with downpointer, set it to shadow.
-    // Since there is at least one node below this one, the deletion is
-    // complete.  The down node from this node might be all by itself on a
-    // single level, so we could collapse the subtree to reduce the levels
-    if (node->down_ != NULL) {
-        assert(node->is_shadow_ == false);
-        node->is_shadow_ = true;
-        RBNode<T>* down_node = node->down_;
-        if (down_node->left_ == NULLNODE &&
-            down_node->right_ == NULLNODE) {
-            nodeFussion(*node);
-        }
-        return (SUCCEED);
-    }
-
-    RBNode<T>** root = up_node ? &up_node->down_ : &root_;
-    eraseNode(root, node);
-
-    if (up_node != NULL) {
-        assert(up_node->down_ != NULL);
-        RBNode<T>* down_node = up_node->down_;
-        if (down_node == NULLNODE) {
-            up_node->down_ = NULL;
-        // if there is only one node in the sub tree, and the up node
-        // is shadow, merge the root of subtree to the up node
-        } else if (up_node->is_shadow_ &&
-                down_node->left_ == NULLNODE &&
-                down_node->right_ == NULLNODE) {
-            nodeFussion(*up_node);
-        }
-    }
-    return (SUCCEED);
-}
-
-template <typename T>
-void
-RBTree<T>::eraseNode(RBNode<T>** root, RBNode<T>* target) {
-    RBNode<T>* to_delete = target;
-
-    if (to_delete->left_ != NULLNODE && to_delete->right_ != NULLNODE)
-        to_delete = to_delete->successor();
-
-    // fix the parent relationship of the child of to_delete
-    RBNode<T>* child = (to_delete->left_ != NULLNODE) ? to_delete->left_ :
-        to_delete->right_;
-    child->parent_ = to_delete->parent_;
-
-    // fix the child relation of the parent of to delete
-    RBNode<T>* parent = to_delete->parent_;
-    if (parent == NULLNODE) {
-        *root = child;
-    } else if (to_delete == parent->left_) {
-        parent->left_ = child;
-    } else {
-        parent->right_ = child;
-    }
-
-    if (to_delete != target) {
-        to_delete->copyContent(*target);
-        to_delete->down_ = NULL;
-    }
-
-    if (to_delete->color_ == BLACK) {
-        deleteRebalance(root, child);
-    }
-
-    to_delete->left_ = NULL;
-    to_delete->right_ = NULL;
-    to_delete->down_ = NULL;
-    freeNode(to_delete);
-    --node_count_;
-}
-
-template <typename T>
-void
-RBTree<T>::nodeFussion(RBNode<T>& up_node) {
-    RBNode<T>* down_node = up_node.down_;
-    assert(down_node);
-
-    const isc::dns::Name merged_name =
-    down_node->name_.concatenate(up_node.name_);
-    down_node->copyContent(up_node);
-    up_node.down_ = NULL;
-    up_node.name_ = merged_name;
-    up_node.is_shadow_ = false;
-    freeNode(down_node);
-
-    --node_count_;
-}
-
-
-template <typename T>
-void
-RBTree<T>::deleteRebalance(RBNode<T>** root, RBNode<T>* node) {
-    RBNode<T>* sibling  = NULLNODE;
-
-    while (node != *root && node->color_ == BLACK) {
-        if (node == node->parent_->left_) {
-            sibling = node->parent_->right_;
-
-            if (sibling->color_ == RED) {
-                sibling->color_ = BLACK;
-                node->parent_->color_ = RED;
-                leftRotate(root, node->parent_);
-                sibling = node->parent_->right_;
-            }
-
-            if (sibling->left_->color_ == BLACK && sibling->right_->color_ == BLACK) {
-                sibling->color_ = RED;
-                node = node->parent_;
-            } else {
-                if (sibling->right_->color_ == BLACK) {
-                    sibling->left_->color_ = BLACK;
-                    sibling->color_ = RED;
-                    rightRotate(root, sibling);
-                    sibling = node->parent_->right_;
-                }
-
-                sibling->color_ = node->parent_->color_;
-                node->parent_->color_ = BLACK;
-                sibling->right_->color_ = BLACK;
-                leftRotate(root, node->parent_);
-                node = *root;
-            }
-        } else {
-            sibling = node->parent_->left_;
-            if (sibling->color_ == RED) {
-                sibling->color_ = BLACK;
-                node->parent_->color_ = RED;
-                rightRotate(root, node->parent_);
-                sibling = node->parent_->left_;
-            }
-
-            if (sibling->right_->color_ == BLACK && sibling->left_->color_ == BLACK) {
-                sibling->color_ = RED;
-                node = node->parent_;
-            } else {
-                if (sibling->left_->color_ == BLACK) {
-                    sibling->right_->color_ = BLACK;
-                    sibling->color_ = RED;
-                    leftRotate(root, sibling);
-                    sibling = node->parent_->left_;
-                }
-                sibling->color_ = node->parent_->color_;
-                node->parent_->color_ = BLACK;
-                sibling->left_->color_ = BLACK;
-                rightRotate(root, node->parent_);
-                node = *root;
-            }
-        }
-    }
-
-    node->color_ = BLACK;
-}
-
-
 template <typename T>
 void
 RBTree<T>::dumpTree(std::ostream& os, unsigned int depth) const {
@@ -996,76 +678,6 @@ RBTree<T>::dumpTreeHelper(std::ostream& os, const RBNode<T>* node,
     }
 }
 
-template <typename T>
-RBTree<T>::Iterator::Iterator(const RBTree<T>::Iterator& itr) {
-    node_ = itr.node_;
-    tree_ = itr.tree_;
-    path_len_ = itr.path_len_;
-    if (path_len_ > 0) {
-        memcpy(up_node_path_, itr.up_node_path_, path_len_ * sizeof(RBNode<T> *));
-    }
-}
-
-template <typename T>
-typename RBTree<T>::Iterator&
-RBTree<T>::Iterator::operator=(const RBTree<T>::Iterator& itr) {
-    node_ = itr.node_;
-    tree_ = itr.tree_;
-    path_len_ = itr.path_len_;
-    if (path_len_ > 0) {
-        memcpy(up_node_path_, itr.up_node_path_, path_len_ * sizeof(RBNode<T> *));
-    }
-    return (*this);
-}
-
-template <typename T>
-RBTree<T>::Iterator::Iterator(RBNode<T>* node, RBTree<T>* tree,
-                              RBNode<T>** nodes_to_root_path, int path_len) :
-                         node_(node),
-                         tree_(tree),
-                         path_len_(path_len)
-{
-    if (path_len > 0) {
-        memcpy(up_node_path_, nodes_to_root_path, path_len * sizeof(RBNode<T>*));
-    }
-}
-
-template <typename T>
-RBNode<T>*
-RBTree<T>::Iterator::nextVisibleSuccessor(RBNode<T>* node) {
-    // If node has down tree, next bigger node should resides in it
-    if (node->down_) {
-        up_node_path_[path_len_ ++] = node;
-        RBNode<T>* smallest_node = tree_->smallestNodeInTree(node->down_);
-        if (!smallest_node->is_shadow_) {
-            return (smallest_node);
-        } else {
-            return (nextVisibleSuccessor(smallest_node));
-        }
-    }
-    // otherwise found the visible successor in current level
-    // if no successor found move to up level, the next visible successor
-    // is the successor of up node in the up level tree
-    RBNode<T>* next_visible = node->successor();
-    if (next_visible == tree_->NULLNODE) {
-        while (path_len_ > 0) {
-            RBNode<T>* up_node = up_node_path_[--path_len_];
-            RBNode<T>* up_next = up_node->successor();
-            if (up_next != tree_->NULLNODE) {
-                if (up_next->is_shadow_) {
-                    return (nextVisibleSuccessor(up_next));
-                } else {
-                    return (up_next);
-                }
-            }
-        }
-        return (tree_->NULLNODE);
-    } else if (next_visible->is_shadow_) {
-        return nextVisibleSuccessor(next_visible);
-    } else {
-        return (next_visible);
-    }
-}
 }
 }
 

+ 1 - 0
src/lib/datasrc/tests/Makefile.am

@@ -22,6 +22,7 @@ run_unittests_SOURCES += static_unittest.cc
 run_unittests_SOURCES += query_unittest.cc
 run_unittests_SOURCES += cache_unittest.cc
 run_unittests_SOURCES += test_datasrc.h test_datasrc.cc
+run_unittests_SOURCES += rbtree_unittest.cc
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 run_unittests_LDADD = $(GTEST_LDADD)

Fichier diff supprimé car celui-ci est trop grand
+ 160 - 0
src/lib/datasrc/tests/rbtree_unittest.cc