]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[2105] Introduce node deleter as a template parameter
authorMukund Sivaraman <muks@isc.org>
Mon, 30 Jul 2012 20:07:31 +0000 (01:37 +0530)
committerMukund Sivaraman <muks@isc.org>
Mon, 30 Jul 2012 20:07:31 +0000 (01:37 +0530)
src/lib/datasrc/memory/domaintree.h
src/lib/datasrc/memory/tests/domaintree_unittest.cc

index d52dc70c06826b8ad88cf2c6b82f712db497a3e3..9c5d5330f78b487a8c1f69a84034afd5b19e2b2d 100644 (file)
@@ -43,7 +43,7 @@ namespace memory {
 
 /// Forward declare DomainTree class here is convinent for following friend
 /// class declare inside DomainTreeNode and DomainTreeNodeChain
-template <typename T>
+template <typename T, typename DT>
 class DomainTree;
 
 /// \brief \c DomainTreeNode is used by DomainTree to store any data related to one domain
@@ -76,18 +76,18 @@ class DomainTree;
 /// as opaque binary immediately following the main node object.  The size
 /// of the allocated space for the labels data is encoded by borrowing some
 /// bits of the "flags" field.
-template <typename T>
+template <typename T, typename DT>
 class DomainTreeNode : public boost::noncopyable {
 private:
     /// The DomainTreeNode is meant for use from within DomainTree, so it has access to
     /// it.
-    friend class DomainTree<T>;
+    friend class DomainTree<T,DT>;
 
     /// \brief Just a type alias
     ///
     /// We are going to use a lot of these offset pointers here and they
     /// have a long name.
-    typedef boost::interprocess::offset_ptr<DomainTreeNode<T> > DomainTreeNodePtr;
+    typedef boost::interprocess::offset_ptr<DomainTreeNode<T,DT> > DomainTreeNodePtr;
 
     /// \name Constructors
     ///
@@ -127,12 +127,12 @@ private:
     ///
     /// \param mem_sgmt A \c MemorySegment from which memory for the new
     /// \c DomainTreeNode is allocated.
-    static DomainTreeNode<T>* create(util::MemorySegment& mem_sgmt,
+    static DomainTreeNode<T,DT>* create(util::MemorySegment& mem_sgmt,
                              const dns::LabelSequence& labels)
     {
         const size_t labels_len = labels.getSerializedLength();
-        void* p = mem_sgmt.allocate(sizeof(DomainTreeNode<T>) + labels_len);
-        DomainTreeNode<T>* node = new(p) DomainTreeNode<T>(labels_len);
+        void* p = mem_sgmt.allocate(sizeof(DomainTreeNode<T,DT>) + labels_len);
+        DomainTreeNode<T,DT>* node = new(p) DomainTreeNode<T,DT>(labels_len);
         labels.serialize(node->getLabelsData(), labels_len);
         return (node);
     }
@@ -146,10 +146,10 @@ private:
     /// \param rbnode A non NULL pointer to a valid \c DomainTreeNode 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, DomainTreeNode<T>* rbnode) {
+    static void destroy(util::MemorySegment& mem_sgmt, DomainTreeNode<T,DT>* rbnode) {
         const size_t labels_capacity = rbnode->labels_capacity_;
-        rbnode->~DomainTreeNode<T>();
-        mem_sgmt.deallocate(rbnode, sizeof(DomainTreeNode<T>) + labels_capacity);
+        rbnode->~DomainTreeNode<T,DT>();
+        mem_sgmt.deallocate(rbnode, sizeof(DomainTreeNode<T,DT>) + labels_capacity);
     }
 
     /// \brief Reset node's label sequence to a new one.
@@ -161,9 +161,6 @@ private:
     }
 
 public:
-    /// \brief Alias for shared pointer to the data.
-    typedef boost::shared_ptr<T> NodeDataPtr;
-
     /// Node flags.
     ///
     /// Each flag value defines a non default property for a specific node.
@@ -225,22 +222,27 @@ public:
     /// \brief Return the data stored in this node.
     ///
     /// You should not delete the data, it is handled by shared pointers.
-    NodeDataPtr& getData() { return (data_); }
+    T* getData() { return (data_); }
     /// \brief Return the data stored in this node.
-    const NodeDataPtr& getData() const { return (data_); }
+    const T* getData() const { return (data_); }
 
     /// \brief return whether the node has related data.
     ///
     /// There can be empty nodes inside the DomainTree. They are usually the
     /// non-terminal domains, but it is possible (yet probably meaningless)
     /// empty nodes anywhere.
-    bool isEmpty() const { return (data_.get() == NULL); }
+    bool isEmpty() const { return (data_ == NULL); }
     //@}
 
     /// \name Setter functions.
     //@{
     /// \brief Set the data stored in the node.
-    void setData(const NodeDataPtr& data) { data_ = data; }
+    void setData(T* data) {
+        const DT deleter;
+        deleter(data_);
+
+        data_ = data;
+    }
     //@}
 
     /// \name Node flag manipulation methods
@@ -291,7 +293,7 @@ public:
 private:
     /// \name Callback related methods
     ///
-    /// See the description of \c DomainTree<T>::find() at \ref callback
+    /// See the description of \c DomainTree<T,DT>::find() at \ref callback
     /// about callbacks.
     ///
     /// These methods never throw an exception.
@@ -342,7 +344,7 @@ public:
     /// (which should be absolute), it will return \c NULL.
     ///
     /// This method never throws an exception.
-    const DomainTreeNode<T>* getUpperNode() const;
+    const DomainTreeNode<T,DT>* getUpperNode() const;
 
 private:
     /// \brief return the next node which is bigger than current node
@@ -360,7 +362,7 @@ private:
     /// returns \c NULL.
     ///
     /// This method never throws an exception.
-    const DomainTreeNode<T>* successor() const;
+    const DomainTreeNode<T,DT>* successor() const;
 
     /// \brief return the next node which is smaller than current node
     /// in the same subtree
@@ -377,7 +379,7 @@ private:
     /// returns \c NULL.
     ///
     /// This method never throws an exception.
-    const DomainTreeNode<T>* predecessor() const;
+    const DomainTreeNode<T,DT>* predecessor() const;
 
     /// \brief private shared implementation of successor and predecessor
     ///
@@ -390,9 +392,9 @@ private:
     /// The overhead of the member pointers should be optimised out, as this
     /// will probably get completely inlined into predecessor and successor
     /// methods.
-    const DomainTreeNode<T>*
-        abstractSuccessor(typename DomainTreeNode<T>::DomainTreeNodePtr DomainTreeNode<T>::*left,
-                          typename DomainTreeNode<T>::DomainTreeNodePtr DomainTreeNode<T>::*right)
+    const DomainTreeNode<T,DT>*
+        abstractSuccessor(typename DomainTreeNode<T,DT>::DomainTreeNodePtr DomainTreeNode<T,DT>::*left,
+                          typename DomainTreeNode<T,DT>::DomainTreeNodePtr DomainTreeNode<T,DT>::*right)
         const;
 
     /// \name Data to maintain the rbtree structure.
@@ -405,35 +407,35 @@ private:
     //@{
     DomainTreeNodePtr parent_;
     /// \brief Access the parent_ as bare pointer.
-    DomainTreeNode<T>* getParent() {
+    DomainTreeNode<T,DT>* getParent() {
         return (parent_.get());
     }
     /// \brief Access the parent_ as bare pointer, const.
-    const DomainTreeNode<T>* getParent() const {
+    const DomainTreeNode<T,DT>* getParent() const {
         return (parent_.get());
     }
     DomainTreeNodePtr left_;
     /// \brief Access the left_ as bare pointer.
-    DomainTreeNode<T>* getLeft() {
+    DomainTreeNode<T,DT>* getLeft() {
         return (left_.get());
     }
     /// \brief Access the left_ as bare pointer, const.
-    const DomainTreeNode<T>* getLeft() const {
+    const DomainTreeNode<T,DT>* getLeft() const {
         return (left_.get());
     }
     DomainTreeNodePtr right_;
     /// \brief Access the right_ as bare pointer.
-    DomainTreeNode<T>* getRight() {
+    DomainTreeNode<T,DT>* getRight() {
         return (right_.get());
     }
     /// \brief Access the right_ as bare pointer, const.
-    const DomainTreeNode<T>* getRight() const {
+    const DomainTreeNode<T,DT>* getRight() const {
         return (right_.get());
     }
     //@}
 
     /// \brief Data stored here.
-    NodeDataPtr       data_;
+    T* data_;
 
     /// \brief The subdomain tree.
     ///
@@ -446,11 +448,11 @@ private:
     ///     avoiding storage of the same domain labels multiple times.
     DomainTreeNodePtr down_;
     /// \brief Access the down_ as bare pointer.
-    DomainTreeNode<T>* getDown() {
+    DomainTreeNode<T,DT>* getDown() {
         return (down_.get());
     }
     /// \brief Access the down_ as bare pointer, const.
-    const DomainTreeNode<T>* getDown() const {
+    const DomainTreeNode<T,DT>* getDown() const {
         return (down_.get());
     }
 
@@ -474,8 +476,8 @@ private:
     BOOST_STATIC_ASSERT((1 << 9) > dns::LabelSequence::MAX_SERIALIZED_LENGTH);
 };
 
-template <typename T>
-DomainTreeNode<T>::DomainTreeNode(size_t labels_capacity) :
+template <typename T, typename DT>
+DomainTreeNode<T,DT>::DomainTreeNode(size_t labels_capacity) :
     parent_(NULL),
     left_(NULL),
     right_(NULL),
@@ -483,16 +485,17 @@ DomainTreeNode<T>::DomainTreeNode(size_t labels_capacity) :
     flags_(FLAG_RED | FLAG_SUBTREE_ROOT),
     labels_capacity_(labels_capacity)
 {
+    data_ = NULL;
 }
 
-template <typename T>
-DomainTreeNode<T>::~DomainTreeNode() {
+template <typename T, typename DT>
+DomainTreeNode<T,DT>::~DomainTreeNode() {
 }
 
-template <typename T>
-const DomainTreeNode<T>*
-DomainTreeNode<T>::getUpperNode() const {
-    const DomainTreeNode<T>* current = this;
+template <typename T, typename DT>
+const DomainTreeNode<T,DT>*
+DomainTreeNode<T,DT>::getUpperNode() const {
+    const DomainTreeNode<T,DT>* current = this;
 
     // current would never be equal to NULL here (in a correct tree
     // implementation)
@@ -503,10 +506,10 @@ DomainTreeNode<T>::getUpperNode() const {
     return (current->getParent());
 }
 
-template <typename T>
-const DomainTreeNode<T>*
-DomainTreeNode<T>::abstractSuccessor(typename DomainTreeNode<T>::DomainTreeNodePtr DomainTreeNode<T>::*left,
-                             typename DomainTreeNode<T>::DomainTreeNodePtr DomainTreeNode<T>::*right)
+template <typename T, typename DT>
+const DomainTreeNode<T,DT>*
+DomainTreeNode<T,DT>::abstractSuccessor(typename DomainTreeNode<T,DT>::DomainTreeNodePtr DomainTreeNode<T,DT>::*left,
+                             typename DomainTreeNode<T,DT>::DomainTreeNodePtr DomainTreeNode<T,DT>::*right)
     const
 {
     // This function is written as a successor. It becomes predecessor if
@@ -514,12 +517,12 @@ DomainTreeNode<T>::abstractSuccessor(typename DomainTreeNode<T>::DomainTreeNodeP
     // the left pointer points to right and vice versa. Don't get confused
     // by the idea, just imagine the pointers look into a mirror.
 
-    const DomainTreeNode<T>* current = this;
+    const DomainTreeNode<T,DT>* current = this;
     // If it has right node, the successor is the left-most node of the right
     // subtree.
     if ((current->*right).get() != NULL) {
         current = (current->*right).get();
-        const DomainTreeNode<T>* left_n;
+        const DomainTreeNode<T,DT>* left_n;
         while ((left_n = (current->*left).get()) != NULL) {
             current = left_n;
         }
@@ -529,7 +532,7 @@ DomainTreeNode<T>::abstractSuccessor(typename DomainTreeNode<T>::DomainTreeNodeP
     // 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
-    const DomainTreeNode<T>* parent = current->getParent();
+    const DomainTreeNode<T,DT>* parent = current->getParent();
     while ((!current->isSubTreeRoot()) &&
            (current == (parent->*right).get())) {
         current = parent;
@@ -543,17 +546,17 @@ DomainTreeNode<T>::abstractSuccessor(typename DomainTreeNode<T>::DomainTreeNodeP
     }
 }
 
-template <typename T>
-const DomainTreeNode<T>*
-DomainTreeNode<T>::successor() const {
-    return (abstractSuccessor(&DomainTreeNode<T>::left_, &DomainTreeNode<T>::right_));
+template <typename T, typename DT>
+const DomainTreeNode<T,DT>*
+DomainTreeNode<T,DT>::successor() const {
+    return (abstractSuccessor(&DomainTreeNode<T,DT>::left_, &DomainTreeNode<T,DT>::right_));
 }
 
-template <typename T>
-const DomainTreeNode<T>*
-DomainTreeNode<T>::predecessor() const {
+template <typename T, typename DT>
+const DomainTreeNode<T,DT>*
+DomainTreeNode<T,DT>::predecessor() const {
     // Swap the left and right pointers for the abstractSuccessor
-    return (abstractSuccessor(&DomainTreeNode<T>::right_, &DomainTreeNode<T>::left_));
+    return (abstractSuccessor(&DomainTreeNode<T,DT>::right_, &DomainTreeNode<T,DT>::left_));
 }
 
 /// \brief DomainTreeNodeChain stores detailed information of \c DomainTree::find()
@@ -590,11 +593,11 @@ DomainTreeNode<T>::predecessor() const {
 /// DomainTree.
 /// This is the reason why manipulation methods such as \c push() and \c pop()
 /// are private (and not shown in the doxygen document).
-template <typename T>
+template <typename T, typename DT>
 class DomainTreeNodeChain {
     /// DomainTreeNodeChain is initialized by DomainTree, only DomainTree has
     /// knowledge to manipulate it.
-    friend class DomainTree<T>;
+    friend class DomainTree<T,DT>;
 public:
     /// \name Constructors and Assignment Operator.
     ///
@@ -614,8 +617,8 @@ public:
     {}
 
 private:
-    DomainTreeNodeChain(const DomainTreeNodeChain<T>&);
-    DomainTreeNodeChain<T>& operator=(const DomainTreeNodeChain<T>&);
+    DomainTreeNodeChain(const DomainTreeNodeChain<T,DT>&);
+    DomainTreeNodeChain<T,DT>& operator=(const DomainTreeNodeChain<T,DT>&);
     //@}
 
 public:
@@ -641,7 +644,7 @@ public:
     /// this method returns \c NULL.
     ///
     /// \exception None
-    const DomainTreeNode<T>* getLastComparedNode() const {
+    const DomainTreeNode<T,DT>* getLastComparedNode() const {
         return (last_compared_);
     }
 
@@ -681,7 +684,7 @@ public:
                       "chain");
         }
 
-        const DomainTreeNode<T>* top_node = top();
+        const DomainTreeNode<T,DT>* top_node = top();
         isc::dns::Name absolute_name = top_node->getName();
         int node_count = node_count_ - 1;
         while (node_count > 0) {
@@ -709,7 +712,7 @@ private:
     /// root node of DomainTree
     ///
     /// \exception None
-    const DomainTreeNode<T>* top() const {
+    const DomainTreeNode<T,DT>* top() const {
         assert(!isEmpty());
         return (nodes_[node_count_ - 1]);
     }
@@ -732,7 +735,7 @@ private:
     /// otherwise the node should be the root node of DomainTree.
     ///
     /// \exception None
-    void push(const DomainTreeNode<T>* node) {
+    void push(const DomainTreeNode<T,DT>* node) {
         assert(node_count_ < RBT_MAX_LEVEL);
         nodes_[node_count_++] = node;
     }
@@ -744,8 +747,8 @@ private:
     const static int RBT_MAX_LEVEL = isc::dns::Name::MAX_LABELS;
 
     int node_count_;
-    const DomainTreeNode<T>* nodes_[RBT_MAX_LEVEL];
-    const DomainTreeNode<T>* last_compared_;
+    const DomainTreeNode<T,DT>* nodes_[RBT_MAX_LEVEL];
+    const DomainTreeNode<T,DT>* last_compared_;
     isc::dns::NameComparisonResult last_comparison_;
 };
 
@@ -813,9 +816,9 @@ private:
  *  \todo
  *  - add remove interface
  */
-template <typename T>
+template <typename T, typename DT>
 class DomainTree : public boost::noncopyable {
-    friend class DomainTreeNode<T>;
+    friend class DomainTreeNode<T,DT>;
 public:
     /// \brief The return value for the \c find() and insert() methods
     enum Result {
@@ -841,8 +844,8 @@ public:
     static DomainTree* create(util::MemorySegment& mem_sgmt,
                           bool return_empty_node = false)
     {
-        void* p = mem_sgmt.allocate(sizeof(DomainTree<T>));
-        return (new(p) DomainTree<T>(return_empty_node));
+        void* p = mem_sgmt.allocate(sizeof(DomainTree<T,DT>));
+        return (new(p) DomainTree<T,DT>(return_empty_node));
     }
 
     /// \brief Destruct and deallocate \c DomainTree
@@ -870,10 +873,10 @@ public:
     /// \param rbtree A non NULL pointer to a valid \c DomainTree 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, DomainTree<T>* rbtree) {
+    static void destroy(util::MemorySegment& mem_sgmt, DomainTree<T,DT>* rbtree) {
         rbtree->deleteAllNodes(mem_sgmt);
-        rbtree->~DomainTree<T>();
-        mem_sgmt.deallocate(rbtree, sizeof(DomainTree<T>));
+        rbtree->~DomainTree<T,DT>();
+        mem_sgmt.deallocate(rbtree, sizeof(DomainTree<T,DT>));
     }
 
 private:
@@ -947,8 +950,8 @@ public:
     /// \brief Simple find.
     ///
     /// Acts as described in the \ref find section.
-    Result find(const isc::dns::Name& name, DomainTreeNode<T>** node) const {
-        DomainTreeNodeChain<T> node_path;
+    Result find(const isc::dns::Name& name, DomainTreeNode<T,DT>** node) const {
+        DomainTreeNodeChain<T,DT> node_path;
         const isc::dns::LabelSequence ls(name);
         return (find<void*>(ls, node, node_path, NULL, NULL));
     }
@@ -957,9 +960,9 @@ public:
     ///
     /// Acts as described in the \ref find section, but returns immutable node
     /// pointer.
-    Result find(const isc::dns::Name& name, const DomainTreeNode<T>** node) const {
-        DomainTreeNodeChain<T> node_path;
-        DomainTreeNode<T> *target_node = NULL;
+    Result find(const isc::dns::Name& name, const DomainTreeNode<T,DT>** node) const {
+        DomainTreeNodeChain<T,DT> node_path;
+        DomainTreeNode<T,DT> *target_node = NULL;
         const isc::dns::LabelSequence ls(name);
         Result ret = (find<void*>(ls, &target_node, node_path, NULL, NULL));
         if (ret != NOTFOUND) {
@@ -971,8 +974,8 @@ public:
     /// \brief Simple find, with node_path tracking
     ///
     /// Acts as described in the \ref find section.
-    Result find(const isc::dns::Name& name, DomainTreeNode<T>** node,
-                DomainTreeNodeChain<T>& node_path) const
+    Result find(const isc::dns::Name& name, DomainTreeNode<T,DT>** node,
+                DomainTreeNodeChain<T,DT>& node_path) const
     {
         const isc::dns::LabelSequence ls(name);
         return (find<void*>(ls, node, node_path, NULL, NULL));
@@ -982,10 +985,10 @@ public:
     ///
     /// Acts as described in the \ref find section, but returns immutable node
     /// pointer.
-    Result find(const isc::dns::Name& name, const DomainTreeNode<T>** node,
-                DomainTreeNodeChain<T>& node_path) const
+    Result find(const isc::dns::Name& name, const DomainTreeNode<T,DT>** node,
+                DomainTreeNodeChain<T,DT>& node_path) const
     {
-        DomainTreeNode<T> *target_node = NULL;
+        DomainTreeNode<T,DT> *target_node = NULL;
         const isc::dns::LabelSequence ls(name);
         Result ret = (find<void*>(ls, &target_node, node_path, NULL, NULL));
         if (ret != NOTFOUND) {
@@ -1000,12 +1003,12 @@ public:
     /// node pointer.
     template <typename CBARG>
     Result find(const isc::dns::Name& name,
-                const DomainTreeNode<T>** node,
-                DomainTreeNodeChain<T>& node_path,
-                bool (*callback)(const DomainTreeNode<T>&, CBARG),
+                const DomainTreeNode<T,DT>** node,
+                DomainTreeNodeChain<T,DT>& node_path,
+                bool (*callback)(const DomainTreeNode<T,DT>&, CBARG),
                 CBARG callback_arg) const
     {
-        DomainTreeNode<T>* target_node = NULL;
+        DomainTreeNode<T,DT>* target_node = NULL;
         const isc::dns::LabelSequence ls(name);
         Result ret = find(ls, &target_node, node_path, callback,
                           callback_arg);
@@ -1089,9 +1092,9 @@ public:
     ///     \c true, it returns immediately with the current node.
     template <typename CBARG>
     Result find(const isc::dns::LabelSequence& target_labels_orig,
-                DomainTreeNode<T>** node,
-                DomainTreeNodeChain<T>& node_path,
-                bool (*callback)(const DomainTreeNode<T>&, CBARG),
+                DomainTreeNode<T,DT>** node,
+                DomainTreeNodeChain<T,DT>& node_path,
+                bool (*callback)(const DomainTreeNode<T,DT>&, CBARG),
                 CBARG callback_arg) const;
 
     /// \brief Simple find returning immutable node.
@@ -1100,12 +1103,12 @@ public:
     /// node pointer.
     template <typename CBARG>
     Result find(const isc::dns::LabelSequence& target_labels,
-                const DomainTreeNode<T>** node,
-                DomainTreeNodeChain<T>& node_path,
-                bool (*callback)(const DomainTreeNode<T>&, CBARG),
+                const DomainTreeNode<T,DT>** node,
+                DomainTreeNodeChain<T,DT>& node_path,
+                bool (*callback)(const DomainTreeNode<T,DT>&, CBARG),
                 CBARG callback_arg) const
     {
-        DomainTreeNode<T>* target_node = NULL;
+        DomainTreeNode<T,DT>* target_node = NULL;
         Result ret = find(target_labels, &target_node, node_path,
                           callback, callback_arg);
         if (ret != NOTFOUND) {
@@ -1138,7 +1141,7 @@ public:
     ///
     /// \return An \c DomainTreeNode that is next bigger than \c node; if \c node is
     /// the largest, \c NULL will be returned.
-    const DomainTreeNode<T>* nextNode(DomainTreeNodeChain<T>& node_path) const;
+    const DomainTreeNode<T,DT>* nextNode(DomainTreeNodeChain<T,DT>& node_path) const;
 
     /// \brief return the next smaller node in DNSSEC order from a node
     ///     searched by DomainTree::find().
@@ -1162,7 +1165,7 @@ public:
     ///
     /// \return An \c DomainTreeNode that is next smaller than \c node; if \c node is
     /// the smallest, \c NULL will be returned.
-    const DomainTreeNode<T>* previousNode(DomainTreeNodeChain<T>& node_path) const;
+    const DomainTreeNode<T,DT>* previousNode(DomainTreeNodeChain<T,DT>& node_path) const;
 
     /// \brief Get the total number of nodes in the tree
     ///
@@ -1225,7 +1228,7 @@ public:
     ///  - ALREADYEXISTS There was already a node of that name, so it was not
     ///     added.
     Result insert(util::MemorySegment& mem_sgmt, const isc::dns::Name& name,
-                  DomainTreeNode<T>** inserted_node);
+                  DomainTreeNode<T,DT>** inserted_node);
 
     /// \brief Delete all tree nodes.
     ///
@@ -1244,7 +1247,7 @@ public:
     ///
     /// This acts the same as many std::*.swap functions, exchanges the
     /// contents. This doesn't throw anything.
-    void swap(DomainTree<T>& other) {
+    void swap(DomainTree<T,DT>& other) {
         std::swap(root_, other.root_);
         std::swap(node_count_, other.node_count_);
     }
@@ -1253,24 +1256,25 @@ public:
 private:
     /// \name DomainTree balance functions
     //@{
-    void insertRebalance(typename DomainTreeNode<T>::DomainTreeNodePtr* root, DomainTreeNode<T>* node);
-    DomainTreeNode<T>* rightRotate(typename DomainTreeNode<T>::DomainTreeNodePtr* root,
-                           DomainTreeNode<T>* node);
-    DomainTreeNode<T>* leftRotate(typename DomainTreeNode<T>::DomainTreeNodePtr* root,
-                          DomainTreeNode<T>* node);
+    void insertRebalance(typename DomainTreeNode<T,DT>::DomainTreeNodePtr* root, DomainTreeNode<T,DT>* node);
+    DomainTreeNode<T,DT>* rightRotate(typename DomainTreeNode<T,DT>::DomainTreeNodePtr* root,
+                           DomainTreeNode<T,DT>* node);
+    DomainTreeNode<T,DT>* leftRotate(typename DomainTreeNode<T,DT>::DomainTreeNodePtr* root,
+                          DomainTreeNode<T,DT>* node);
     //@}
 
     /// \name Helper functions
     //@{
     /// \brief delete tree whose root is equal to node
-    void deleteHelper(util::MemorySegment& mem_sgmt, DomainTreeNode<T> *node);
+    void deleteHelper(util::MemorySegment& mem_sgmt, DomainTreeNode<T,DT> *node,
+                     const DT& deleter);
 
     /// \brief Print the information of given DomainTreeNode.
-    void dumpTreeHelper(std::ostream& os, const DomainTreeNode<T>* node,
+    void dumpTreeHelper(std::ostream& os, const DomainTreeNode<T,DT>* node,
                         unsigned int depth) const;
 
     /// \brief Print the information of given DomainTreeNode for dot.
-    int dumpDotHelper(std::ostream& os, const DomainTreeNode<T>* node,
+    int dumpDotHelper(std::ostream& os, const DomainTreeNode<T,DT>* node,
                       int* nodecount, bool show_pointers) const;
 
     /// \brief Indentation helper function for dumpTree
@@ -1282,79 +1286,82 @@ private:
     /// The newly created node represents the labels that the original node
     /// did, so necessary data are swapped.
     /// (Note: as commented in the code, this behavior should be changed).
-    void nodeFission(util::MemorySegment& mem_sgmt, DomainTreeNode<T>& node,
+    void nodeFission(util::MemorySegment& mem_sgmt, DomainTreeNode<T,DT>& node,
                      const isc::dns::LabelSequence& new_prefix,
                      const isc::dns::LabelSequence& new_suffix);
     //@}
 
-    typename DomainTreeNode<T>::DomainTreeNodePtr root_;
+    typename DomainTreeNode<T,DT>::DomainTreeNodePtr root_;
     /// the node count of current tree
     unsigned int node_count_;
     /// search policy for rbtree
     const bool needsReturnEmptyNode_;
 };
 
-template <typename T>
-DomainTree<T>::DomainTree(bool returnEmptyNode) :
+template <typename T, typename DT>
+DomainTree<T,DT>::DomainTree(bool returnEmptyNode) :
     root_(NULL),
     node_count_(0),
     needsReturnEmptyNode_(returnEmptyNode)
 {
 }
 
-template <typename T>
-DomainTree<T>::~DomainTree() {
+template <typename T, typename DT>
+DomainTree<T,DT>::~DomainTree() {
     assert(node_count_ == 0);
 }
 
-template <typename T>
+template <typename T, typename DT>
 void
-DomainTree<T>::deleteHelper(util::MemorySegment& mem_sgmt, DomainTreeNode<T>* root) {
+DomainTree<T,DT>::deleteHelper(util::MemorySegment& mem_sgmt, DomainTreeNode<T,DT>* root,
+                              const DT& deleter) {
     if (root == NULL) {
         return;
     }
 
-    DomainTreeNode<T>* node = root;
+    DomainTreeNode<T,DT>* node = root;
     while (root->getLeft() != NULL || root->getRight() != NULL) {
-        DomainTreeNode<T>* left(NULL);
-        DomainTreeNode<T>* right(NULL);
+        DomainTreeNode<T,DT>* left(NULL);
+        DomainTreeNode<T,DT>* right(NULL);
         while ((left = node->getLeft()) != NULL ||
                (right = node->getRight()) != NULL) {
             node = (left != NULL) ? left : right;
         }
 
-        DomainTreeNode<T>* parent = node->getParent();
+        DomainTreeNode<T,DT>* parent = node->getParent();
         if (parent->getLeft() == node) {
             parent->left_ = NULL;
         } else {
             parent->right_ = NULL;
         }
 
-        deleteHelper(mem_sgmt, node->getDown());
-        DomainTreeNode<T>::destroy(mem_sgmt, node);
+        deleteHelper(mem_sgmt, node->getDown(), deleter);
+       deleter(node->data_);
+        DomainTreeNode<T,DT>::destroy(mem_sgmt, node);
         --node_count_;
         node = parent;
     }
 
-    deleteHelper(mem_sgmt, root->getDown());
-    DomainTreeNode<T>::destroy(mem_sgmt, root);
+    deleteHelper(mem_sgmt, root->getDown(), deleter);
+    deleter(root->data_);
+    DomainTreeNode<T,DT>::destroy(mem_sgmt, root);
     --node_count_;
 }
 
-template <typename T>
+template <typename T, typename DT>
 template <typename CBARG>
-typename DomainTree<T>::Result
-DomainTree<T>::find(const isc::dns::LabelSequence& target_labels_orig,
-                DomainTreeNode<T>** target,
-                DomainTreeNodeChain<T>& node_path,
-                bool (*callback)(const DomainTreeNode<T>&, CBARG),
+typename DomainTree<T,DT>::Result
+DomainTree<T,DT>::find(const isc::dns::LabelSequence& target_labels_orig,
+                DomainTreeNode<T,DT>** target,
+                DomainTreeNodeChain<T,DT>& node_path,
+                bool (*callback)(const DomainTreeNode<T,DT>&, CBARG),
                 CBARG callback_arg) const
 {
     if (!node_path.isEmpty()) {
         isc_throw(isc::BadValue, "DomainTree::find is given a non empty chain");
     }
 
-    DomainTreeNode<T>* node = root_.get();
+    DomainTreeNode<T,DT>* node = root_.get();
     Result ret = NOTFOUND;
     dns::LabelSequence target_labels(target_labels_orig);
 
@@ -1382,7 +1389,7 @@ DomainTree<T>::find(const isc::dns::LabelSequence& target_labels_orig,
                     ret = PARTIALMATCH;
                     *target = node;
                     if (callback != NULL &&
-                        node->getFlag(DomainTreeNode<T>::FLAG_CALLBACK)) {
+                        node->getFlag(DomainTreeNode<T,DT>::FLAG_CALLBACK)) {
                         if ((callback)(*node, callback_arg)) {
                             break;
                         }
@@ -1401,19 +1408,19 @@ DomainTree<T>::find(const isc::dns::LabelSequence& target_labels_orig,
     return (ret);
 }
 
-template <typename T>
-const DomainTreeNode<T>*
-DomainTree<T>::nextNode(DomainTreeNodeChain<T>& node_path) const {
+template <typename T, typename DT>
+const DomainTreeNode<T,DT>*
+DomainTree<T,DT>::nextNode(DomainTreeNodeChain<T,DT>& node_path) const {
     if (node_path.isEmpty()) {
         isc_throw(isc::BadValue, "DomainTree::nextNode is given an empty chain");
     }
 
-    const DomainTreeNode<T>* node = node_path.top();
+    const DomainTreeNode<T,DT>* node = node_path.top();
     // if node has sub domain, the next domain is the smallest
     // domain in sub domain tree
-    const DomainTreeNode<T>* down = node->getDown();
+    const DomainTreeNode<T,DT>* down = node->getDown();
     if (down != NULL) {
-        const DomainTreeNode<T>* left_most = down;
+        const DomainTreeNode<T,DT>* left_most = down;
         while (left_most->getLeft() != NULL) {
             left_most = left_most->getLeft();
         }
@@ -1427,7 +1434,7 @@ DomainTree<T>::nextNode(DomainTreeNodeChain<T>& node_path) const {
     // up node doesn't have successor we gonna keep moving to up
     // level
     while (!node_path.isEmpty()) {
-        const DomainTreeNode<T>* up_node_successor = node_path.top()->successor();
+        const DomainTreeNode<T,DT>* up_node_successor = node_path.top()->successor();
         node_path.pop();
         if (up_node_successor != NULL) {
             node_path.push(up_node_successor);
@@ -1438,9 +1445,9 @@ DomainTree<T>::nextNode(DomainTreeNodeChain<T>& node_path) const {
     return (NULL);
 }
 
-template <typename T>
-const DomainTreeNode<T>*
-DomainTree<T>::previousNode(DomainTreeNodeChain<T>& node_path) const {
+template <typename T, typename DT>
+const DomainTreeNode<T,DT>*
+DomainTree<T,DT>::previousNode(DomainTreeNodeChain<T,DT>& node_path) const {
     if (getNodeCount() == 0) {
         // Special case for empty trees. It would look every time like
         // we didn't search, because the last compared is empty. This is
@@ -1480,13 +1487,13 @@ DomainTree<T>::previousNode(DomainTreeNodeChain<T>& node_path) const {
                 // compared one (it is either the compared one, or some
                 // subdomain of it). There probably is not an easy trick
                 // for this, so we just find the correct place.
-                const DomainTreeNode<T>* current(node_path.last_compared_);
+                const DomainTreeNode<T,DT>* current(node_path.last_compared_);
                 while (current != NULL) {
                     node_path.push(current);
                     // Go a level down and as much right there as possible
                     current = current->getDown();
                     if (current != NULL) {
-                        const DomainTreeNode<T>* right;
+                        const DomainTreeNode<T,DT>* right;
                         while ((right = current->getRight()) != NULL) {
                             current = right;
                         }
@@ -1537,7 +1544,7 @@ DomainTree<T>::previousNode(DomainTreeNodeChain<T>& node_path) const {
         return (NULL);
     }
 
-    const DomainTreeNode<T>* node(node_path.top());
+    const DomainTreeNode<T,DT>* node(node_path.top());
 
     // Try going left in this tree
     node = node->predecessor();
@@ -1560,13 +1567,13 @@ DomainTree<T>::previousNode(DomainTreeNodeChain<T>& node_path) const {
     node_path.push(node);
 
     // Try going as deep as possible, keeping on the right side of the trees
-    const DomainTreeNode<T>* down;
+    const DomainTreeNode<T,DT>* down;
     while ((down = node->getDown()) != NULL) {
         // Move to the tree below
         node = down;
         if (node != NULL) {
             // And get as much to the right of the tree as possible
-            const DomainTreeNode<T>* right;
+            const DomainTreeNode<T,DT>* right;
             while ((right = node->getRight()) != NULL) {
                 node = right;
             }
@@ -1581,14 +1588,14 @@ DomainTree<T>::previousNode(DomainTreeNodeChain<T>& node_path) const {
     return (node);
 }
 
-template <typename T>
-typename DomainTree<T>::Result
-DomainTree<T>::insert(util::MemorySegment& mem_sgmt,
-                  const isc::dns::Name& target_name, DomainTreeNode<T>** new_node)
+template <typename T, typename DT>
+typename DomainTree<T,DT>::Result
+DomainTree<T,DT>::insert(util::MemorySegment& mem_sgmt,
+                  const isc::dns::Name& target_name, DomainTreeNode<T,DT>** new_node)
 {
-    DomainTreeNode<T>* parent = NULL;
-    DomainTreeNode<T>* current = root_.get();
-    DomainTreeNode<T>* up_node = NULL;
+    DomainTreeNode<T,DT>* parent = NULL;
+    DomainTreeNode<T,DT>* current = root_.get();
+    DomainTreeNode<T,DT>* up_node = NULL;
     isc::dns::LabelSequence target_labels(target_name);
 
     int order = -1;
@@ -1627,16 +1634,16 @@ DomainTree<T>::insert(util::MemorySegment& mem_sgmt,
         }
     }
 
-    typename DomainTreeNode<T>::DomainTreeNodePtr* current_root = (up_node != NULL) ?
+    typename DomainTreeNode<T,DT>::DomainTreeNodePtr* current_root = (up_node != NULL) ?
         &(up_node->down_) : &root_;
     // 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.
-    DomainTreeNode<T>* node = DomainTreeNode<T>::create(mem_sgmt, target_labels);
+    DomainTreeNode<T,DT>* node = DomainTreeNode<T,DT>::create(mem_sgmt, target_labels);
     node->parent_ = parent;
     if (parent == NULL) {
         *current_root = node;
         // node is the new root of sub tree, so its init color is BLACK
-        node->setColor(DomainTreeNode<T>::BLACK);
+        node->setColor(DomainTreeNode<T,DT>::BLACK);
         node->setSubTreeRoot(true);
         node->parent_ = up_node;
     } else if (order < 0) {
@@ -1655,10 +1662,11 @@ DomainTree<T>::insert(util::MemorySegment& mem_sgmt,
     return (SUCCESS);
 }
 
-template <typename T>
+template <typename T, typename DT>
 void
-DomainTree<T>::deleteAllNodes(util::MemorySegment& mem_sgmt) {
-    deleteHelper(mem_sgmt, root_.get());
+DomainTree<T,DT>::deleteAllNodes(util::MemorySegment& mem_sgmt) {
+    const DT deleter;
+    deleteHelper(mem_sgmt, root_.get(), deleter);
     root_ = NULL;
 }
 
@@ -1667,9 +1675,9 @@ DomainTree<T>::deleteAllNodes(util::MemorySegment& mem_sgmt) {
 // name (and therefore the name for the existing node doesn't change).
 // Otherwise, things like shortcut links between nodes won't work.
 // See Trac #2054.
-template <typename T>
+template <typename T, typename DT>
 void
-DomainTree<T>::nodeFission(util::MemorySegment& mem_sgmt, DomainTreeNode<T>& node,
+DomainTree<T,DT>::nodeFission(util::MemorySegment& mem_sgmt, DomainTreeNode<T,DT>& node,
                        const isc::dns::LabelSequence& new_prefix,
                        const isc::dns::LabelSequence& new_suffix)
 {
@@ -1678,7 +1686,7 @@ DomainTree<T>::nodeFission(util::MemorySegment& mem_sgmt, DomainTreeNode<T>& nod
     // the end of the function, and it will keep consistent behavior
     // (i.e., a weak form of strong exception guarantee) even if code
     // after the call to this function throws an exception.
-    DomainTreeNode<T>* down_node = DomainTreeNode<T>::create(mem_sgmt, new_prefix);
+    DomainTreeNode<T,DT>* down_node = DomainTreeNode<T,DT>::create(mem_sgmt, new_prefix);
     node.resetLabels(new_suffix);
 
     std::swap(node.data_, down_node->data_);
@@ -1706,7 +1714,7 @@ DomainTree<T>::nodeFission(util::MemorySegment& mem_sgmt, DomainTreeNode<T>& nod
     node.setColor(down_node->getColor());
 
     // root node of sub tree, the initial color is BLACK
-    down_node->setColor(DomainTreeNode<T>::BLACK);
+    down_node->setColor(DomainTreeNode<T,DT>::BLACK);
 
     // mark it as the root of a subtree
     down_node->setSubTreeRoot(true);
@@ -1715,24 +1723,24 @@ DomainTree<T>::nodeFission(util::MemorySegment& mem_sgmt, DomainTreeNode<T>& nod
 }
 
 
-template <typename T>
+template <typename T, typename DT>
 void
-DomainTree<T>::insertRebalance(typename DomainTreeNode<T>::DomainTreeNodePtr* root,
-                           DomainTreeNode<T>* node)
+DomainTree<T,DT>::insertRebalance(typename DomainTreeNode<T,DT>::DomainTreeNodePtr* root,
+                           DomainTreeNode<T,DT>* node)
 {
-    DomainTreeNode<T>* uncle;
-    DomainTreeNode<T>* parent;
+    DomainTreeNode<T,DT>* uncle;
+    DomainTreeNode<T,DT>* parent;
     while (node != (*root).get() &&
-           (parent = node->getParent())->getColor() == DomainTreeNode<T>::RED) {
+           (parent = node->getParent())->getColor() == DomainTreeNode<T,DT>::RED) {
         // Here, node->parent_ is not NULL and it is also red, so
         // node->parent_->parent_ is also not NULL.
         if (parent == parent->getParent()->getLeft()) {
             uncle = parent->getParent()->getRight();
 
-            if (uncle != NULL && uncle->getColor() == DomainTreeNode<T>::RED) {
-                parent->setColor(DomainTreeNode<T>::BLACK);
-                uncle->setColor(DomainTreeNode<T>::BLACK);
-                parent->getParent()->setColor(DomainTreeNode<T>::RED);
+            if (uncle != NULL && uncle->getColor() == DomainTreeNode<T,DT>::RED) {
+                parent->setColor(DomainTreeNode<T,DT>::BLACK);
+                uncle->setColor(DomainTreeNode<T,DT>::BLACK);
+                parent->getParent()->setColor(DomainTreeNode<T,DT>::RED);
                 node = parent->getParent();
             } else {
                 if (node == parent->getRight()) {
@@ -1740,16 +1748,16 @@ DomainTree<T>::insertRebalance(typename DomainTreeNode<T>::DomainTreeNodePtr* ro
                     leftRotate(root, node);
                     parent = node->getParent();
                 }
-                parent->setColor(DomainTreeNode<T>::BLACK);
-                parent->getParent()->setColor(DomainTreeNode<T>::RED);
+                parent->setColor(DomainTreeNode<T,DT>::BLACK);
+                parent->getParent()->setColor(DomainTreeNode<T,DT>::RED);
                 rightRotate(root, parent->getParent());
             }
         } else {
             uncle = parent->getParent()->getLeft();
-            if (uncle != NULL && uncle->getColor() == DomainTreeNode<T>::RED) {
-                parent->setColor(DomainTreeNode<T>::BLACK);
-                uncle->setColor(DomainTreeNode<T>::BLACK);
-                parent->getParent()->setColor(DomainTreeNode<T>::RED);
+            if (uncle != NULL && uncle->getColor() == DomainTreeNode<T,DT>::RED) {
+                parent->setColor(DomainTreeNode<T,DT>::BLACK);
+                uncle->setColor(DomainTreeNode<T,DT>::BLACK);
+                parent->getParent()->setColor(DomainTreeNode<T,DT>::RED);
                 node = parent->getParent();
             } else {
                 if (node == parent->getLeft()) {
@@ -1757,28 +1765,28 @@ DomainTree<T>::insertRebalance(typename DomainTreeNode<T>::DomainTreeNodePtr* ro
                     rightRotate(root, node);
                     parent = node->getParent();
                 }
-                parent->setColor(DomainTreeNode<T>::BLACK);
-                parent->getParent()->setColor(DomainTreeNode<T>::RED);
+                parent->setColor(DomainTreeNode<T,DT>::BLACK);
+                parent->getParent()->setColor(DomainTreeNode<T,DT>::RED);
                 leftRotate(root, parent->getParent());
             }
         }
     }
 
-    (*root)->setColor(DomainTreeNode<T>::BLACK);
+    (*root)->setColor(DomainTreeNode<T,DT>::BLACK);
 }
 
 
-template <typename T>
-DomainTreeNode<T>*
-DomainTree<T>::leftRotate(typename DomainTreeNode<T>::DomainTreeNodePtr* root, DomainTreeNode<T>* node) {
-    DomainTreeNode<T>* const right = node->getRight();
-    DomainTreeNode<T>* const rleft = right->getLeft();
+template <typename T, typename DT>
+DomainTreeNode<T,DT>*
+DomainTree<T,DT>::leftRotate(typename DomainTreeNode<T,DT>::DomainTreeNodePtr* root, DomainTreeNode<T,DT>* node) {
+    DomainTreeNode<T,DT>* const right = node->getRight();
+    DomainTreeNode<T,DT>* const rleft = right->getLeft();
     node->right_ = rleft;
     if (rleft != NULL) {
         rleft->parent_ = node;
     }
 
-    DomainTreeNode<T>* const parent = node->getParent();
+    DomainTreeNode<T,DT>* const parent = node->getParent();
     right->parent_ = parent;
 
     if (!node->isSubTreeRoot()) {
@@ -1799,17 +1807,17 @@ DomainTree<T>::leftRotate(typename DomainTreeNode<T>::DomainTreeNodePtr* root, D
     return (node);
 }
 
-template <typename T>
-DomainTreeNode<T>*
-DomainTree<T>::rightRotate(typename DomainTreeNode<T>::DomainTreeNodePtr* root, DomainTreeNode<T>* node) {
-    DomainTreeNode<T>* const left = node->getLeft();
-    DomainTreeNode<T>* const lright = left->getRight();
+template <typename T, typename DT>
+DomainTreeNode<T,DT>*
+DomainTree<T,DT>::rightRotate(typename DomainTreeNode<T,DT>::DomainTreeNodePtr* root, DomainTreeNode<T,DT>* node) {
+    DomainTreeNode<T,DT>* const left = node->getLeft();
+    DomainTreeNode<T,DT>* const lright = left->getRight();
     node->left_ = lright;
     if (lright != NULL) {
         lright->parent_ = node;
     }
 
-    DomainTreeNode<T>* const parent = node->getParent();
+    DomainTreeNode<T,DT>* const parent = node->getParent();
     left->parent_ = parent;
 
     if (!node->isSubTreeRoot()) {
@@ -1831,17 +1839,17 @@ DomainTree<T>::rightRotate(typename DomainTreeNode<T>::DomainTreeNodePtr* root,
 }
 
 
-template <typename T>
+template <typename T, typename DT>
 void
-DomainTree<T>::dumpTree(std::ostream& os, unsigned int depth) const {
+DomainTree<T,DT>::dumpTree(std::ostream& os, unsigned int depth) const {
     indent(os, depth);
     os << "tree has " << node_count_ << " node(s)\n";
     dumpTreeHelper(os, root_.get(), depth);
 }
 
-template <typename T>
+template <typename T, typename DT>
 void
-DomainTree<T>::dumpTreeHelper(std::ostream& os, const DomainTreeNode<T>* node,
+DomainTree<T,DT>::dumpTreeHelper(std::ostream& os, const DomainTreeNode<T,DT>* node,
                           unsigned int depth) const
 {
     if (node == NULL) {
@@ -1852,7 +1860,7 @@ DomainTree<T>::dumpTreeHelper(std::ostream& os, const DomainTreeNode<T>* node,
 
     indent(os, depth);
     os << node->getLabels() << " ("
-       << ((node->getColor() == DomainTreeNode<T>::BLACK) ? "black" : "red")
+       << ((node->getColor() == DomainTreeNode<T,DT>::BLACK) ? "black" : "red")
        << ")";
     if (node->isEmpty()) {
         os << " [invisible]";
@@ -1862,7 +1870,7 @@ DomainTree<T>::dumpTreeHelper(std::ostream& os, const DomainTreeNode<T>* node,
     }
     os << "\n";
 
-    const DomainTreeNode<T>* down = node->getDown();
+    const DomainTreeNode<T,DT>* down = node->getDown();
     if (down != NULL) {
         indent(os, depth + 1);
         os << "begin down from " << node->getLabels() << "\n";
@@ -1874,16 +1882,16 @@ DomainTree<T>::dumpTreeHelper(std::ostream& os, const DomainTreeNode<T>* node,
     dumpTreeHelper(os, node->getRight(), depth + 1);
 }
 
-template <typename T>
+template <typename T, typename DT>
 void
-DomainTree<T>::indent(std::ostream& os, unsigned int depth) {
+DomainTree<T,DT>::indent(std::ostream& os, unsigned int depth) {
     static const unsigned int INDENT_FOR_EACH_DEPTH = 5;
     os << std::string(depth * INDENT_FOR_EACH_DEPTH, ' ');
 }
 
-template <typename T>
+template <typename T, typename DT>
 void
-DomainTree<T>::dumpDot(std::ostream& os, bool show_pointers) const {
+DomainTree<T,DT>::dumpDot(std::ostream& os, bool show_pointers) const {
     int nodecount = 0;
 
     os << "digraph g {\n";
@@ -1892,9 +1900,9 @@ DomainTree<T>::dumpDot(std::ostream& os, bool show_pointers) const {
     os << "}\n";
 }
 
-template <typename T>
+template <typename T, typename DT>
 int
-DomainTree<T>::dumpDotHelper(std::ostream& os, const DomainTreeNode<T>* node,
+DomainTree<T,DT>::dumpDotHelper(std::ostream& os, const DomainTreeNode<T,DT>* node,
                          int* nodecount, bool show_pointers) const
 {
     if (node == NULL) {
@@ -1915,7 +1923,7 @@ DomainTree<T>::dumpDotHelper(std::ostream& os, const DomainTreeNode<T>* node,
     }
     os << "\"] [";
 
-    if (node->getColor() == DomainTreeNode<T>::RED) {
+    if (node->getColor() == DomainTreeNode<T,DT>::RED) {
         os << "color=red";
     } else {
         os << "color=black";
index 6af83c519dc3fbde9f572a90ada3935214eb6a69..7def7d6d09eb03c08df4b8635f1b03eac1e5e667 100644 (file)
@@ -58,26 +58,38 @@ const size_t Name::MAX_LABELS;
  */
 
 namespace {
+
+class DeleterType {
+public:
+    void operator()(int *i) const {
+        delete i;
+    }
+};
+
+typedef DomainTree<int, DeleterType> TestDomainTree;
+typedef DomainTreeNode<int, DeleterType> TestDomainTreeNode;
+typedef DomainTreeNodeChain<int, DeleterType> TestDomainTreeNodeChain;
+
 class TreeHolder {
 public:
-    TreeHolder(util::MemorySegment& mem_sgmt, DomainTree<int>* tree) :
+    TreeHolder(util::MemorySegment& mem_sgmt, TestDomainTree* tree) :
         mem_sgmt_(mem_sgmt), tree_(tree)
     {}
     ~TreeHolder() {
-        DomainTree<int>::destroy(mem_sgmt_, tree_);
+        TestDomainTree::destroy(mem_sgmt_, tree_);
     }
-    DomainTree<int>* get() { return (tree_); }
+    TestDomainTree* get() { return (tree_); }
 private:
     util::MemorySegment& mem_sgmt_;
-    DomainTree<int>* tree_;
+    TestDomainTree* tree_;
 };
 
 class DomainTreeTest : public::testing::Test {
 protected:
     DomainTreeTest() :
-        rbtree_holder_(mem_sgmt_, DomainTree<int>::create(mem_sgmt_)),
+        rbtree_holder_(mem_sgmt_, TestDomainTree::create(mem_sgmt_)),
         rbtree_expose_empty_node_holder_(mem_sgmt_,
-                                         DomainTree<int>::create(mem_sgmt_, true)),
+                                         TestDomainTree::create(mem_sgmt_, true)),
         rbtree(*rbtree_holder_.get()),
         rbtree_expose_empty_node(*rbtree_expose_empty_node_holder_.get()),
         crbtnode(NULL)
@@ -88,11 +100,11 @@ protected:
         int name_count = sizeof(domain_names) / sizeof(domain_names[0]);
         for (int i = 0; i < name_count; ++i) {
             rbtree.insert(mem_sgmt_, Name(domain_names[i]), &rbtnode);
-            rbtnode->setData(DomainTreeNode<int>::NodeDataPtr(new int(i + 1)));
+            rbtnode->setData(new int(i + 1));
 
             rbtree_expose_empty_node.insert(mem_sgmt_, Name(domain_names[i]),
                                             &rbtnode);
-            rbtnode->setData(DomainTreeNode<int>::NodeDataPtr(new int(i + 1)));
+            rbtnode->setData(new int(i + 1));
 
         }
     }
@@ -100,10 +112,10 @@ protected:
     util::MemorySegmentLocal mem_sgmt_;
     TreeHolder rbtree_holder_;
     TreeHolder rbtree_expose_empty_node_holder_;
-    DomainTree<int>& rbtree;
-    DomainTree<int>& rbtree_expose_empty_node;
-    DomainTreeNode<int>* rbtnode;
-    const DomainTreeNode<int>* crbtnode;
+    TestDomainTree& rbtree;
+    TestDomainTree& rbtree_expose_empty_node;
+    TestDomainTreeNode* rbtnode;
+    const TestDomainTreeNode* crbtnode;
 };
 
 TEST_F(DomainTreeTest, nodeCount) {
@@ -116,97 +128,97 @@ TEST_F(DomainTreeTest, nodeCount) {
 }
 
 TEST_F(DomainTreeTest, setGetData) {
-    rbtnode->setData(DomainTreeNode<int>::NodeDataPtr(new int(11)));
+    rbtnode->setData(new int(11));
     EXPECT_EQ(11, *(rbtnode->getData()));
 }
 
 TEST_F(DomainTreeTest, insertNames) {
-    EXPECT_EQ(DomainTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt_,
+    EXPECT_EQ(TestDomainTree::ALREADYEXISTS, rbtree.insert(mem_sgmt_,
                                                         Name("d.e.f"),
                                                         &rbtnode));
     EXPECT_EQ(Name("d.e.f"), rbtnode->getName());
     EXPECT_EQ(15, rbtree.getNodeCount());
 
     // insert not exist node
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("0"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("0"),
                                                   &rbtnode));
     EXPECT_EQ(Name("0"), rbtnode->getName());
     EXPECT_EQ(16, rbtree.getNodeCount());
 
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_,
                                                   Name("example.com"),
                                                   &rbtnode));
     EXPECT_EQ(17, rbtree.getNodeCount());
-    rbtnode->setData(DomainTreeNode<int>::NodeDataPtr(new int(12)));
+    rbtnode->setData(new int(12));
 
     // return ALREADYEXISTS, since node "example.com" already has
     // been explicitly inserted
-    EXPECT_EQ(DomainTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt_,
+    EXPECT_EQ(TestDomainTree::ALREADYEXISTS, rbtree.insert(mem_sgmt_,
                                                         Name("example.com"),
                                                         &rbtnode));
     EXPECT_EQ(17, rbtree.getNodeCount());
 
     // split the node "d.e.f"
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("k.e.f"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("k.e.f"),
                                                   &rbtnode));
     EXPECT_EQ(Name("k"), rbtnode->getName());
     EXPECT_EQ(19, rbtree.getNodeCount());
 
     // split the node "g.h"
-    EXPECT_EQ(DomainTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt_, Name("h"),
+    EXPECT_EQ(TestDomainTree::ALREADYEXISTS, rbtree.insert(mem_sgmt_, Name("h"),
                                                         &rbtnode));
     EXPECT_EQ(Name("h"), rbtnode->getName());
     EXPECT_EQ(20, rbtree.getNodeCount());
 
     // add child domain
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_,
                                                   Name("m.p.w.y.d.e.f"),
                                                   &rbtnode));
     EXPECT_EQ(Name("m"), rbtnode->getName());
     EXPECT_EQ(21, rbtree.getNodeCount());
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_,
                                                   Name("n.p.w.y.d.e.f"),
                                                   &rbtnode));
     EXPECT_EQ(Name("n"), rbtnode->getName());
     EXPECT_EQ(22, rbtree.getNodeCount());
 
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("l.a"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("l.a"),
                                                   &rbtnode));
     EXPECT_EQ(Name("l"), rbtnode->getName());
     EXPECT_EQ(23, rbtree.getNodeCount());
 
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("r.d.e.f"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("r.d.e.f"),
                                                   &rbtnode));
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("s.d.e.f"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("s.d.e.f"),
                                                   &rbtnode));
     EXPECT_EQ(25, rbtree.getNodeCount());
 
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
+    EXPECT_EQ(TestDomainTree::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(DomainTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt_, Name("f"),
+    EXPECT_EQ(TestDomainTree::ALREADYEXISTS, rbtree.insert(mem_sgmt_, Name("f"),
                                                         &rbtnode));
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("m"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("m"),
                                                   &rbtnode));
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("nm"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("nm"),
                                                   &rbtnode));
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("om"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("om"),
                                                   &rbtnode));
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("k"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("k"),
                                                   &rbtnode));
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("l"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("l"),
                                                   &rbtnode));
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("fe"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("fe"),
                                                   &rbtnode));
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("ge"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("ge"),
                                                   &rbtnode));
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("i"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("i"),
                                                   &rbtnode));
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("ae"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("ae"),
                                                   &rbtnode));
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_, Name("n"),
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_, Name("n"),
                                                   &rbtnode));
 }
 
@@ -216,76 +228,76 @@ TEST_F(DomainTreeTest, subTreeRoot) {
     // that when a node was fissioned, FLAG_SUBTREE_ROOT was not being
     // copied correctly.
 
-    EXPECT_EQ(DomainTree<int>::ALREADYEXISTS,
+    EXPECT_EQ(TestDomainTree::ALREADYEXISTS,
               rbtree_expose_empty_node.insert(mem_sgmt_, Name("d.e.f"),
                                               &rbtnode));
-    EXPECT_EQ(DomainTree<int>::SUCCESS,
+    EXPECT_EQ(TestDomainTree::SUCCESS,
               rbtree_expose_empty_node.insert(mem_sgmt_, Name("0"),
                                               &rbtnode));
-    EXPECT_EQ(DomainTree<int>::SUCCESS,
+    EXPECT_EQ(TestDomainTree::SUCCESS,
               rbtree_expose_empty_node.insert(mem_sgmt_, Name("example.com"),
                                               &rbtnode));
-    EXPECT_EQ(DomainTree<int>::ALREADYEXISTS,
+    EXPECT_EQ(TestDomainTree::ALREADYEXISTS,
               rbtree_expose_empty_node.insert(mem_sgmt_, Name("example.com"),
                                               &rbtnode));
-    EXPECT_EQ(DomainTree<int>::SUCCESS,
+    EXPECT_EQ(TestDomainTree::SUCCESS,
               rbtree_expose_empty_node.insert(mem_sgmt_, Name("k.e.f"),
                                               &rbtnode));
 
     // "g.h" is not a subtree root
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               rbtree_expose_empty_node.find(Name("g.h"), &rbtnode));
-    EXPECT_FALSE(rbtnode->getFlag(DomainTreeNode<int>::FLAG_SUBTREE_ROOT));
+    EXPECT_FALSE(rbtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
 
     // fission the node "g.h"
-    EXPECT_EQ(DomainTree<int>::ALREADYEXISTS,
+    EXPECT_EQ(TestDomainTree::ALREADYEXISTS,
               rbtree_expose_empty_node.insert(mem_sgmt_, Name("h"),
                                               &rbtnode));
 
     // the node "h" (h.down_ -> "g") should not be a subtree root. "g"
     // should be a subtree root.
-    EXPECT_FALSE(rbtnode->getFlag(DomainTreeNode<int>::FLAG_SUBTREE_ROOT));
+    EXPECT_FALSE(rbtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
 
     // "g.h" should be a subtree root now.
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               rbtree_expose_empty_node.find(Name("g.h"), &rbtnode));
-    EXPECT_TRUE(rbtnode->getFlag(DomainTreeNode<int>::FLAG_SUBTREE_ROOT));
+    EXPECT_TRUE(rbtnode->getFlag(TestDomainTreeNode::FLAG_SUBTREE_ROOT));
 }
 
 TEST_F(DomainTreeTest, findName) {
     // find const rbtnode
     // exact match
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH, rbtree.find(Name("a"), &crbtnode));
+    EXPECT_EQ(TestDomainTree::EXACTMATCH, rbtree.find(Name("a"), &crbtnode));
     EXPECT_EQ(Name("a"), crbtnode->getName());
 
     // not found
-    EXPECT_EQ(DomainTree<int>::NOTFOUND, rbtree.find(Name("d.e.f"), &crbtnode));
-    EXPECT_EQ(DomainTree<int>::NOTFOUND, rbtree.find(Name("y.d.e.f"), &crbtnode));
-    EXPECT_EQ(DomainTree<int>::NOTFOUND, rbtree.find(Name("x"), &crbtnode));
-    EXPECT_EQ(DomainTree<int>::NOTFOUND, rbtree.find(Name("m.n"), &crbtnode));
+    EXPECT_EQ(TestDomainTree::NOTFOUND, rbtree.find(Name("d.e.f"), &crbtnode));
+    EXPECT_EQ(TestDomainTree::NOTFOUND, rbtree.find(Name("y.d.e.f"), &crbtnode));
+    EXPECT_EQ(TestDomainTree::NOTFOUND, rbtree.find(Name("x"), &crbtnode));
+    EXPECT_EQ(TestDomainTree::NOTFOUND, rbtree.find(Name("m.n"), &crbtnode));
 
     // if we expose empty node, we can get the empty node created during insert
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               rbtree_expose_empty_node.find(Name("d.e.f"), &crbtnode));
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               rbtree_expose_empty_node.find(Name("w.y.d.e.f"), &crbtnode));
 
     // partial match
-    EXPECT_EQ(DomainTree<int>::PARTIALMATCH, rbtree.find(Name("m.b"), &crbtnode));
+    EXPECT_EQ(TestDomainTree::PARTIALMATCH, rbtree.find(Name("m.b"), &crbtnode));
     EXPECT_EQ(Name("b"), crbtnode->getName());
-    EXPECT_EQ(DomainTree<int>::PARTIALMATCH,
+    EXPECT_EQ(TestDomainTree::PARTIALMATCH,
               rbtree_expose_empty_node.find(Name("m.d.e.f"), &crbtnode));
 
     // find rbtnode
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH, rbtree.find(Name("q.w.y.d.e.f"),
+    EXPECT_EQ(TestDomainTree::EXACTMATCH, rbtree.find(Name("q.w.y.d.e.f"),
                                                    &rbtnode));
     EXPECT_EQ(Name("q"), rbtnode->getName());
 }
 
 TEST_F(DomainTreeTest, findError) {
     // For the version that takes a node chain, the chain must be empty.
-    DomainTreeNodeChain<int> chain;
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH, rbtree.find(Name("a"), &crbtnode,
+    TestDomainTreeNodeChain chain;
+    EXPECT_EQ(TestDomainTree::EXACTMATCH, rbtree.find(Name("a"), &crbtnode,
                                                    chain));
     // trying to reuse the same chain.  it should result in an exception.
     EXPECT_THROW(rbtree.find(Name("a"), &crbtnode, chain),
@@ -293,94 +305,94 @@ TEST_F(DomainTreeTest, findError) {
 }
 
 TEST_F(DomainTreeTest, flags) {
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt_,
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt_,
                                                   Name("flags.example"),
                                                   &rbtnode));
 
     // by default, flags are all off
-    EXPECT_FALSE(rbtnode->getFlag(DomainTreeNode<int>::FLAG_CALLBACK));
+    EXPECT_FALSE(rbtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
 
     // set operation, by default it enables the flag
-    rbtnode->setFlag(DomainTreeNode<int>::FLAG_CALLBACK);
-    EXPECT_TRUE(rbtnode->getFlag(DomainTreeNode<int>::FLAG_CALLBACK));
+    rbtnode->setFlag(TestDomainTreeNode::FLAG_CALLBACK);
+    EXPECT_TRUE(rbtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
 
     // try disable the flag explicitly
-    rbtnode->setFlag(DomainTreeNode<int>::FLAG_CALLBACK, false);
-    EXPECT_FALSE(rbtnode->getFlag(DomainTreeNode<int>::FLAG_CALLBACK));
+    rbtnode->setFlag(TestDomainTreeNode::FLAG_CALLBACK, false);
+    EXPECT_FALSE(rbtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
 
     // try enable the flag explicitly
-    rbtnode->setFlag(DomainTreeNode<int>::FLAG_CALLBACK, true);
-    EXPECT_TRUE(rbtnode->getFlag(DomainTreeNode<int>::FLAG_CALLBACK));
+    rbtnode->setFlag(TestDomainTreeNode::FLAG_CALLBACK, true);
+    EXPECT_TRUE(rbtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
 
     // setting an unknown flag will trigger an exception
-    EXPECT_THROW(rbtnode->setFlag(static_cast<DomainTreeNode<int>::Flags>(2), true),
+    EXPECT_THROW(rbtnode->setFlag(static_cast<TestDomainTreeNode::Flags>(2), true),
                  isc::InvalidParameter);
 }
 
 bool
-testCallback(const DomainTreeNode<int>&, bool* callback_checker) {
+testCallback(const TestDomainTreeNode&, bool* callback_checker) {
     *callback_checker = true;
     return (false);
 }
 
 template <typename T>
 void
-performCallbackTest(DomainTree<int>& rbtree,
+performCallbackTest(TestDomainTree& rbtree,
                     util::MemorySegmentLocal& mem_sgmt,
                     const T& name_called,
                     const T& name_not_called)
 {
-    DomainTreeNode<int>* rbtnode;
-    const DomainTreeNode<int>* crbtnode;
+    TestDomainTreeNode* rbtnode;
+    const TestDomainTreeNode* crbtnode;
 
     // by default callback isn't enabled
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt,
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt,
                                                   Name("callback.example"),
                                                   &rbtnode));
-    rbtnode->setData(DomainTreeNode<int>::NodeDataPtr(new int(1)));
-    EXPECT_FALSE(rbtnode->getFlag(DomainTreeNode<int>::FLAG_CALLBACK));
+    rbtnode->setData(new int(1));
+    EXPECT_FALSE(rbtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
 
     // enable/re-disable callback
-    rbtnode->setFlag(DomainTreeNode<int>::FLAG_CALLBACK);
-    EXPECT_TRUE(rbtnode->getFlag(DomainTreeNode<int>::FLAG_CALLBACK));
-    rbtnode->setFlag(DomainTreeNode<int>::FLAG_CALLBACK, false);
-    EXPECT_FALSE(rbtnode->getFlag(DomainTreeNode<int>::FLAG_CALLBACK));
+    rbtnode->setFlag(TestDomainTreeNode::FLAG_CALLBACK);
+    EXPECT_TRUE(rbtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
+    rbtnode->setFlag(TestDomainTreeNode::FLAG_CALLBACK, false);
+    EXPECT_FALSE(rbtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
 
     // enable again for subsequent tests
-    rbtnode->setFlag(DomainTreeNode<int>::FLAG_CALLBACK);
+    rbtnode->setFlag(TestDomainTreeNode::FLAG_CALLBACK);
     // add more levels below and above the callback node for partial match.
-    DomainTreeNode<int>* subrbtnode;
-    EXPECT_EQ(DomainTree<int>::SUCCESS, rbtree.insert(mem_sgmt,
+    TestDomainTreeNode* subrbtnode;
+    EXPECT_EQ(TestDomainTree::SUCCESS, rbtree.insert(mem_sgmt,
                                                   Name("sub.callback.example"),
                                                   &subrbtnode));
-    subrbtnode->setData(DomainTreeNode<int>::NodeDataPtr(new int(2)));
-    DomainTreeNode<int>* parentrbtnode;
-    EXPECT_EQ(DomainTree<int>::ALREADYEXISTS, rbtree.insert(mem_sgmt,
+    subrbtnode->setData(new int(2));
+    TestDomainTreeNode* parentrbtnode;
+    EXPECT_EQ(TestDomainTree::ALREADYEXISTS, rbtree.insert(mem_sgmt,
                                                         Name("example"),
                                                         &parentrbtnode));
     // the child/parent nodes shouldn't "inherit" the callback flag.
     // "rbtnode" may be invalid due to the insertion, so we need to re-find
     // it.
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH, rbtree.find(Name("callback.example"),
+    EXPECT_EQ(TestDomainTree::EXACTMATCH, rbtree.find(Name("callback.example"),
                                                    &rbtnode));
-    EXPECT_TRUE(rbtnode->getFlag(DomainTreeNode<int>::FLAG_CALLBACK));
-    EXPECT_FALSE(subrbtnode->getFlag(DomainTreeNode<int>::FLAG_CALLBACK));
-    EXPECT_FALSE(parentrbtnode->getFlag(DomainTreeNode<int>::FLAG_CALLBACK));
+    EXPECT_TRUE(rbtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
+    EXPECT_FALSE(subrbtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
+    EXPECT_FALSE(parentrbtnode->getFlag(TestDomainTreeNode::FLAG_CALLBACK));
 
     // check if the callback is called from find()
-    DomainTreeNodeChain<int> node_path1;
+    TestDomainTreeNodeChain node_path1;
     bool callback_called = false;
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               rbtree.find(name_called, &crbtnode, node_path1,
                           testCallback, &callback_called));
     EXPECT_TRUE(callback_called);
 
     // enable callback at the parent node, but it doesn't have data so
     // the callback shouldn't be called.
-    DomainTreeNodeChain<int> node_path2;
-    parentrbtnode->setFlag(DomainTreeNode<int>::FLAG_CALLBACK);
+    TestDomainTreeNodeChain node_path2;
+    parentrbtnode->setFlag(TestDomainTreeNode::FLAG_CALLBACK);
     callback_called = false;
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               rbtree.find(name_not_called, &crbtnode, node_path2,
                           testCallback, &callback_called));
     EXPECT_FALSE(callback_called);
@@ -403,19 +415,19 @@ TEST_F(DomainTreeTest, callbackLabelSequence) {
 }
 
 TEST_F(DomainTreeTest, chainLevel) {
-    DomainTreeNodeChain<int> chain;
+    TestDomainTreeNodeChain chain;
 
     // by default there should be no level in the chain.
     EXPECT_EQ(0, chain.getLevelCount());
 
     // insert one node to the tree and find it.  there should be exactly
     // one level in the chain.
-    TreeHolder tree_holder(mem_sgmt_, DomainTree<int>::create(mem_sgmt_, true));
-    DomainTree<int>& tree(*tree_holder.get());
+    TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_, true));
+    TestDomainTree& tree(*tree_holder.get());
     Name node_name(Name::ROOT_NAME());
-    EXPECT_EQ(DomainTree<int>::SUCCESS, tree.insert(mem_sgmt_, node_name,
+    EXPECT_EQ(TestDomainTree::SUCCESS, tree.insert(mem_sgmt_, node_name,
                                                 &rbtnode));
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               tree.find(node_name, &crbtnode, chain));
     EXPECT_EQ(1, chain.getLevelCount());
 
@@ -436,10 +448,10 @@ TEST_F(DomainTreeTest, chainLevel) {
      */
     for (unsigned int i = 2; i <= Name::MAX_LABELS; ++i) {
         node_name = Name("a.").concatenate(node_name);
-        EXPECT_EQ(DomainTree<int>::SUCCESS, tree.insert(mem_sgmt_, node_name,
+        EXPECT_EQ(TestDomainTree::SUCCESS, tree.insert(mem_sgmt_, node_name,
                                                     &rbtnode));
-        DomainTreeNodeChain<int> found_chain;
-        EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+        TestDomainTreeNodeChain found_chain;
+        EXPECT_EQ(TestDomainTree::EXACTMATCH,
                   tree.find(node_name, &crbtnode, found_chain));
         EXPECT_EQ(i, found_chain.getLevelCount());
     }
@@ -453,7 +465,7 @@ TEST_F(DomainTreeTest, chainLevel) {
 
 TEST_F(DomainTreeTest, getAbsoluteNameError) {
     // an empty chain isn't allowed.
-    DomainTreeNodeChain<int> chain;
+    TestDomainTreeNodeChain chain;
     EXPECT_THROW(chain.getAbsoluteName(), BadValue);
 }
 
@@ -489,19 +501,19 @@ const char* const upper_node_names[] = {
     ".", "g.h", "g.h"};
 
 TEST_F(DomainTreeTest, getUpperNode) {
-    DomainTreeNodeChain<int> node_path;
-    const DomainTreeNode<int>* node = NULL;
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    TestDomainTreeNodeChain node_path;
+    const TestDomainTreeNode* node = NULL;
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               rbtree_expose_empty_node.find(Name(names[0]),
                                             &node,
                                             node_path));
     for (int i = 0; i < name_count; ++i) {
         EXPECT_NE(static_cast<void*>(NULL), node);
 
-        const DomainTreeNode<int>* upper_node = node->getUpperNode();
+        const TestDomainTreeNode* upper_node = node->getUpperNode();
         if (upper_node_names[i] != NULL) {
-            const DomainTreeNode<int>* upper_node2 = NULL;
-            EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+            const TestDomainTreeNode* upper_node2 = NULL;
+            EXPECT_EQ(TestDomainTree::EXACTMATCH,
                       rbtree_expose_empty_node.find(Name(upper_node_names[i]),
                                                     &upper_node2));
             EXPECT_NE(static_cast<void*>(NULL), upper_node2);
@@ -518,9 +530,9 @@ TEST_F(DomainTreeTest, getUpperNode) {
 }
 
 TEST_F(DomainTreeTest, nextNode) {
-    DomainTreeNodeChain<int> node_path;
-    const DomainTreeNode<int>* node = NULL;
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    TestDomainTreeNodeChain node_path;
+    const TestDomainTreeNode* node = NULL;
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               rbtree.find(Name(names[0]), &node, node_path));
     for (int i = 0; i < name_count; ++i) {
         EXPECT_NE(static_cast<void*>(NULL), node);
@@ -546,8 +558,8 @@ TEST_F(DomainTreeTest, nextNode) {
 //   (true is for finds that return no match, false for the ones that return
 //   match)
 void
-previousWalk(DomainTree<int>& rbtree, const DomainTreeNode<int>* node,
-             DomainTreeNodeChain<int>& node_path, size_t chain_length,
+previousWalk(TestDomainTree& rbtree, const TestDomainTreeNode* node,
+             TestDomainTreeNodeChain& node_path, size_t chain_length,
              bool skip_first)
 {
     if (skip_first) {
@@ -564,9 +576,9 @@ previousWalk(DomainTree<int>& rbtree, const DomainTreeNode<int>* node,
         //
         // The "empty" nodes can not be found
         if (node->getData()) {
-            const DomainTreeNode<int>* node2(NULL);
-            DomainTreeNodeChain<int> node_path2;
-            EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+            const TestDomainTreeNode* node2(NULL);
+            TestDomainTreeNodeChain node_path2;
+            EXPECT_EQ(TestDomainTree::EXACTMATCH,
                       rbtree.find(Name(names[i - 1]), &node2, node_path2));
             EXPECT_EQ(node, node2);
         }
@@ -590,13 +602,13 @@ previousWalk(DomainTree<int>& rbtree, const DomainTreeNode<int>* node,
 // Check the previousNode
 TEST_F(DomainTreeTest, previousNode) {
     // First, iterate the whole tree from the end to the beginning.
-    DomainTreeNodeChain<int> node_path;
+    TestDomainTreeNodeChain node_path;
     EXPECT_THROW(rbtree.previousNode(node_path), isc::BadValue) <<
         "Throw before a search was done on the path";
-    const DomainTreeNode<int>* node(NULL);
+    const TestDomainTreeNode* node(NULL);
     {
         SCOPED_TRACE("Iterate through");
-        EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+        EXPECT_EQ(TestDomainTree::EXACTMATCH,
                   rbtree.find(Name(names[name_count - 1]), &node, node_path));
         previousWalk(rbtree, node, node_path, name_count, false);
         node = NULL;
@@ -606,7 +618,7 @@ TEST_F(DomainTreeTest, previousNode) {
     {
         SCOPED_TRACE("Iterate from the middle");
         // Now, start somewhere in the middle, but within the real node.
-        EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+        EXPECT_EQ(TestDomainTree::EXACTMATCH,
                   rbtree.find(Name(names[4]), &node, node_path));
         previousWalk(rbtree, node, node_path, 5, false);
         node = NULL;
@@ -617,7 +629,7 @@ TEST_F(DomainTreeTest, previousNode) {
         SCOPED_TRACE("Start at the first");
         // If we start at the lowest (which is "a"), we get to the beginning
         // right away.
-        EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+        EXPECT_EQ(TestDomainTree::EXACTMATCH,
                   rbtree.find(Name(names[0]), &node, node_path));
         EXPECT_NE(static_cast<void*>(NULL), node);
         node = rbtree.previousNode(node_path);
@@ -631,7 +643,7 @@ TEST_F(DomainTreeTest, previousNode) {
         SCOPED_TRACE("Start before the first");
         // If we start before the lowest (. < 0. < a.), we should not get a
         // node.  Its previous node should be the root.
-        EXPECT_EQ(DomainTree<int>::NOTFOUND,
+        EXPECT_EQ(TestDomainTree::NOTFOUND,
                   rbtree.find<void*>(Name("0"), &node, node_path, NULL, NULL));
         EXPECT_EQ(static_cast<void*>(NULL), node);
         node = rbtree.previousNode(node_path);
@@ -643,7 +655,7 @@ TEST_F(DomainTreeTest, previousNode) {
 
     {
         SCOPED_TRACE("Start after the last");
-        EXPECT_EQ(DomainTree<int>::NOTFOUND,
+        EXPECT_EQ(TestDomainTree::NOTFOUND,
                   rbtree.find(Name("z"), &node, node_path));
         previousWalk(rbtree, node, node_path, name_count, true);
         node = NULL;
@@ -655,7 +667,7 @@ TEST_F(DomainTreeTest, previousNode) {
         // We exit a leaf by going down. We should start by the one
         // we exited - 'c' (actually, we should get it by the find, as partial
         // match).
-        EXPECT_EQ(DomainTree<int>::PARTIALMATCH,
+        EXPECT_EQ(TestDomainTree::PARTIALMATCH,
                   rbtree.find(Name("b.c"), &node, node_path));
         previousWalk(rbtree, node, node_path, 3, false);
         node = NULL;
@@ -669,7 +681,7 @@ TEST_F(DomainTreeTest, previousNode) {
 
         // The d.e.f is empty node, so it is hidden by find. Therefore NOTFOUND
         // and not PARTIALMATCH.
-        EXPECT_EQ(DomainTree<int>::NOTFOUND,
+        EXPECT_EQ(TestDomainTree::NOTFOUND,
                   rbtree.find(Name("xy.d.e.f"), &node, node_path));
         previousWalk(rbtree, node, node_path, 5, true);
         node = NULL;
@@ -683,7 +695,7 @@ TEST_F(DomainTreeTest, previousNode) {
 
         // The d.e.f is empty node, so it is hidden by find. Therefore NOTFOUND
         // and not PARTIALMATCH.
-        EXPECT_EQ(DomainTree<int>::NOTFOUND,
+        EXPECT_EQ(TestDomainTree::NOTFOUND,
                   rbtree.find(Name("yz.d.e.f"), &node, node_path));
         previousWalk(rbtree, node, node_path, 9, true);
         node = NULL;
@@ -697,7 +709,7 @@ TEST_F(DomainTreeTest, previousNode) {
 
         // 'g.h' is an empty node, so we get a NOTFOUND and not
         // PARTIALMATCH.
-        EXPECT_EQ(DomainTree<int>::NOTFOUND,
+        EXPECT_EQ(TestDomainTree::NOTFOUND,
                   rbtree.find(Name("x.h"), &node, node_path));
         // 'g.h' is the COMMONANCESTOR.
         EXPECT_EQ(node_path.getLastComparedNode()->getName(), Name("g.h"));
@@ -716,7 +728,7 @@ TEST_F(DomainTreeTest, previousNode) {
         SCOPED_TRACE("Start inside a wrong node");
         // The d.e.f is a single node, but we want only part of it. We
         // should start iterating before it.
-        EXPECT_EQ(DomainTree<int>::NOTFOUND,
+        EXPECT_EQ(TestDomainTree::NOTFOUND,
                   rbtree.find(Name("e.f"), &node, node_path));
         previousWalk(rbtree, node, node_path, 3, true);
         node = NULL;
@@ -726,9 +738,9 @@ TEST_F(DomainTreeTest, previousNode) {
     {
         SCOPED_TRACE("Lookup in empty tree");
         // Just check it doesn't crash, etc.
-        TreeHolder tree_holder(mem_sgmt_, DomainTree<int>::create(mem_sgmt_));
-        DomainTree<int>& empty_tree(*tree_holder.get());
-        EXPECT_EQ(DomainTree<int>::NOTFOUND,
+        TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_));
+        TestDomainTree& empty_tree(*tree_holder.get());
+        EXPECT_EQ(TestDomainTree::NOTFOUND,
                   empty_tree.find(Name("x"), &node, node_path));
         EXPECT_EQ(static_cast<void*>(NULL), node);
         EXPECT_EQ(static_cast<void*>(NULL),
@@ -740,13 +752,13 @@ TEST_F(DomainTreeTest, previousNode) {
 
 TEST_F(DomainTreeTest, nextNodeError) {
     // Empty chain for nextNode() is invalid.
-    DomainTreeNodeChain<int> chain;
+    TestDomainTreeNodeChain chain;
     EXPECT_THROW(rbtree.nextNode(chain), BadValue);
 }
 
 // A helper function for getLastComparedNode() below.
 void
-comparisonChecks(const DomainTreeNodeChain<int>& chain,
+comparisonChecks(const TestDomainTreeNodeChain& chain,
                  int expected_order, int expected_common_labels,
                  NameComparisonResult::NameRelation expected_reln)
 {
@@ -764,24 +776,24 @@ comparisonChecks(const DomainTreeNodeChain<int>& chain,
 }
 
 TEST_F(DomainTreeTest, getLastComparedNode) {
-    DomainTree<int>& tree = rbtree_expose_empty_node; // use the "empty OK" mode
-    DomainTreeNodeChain<int> chain;
+    TestDomainTree& tree = rbtree_expose_empty_node; // use the "empty OK" mode
+    TestDomainTreeNodeChain chain;
 
     // initially there should be no 'last compared'.
     EXPECT_EQ(static_cast<void*>(NULL), chain.getLastComparedNode());
 
     // A search for an empty tree should result in no 'last compared', too.
-    TreeHolder tree_holder(mem_sgmt_, DomainTree<int>::create(mem_sgmt_));
-    DomainTree<int>& empty_tree(*tree_holder.get());
-    EXPECT_EQ(DomainTree<int>::NOTFOUND,
+    TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_));
+    TestDomainTree& empty_tree(*tree_holder.get());
+    EXPECT_EQ(TestDomainTree::NOTFOUND,
               empty_tree.find(Name("a"), &crbtnode, chain));
     EXPECT_EQ(static_cast<void*>(NULL), chain.getLastComparedNode());
     chain.clear();
 
-    const DomainTreeNode<int>* expected_node = NULL;
+    const TestDomainTreeNode* expected_node = NULL;
 
     // Exact match case.  The returned node should be last compared.
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               tree.find(Name("x.d.e.f"), &expected_node, chain));
     EXPECT_EQ(expected_node, chain.getLastComparedNode());
     // 1 = # labels of "x" (note: excluding ".")
@@ -790,9 +802,9 @@ TEST_F(DomainTreeTest, getLastComparedNode) {
 
     // Partial match, search stopped at the matching node, which should be
     // the last compared node.
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               tree.find(Name("k.g.h"), &expected_node));
-    EXPECT_EQ(DomainTree<int>::PARTIALMATCH,
+    EXPECT_EQ(TestDomainTree::PARTIALMATCH,
               tree.find(Name("x.k.g.h"), &crbtnode, chain));
     EXPECT_EQ(expected_node, chain.getLastComparedNode());
     // k.g.h < x.k.g.h, 1 = # labels of "k"
@@ -801,9 +813,9 @@ TEST_F(DomainTreeTest, getLastComparedNode) {
 
     // Partial match, search stopped in the subtree below the matching node
     // after following a left branch.
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               tree.find(Name("x.d.e.f"), &expected_node));
-    EXPECT_EQ(DomainTree<int>::PARTIALMATCH,
+    EXPECT_EQ(TestDomainTree::PARTIALMATCH,
               tree.find(Name("a.d.e.f"), &crbtnode, chain));
     EXPECT_EQ(expected_node, chain.getLastComparedNode());
     // a < x, no common labels
@@ -812,9 +824,9 @@ TEST_F(DomainTreeTest, getLastComparedNode) {
 
     // Partial match, search stopped in the subtree below the matching node
     // after following a right branch.
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               tree.find(Name("z.d.e.f"), &expected_node));
-    EXPECT_EQ(DomainTree<int>::PARTIALMATCH,
+    EXPECT_EQ(TestDomainTree::PARTIALMATCH,
               tree.find(Name("zz.d.e.f"), &crbtnode, chain));
     EXPECT_EQ(expected_node, chain.getLastComparedNode());
     // zz > z, no common label
@@ -823,9 +835,9 @@ TEST_F(DomainTreeTest, getLastComparedNode) {
 
     // Partial match, search stopped at a node for a super domain of the
     // search name in the subtree below the matching node.
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               tree.find(Name("w.y.d.e.f"), &expected_node));
-    EXPECT_EQ(DomainTree<int>::PARTIALMATCH,
+    EXPECT_EQ(TestDomainTree::PARTIALMATCH,
               tree.find(Name("y.d.e.f"), &crbtnode, chain));
     EXPECT_EQ(expected_node, chain.getLastComparedNode());
     // y < w.y, 1 = # labels of "y"
@@ -835,7 +847,7 @@ TEST_F(DomainTreeTest, getLastComparedNode) {
     // Partial match, search stopped at a node that share a common ancestor
     // with the search name in the subtree below the matching node.
     // (the expected node is the same as the previous case)
-    EXPECT_EQ(DomainTree<int>::PARTIALMATCH,
+    EXPECT_EQ(TestDomainTree::PARTIALMATCH,
               tree.find(Name("z.y.d.e.f"), &crbtnode, chain));
     EXPECT_EQ(expected_node, chain.getLastComparedNode());
     // z.y > w.y, 1 = # labels of "y"
@@ -844,8 +856,8 @@ TEST_F(DomainTreeTest, getLastComparedNode) {
 
     // Search stops in the highest level (under ".") after following a left
     // branch. (find() still returns PARTIALMATCH due to the top level ".")
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH, tree.find(Name("c"), &expected_node));
-    EXPECT_EQ(DomainTree<int>::PARTIALMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH, tree.find(Name("c"), &expected_node));
+    EXPECT_EQ(TestDomainTree::PARTIALMATCH,
               tree.find(Name("bb"), &crbtnode, chain));
     EXPECT_EQ(expected_node, chain.getLastComparedNode());
     // bb < c, no common label
@@ -854,7 +866,7 @@ TEST_F(DomainTreeTest, getLastComparedNode) {
 
     // Search stops in the highest level (under ".") after following a right
     // branch. (the expected node is the same as the previous case)
-    EXPECT_EQ(DomainTree<int>::PARTIALMATCH,
+    EXPECT_EQ(TestDomainTree::PARTIALMATCH,
               tree.find(Name("d"), &crbtnode, chain));
     EXPECT_EQ(expected_node, chain.getLastComparedNode());
     // d > c, no common label
@@ -923,9 +935,9 @@ TEST_F(DomainTreeTest, swap) {
     size_t count1(rbtree.getNodeCount());
 
     // Create second one and store state
-    TreeHolder tree_holder(mem_sgmt_, DomainTree<int>::create(mem_sgmt_));
-    DomainTree<int>& tree2(*tree_holder.get());
-    DomainTreeNode<int>* node;
+    TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_));
+    TestDomainTree& tree2(*tree_holder.get());
+    TestDomainTreeNode* node;
     tree2.insert(mem_sgmt_, Name("second"), &node);
     std::ostringstream str2;
     tree2.dumpTree(str2);
@@ -950,41 +962,41 @@ TEST_F(DomainTreeTest, swap) {
 // any domain names should be considered a subdomain of it), so it makes
 // sense to test cases with the root zone explicitly.
 TEST_F(DomainTreeTest, root) {
-    TreeHolder tree_holder(mem_sgmt_, DomainTree<int>::create(mem_sgmt_));
-    DomainTree<int>& root(*tree_holder.get());
+    TreeHolder tree_holder(mem_sgmt_, TestDomainTree::create(mem_sgmt_));
+    TestDomainTree& root(*tree_holder.get());
     root.insert(mem_sgmt_, Name::ROOT_NAME(), &rbtnode);
-    rbtnode->setData(DomainTreeNode<int>::NodeDataPtr(new int(1)));
+    rbtnode->setData(new int(1));
 
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               root.find(Name::ROOT_NAME(), &crbtnode));
     EXPECT_EQ(rbtnode, crbtnode);
-    EXPECT_EQ(DomainTree<int>::PARTIALMATCH,
+    EXPECT_EQ(TestDomainTree::PARTIALMATCH,
               root.find(Name("example.com"), &crbtnode));
     EXPECT_EQ(rbtnode, crbtnode);
 
     // Insert a new name that better matches the query name.  find() should
     // find the better one.
     root.insert(mem_sgmt_, Name("com"), &rbtnode);
-    rbtnode->setData(DomainTreeNode<int>::NodeDataPtr(new int(2)));
-    EXPECT_EQ(DomainTree<int>::PARTIALMATCH,
+    rbtnode->setData(new int(2));
+    EXPECT_EQ(TestDomainTree::PARTIALMATCH,
               root.find(Name("example.com"), &crbtnode));
     EXPECT_EQ(rbtnode, crbtnode);
 
     // Perform the same tests for the tree that allows matching against empty
     // nodes.
     TreeHolder tree_holder_emptyok(mem_sgmt_,
-                                   DomainTree<int>::create(mem_sgmt_, true));
-    DomainTree<int>& root_emptyok(*tree_holder_emptyok.get());
+                                   TestDomainTree::create(mem_sgmt_, true));
+    TestDomainTree& root_emptyok(*tree_holder_emptyok.get());
     root_emptyok.insert(mem_sgmt_, Name::ROOT_NAME(), &rbtnode);
-    EXPECT_EQ(DomainTree<int>::EXACTMATCH,
+    EXPECT_EQ(TestDomainTree::EXACTMATCH,
               root_emptyok.find(Name::ROOT_NAME(), &crbtnode));
     EXPECT_EQ(rbtnode, crbtnode);
-    EXPECT_EQ(DomainTree<int>::PARTIALMATCH,
+    EXPECT_EQ(TestDomainTree::PARTIALMATCH,
               root_emptyok.find(Name("example.com"), &crbtnode));
     EXPECT_EQ(rbtnode, crbtnode);
 
     root.insert(mem_sgmt_, Name("com"), &rbtnode);
-    EXPECT_EQ(DomainTree<int>::PARTIALMATCH,
+    EXPECT_EQ(TestDomainTree::PARTIALMATCH,
               root.find(Name("example.com"), &crbtnode));
     EXPECT_EQ(rbtnode, crbtnode);
 }