/// 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
/// 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
///
///
/// \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);
}
/// \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.
}
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.
/// \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
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.
/// (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
/// 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
/// 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
///
/// 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.
//@{
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.
///
/// 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());
}
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),
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)
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
// 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;
}
// 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;
}
}
-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()
/// 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.
///
{}
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:
/// this method returns \c NULL.
///
/// \exception None
- const DomainTreeNode<T>* getLastComparedNode() const {
+ const DomainTreeNode<T,DT>* getLastComparedNode() const {
return (last_compared_);
}
"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) {
/// root node of DomainTree
///
/// \exception None
- const DomainTreeNode<T>* top() const {
+ const DomainTreeNode<T,DT>* top() const {
assert(!isEmpty());
return (nodes_[node_count_ - 1]);
}
/// 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;
}
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_;
};
* \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 {
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
/// \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:
/// \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));
}
///
/// 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) {
/// \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));
///
/// 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) {
/// 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);
/// \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.
/// 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) {
///
/// \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().
///
/// \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
///
/// - 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.
///
///
/// 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_);
}
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
/// 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);
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;
}
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();
}
// 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);
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
// 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;
}
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();
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;
}
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;
}
}
- 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) {
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;
}
// 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)
{
// 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_);
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);
}
-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()) {
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()) {
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()) {
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()) {
}
-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) {
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]";
}
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";
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";
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) {
}
os << "\"] [";
- if (node->getColor() == DomainTreeNode<T>::RED) {
+ if (node->getColor() == DomainTreeNode<T,DT>::RED) {
os << "color=red";
} else {
os << "color=black";
*/
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)
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));
}
}
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) {
}
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));
}
// 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),
}
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);
}
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());
*/
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());
}
TEST_F(DomainTreeTest, getAbsoluteNameError) {
// an empty chain isn't allowed.
- DomainTreeNodeChain<int> chain;
+ TestDomainTreeNodeChain chain;
EXPECT_THROW(chain.getAbsoluteName(), BadValue);
}
".", "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);
}
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);
// (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) {
//
// 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);
}
// 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;
{
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;
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);
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);
{
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;
// 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;
// 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;
// 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;
// '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"));
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;
{
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),
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)
{
}
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 ".")
// 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"
// 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
// 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
// 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"
// 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"
// 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
// 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
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);
// 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);
}