diff options
author | JINMEI Tatuya <jinmei@isc.org> | 2012-07-20 02:39:11 +0200 |
---|---|---|
committer | JINMEI Tatuya <jinmei@isc.org> | 2012-07-20 02:39:11 +0200 |
commit | d6b44e0b1af751de561e2ededf302389f3507579 (patch) | |
tree | 99812efff504be915b433466d249607183e09073 | |
parent | [2091] use memory segment for creating/destroying RBTrees. (diff) | |
download | kea-d6b44e0b1af751de561e2ededf302389f3507579.tar.xz kea-d6b44e0b1af751de561e2ededf302389f3507579.zip |
[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.
Diffstat (limited to '')
-rw-r--r-- | src/lib/datasrc/memory_datasrc.cc | 36 | ||||
-rw-r--r-- | src/lib/datasrc/rbtree.h | 135 | ||||
-rw-r--r-- | src/lib/datasrc/tests/rbtree_unittest.cc | 116 | ||||
-rw-r--r-- | src/lib/datasrc/tests/zonetable_unittest.cc | 33 | ||||
-rw-r--r-- | src/lib/datasrc/zonetable.cc | 8 | ||||
-rw-r--r-- | src/lib/datasrc/zonetable.h | 2 |
6 files changed, 214 insertions, 116 deletions
diff --git a/src/lib/datasrc/memory_datasrc.cc b/src/lib/datasrc/memory_datasrc.cc index 85739a0cac..8a58afe0f5 100644 --- a/src/lib/datasrc/memory_datasrc.cc +++ b/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; } diff --git a/src/lib/datasrc/rbtree.h b/src/lib/datasrc/rbtree.h index f9a3b05d3a..f45972c002 100644 --- a/src/lib/datasrc/rbtree.h +++ b/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(); } diff --git a/src/lib/datasrc/tests/rbtree_unittest.cc b/src/lib/datasrc/tests/rbtree_unittest.cc index 99caf3403d..1009e6428b 100644 --- a/src/lib/datasrc/tests/rbtree_unittest.cc +++ b/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); diff --git a/src/lib/datasrc/tests/zonetable_unittest.cc b/src/lib/datasrc/tests/zonetable_unittest.cc index bfc6d61c25..5a29a44a77 100644 --- a/src/lib/datasrc/tests/zonetable_unittest.cc +++ b/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()); } diff --git a/src/lib/datasrc/zonetable.cc b/src/lib/datasrc/zonetable.cc index f2e7e2ccd2..11931819e6 100644 --- a/src/lib/datasrc/zonetable.cc +++ b/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 diff --git a/src/lib/datasrc/zonetable.h b/src/lib/datasrc/zonetable.h index 427d1a9b00..93a021c9e8 100644 --- a/src/lib/datasrc/zonetable.h +++ b/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. /// |