Commit 878a6a4b authored by hanfeng's avatar hanfeng
Browse files

change the policy class to bool variable

parent 006424d3
......@@ -54,7 +54,7 @@ operator-(const isc::dns::Name& super_name, const isc::dns::Name& sub_name) {
}
}
template <typename T, typename SearchPolicy>
template <typename T, bool returnEmptyNode>
class RBTree;
/// \brief \c RBNode is used by RBTree to store any data related to one domain
......@@ -82,7 +82,7 @@ class RBNode : public boost::noncopyable {
private:
/// The RBNode is meant for use from within RBTree, so it has access to
/// it.
template <typename U, typename SearchPolicy>
template <typename U, bool returnEmptyNode>
friend class RBTree;
/// \name Constructors
......@@ -239,24 +239,6 @@ template <typename T>
RBNode<T>::~RBNode() {
}
/// \brief search policy for rbtree which will affect the find function
/// behavior, depend on usage for rbtree, sometimes it needs return
/// empty node like using rbtree as zone data, the default search policy
/// for rbtree is ReturnNonEmptyNodePolicy.
/// \note to use policy class instead of just a bool variable to add to
/// the construction function of rbtree is considering the extendibility
/// also it is more clean use policy based programming which typically
/// use template class as the policy class
class ReturnEmptyNodePolicy {
public:
bool returnEmptyNode()const { return true; }
};
class ReturnNonEmptyNodePolicy {
public:
bool returnEmptyNode()const { return false; }
};
// note: the following class description is documented using multiline comments
// because the verbatim diagram contain a backslash, which could be interpreted
......@@ -276,10 +258,10 @@ class ReturnNonEmptyNodePolicy {
* - Decreases the memory footprint, as it doesn't store the suffix labels
* multiple times.
*
* Depending on different usage, rbtree will support different search policy.
* Whether return empty node to end user is one policy among them. Search
* policy is as the last template parameter, the default policy will NOT
* return empty node to end user, choose ReturnEmptyNodePolicy is empty node
* Depending on different usage, rbtree will support different search policy.
* Whether return empty node to end user is one policy among them. Search
* policy is as the last template parameter, the default policy will NOT
* return empty node to end user, pass ture will get empty node during find
* is needed
*
* \anchor diagram
......@@ -318,8 +300,8 @@ class ReturnNonEmptyNodePolicy {
* - since \c RBNode only has down pointer without up pointer, the node path
* during finding should be recorded for later use
*/
template <typename T, typename SearchPolicy = ReturnNonEmptyNodePolicy>
class RBTree : public boost::noncopyable, public SearchPolicy {
template <typename T, bool returnEmptyNode = false>
class RBTree : public boost::noncopyable {
friend class RBNode<T>;
public:
/// \brief The return value for the \c find() and insert() methods
......@@ -553,20 +535,20 @@ private:
unsigned int node_count_;
};
template <typename T, typename S>
template <typename T, bool S>
RBTree<T,S>::RBTree() {
NULLNODE = RBNode<T>::NULL_NODE();
root_ = NULLNODE;
node_count_ = 0;
}
template <typename T, typename S>
template <typename T, bool S>
RBTree<T,S>::~RBTree() {
deleteHelper(root_);
assert(node_count_ == 0);
}
template <typename T, typename S>
template <typename T, bool S>
void
RBTree<T,S>::deleteHelper(RBNode<T> *root) {
if (root == NULLNODE) {
......@@ -597,7 +579,7 @@ RBTree<T,S>::deleteHelper(RBNode<T> *root) {
--node_count_;
}
template <typename T, typename S>
template <typename T, bool S>
template <typename CBARG>
typename RBTree<T,S>::Result
RBTree<T,S>::find(const isc::dns::Name& name, RBNode<T>** node,
......@@ -608,7 +590,7 @@ RBTree<T,S>::find(const isc::dns::Name& name, RBNode<T>** node,
return (findHelper(name, &up_node, node, callback, callback_arg));
}
template <typename T, typename S>
template <typename T, bool S>
template <typename CBARG>
typename RBTree<T,S>::Result
RBTree<T,S>::find(const isc::dns::Name& name, const RBNode<T>** node,
......@@ -625,14 +607,14 @@ RBTree<T,S>::find(const isc::dns::Name& name, const RBNode<T>** node,
return (ret);
}
template <typename T, typename S>
template <typename T, bool returnEmptyNode>
template <typename CBARG>
typename RBTree<T,S>::Result
RBTree<T,S>::findHelper(const isc::dns::Name& target_name,
const RBNode<T>** up_node,
RBNode<T>** target,
bool (*callback)(const RBNode<T>&, CBARG),
CBARG callback_arg) const
typename RBTree<T,returnEmptyNode>::Result
RBTree<T,returnEmptyNode>::findHelper(const isc::dns::Name& target_name,
const RBNode<T>** up_node,
RBNode<T>** target,
bool (*callback)(const RBNode<T>&, CBARG),
CBARG callback_arg) const
{
using namespace helper;
......@@ -647,7 +629,7 @@ RBTree<T,S>::findHelper(const isc::dns::Name& target_name,
const isc::dns::NameComparisonResult::NameRelation relation =
compare_result.getRelation();
if (relation == isc::dns::NameComparisonResult::EQUAL) {
if (S::returnEmptyNode() || !node->isEmpty()) {
if (returnEmptyNode || !node->isEmpty()) {
*target = node;
ret = EXACTMATCH;
}
......@@ -660,7 +642,7 @@ RBTree<T,S>::findHelper(const isc::dns::Name& target_name,
node = (compare_result.getOrder() < 0) ?
node->left_ : node->right_;
} else if (relation == isc::dns::NameComparisonResult::SUBDOMAIN) {
if (S::returnEmptyNode() || !node->isEmpty()) {
if (returnEmptyNode || !node->isEmpty()) {
ret = RBTree<T>::PARTIALMATCH;
*target = node;
if (callback != NULL && node->callback_required_) {
......@@ -682,9 +664,10 @@ RBTree<T,S>::findHelper(const isc::dns::Name& target_name,
}
template <typename T, typename S>
typename RBTree<T,S>::Result
RBTree<T,S>::insert(const isc::dns::Name& target_name, RBNode<T>** new_node) {
template <typename T, bool returnEmptyNode>
typename RBTree<T,returnEmptyNode>::Result
RBTree<T,returnEmptyNode>::insert(const isc::dns::Name& target_name,
RBNode<T>** new_node) {
using namespace helper;
RBNode<T>* parent = NULLNODE;
RBNode<T>* current = root_;
......@@ -702,7 +685,7 @@ RBTree<T,S>::insert(const isc::dns::Name& target_name, RBNode<T>** new_node) {
*new_node = current;
}
if (current->isEmpty() && !S::returnEmptyNode()) {
if (current->isEmpty() && !returnEmptyNode) {
return (SUCCESS);
} else {
return (ALREADYEXISTS);
......@@ -763,7 +746,7 @@ RBTree<T,S>::insert(const isc::dns::Name& target_name, RBNode<T>** new_node) {
}
template <typename T, typename S>
template <typename T, bool S>
void
RBTree<T,S>::nodeFission(RBNode<T>& node, const isc::dns::Name& base_name) {
using namespace helper;
......@@ -786,7 +769,7 @@ RBTree<T,S>::nodeFission(RBNode<T>& node, const isc::dns::Name& base_name) {
}
template <typename T, typename S>
template <typename T, bool S>
void
RBTree<T,S>::insertRebalance(RBNode<T>** root, RBNode<T>* node) {
......@@ -832,7 +815,7 @@ RBTree<T,S>::insertRebalance(RBNode<T>** root, RBNode<T>* node) {
}
template <typename T, typename S>
template <typename T, bool S>
RBNode<T>*
RBTree<T,S>::leftRotate(RBNode<T>** root, RBNode<T>* node) {
RBNode<T>* right = node->right_;
......@@ -857,7 +840,7 @@ RBTree<T,S>::leftRotate(RBNode<T>** root, RBNode<T>* node) {
return (node);
}
template <typename T, typename S>
template <typename T, bool S>
RBNode<T>*
RBTree<T,S>::rightRotate(RBNode<T>** root, RBNode<T>* node) {
RBNode<T>* left = node->left_;
......@@ -882,7 +865,7 @@ RBTree<T,S>::rightRotate(RBNode<T>** root, RBNode<T>* node) {
}
template <typename T, typename S>
template <typename T, bool S>
void
RBTree<T,S>::dumpTree(std::ostream& os, unsigned int depth) const {
indent(os, depth);
......@@ -890,7 +873,7 @@ RBTree<T,S>::dumpTree(std::ostream& os, unsigned int depth) const {
dumpTreeHelper(os, root_, depth);
}
template <typename T, typename S>
template <typename T, bool S>
void
RBTree<T,S>::dumpTreeHelper(std::ostream& os, const RBNode<T>* node,
unsigned int depth) const
......@@ -917,7 +900,7 @@ RBTree<T,S>::dumpTreeHelper(std::ostream& os, const RBNode<T>* node,
dumpTreeHelper(os, node->right_, depth + 1);
}
template <typename T, typename S>
template <typename T, bool S>
void
RBTree<T,S>::indent(std::ostream& os, unsigned int depth) {
static const unsigned int INDENT_FOR_EACH_DEPTH = 5;
......
......@@ -65,7 +65,7 @@ protected:
}
RBTree<int> rbtree;
RBTree<int, ReturnEmptyNodePolicy> rbtree_expose_empty_node;
RBTree<int, true> rbtree_expose_empty_node;
RBNode<int>* rbtnode;
const RBNode<int>* crbtnode;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment