Browse Source

[2091] use memory segment for creating/destroying RBNodes.

Like the previous change, the part of the changes are big, but this is
essentially a straightforward refactoring.
JINMEI Tatuya 12 years ago
parent
commit
d6b44e0b1a

+ 21 - 15
src/lib/datasrc/memory_datasrc.cc

@@ -134,7 +134,7 @@ struct ZoneData {
         nsec_signed_(false)
     {
         // We create the node for origin (it needs to exist anyway in future)
-        domains_.insert(origin, &origin_data_);
+        domains_.insert(local_mem_sgmt_, origin, &origin_data_);
         DomainPtr origin_domain(new Domain);
         origin_data_->setData(origin_domain);
     }
@@ -886,7 +886,9 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
     //
     // We also perform the same trick for empty wild card names possibly
     // contained in 'name' (e.g., '*.foo.example' in 'bar.*.foo.example').
-    void addWildcards(DomainTree& domains, const Name& name) {
+    void addWildcards(util::MemorySegment& mem_sgmt, DomainTree& domains,
+                      const Name& name)
+    {
         Name wname(name);
         const unsigned int labels(wname.getLabelCount());
         const unsigned int origin_labels(origin_.getLabelCount());
@@ -899,7 +901,8 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
                 // Ensure a separate level exists for the "wildcarding" name,
                 // and mark the node as "wild".
                 DomainNode* node;
-                DomainTree::Result result(domains.insert(wname.split(1),
+                DomainTree::Result result(domains.insert(mem_sgmt,
+                                                         wname.split(1),
                                                          &node));
                 assert(result == DomainTree::SUCCESS ||
                        result == DomainTree::ALREADYEXISTS);
@@ -909,7 +912,7 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
                 // Note: for 'name' itself we do this later anyway, but the
                 // overhead should be marginal because wildcard names should
                 // be rare.
-                result = domains.insert(wname, &node);
+                result = domains.insert(mem_sgmt, wname, &node);
                 assert(result == DomainTree::SUCCESS ||
                        result == DomainTree::ALREADYEXISTS);
             }
@@ -1196,12 +1199,14 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
         // tree.
         // Note: this can throw an exception, breaking strong exception
         // guarantee.  (see also the note for contextCheck() below).
-        addWildcards(zone_data.domains_, rrset->getName());
+        addWildcards(zone_data.local_mem_sgmt_, zone_data.domains_,
+                     rrset->getName());
 
         // Get the node
         DomainNode* node;
-        DomainTree::Result result = zone_data.domains_.insert(rrset->getName(),
-                                                              &node);
+        DomainTree::Result result =
+            zone_data.domains_.insert(zone_data.local_mem_sgmt_,
+                                      rrset->getName(), &node);
         // Just check it returns reasonable results
         assert((result == DomainTree::SUCCESS ||
                 result == DomainTree::ALREADYEXISTS) && node!= NULL);
@@ -1634,7 +1639,8 @@ addAdditional(RBNodeRRset* rrset, ZoneData* zone_data,
             // Wildcard and glue shouldn't coexist.  Make it sure here.
             assert(!node->getFlag(domain_flag::GLUE));
 
-            if (zone_data->getAuxWildDomains().insert(name, &wildnode)
+            if (zone_data->getAuxWildDomains().insert(
+                    zone_data->local_mem_sgmt_, name, &wildnode)
                 == DomainTree::SUCCESS) {
                 // If we first insert the node, copy the RRsets.  If the
                 // original node was empty, we add empty data so
@@ -1812,20 +1818,19 @@ InMemoryZoneFinder::getFileName() const {
 class InMemoryClient::InMemoryClientImpl {
 public:
     InMemoryClientImpl() : zone_count(0),
-                           zone_table(ZoneTable::create(local_mem_sgmt_))
+                           zone_table(ZoneTable::create(local_mem_sgmt))
     {}
     ~InMemoryClientImpl() {
-        ZoneTable::destroy(local_mem_sgmt_, zone_table);
+        ZoneTable::destroy(local_mem_sgmt, zone_table);
 
         // see above for the assert().
-        assert(local_mem_sgmt_.allMemoryDeallocated());
+        assert(local_mem_sgmt.allMemoryDeallocated());
     }
-private:
+
     // Memory segment to allocate/deallocate memory for the zone table.
     // (This will eventually have to be abstract; for now we hardcode the
     // specific derived segment class).
-    util::MemorySegmentLocal local_mem_sgmt_;
-public:
+    util::MemorySegmentLocal local_mem_sgmt;
     unsigned int zone_count;
     ZoneTable* zone_table;
 };
@@ -1852,7 +1857,8 @@ InMemoryClient::addZone(ZoneFinderPtr zone_finder) {
     LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEM_ADD_ZONE).
         arg(zone_finder->getOrigin()).arg(zone_finder->getClass().toText());
 
-    const result::Result result = impl_->zone_table->addZone(zone_finder);
+    const result::Result result =
+        impl_->zone_table->addZone(impl_->local_mem_sgmt, zone_finder);
     if (result == result::SUCCESS) {
         ++impl_->zone_count;
     }

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

@@ -107,8 +107,42 @@ private:
     /// \param name The *relative* domain name (if this will live inside
     ///     a.b.c and is called d.e.a.b.c, then you pass d.e).
     RBNode(const isc::dns::Name& name);
+
+    /// \brief Destructor
+    ~RBNode();
     //@}
 
+    /// \brief Allocate and construct \c RBNode
+    ///
+    /// This static method allocates memory for a new \c RBNode object
+    /// from the given memory segment, constructs the object, and returns
+    /// a pointer to it.
+    ///
+    /// \throw std::bad_alloc Memory allocation fails.
+    ///
+    /// \param mem_sgmt A \c MemorySegment from which memory for the new
+    /// \c RBNode is allocated.
+    static RBNode<T>* create(util::MemorySegment& mem_sgmt,
+                             const dns::Name& name)
+    {
+        void* p = mem_sgmt.allocate(sizeof(RBNode<T>));
+        return (new(p) RBNode<T>(name));
+    }
+
+    /// \brief Destruct and deallocate \c RBNode
+    ///
+    /// \throw none
+    ///
+    /// \param mem_sgmt The \c MemorySegment that allocated memory for
+    /// \c rbnode.
+    /// \param ztable A non NULL pointer to a valid \c RBNode object
+    /// that was originally created by the \c create() method (the behavior
+    /// is undefined if this condition isn't met).
+    static void destroy(util::MemorySegment& mem_sgmt, RBNode<T>* rbnode) {
+        rbnode->~RBNode<T>();
+        mem_sgmt.deallocate(rbnode, sizeof(RBNode<T>));
+    }
+
 public:
     /// \brief Alias for shared pointer to the data.
     typedef boost::shared_ptr<T> NodeDataPtr;
@@ -141,17 +175,6 @@ private:
 
 public:
 
-    /// \brief Destructor
-    ///
-    /// It might seem strange that constructors are private and destructor
-    /// public, but this is needed because of shared pointers need access
-    /// to the destructor.
-    ///
-    /// You should never call anything like:
-    /// \code delete pointer_to_node; \endcode
-    /// The RBTree handles both creation and destructoion of nodes.
-    ~RBNode();
-
     /// \name Getter functions.
     //@{
     /// \brief Return the name of current node.
@@ -728,14 +751,19 @@ public:
 
     /// \brief Destruct and deallocate \c RBTree
     ///
+    /// This method also destroys and deallocates all nodes inserted to the
+    /// tree.
+    ///
     /// \throw none
     ///
     /// \param mem_sgmt The \c MemorySegment that allocated memory for
-    /// \c rbtree.
+    /// \c rbtree (and for all nodes inserted to the tree, due to the
+    /// requirement of \c insert()).
     /// \param rbtree A non NULL pointer to a valid \c RBTree object
     /// that was originally created by the \c create() method (the behavior
     /// is undefined if this condition isn't met).
     static void destroy(util::MemorySegment& mem_sgmt, RBTree<T>* rbtree) {
+        rbtree->deleteAllNodes(mem_sgmt);
         rbtree->~RBTree<T>();
         mem_sgmt.deallocate(rbtree, sizeof(RBTree<T>));
     }
@@ -1037,6 +1065,9 @@ public:
     /// the same.  This method provides the weak exception guarantee in its
     /// normal sense.
     ///
+    /// \param mem_sgmt A \c MemorySegment object for allocating memory of
+    /// a new node to be inserted.  Must be the same segment as that used
+    /// for creating the tree itself.
     /// \param name The name to be inserted into the tree.
     /// \param inserted_node This is an output parameter and is set to the
     ///     node.
@@ -1045,7 +1076,17 @@ public:
     ///  - SUCCESS The node was added.
     ///  - ALREADYEXISTS There was already a node of that name, so it was not
     ///     added.
-    Result insert(const isc::dns::Name& name, RBNode<T>** inserted_node);
+    Result insert(util::MemorySegment& mem_sgmt, const isc::dns::Name& name,
+                  RBNode<T>** inserted_node);
+
+    /// \brief Delete all tree nodes.
+    ///
+    /// \throw none.
+    ///
+    /// \param mem_sgmt The \c MemorySegment object used to insert the nodes
+    /// (which was also used for creating the tree due to the requirement of
+    /// \c inert()).
+    void deleteAllNodes(util::MemorySegment& mem_sgmt);
 
     /// \brief Swaps two tree's contents.
     ///
@@ -1069,7 +1110,7 @@ private:
     /// \name Helper functions
     //@{
     /// \brief delete tree whose root is equal to node
-    void deleteHelper(RBNode<T> *node);
+    void deleteHelper(util::MemorySegment& mem_sgmt, RBNode<T> *node);
 
     /// \brief Print the information of given RBNode.
     void dumpTreeHelper(std::ostream& os, const RBNode<T>* node,
@@ -1081,8 +1122,10 @@ private:
     /// 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
     /// of old node, new node will hold the sub_name, the data
-    /// of old node will be move into new node, and old node became non-terminal
-    void nodeFission(RBNode<T>& node, const isc::dns::Name& sub_name);
+    /// of old node will be move into new node, and old node became
+    /// non-terminal
+    void nodeFission(util::MemorySegment& mem_sgmt, RBNode<T>& node,
+                     const isc::dns::Name& sub_name);
     //@}
 
     RBNode<T>*  NULLNODE;
@@ -1104,13 +1147,12 @@ RBTree<T>::RBTree(bool returnEmptyNode) :
 
 template <typename T>
 RBTree<T>::~RBTree() {
-    deleteHelper(root_);
     assert(node_count_ == 0);
 }
 
 template <typename T>
 void
-RBTree<T>::deleteHelper(RBNode<T>* root) {
+RBTree<T>::deleteHelper(util::MemorySegment& mem_sgmt, RBNode<T>* root) {
     if (root == NULLNODE) {
         return;
     }
@@ -1128,14 +1170,14 @@ RBTree<T>::deleteHelper(RBNode<T>* root) {
             parent->right_ = NULLNODE;
         }
 
-        deleteHelper(node->down_);
-        delete node;
+        deleteHelper(mem_sgmt, node->down_);
+        RBNode<T>::destroy(mem_sgmt, node);
         --node_count_;
         node = parent;
     }
 
-    deleteHelper(root->down_);
-    delete root;
+    deleteHelper(mem_sgmt, root->down_);
+    RBNode<T>::destroy(mem_sgmt, root);
     --node_count_;
 }
 
@@ -1388,7 +1430,9 @@ RBTree<T>::previousNode(RBTreeNodeChain<T>& node_path) const {
 
 template <typename T>
 typename RBTree<T>::Result
-RBTree<T>::insert(const isc::dns::Name& target_name, RBNode<T>** new_node) {
+RBTree<T>::insert(util::MemorySegment& mem_sgmt,
+                  const isc::dns::Name& target_name, RBNode<T>** new_node)
+{
     using namespace helper;
     RBNode<T>* parent = NULLNODE;
     RBNode<T>* current = root_;
@@ -1429,7 +1473,7 @@ RBTree<T>::insert(const isc::dns::Name& target_name, RBNode<T>** new_node) {
                     const isc::dns::Name common_ancestor = name.split(
                         name.getLabelCount() - common_label_count,
                         common_label_count);
-                    nodeFission(*current, common_ancestor);
+                    nodeFission(mem_sgmt, *current, common_ancestor);
                 }
             }
         }
@@ -1437,34 +1481,37 @@ RBTree<T>::insert(const isc::dns::Name& target_name, RBNode<T>** new_node) {
 
     RBNode<T>** current_root = (up_node != NULLNODE) ?
         &(up_node->down_) : &root_;
-    // using auto_ptr here is avoid memory leak in case of exceptoin raised
-    // after the RBNode creation, if we can make sure no exception will be
-    // raised until the end of the function, we can remove it for optimization
-    std::auto_ptr<RBNode<T> > node(new RBNode<T>(name));
+    // Once a new node is created, no exception will be thrown until the end
+    // of the function, so we can simply create and hold a new node pointer.
+    RBNode<T>* node = RBNode<T>::create(mem_sgmt, name);
     node->parent_ = parent;
     if (parent == NULLNODE) {
-        *current_root = node.get();
-        //node is the new root of sub tree, so its init color
-        // is BLACK
+        *current_root = node;
+        // node is the new root of sub tree, so its init color is BLACK
         node->setColor(RBNode<T>::BLACK);
         node->setSubTreeRoot(true);
     } else if (order < 0) {
         node->setSubTreeRoot(false);
-        parent->left_ = node.get();
+        parent->left_ = node;
     } else {
         node->setSubTreeRoot(false);
-        parent->right_ = node.get();
+        parent->right_ = node;
     }
-    insertRebalance(current_root, node.get());
+    insertRebalance(current_root, node);
     if (new_node != NULL) {
-        *new_node = node.get();
+        *new_node = node;
     }
 
     ++node_count_;
-    node.release();
     return (SUCCESS);
 }
 
+template <typename T>
+void
+RBTree<T>::deleteAllNodes(util::MemorySegment& mem_sgmt) {
+    deleteHelper(mem_sgmt, root_);
+    root_ = NULLNODE;
+}
 
 // Note: when we redesign this (still keeping the basic concept), we should
 // change this part so the newly created node will be used for the inserted
@@ -1472,12 +1519,14 @@ RBTree<T>::insert(const isc::dns::Name& target_name, RBNode<T>** new_node) {
 // Otherwise, things like shortcut links between nodes won't work.
 template <typename T>
 void
-RBTree<T>::nodeFission(RBNode<T>& node, const isc::dns::Name& base_name) {
+RBTree<T>::nodeFission(util::MemorySegment& mem_sgmt, RBNode<T>& node,
+                       const isc::dns::Name& base_name)
+{
     using namespace helper;
     const isc::dns::Name sub_name = node.name_ - base_name;
-    // using auto_ptr here is to avoid memory leak in case of exception raised
-    // after the RBNode creation
-    std::auto_ptr<RBNode<T> > down_node(new RBNode<T>(sub_name));
+    // Note: the following code is not entirely exception safe (name copy
+    // can result in exception), but will soon be so within Trac #2091.
+    RBNode<T>* down_node = RBNode<T>::create(mem_sgmt, sub_name);
     node.name_ = base_name;
     // the rest of this function should be exception free so that it keeps
     // consistent behavior (i.e., a weak form of strong exception guarantee)
@@ -1486,9 +1535,10 @@ RBTree<T>::nodeFission(RBNode<T>& node, const isc::dns::Name& base_name) {
     std::swap(node.flags_, down_node->flags_);
 
     down_node->down_ = node.down_;
-    node.down_ = down_node.get();
+    node.down_ = down_node;
 
-    // Restore the color of the node (may have gotten changed by the flags swap)
+    // Restore the color of the node (may have gotten changed by the flags
+    // swap)
     node.setColor(down_node->getColor());
 
     // root node of sub tree, the initial color is BLACK
@@ -1498,7 +1548,6 @@ RBTree<T>::nodeFission(RBNode<T>& node, const isc::dns::Name& base_name) {
     down_node->setSubTreeRoot(true);
 
     ++node_count_;
-    down_node.release();
 }
 
 

+ 78 - 38
src/lib/datasrc/tests/rbtree_unittest.cc

@@ -85,10 +85,11 @@ protected:
             "j.z.d.e.f", "p.w.y.d.e.f", "q.w.y.d.e.f", "k.g.h"};
         int name_count = sizeof(domain_names) / sizeof(domain_names[0]);
         for (int i = 0; i < name_count; ++i) {
-            rbtree.insert(Name(domain_names[i]), &rbtnode);
+            rbtree.insert(mem_sgmt_, Name(domain_names[i]), &rbtnode);
             rbtnode->setData(RBNode<int>::NodeDataPtr(new int(i + 1)));
 
-            rbtree_expose_empty_node.insert(Name(domain_names[i]), &rbtnode);
+            rbtree_expose_empty_node.insert(mem_sgmt_, Name(domain_names[i]),
+                                            &rbtnode);
             rbtnode->setData(RBNode<int>::NodeDataPtr(new int(i + 1)));
 
         }
@@ -103,8 +104,13 @@ protected:
     const RBNode<int>* crbtnode;
 };
 
-TEST_F(RBTreeTest, getNodeCount) {
+TEST_F(RBTreeTest, nodeCount) {
     EXPECT_EQ(14, rbtree.getNodeCount());
+
+    // Delete all nodes, then the count should be set to 0.  This also tests
+    // the behavior of deleteAllNodes().
+    rbtree.deleteAllNodes(mem_sgmt_);
+    EXPECT_EQ(0, rbtree.getNodeCount());
 }
 
 TEST_F(RBTreeTest, setGetData) {
@@ -113,64 +119,92 @@ TEST_F(RBTreeTest, setGetData) {
 }
 
 TEST_F(RBTreeTest, insertNames) {
-    EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(Name("d.e.f"),
+    EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt_,
+                                                        Name("d.e.f"),
                                                         &rbtnode));
     EXPECT_EQ(Name("d.e.f"), rbtnode->getName());
     EXPECT_EQ(14, rbtree.getNodeCount());
 
     //insert not exist node
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("."), &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("."),
+                                                  &rbtnode));
     EXPECT_EQ(Name("."), rbtnode->getName());
     EXPECT_EQ(15, rbtree.getNodeCount());
 
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("example.com"), &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
+                                                  Name("example.com"),
+                                                  &rbtnode));
     EXPECT_EQ(16, rbtree.getNodeCount());
     rbtnode->setData(RBNode<int>::NodeDataPtr(new int(12)));
 
     // return ALREADYEXISTS, since node "example.com" already has been explicitly inserted
-    EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(Name("example.com"), &rbtnode));
+    EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt_,
+                                                        Name("example.com"),
+                                                        &rbtnode));
     EXPECT_EQ(16, rbtree.getNodeCount());
 
     // split the node "d.e.f"
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("k.e.f"), &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("k.e.f"),
+                                                  &rbtnode));
     EXPECT_EQ(Name("k"), rbtnode->getName());
     EXPECT_EQ(18, rbtree.getNodeCount());
 
     // split the node "g.h"
-    EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(Name("h"), &rbtnode));
+    EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt_, Name("h"),
+                                                        &rbtnode));
     EXPECT_EQ(Name("h"), rbtnode->getName());
     EXPECT_EQ(19, rbtree.getNodeCount());
 
     // add child domain
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("m.p.w.y.d.e.f"), &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
+                                                  Name("m.p.w.y.d.e.f"),
+                                                  &rbtnode));
     EXPECT_EQ(Name("m"), rbtnode->getName());
     EXPECT_EQ(20, rbtree.getNodeCount());
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("n.p.w.y.d.e.f"), &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
+                                                  Name("n.p.w.y.d.e.f"),
+                                                  &rbtnode));
     EXPECT_EQ(Name("n"), rbtnode->getName());
     EXPECT_EQ(21, rbtree.getNodeCount());
 
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("l.a"), &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("l.a"),
+                                                  &rbtnode));
     EXPECT_EQ(Name("l"), rbtnode->getName());
     EXPECT_EQ(22, rbtree.getNodeCount());
 
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("r.d.e.f"), &rbtnode));
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("s.d.e.f"), &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("r.d.e.f"),
+                                                  &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("s.d.e.f"),
+                                                  &rbtnode));
     EXPECT_EQ(24, rbtree.getNodeCount());
 
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("h.w.y.d.e.f"), &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
+                                                  Name("h.w.y.d.e.f"),
+                                                  &rbtnode));
 
     // add more nodes one by one to cover leftRotate and rightRotate
-    EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(Name("f"), &rbtnode));
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("m"), &rbtnode));
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("nm"), &rbtnode));
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("om"), &rbtnode));
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("k"), &rbtnode));
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("l"), &rbtnode));
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("fe"), &rbtnode));
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("ge"), &rbtnode));
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("i"), &rbtnode));
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("ae"), &rbtnode));
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("n"), &rbtnode));
+    EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt_, Name("f"),
+                                                        &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("m"),
+                                                  &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("nm"),
+                                                  &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("om"),
+                                                  &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("k"),
+                                                  &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("l"),
+                                                  &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("fe"),
+                                                  &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("ge"),
+                                                  &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("i"),
+                                                  &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("ae"),
+                                                  &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("n"),
+                                                  &rbtnode));
 }
 
 TEST_F(RBTreeTest, findName) {
@@ -213,7 +247,8 @@ TEST_F(RBTreeTest, findError) {
 }
 
 TEST_F(RBTreeTest, flags) {
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("flags.example"),
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
+                                                  Name("flags.example"),
                                                   &rbtnode));
 
     // by default, flags are all off
@@ -244,7 +279,8 @@ testCallback(const RBNode<int>&, bool* callack_checker) {
 
 TEST_F(RBTreeTest, callback) {
     // by default callback isn't enabled
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("callback.example"),
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
+                                                  Name("callback.example"),
                                                   &rbtnode));
     rbtnode->setData(RBNode<int>::NodeDataPtr(new int(1)));
     EXPECT_FALSE(rbtnode->getFlag(RBNode<int>::FLAG_CALLBACK));
@@ -259,12 +295,14 @@ TEST_F(RBTreeTest, callback) {
     rbtnode->setFlag(RBNode<int>::FLAG_CALLBACK);
     // add more levels below and above the callback node for partial match.
     RBNode<int>* subrbtnode;
-    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(Name("sub.callback.example"),
+    EXPECT_EQ(RBTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
+                                                  Name("sub.callback.example"),
                                                   &subrbtnode));
     subrbtnode->setData(RBNode<int>::NodeDataPtr(new int(2)));
     RBNode<int>* parentrbtnode;
-    EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(Name("example"),
-                                                       &parentrbtnode));
+    EXPECT_EQ(RBTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt_,
+                                                        Name("example"),
+                                                        &parentrbtnode));
     //  the chilld/parent nodes shouldn't "inherit" the callback flag.
     // "rbtnode" may be invalid due to the insertion, so we need to re-find
     // it.
@@ -304,7 +342,8 @@ TEST_F(RBTreeTest, chainLevel) {
     TreeHolder tree_holder(mem_sgmt_, RBTree<int>::create(mem_sgmt_, true));
     RBTree<int>& tree(*tree_holder.get());
     Name node_name(Name::ROOT_NAME());
-    EXPECT_EQ(RBTree<int>::SUCCESS, tree.insert(node_name, &rbtnode));
+    EXPECT_EQ(RBTree<int>::SUCCESS, tree.insert(mem_sgmt_, node_name,
+                                                &rbtnode));
     EXPECT_EQ(RBTree<int>::EXACTMATCH,
               tree.find(node_name, &crbtnode, chain));
     EXPECT_EQ(1, chain.getLevelCount());
@@ -326,7 +365,8 @@ TEST_F(RBTreeTest, chainLevel) {
      */
     for (unsigned int i = 2; i <= Name::MAX_LABELS; ++i) {
         node_name = Name("a.").concatenate(node_name);
-        EXPECT_EQ(RBTree<int>::SUCCESS, tree.insert(node_name, &rbtnode));
+        EXPECT_EQ(RBTree<int>::SUCCESS, tree.insert(mem_sgmt_, node_name,
+                                                    &rbtnode));
         RBTreeNodeChain<int> found_chain;
         EXPECT_EQ(RBTree<int>::EXACTMATCH,
                   tree.find(node_name, &crbtnode, found_chain));
@@ -763,7 +803,7 @@ TEST_F(RBTreeTest, swap) {
     TreeHolder tree_holder(mem_sgmt_, RBTree<int>::create(mem_sgmt_));
     RBTree<int>& tree2(*tree_holder.get());
     RBNode<int>* node;
-    tree2.insert(Name("second"), &node);
+    tree2.insert(mem_sgmt_, Name("second"), &node);
     std::ostringstream str2;
     tree2.dumpTree(str2);
 
@@ -789,7 +829,7 @@ TEST_F(RBTreeTest, swap) {
 TEST_F(RBTreeTest, root) {
     TreeHolder tree_holder(mem_sgmt_, RBTree<int>::create(mem_sgmt_));
     RBTree<int>& root(*tree_holder.get());
-    root.insert(Name::ROOT_NAME(), &rbtnode);
+    root.insert(mem_sgmt_, Name::ROOT_NAME(), &rbtnode);
     rbtnode->setData(RBNode<int>::NodeDataPtr(new int(1)));
 
     EXPECT_EQ(RBTree<int>::EXACTMATCH,
@@ -801,7 +841,7 @@ TEST_F(RBTreeTest, root) {
 
     // Insert a new name that better matches the query name.  find() should
     // find the better one.
-    root.insert(Name("com"), &rbtnode);
+    root.insert(mem_sgmt_, Name("com"), &rbtnode);
     rbtnode->setData(RBNode<int>::NodeDataPtr(new int(2)));
     EXPECT_EQ(RBTree<int>::PARTIALMATCH,
               root.find(Name("example.com"), &crbtnode));
@@ -812,7 +852,7 @@ TEST_F(RBTreeTest, root) {
     TreeHolder tree_holder_emptyok(mem_sgmt_,
                                    RBTree<int>::create(mem_sgmt_, true));
     RBTree<int>& root_emptyok(*tree_holder_emptyok.get());
-    root_emptyok.insert(Name::ROOT_NAME(), &rbtnode);
+    root_emptyok.insert(mem_sgmt_, Name::ROOT_NAME(), &rbtnode);
     EXPECT_EQ(RBTree<int>::EXACTMATCH,
               root_emptyok.find(Name::ROOT_NAME(), &crbtnode));
     EXPECT_EQ(rbtnode, crbtnode);
@@ -820,7 +860,7 @@ TEST_F(RBTreeTest, root) {
               root_emptyok.find(Name("example.com"), &crbtnode));
     EXPECT_EQ(rbtnode, crbtnode);
 
-    root.insert(Name("com"), &rbtnode);
+    root.insert(mem_sgmt_, Name("com"), &rbtnode);
     EXPECT_EQ(RBTree<int>::PARTIALMATCH,
               root.find(Name("example.com"), &crbtnode));
     EXPECT_EQ(rbtnode, crbtnode);

+ 18 - 15
src/lib/datasrc/tests/zonetable_unittest.cc

@@ -53,51 +53,54 @@ protected:
                                                    Name("example.net"))),
                       zone3(new InMemoryZoneFinder(RRClass::IN(),
                                                    Name("example"))),
-                      zone_table(ZoneTable::create(local_mem_sgmt_))
+                      zone_table(ZoneTable::create(mem_sgmt_))
     {}
 
     ~ZoneTableTest() {
-        ZoneTable::destroy(local_mem_sgmt_, zone_table);
+        ZoneTable::destroy(mem_sgmt_, zone_table);
     }
     ZoneFinderPtr zone1, zone2, zone3;
-    isc::util::MemorySegmentLocal local_mem_sgmt_;
+    isc::util::MemorySegmentLocal mem_sgmt_;
     ZoneTable* zone_table;
 };
 
 TEST_F(ZoneTableTest, addZone) {
-    EXPECT_EQ(result::SUCCESS, zone_table->addZone(zone1));
-    EXPECT_EQ(result::EXIST, zone_table->addZone(zone1));
+    EXPECT_EQ(result::SUCCESS, zone_table->addZone(mem_sgmt_, zone1));
+    EXPECT_EQ(result::EXIST, zone_table->addZone(mem_sgmt_, zone1));
     // names are compared in a case insensitive manner.
     EXPECT_EQ(result::EXIST, zone_table->addZone(
+                  mem_sgmt_,
                   ZoneFinderPtr(new InMemoryZoneFinder(RRClass::IN(),
                                                        Name("EXAMPLE.COM")))));
 
-    EXPECT_EQ(result::SUCCESS, zone_table->addZone(zone2));
-    EXPECT_EQ(result::SUCCESS, zone_table->addZone(zone3));
+    EXPECT_EQ(result::SUCCESS, zone_table->addZone(mem_sgmt_, zone2));
+    EXPECT_EQ(result::SUCCESS, zone_table->addZone(mem_sgmt_, zone3));
 
     // Zone table is indexed only by name.  Duplicate origin name with
     // different zone class isn't allowed.
     EXPECT_EQ(result::EXIST, zone_table->addZone(
+                  mem_sgmt_,
                   ZoneFinderPtr(new InMemoryZoneFinder(RRClass::CH(),
                                                        Name("example.com")))));
 
     /// Bogus zone (NULL)
-    EXPECT_THROW(zone_table->addZone(ZoneFinderPtr()), isc::InvalidParameter);
+    EXPECT_THROW(zone_table->addZone(mem_sgmt_, ZoneFinderPtr()),
+                 isc::InvalidParameter);
 }
 
 TEST_F(ZoneTableTest, DISABLED_removeZone) {
-    EXPECT_EQ(result::SUCCESS, zone_table->addZone(zone1));
-    EXPECT_EQ(result::SUCCESS, zone_table->addZone(zone2));
-    EXPECT_EQ(result::SUCCESS, zone_table->addZone(zone3));
+    EXPECT_EQ(result::SUCCESS, zone_table->addZone(mem_sgmt_, zone1));
+    EXPECT_EQ(result::SUCCESS, zone_table->addZone(mem_sgmt_, zone2));
+    EXPECT_EQ(result::SUCCESS, zone_table->addZone(mem_sgmt_, zone3));
 
     EXPECT_EQ(result::SUCCESS, zone_table->removeZone(Name("example.net")));
     EXPECT_EQ(result::NOTFOUND, zone_table->removeZone(Name("example.net")));
 }
 
 TEST_F(ZoneTableTest, findZone) {
-    EXPECT_EQ(result::SUCCESS, zone_table->addZone(zone1));
-    EXPECT_EQ(result::SUCCESS, zone_table->addZone(zone2));
-    EXPECT_EQ(result::SUCCESS, zone_table->addZone(zone3));
+    EXPECT_EQ(result::SUCCESS, zone_table->addZone(mem_sgmt_, zone1));
+    EXPECT_EQ(result::SUCCESS, zone_table->addZone(mem_sgmt_, zone2));
+    EXPECT_EQ(result::SUCCESS, zone_table->addZone(mem_sgmt_, zone3));
 
     EXPECT_EQ(result::SUCCESS, zone_table->findZone(Name("example.com")).code);
     EXPECT_EQ(Name("example.com"),
@@ -118,7 +121,7 @@ TEST_F(ZoneTableTest, findZone) {
     // make sure the partial match is indeed the longest match by adding
     // a zone with a shorter origin and query again.
     ZoneFinderPtr zone_com(new InMemoryZoneFinder(RRClass::IN(), Name("com")));
-    EXPECT_EQ(result::SUCCESS, zone_table->addZone(zone_com));
+    EXPECT_EQ(result::SUCCESS, zone_table->addZone(mem_sgmt_, zone_com));
     EXPECT_EQ(Name("example.com"),
               zone_table->findZone(Name("www.example.com")).zone->getOrigin());
 }

+ 4 - 4
src/lib/datasrc/zonetable.cc

@@ -48,7 +48,7 @@ struct ZoneTable::ZoneTableImpl {
      */
 
     // Implementation of ZoneTable::addZone
-    result::Result addZone(ZoneFinderPtr zone) {
+    result::Result addZone(util::MemorySegment& mem_sgmt, ZoneFinderPtr zone) {
         // Sanity check
         if (!zone) {
             isc_throw(InvalidParameter,
@@ -57,7 +57,7 @@ struct ZoneTable::ZoneTableImpl {
 
         // Get the node where we put the zone
         ZoneNode* node(NULL);
-        switch (zones_->insert(zone->getOrigin(), &node)) {
+        switch (zones_->insert(mem_sgmt, zone->getOrigin(), &node)) {
             // This is OK
             case ZoneTree::SUCCESS:
             case ZoneTree::ALREADYEXISTS:
@@ -139,8 +139,8 @@ ZoneTable::destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable) {
 }
 
 result::Result
-ZoneTable::addZone(ZoneFinderPtr zone) {
-    return (impl_->addZone(zone));
+ZoneTable::addZone(util::MemorySegment& mem_sgmt, ZoneFinderPtr zone) {
+    return (impl_->addZone(mem_sgmt, zone));
 }
 
 result::Result

+ 1 - 1
src/lib/datasrc/zonetable.h

@@ -114,7 +114,7 @@ public:
     /// added to the zone table.
     /// \return \c result::EXIST The zone table already contains
     /// zone of the same origin.
-    result::Result addZone(ZoneFinderPtr zone);
+    result::Result addZone(util::MemorySegment& mem_sgmt, ZoneFinderPtr zone);
 
     /// Remove a \c Zone of the given origin name from the \c ZoneTable.
     ///