From: Sage Weil Date: Wed, 8 Feb 2012 06:07:46 +0000 (-0800) Subject: mds: remove IntervalTree code X-Git-Tag: v0.44~58 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1a028e5c9eb1c34ba6fce6691b7ab6a8e2d5b8c6;p=ceph.git mds: remove IntervalTree code Not used, not tested. Signed-off-by: Sage Weil --- diff --git a/src/Makefile.am b/src/Makefile.am index 7e6c2efa749b..b6ec3a54c654 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -622,11 +622,6 @@ unittest_librgw_CXXFLAGS = ${CRYPTO_CFLAGS} ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} check_PROGRAMS += unittest_librgw endif -#unittest_interval_tree_SOURCES = test/TestIntervalTree.cc -#unittest_interval_tree_LDADD = ${UNITTEST_LDADD} $(LIBGLOBAL_LDA) -#unittest_interval_tree_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} -#check_PROGRAMS += unittest_interval_tree - unittest_ipaddr_SOURCES = test/test_ipaddr.cc unittest_ipaddr_LDADD = ${UNITTEST_LDADD} $(LIBGLOBAL_LDA) unittest_ipaddr_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} diff --git a/src/mds/IntervalTree.h b/src/mds/IntervalTree.h deleted file mode 100644 index 23016def084d..000000000000 --- a/src/mds/IntervalTree.h +++ /dev/null @@ -1,1466 +0,0 @@ -// -*-#define dbg(lvl)\ mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - * author: Jojy George Varghese - */ - -#ifndef CEPH_INTERVALTREE_H -#define CEPH_INTERVALTREE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_LVL 1 - -#define dbg(lvl)\ - if(lvl <= DEBUG_LVL)\ - std::cout <<"[DEBUG][" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] :: " ;\ - if(lvl <= DEBUG_LVL)\ - std::cout - -#define derr\ - std::cout <<"[ERROR][" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] :: " ;std::cout - -#define dendl\ - std::endl - -class IntervalTreeException:public std::exception { -public: - IntervalTreeException(const std::string& msg):message(msg) - {} - - ~IntervalTreeException() throw() - {} - - const char * what() const throw() - { - return message.c_str(); - } - -protected: - std::string message; -}; - -class BadParameterException: public IntervalTreeException { -public: - BadParameterException(const std::string& msg):IntervalTreeException(msg) - {} -}; - -template -class IntervalTree { -public: - - typedef std::list NodeList; - typedef U value_type; - - IntervalTree(): - root(NULL) - { - } - - ~IntervalTree() - { - destroy(); - } - -private: - IntervalTree(const IntervalTree&); - IntervalTree& operator=(const IntervalTree&); - - struct IntervalNode { - explicit IntervalNode(const T& in): node(in) - { - } - - T node; - value_type start; - value_type end; - - bool operator<(const IntervalNode& rhs) const - { - return start < rhs.start; - } - - bool operator==(const IntervalNode& rhs) const - { - return(start == rhs.start && end == rhs.end && node == rhs.node); - } - }; - - struct IntervalNodeDataPred { - explicit IntervalNodeDataPred(const T& t):data(t) - { - } - const T& data; - bool operator()(const IntervalNode& rhs) - { - return rhs.node == data; - } - }; - - struct IntervalRange { - value_type start; - value_type end; - std::list intervalNodeSet; - - bool operator<(const IntervalRange& rhs) const - { - return start < rhs.start; - } - - bool operator==(const IntervalRange& rhs) const - { - return(start == rhs.start && end == rhs.end); - } - - void printRange(std::ostream&) const; - }; - - struct IntervalRangePredicate { - value_type start; - value_type end; - - bool operator() (const IntervalRange& rhs) - { - return((start != rhs.start) || (end != rhs.end)); - } - }; - - struct RemoveIntervalRangePredicate { - bool operator() (const IntervalRange& rhs) - { - return(rhs.intervalNodeSet.size() == 0); - } - }; - - struct RemoveNodePredicate { - explicit RemoveNodePredicate(const T& t): data(t) - { - } - - const T& data; - bool operator() (const IntervalNode& rhs) const - { - return( data == rhs.node); - } - }; - - struct TreeNode { - typedef enum { - LEFT, - RIGHT - }Child; - -#ifdef DEBUG - ~TreeNode() - { - } -#endif - - TreeNode* left; - TreeNode* right; - TreeNode* parent; - unsigned short height; - value_type value; - unsigned int refCount; - bool visited; - - std::list rangeList; - std::pair spanNodes; - - // operations - int getBalance() const; - void addNode(TreeNode* node, Child); - void adjustHeight(); - void printNodes(std::ostream&) const; - - }; - - TreeNode* root; - typedef void (IntervalTree::*NodeOperation)(TreeNode*, void*); - - /////// - // Methods - ////// - -public: - - void addInterval(const value_type& start, const value_type& end, const T& in) - { - dbg(20) << "=========== adding new interval :{%s}===========" << in << dendl; - - if(start > end) { - throw BadParameterException("invalid range - left value is greater than right value"); - } - - insert(start); - insert(end); - - IntervalNode inode(in); - inode.start = start; - inode.end = end; - - insertNode(inode, start); - insertNode(inode, end); - -#ifdef DEBUG - dbg(20) << "tree after insert node: " << dendl; - printTree(std::cout); -#endif - } - - typename IntervalTree::NodeList getIntervalSet(const value_type& left, const value_type& right) const - { - dbg(20) << "searching for interval {" << left << "-" << right <<"}" < right) { - throw BadParameterException("invalid range - left value is greater than right value"); - } - - IntervalRange range; - range.start = left; - range.end = right; - std::list nodeSet; - search(left, range, nodeSet); - search(right, range, nodeSet); - - nodeSet.sort(); - nodeSet.unique(); - return nodeSet; - } - - void removeInterval(const value_type& start, const value_type& end, const T& in) - { - if(root == NULL) { - derr << "tree not initialized" << dendl; - return; - } - - if(start > end) { - throw BadParameterException("invalid range - left value is greater than right value"); - } - - std::list dispList, splitNodes; - IntervalRange range; - range.start = start; - range.end = end; - searchAndRemove(start, range, in, dispList); - searchAndRemove(end,range, in, dispList); - - typename std::list::iterator i,j, jEnd, iEnd = dispList.end(); - for(i = dispList.begin(); i != iEnd; ++i) { - dbg(20) << "relocating node " << (*i).node << dendl; - splitIntervalNode((*i), range, splitNodes); - jEnd = splitNodes.end(); - for(j = splitNodes.begin(); j != jEnd; ++j) { - dbg(20) << "split node " << (*j).node << "{ " << (*j).start << "-" << (*j).end <<"}" << dendl; - insert((*j).start); - insert((*j).end); - insertNodeList(splitNodes); - } - } - } - - void removeInterval(const value_type& left , const value_type& right) - { - if(root == NULL) { - derr << "tree not initialized" < right) { - throw BadParameterException("Invalid range -left value is greater than right value\n"); - } - - std::list dispNodes, splitNodes; - IntervalRange range; - range.start = left; - range.end = right; - remove(left, range, dispNodes); - remove(right, range, dispNodes); - - typename std::list::iterator i,j, jEnd, iEnd = dispNodes.end(); - for(i = dispNodes.begin(); i != iEnd; ++i) { - dbg(20) << "relocating node " << (*i).node << dendl; - splitIntervalNode((*i), range, splitNodes); - jEnd = splitNodes.end(); - for(j = splitNodes.begin(); j != jEnd; ++j) { - dbg(20) << "split node " << (*j).node << "{ " << (*j).start << "-" << (*j).end <<"}" << dendl; - insert((*j).start); - insert((*j).end); - insertNodeList(splitNodes); - } - } - } - - void removeAll(const T& in) - { - if(root == NULL) { - derr << "tree not initialized" <& list ):node(n), dList(list) - { - } - const T& node; - std::list& dList; - }; - - std::list intNodeList; - std::list delList; - struct DeleteNodeArg arg(in, delList); - - if(!delList.size()) { - dbg(20) << "no nodes gets deleted" << dendl; - } - - doTreeWalkOperation(&IntervalTree::deleteIntervalNode, (void*)&arg, false); - } - - void printTree(std::ostream& out) - { - dbg(1) << "---------------- tree ------------- :::" < dispList; - - while(node) { - node->adjustHeight(); - dbg(20) << "rebalancing" << toString(node) << dendl ; - node = rebalanceTree(node, dispList); - dbg(20) << "after rotation.... current root :" << toString(node) << dendl; - last = node; - node = node->parent; - } - root = last; - - insertNodeList(dispList); - } - - void insertNodeList(std::list& nodeList) - { - typename std::list::iterator i = nodeList.begin(); - - while(i != nodeList.end()) { - dbg(20) << "inserting displaced node" << (*i).node << dendl; - insertNode(*i, (*i).start); - insertNode(*i, (*i).end); - ++i; - } - } - - void remove(const value_type& value , const IntervalRange& range, std::list& dispList) - { - assert(root != NULL); - dbg(20) << "removing ' " << value << " ' range :{" << range.start << "-" << range.end << "}" << dendl; - - TreeNode* current = root; - std::pair spanNodes; - std::vector remTreeNodes; - - while(current) { - dbg(20) << "current :"<< toString(current) << dendl; - spanNodes = current->spanNodes; - - typename std::list::iterator i, iEnd = current->rangeList.end(); - for(i = current->rangeList.begin(); i != iEnd; ++i) { - IntervalRange& currRange = *i; - if(isInterSect(range.start, range.end, currRange.start, currRange.end)) { - dispList.splice(dispList.end(), (*i).intervalNodeSet); - currRange.intervalNodeSet.clear(); - } - } - - RemoveIntervalRangePredicate pred; - dbg(20) << "removing displaced lists. current list size :" << current->rangeList.size() << dendl; - current->rangeList.remove_if(pred); - dbg(20) << "after removal... list size :" << current->rangeList.size() << dendl; - - if(value < current->value) { - current = current->left; - } - else { - current = current->right; - } - } - } - - bool isRangeEdge(TreeNode* node, const value_type& value) - { -#ifdef DEBUG - dbg(20) << "checking range of " << toString(node) << dendl; - node->printNodes(std::cout); -#endif - std::list& intRange = node->rangeList; - if(intRange.size() == 0) { - return false; - } - - typename std::list::iterator i, iEnd = intRange.end(); - for(i = intRange.begin(); i != iEnd; ++i) { - if(((*i).start == value)|| ((*i).end == value)) { - return true; - } - } - - return false; - } - - void doTreeWalkOperation(NodeOperation op, void* data, bool isInOrder) - { - assert(root != NULL); - - TreeNode* current = root; - std::stack nodeStack; - - while(true) { - if(current != NULL) { - if(isInOrder) { - (this->*op)(current, data); - } - nodeStack.push(current); - current = current->left; - } - else { - if(nodeStack.empty()) { - break; - } - else { - current = nodeStack.top(); - nodeStack.pop(); - if(!isInOrder) { - (this->*op)(current, data); - } - current = current->right; - } - } - } - } - - bool isEligibleForCleanup(TreeNode* node) - { - dbg(20) << "checking eligiblity of node : " << toString(node) << "for cleanup" << dendl; - if(node == NULL) { - return false; - } - - std::pair span = node->spanNodes; - - if((isRangeEdge (node, node->value)) - ||(isRangeEdge(span.first, node->value)) - ||(isRangeEdge(span.second, node->value))) { - return false; - } - - return true; - } - - bool searchAndRemove(const value_type& searchVal, const IntervalRange& range, const T& in, std::list& displaceNodes) - { - dbg(20) << "search val : " << searchVal << ", interval :{" << range.start << "-" << range.end << "}," << "removing :" << in << dendl; - - TreeNode* current = root; - std::pair spanNodes; - while(current) { - dbg(20) << "current :"<< toString(current) << dendl; - spanNodes = current->spanNodes; - - typename std::list::iterator i, iEnd = current->rangeList.end(); - for(i = current->rangeList.begin(); i != iEnd; ++i) { - IntervalRange& currRange = *i; - if(isInterSect(currRange.start, currRange.end, range.start, range.end)) { - std::list& nodeList = (*i).intervalNodeSet; - IntervalNodeDataPred pred(in); - typename std::list::iterator j = std::find_if(nodeList.begin(), nodeList.end(), pred); - - if(j != nodeList.end()) { - dbg(20) << "found data node" << dendl; - displaceNodes.push_back(*j); - nodeList.remove(*j); - } - } - } - - if(searchVal >= current->value) { - current = current->right; - } - else { - current = current->left; - } - } - - return false; - } - - void deleteIntervalNode(TreeNode* node, void* data) - { - struct DeleteNodeArg { - const T& node; - std::list& dList; - }; - - DeleteNodeArg* arg = static_cast(data); - dbg(20) << "deleting data node :" << arg->node << "in current " << toString(node) <& intRange = node->rangeList; - typename std::list::iterator i, iEnd = intRange.end(); - - for(i = intRange.begin(); i != iEnd; ++i) { - std::list& nodeList = (*i).intervalNodeSet; - - RemoveNodePredicate remNodePred(arg->node); - nodeList.remove_if(remNodePred); - } - - RemoveIntervalRangePredicate remRangePred; - intRange.remove_if(remRangePred); - - /* - if(isEligibleForCleanup(node)) { - dbg(20) << "node eligible for cleanup" <dList.push_back(node->value); - } - */ - } - - void splitIntervalNode(const IntervalNode& inode, const IntervalRange& range, std::list& nodeList) - { - nodeList.clear(); - - if((inode.start < range.start) || (inode.end > range.end)) { - dbg(20) << "splitting node " << inode.node << dendl; - IntervalNode newNode(inode.node); - - if(inode.start < range.start) { - newNode.start = inode.start; - - if(inode.end > range.end) { - // case 1: original node extends range boundary at both ends - dbg(20) << "case 1 for node :" << inode.node << " interval node :{" << inode.start << " - " < range.end) { - // case 3: original node extends its right boundary to the right of - // range - dbg(20) << "case 3 for node :" << inode.node << " interval node :{" << inode.start << " - " <parent) { - if(node->parent->left == node) { - dbg(20) << "linking to parent " << toString(node->parent) << " 's left" <parent->left = child; - } - else if(node->parent->right == node) { - dbg(20) << "linking to parent " << toString(node->parent) << " 's right" <parent->right = child; - } - } - } - - void adjustSpan(TreeNode* node) - { - assert(node); - node->spanNodes = getSpan(node); - } - - void freeNode(TreeNode* node, void* data) - { - assert(node); - - if(node->parent != NULL) { - if(node->parent->left == node) { - node->parent->left = NULL; - } - if(node->parent->right == node) { - node->parent->right = NULL; - } - } - - delete node; - } - - - TreeNode* deleteNode(TreeNode* node, std::list& dispList) - { - assert(node); - - dbg(20) << "deleting node " << toString(node) <::iterator j; - for(j = dispList.begin() ; j != dispList.end(); ++j) { - dbg(20) << "node :" << (*j).node << dendl; - } -#endif - TreeNode* parent; - if(node->rangeList.size()) { - typename std::list::iterator i ,iEnd = node->rangeList.end(); - for(i = node->rangeList.begin(); i != iEnd; ++i) { - dispList.splice(dispList.end(), (*i).intervalNodeSet); - } - node->rangeList.clear(); - } - - // - // case 1. if no left and right child for the node getting deleted, - // - if((node->left == NULL) && (node->right == NULL)) { - dbg(20) <<"left and right child are absent" << dendl; - parent = node->parent; - linkParent(node, NULL); - TreeNode* prevNode = node->spanNodes.first; - TreeNode* nextNode = node->spanNodes.second; - adjustSpan(prevNode); - adjustSpan(nextNode); - freeNode(node); - } - - // - // case 2. if has left/right child only - // - else if((node->left == NULL) || (node->right == NULL)) { - dbg(20) << "left or right child is absent" << dendl; - parent = node->parent; - if(node->left != NULL) { - dbg(20) << "left child present" << dendl; - TreeNode* prevNode = node->spanNodes.first; - if(prevNode->rangeList.size()) { - typename std::list::iterator i ,iEnd = prevNode->rangeList.end(); - for(i = prevNode->rangeList.begin(); i != iEnd; ++i) { - dispList.splice(dispList.end(), (*i).intervalNodeSet); - } - prevNode->rangeList.clear(); - } - linkParent(node, node->left); - node->left->parent = node->parent; - adjustSpan(prevNode); - } - if(node->right != NULL) { - dbg(20) << "right child present" << dendl; - TreeNode* nextNode = node->spanNodes.second; - if(nextNode->rangeList.size()) { - typename std::list::iterator i ,iEnd = nextNode->rangeList.end(); - for(i = nextNode->rangeList.begin(); i != iEnd; ++i) { - dispList.splice(dispList.end(), (*i).intervalNodeSet); - } - nextNode->rangeList.clear(); - } - linkParent(node, node->right); - node->right->parent = node->parent; - adjustSpan(nextNode); - } - - delete node; - node = NULL; - } - - // - // case 3. if d has left AND right nodes - // - else { - dbg(20) << "both left and right child present" << dendl; - TreeNode* nextNode = node->spanNodes.second, *prevNode = node->spanNodes.first; - parent = nextNode->parent; - - if(prevNode->rangeList.size()) { - typename std::list::iterator i ,iEnd = prevNode->rangeList.end(); - for(i = prevNode->rangeList.begin(); i != iEnd; ++i) { - dispList.splice(dispList.end(), (*i).intervalNodeSet); - } - prevNode->rangeList.clear(); - } - - if(nextNode->rangeList.size()) { - typename std::list::iterator i ,iEnd = nextNode->rangeList.end(); - for(i = nextNode->rangeList.begin(); i != iEnd; ++i) { - dispList.splice(dispList.end(), (*i).intervalNodeSet); - } - nextNode->rangeList.clear(); - } - - dbg(20) << "next node :" << toString(nextNode) << dendl; - node->value = nextNode->value; - - linkParent(nextNode, nextNode->right); - adjustSpan(node); - adjustSpan(prevNode); - if(nextNode->spanNodes.second) { - adjustSpan(nextNode->spanNodes.second); - } - - delete nextNode; - nextNode = NULL; - } - - dispList.sort(); - dispList.unique(); - -#ifdef DEBUG - dbg(20) << "disp nodes after splice:" << dendl; - typename std::list::iterator i; - for(i = dispList.begin() ; i != dispList.end(); ++i) { - dbg(20) << "node :" << (*i).node << dendl; - } -#endif - return parent; - } - - - void search(const value_type& value, const IntervalTree::IntervalRange& searchRange, typename IntervalTree::NodeList& nodeSet) const - { - dbg(20) << "searching for value :" << value <rangeList.size()) { - typename std::list::iterator i ,iEnd = current->rangeList.end(); - for(i = current->rangeList.begin(); i != iEnd; ++i) { - IntervalRange& range = (*i); - dbg(20) << "current node : " <::iterator i; - for(i = nodeSet.begin() ; i != nodeSet.end(); ++i) { - dbg(20) << "node :" << (*i) <value == value && (current->right != NULL)) { - current = current->right; - } - else if((current->left != NULL) && (current->value >= value)) { - current = current->left; - } - else if((current->right != NULL) && (current->value <= value)) { - current = current->right; - } - else - break; - - } - } - - void insertNodeInRange(TreeNode* current, const IntervalNode& in, IntervalRange& spanRange) - { - typename std::list::iterator i; - typename std::list::iterator iEnd; - dbg(20) << "spanRange :{" << spanRange.start << "-" << spanRange.end <<"}" << dendl; - i = std::find(current->rangeList.begin(), current->rangeList.end(), spanRange); -#ifdef DEBUG - dbg(20) << "current nodes :" <printNodes(std::cout); -#endif - if(i == current->rangeList.end()) { - dbg(20) << " could not find the range .. will be adding now" << dendl; - spanRange.intervalNodeSet.push_back(in); - current->rangeList.push_back(spanRange); - } - else { - dbg(20) << " range already in the list" << dendl; - - dbg(20) << "adding node " << in.node << "to the range list" << dendl; - (*i).intervalNodeSet.push_back(in); - (*i).intervalNodeSet.sort(); - (*i).intervalNodeSet.unique(); - - } - - current->rangeList.sort(); - current->rangeList.unique(); - -#ifdef DEBUG - dbg(20) << "nodes after :" <printNodes(std::cout); -#endif - } - - - void insertNode(const IntervalNode& in, const value_type& value) - { - assert(root); - - TreeNode* current = root, *prevNode, *nextNode, *spanPrev, *spanNext; - while(current) { - dbg(20) << "inserting node :" << in.node << " , value : " < span = getSpan(current); - prevNode = prev(current); - prevNode = prevNode == NULL ? current : prevNode; - dbg(25) << "prev node :" << toString(prevNode) << dendl; - - nextNode = next(current); - nextNode = nextNode == NULL ? current : nextNode; - dbg(25) << "next node :" << toString(nextNode) << dendl; - - dbg(25) << "span for node " << toString(current) <<" : {" << toString(span.first) << " - " << toString(span.second) << "}" << - "prev node :" << toString(prevNode) << " , next node :" << toString(nextNode) << dendl; - - current->spanNodes = span; - IntervalRange spanRange; - - if(span.first != NULL && span.second != NULL) { - spanPrev = prev(span.first); - spanNext = next(span.second); - dbg(25) << "span : {" << spanPrev->value << " - " << spanNext->value << "}" << dendl; - if(spanPrev->value >= in.start && spanNext->value <= in.end) { - dbg(25) << "inserting over the full span " << dendl; - - spanRange.start = spanPrev->value; - spanRange.end = spanNext->value; - insertNodeInRange(current, in, spanRange); - return; - } - - if(current->value <= in.start && nextNode->value >= in.end) { - spanRange.start = current->value; - spanRange.end = nextNode->value; - insertNodeInRange(current, in, spanRange); - //return; - } - } - else { - span.first = (span.first == NULL) ? prevNode : prev(span.first); - span.second = (span.second == NULL) ? nextNode : next(span.second); - dbg(20) << "span :{" << span.first->value << " - " << span.second->value << "}" << dendl; - if(span.first->value >= in.start && span.second->value <= in.end) { - spanRange.start = span.first->value; - spanRange.end = span.second->value; - insertNodeInRange(current, in, spanRange); - return; - } - if(span.first->value >= in.start && current->value <= in.end) { - spanRange.start = span.first->value; - spanRange.end = current->value; - insertNodeInRange(current, in, spanRange); - //return; - } - if(current->value >= in.start && span.second->value <= in.end) { - spanRange.start = current->value; - spanRange.end = span.second->value; - insertNodeInRange(current, in, spanRange); - //return; - } - } - - if((current->left != NULL) && ((current->value > value) || (span.first->value > in.start))) { - current = current->left; - } - else if((current->right != NULL) && ( (current->value < value) || (span.second->value < in.end))) { - current = current->right; - } - else - break; - } - } - - - void insert(const value_type& in) - { - TreeNode* newNode = createTreeNode(in); - dbg(20) << "adding new tree node :" << toString(newNode) <value == in) { - dbg(20) << "a node already exists with same value.. abandoning!!\n" <refCount++; - break; - } - //TODO: replace with comparator - if(in <= current->value) { - if(current->left == NULL) { - dbg(20) << "inserting new node " << toString(newNode) << " to LEFT" << dendl; - current->addNode(newNode, TreeNode::LEFT); - break; - } - current = current->left; - } - else { - if(NULL == current->right) { - dbg(20) << "inserting new node " << toString(newNode) << " to RIGHT" << dendl; - current->addNode(newNode, TreeNode::RIGHT); - break; - } - current = current->right; - } - } - - doIterativeRebalance(current); - -#ifdef DEBUG - dbg(20) << "@@ tree after insert " << dendl; - printTree(std::cout); -#endif - } - - - bool isInterSect(const value_type& ax1, const value_type& ax2, const value_type& bx1, const value_type& bx2) const - { - dbg(25) << "ax1 :" << ax1 << ", ax2:" << ax2 << ", bx1 :" << bx1 << ", bx2 :" << bx2 << dendl; - if( - (ax1 >= bx1 && ax1 < bx2) - || (ax2 > bx1 && ax2 <= bx2) - || (ax1 <= bx1 && ax2 > bx2) - ) { - dbg(25) << "intersects!! " << dendl; - return true; - } - - return false; - } - - - void copyItems(const IntervalRange& range, typename std::list& src, typename std::list& dest) const - { - typename std::list::iterator i ; - typename std::list::iterator iEnd= src.end(); - - for(i = src.begin(); i != iEnd; ++i) { - if(isInterSect(range.start, range.end, (*i).start, (*i).end)) { - dest.push_back((*i).node); - } - } - dest.sort(); - dest.unique(); - } - - - TreeNode* createTreeNode(value_type in) - { - TreeNode* node = new TreeNode(); - node->left = NULL; - node->right = NULL; - node->parent = NULL; - node->value = in; - node->height = 0; - node->refCount = 0; - node->visited = false; - - return node; - } - - - void printTreeNode(TreeNode* node, void* data) - { - if(node == NULL) { - return; - } - - std::ostream* out = static_cast(data); - *out << std::endl ; - *out << node << "--- {value :" << node->value << "} {height : " - << node->height << "} L : "<< (node->left? toString(node->left):"{NULL}") - << " R: " << (node->right? toString(node->right) : "{NULL}"); - - if(node->spanNodes.first && node->spanNodes.second) { - *out << std::endl << "span : {" << node->spanNodes.first->value << ", " << - node->spanNodes.second->value << "} " << std::endl; - } - *out << std::endl; - *out << "node lists :" << std::endl; - - typename std::list::iterator i; - typename std::list::iterator iEnd = node->rangeList.end(); - - for(i = node->rangeList.begin(); i != iEnd; ++i) { - (*i).printRange(*out); - } - } - - std::string toString(const TreeNode* nd) const - { - if(NULL == nd) { - return "{NULL}"; - } - - char buff[100]; - memset(buff, 0, 100); - snprintf(buff, 100, "{addr :%p, value :%d, height :%u, left :{%p:%d}, right:{%p:%d}}", - nd, nd->value, nd->height, nd->left? nd->left:0, nd->left? nd->left->value: -999, - nd->right? nd->right:0, nd->right? nd->right->value: -999 ); - - return buff; - } - - TreeNode* doLeftRotation(TreeNode* n) - { - if(n == NULL) { - derr << "cant left rotate a null node" << dendl; - return n; - } - - if(n->right == NULL) { - dbg(20) << "no right child. cant do left rotation" <right) << " on pivot " << toString(n) <right; - TreeNode* left = root->left; - TreeNode* save = n; - - root->left = save; - save->right = left; - if(left) { - left->parent = save; - } - root->parent = save->parent; - save->parent = root; - - save->adjustHeight(); - root->adjustHeight(); - - dbg(20) << "returning root :" << toString(root) <left == NULL) { - dbg(20) << "no left child. cant do right rotation" <left) << "on pivot :" << toString(n) << dendl; - - TreeNode* root = n->left; - TreeNode* right = root->right; - TreeNode* save = n; - - root->right = save; - save->left = right; - if(right) { - right->parent = save; - } - root->parent = save->parent; - save->parent = root; - - save->adjustHeight(); - root->adjustHeight(); - - dbg(20) << "after rotate root->right :" << toString(root->right) <& dispList) - { - TreeNode *prevNode, *nextNode, *spanPrev, *spanNext; - std::pair span = getSpan(current); - prevNode = prev(current); - prevNode = prevNode == NULL ? current : prevNode; - dbg(25) << "prev node :" << toString(prevNode) << dendl; - - nextNode = next(current); - nextNode = nextNode == NULL ? current : nextNode; - dbg(25) << "next node :" << toString(nextNode) << dendl; - - dbg(25) << "span for node " << toString(current) <<" : {" << toString(span.first) << " - " << toString(span.second) << "}" << - "prev node :" << toString(prevNode) << " , next node :" << toString(nextNode) << dendl; - - current->spanNodes = span; - - typename std::list::iterator i; - typename std::list::iterator iEnd; - if(current->rangeList.size()) { - iEnd = current->rangeList.end(); - for(i = current->rangeList.begin(); i != iEnd; ++i) { - IntervalRange& range = *i; - dbg(20) << "range :{" << range.start << "-" << range.end << "}" << dendl; - bool isSpliceRequired = false; - - if(span.first != NULL && span.second != NULL) { - spanPrev = prev(span.first); - spanNext = next(span.second); - if((range.start != spanPrev->value && range.start != current->value) || (range.end !=spanNext->value && range.end != nextNode->value)) { - dbg(20) << "spanPrev :' " << spanPrev->value << " ' , spanNext :' " << - spanNext->value << " ', nextNode :' " << nextNode->value << " ' " << dendl ; - isSpliceRequired = true; - } - } - else { - if(span.first != NULL && span.second == NULL) { - spanPrev = prev(span.first); - if(range.start != spanPrev->value && range.start != current->value) { - isSpliceRequired = true; - } - if(range.end != nextNode->value && range.end != current->value) { - isSpliceRequired = true; - } - } - else if(span.first == NULL && span.second != NULL) { - spanNext = next(span.second); - if(range.start != current->value && range.start != prevNode->value) { - isSpliceRequired = true; - } - if(range.end != current->value && range.end !=spanNext->value) { - isSpliceRequired = true; - } - } - else { - if(range.start != prevNode->value && range.start !=current->value) { - isSpliceRequired = true; - } - if(range.end != current->value && range.end != nextNode->value) { - isSpliceRequired = true; - } - } - } - if(isSpliceRequired) { - dbg(20) << "splicing range :{" << range.start << " - " << range.end <<"}" <rangeList.size() << dendl; - current->rangeList.remove_if(pred); - dbg(25) << "range list size after cleanup:" << current->rangeList.size() << dendl; - } - } - - - TreeNode* rebalanceTree(TreeNode* p, std::list& dispList) - { - assert(p != NULL); - - dbg(20) << "rebalancing :" << toString(p) <parent != NULL) { - isLeft = (root->parent->left == root); - } - - if(p->getBalance() <= -2) { - dbg(20) << "right side heavy" <right != NULL) && (p->right->getBalance() <= -1)) { - dbg(20) << "right child is right heavy" << dendl; - tmp = doLeftRotation(root->right); - p->right = tmp; - adjustSpanAndDisplace(root, dispList); - root = doLeftRotation(root); - - } - else if((p->right != NULL) && (p->right ->getBalance() >= 1)) { - dbg(20) << "right child is left heavy" <right); - p->right = tmp; - adjustSpanAndDisplace(root, dispList); - root = doLeftRotation(root); - } - - } - else if(p->getBalance() >= 2) { - dbg(20) << "left side heavy" << dendl; - if((p->left != NULL) && (p->left->getBalance() >= 1)) { - dbg(20) << "left child is left heavy" <left); - p->left = tmp; - adjustSpanAndDisplace(root, dispList); - root = doRightRotation(root); - } - else if((p->left != NULL) && (p->left ->getBalance() <= -1)) { - dbg(20) << "left child is right heavy" <left); - p->left = tmp; - adjustSpanAndDisplace(root, dispList); - root = doRightRotation(root); - } - } - - if(root->parent != NULL && isLeft) { - dbg(20) << "root : " << toString(root) << " parent : " << toString(root->parent) - << "..setting left child of parent as :" << toString(root) << dendl; - root->parent->left = root; - } - else if(root->parent != NULL && (!isLeft)) { - dbg(20) << "root : " << toString(root) << " parent : " << toString(root->parent) << - "..setting right child of parent as :" << toString(root) << dendl; - root->parent->right = root; - } - - adjustSpanAndDisplace(tmp, dispList); - adjustSpanAndDisplace(p, dispList); - adjustSpanAndDisplace(root, dispList); - return root; - } - - TreeNode* next(TreeNode* node) - { - assert(node != NULL); - - TreeNode* rightTree = node->right, *next = NULL, *parent; - if(rightTree) { - next = rightTree->left; - parent = rightTree; - while(next) { - parent = next; - next = next->left; - } - - return parent; - } - - parent = node->parent; - if(parent == NULL) { - return node; - } - next = node; - - while(parent) { - if((parent->left != NULL) && (parent->left == next)) { - return parent; - } - next = parent; - parent = next->parent; - } - - if(parent == NULL) { - return node; - } - return parent; - } - - - TreeNode* prev(TreeNode* node) - { - assert(node != NULL); - - TreeNode* leftTree = node->left, *next = NULL, *parent; - if(leftTree) { - next = leftTree->right; - parent = leftTree; - while(next) { - parent = next; - next = next->right; - } - dbg(25) <<"returning prev :" << toString(parent) << dendl; - return parent; - } - - parent = node->parent; - if(parent == NULL) { - dbg(25) <<"returning prev :" << toString(node) << dendl; - return node; - } - next = node; - while(parent) { - if((parent->right != NULL) && parent->right == next) { - return parent; - } - next = parent; - parent = next->parent; - } - - if(parent == NULL) { - dbg(25) <<"returning prev :" << toString(node) << dendl; - return node; - } - - dbg(25) <<"returning prev :" << toString(parent) << dendl; - return parent; - } - - - std::pair getSpan(const TreeNode* node) const - { - assert(node != NULL); - - TreeNode* leftMostNode = node->left, *rightMostNode = node->right, *lastLeftNode = NULL, *lastRightNode = NULL; - while(leftMostNode) { - lastLeftNode = leftMostNode; - leftMostNode = leftMostNode->left; - } - - while(rightMostNode) { - lastRightNode = rightMostNode; - rightMostNode = rightMostNode->right; - } - - dbg(25) << "returning span :{" << toString(lastLeftNode) << " , " << toString(lastRightNode) << "}" << dendl; - return std::make_pair(lastLeftNode, lastRightNode); - } - - - bool isElementaryInterval(const value_type& value) const - { - TreeNode* current = root; - while(current) { - if(current->value == value) { - return true; - } - - if(value > current->value) { - current = current->right; - } - else { - current = current->left; - } - } - - return false; - } - -}; - - -template -void IntervalTree::TreeNode::adjustHeight() -{ - if(this->right == NULL && this->left == NULL) { - this->height =0; - return; - } - this->height = max (this->left? left->height: 0 , this->right? right->height:0) + 1 ; -} - - -template -void IntervalTree::TreeNode::addNode(TreeNode* node, Child which) -{ - assert(node); - - if(which == LEFT) { - this->left = node; - } - else { - this->right = node; - } - - node->parent = this; - this->adjustHeight(); -} - -template -void IntervalTree::IntervalRange::printRange(std::ostream& out) const -{ - out << "interval range {" << this->start << "," << this->end << "}:::" ; - typename std::list::const_iterator i; - typename std::list::const_iterator iEnd = this->intervalNodeSet.end(); - - for(i = this->intervalNodeSet.begin(); i != iEnd; ++i) { - out <<"{start :" <<(*i).start <<", end:" << (*i).end << "} {data: " << (*i).node << "}"; - } - out << std::endl; -} - - -template -int IntervalTree::TreeNode::getBalance() const -{ - int bal =0; - if(left != NULL) { - bal = left->height; - } - - if(right != NULL) { - bal -= right->height; - } - - return bal; -} - - -template -void IntervalTree::TreeNode::printNodes(std::ostream& out) const -{ - typename std::list::const_iterator i; - typename std::list::const_iterator iEnd = this->rangeList.end(); - - out << "node list :::" << std::endl; - for(i = this->rangeList.begin(); i != iEnd; ++i) { - (*i).printRange(out); - } - out << std::endl; -} - - -#endif diff --git a/src/test/TestIntervalTree.cc b/src/test/TestIntervalTree.cc deleted file mode 100644 index d6d113bfb47b..000000000000 --- a/src/test/TestIntervalTree.cc +++ /dev/null @@ -1,487 +0,0 @@ -// -*-#define dbg(lvl)\ mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab - -#include -#include - -#include "mds/IntervalTree.h" - - -#define ARRAY_SIZE(a)\ - sizeof(a)/sizeof(a[0]) - -using namespace std; - -struct String { - String(const string& s):str(s) - { - } - - bool operator <(const String& rhs) const - { - return str < rhs.str; - } - - bool operator ==(const String& rhs) const - { - return str == rhs.str; - } - - friend ostream& operator<<(ostream& out, const String& ); - - string toString() const - { - return str; - } - - string str; -}; - - -struct LockHolder { - LockHolder(char nm): - name(nm) - { - } - char name; - - bool operator <(const LockHolder& rhs) const - { - return name < rhs.name; - } - bool operator ==(const LockHolder& rhs) const - { - return(name == rhs.name); - } - string toString() const - { - return std::string(&name, 1); - } - - friend ostream& operator<<(ostream& out, const LockHolder& ); - -}; - -struct Node { - typedef int value_type; - - - Node(value_type s, value_type e): left(s), right(e) - { - } - - - std::string toString() const - { - char buff[50]; - memset(buff, 0, 50); - snprintf(buff, 50, "left:%d, right:%d", left, right); - - return buff; - } - - - bool operator== (const Node& rhs) const - { - return((this->left == rhs.left) && (this->right == rhs.right)); - } - - bool operator< (const Node& rhs) const - { - return left -bool popNode(std::list& result, const T& n) -{ - if(result.front() == n) { - result.pop_front(); - return true; - } - return false; -} - -template -bool hasNode(std::list& result, const T& n) -{ - typename std::list::iterator itr = find(result.begin(), result.end(), n); - return (itr != result.end()); -} - -template -void printResultSet(std::list& result) -{ -#ifdef DEBUG - typename std::list::iterator i, iEnd = result.end(); - for(i = result.begin(); i != iEnd; ++i){ - std::cout << "result ::{" << (*i)<< "} " << std::endl; - } -#endif -} - -template -void printTree(IntervalTree &tree) -{ -#ifdef DEBUG - std::cout << "============= tree ============" << std::endl; - tree.printTree(std::cout); - std::cout << "============= ============" << std::endl; -#endif -} - -void testLocks() -{ - // 1. Create new lock and acquire lock from 1-10 - IntervalTree tree; - LockHolder lockA('A'); - tree.addInterval(1, 10, lockA); - - printTree(tree); - std::list result; - - { - result = tree.getIntervalSet(1,10); - assert(result.size() == 1); - - printResultSet(result); - } - - // Create new lock and acquire from 3-15 - LockHolder lockB('B'); - tree.addInterval(3, 15, lockB); - - { - result = tree.getIntervalSet(1,15); - assert(result.size() == 2); - } - - // Release all locks from 3-10 - tree.removeInterval(3,10); - - // Query the whole range - result = tree.getIntervalSet(1,15); - - assert(result.size() == 2 && (result.front() == 'A') ); - result.pop_front(); - assert(result.front() == 'B'); - - - // Query the range held by only A - result = tree.getIntervalSet(1,5); - assert(result.front().name == 'A'); - - // Query the range held by none - result = tree.getIntervalSet(4,9); - printResultSet(result); - assert(!result.size()); - - // Again acquire lock B from 3-15 - tree.addInterval(3, 15, lockB); - result = tree.getIntervalSet(1,15); - assert(result.size() ==2); - - - // Query the range held by only B - result = tree.getIntervalSet(4,10); - assert((result.size() ==1) && (result.front().name == 'B')); - - - // Again acquire lock A from 3-10 - tree.addInterval(3, 10, lockA); - result = tree.getIntervalSet(3,10); - assert(result.size() ==2); - - // Release only locks held by B from 3-10 - tree.removeInterval(3,10, lockB); - - - // Query interval just released by B - result = tree.getIntervalSet(3,9); - assert((result.size() ==1) && (result.front().name == 'A')); - - - // Query interval now partially owned by B - result = tree.getIntervalSet(3,12); - assert(result.size() ==2); - - - // Add one more lock between 4-8 - LockHolder lockC('C'); - tree.addInterval(4, 8, lockC); - - printTree(tree); - - // Query the interval shared by A,B,C - result = tree.getIntervalSet(3,12); - assert(result.size() ==3); - - - // Query the intervals shared by A, C - result = tree.getIntervalSet(3, 6); - assert(result.size() == 2 && (result.front() == 'A') ); - result.pop_front(); - assert(result.front() == 'C'); - - // Add one more lock between 2-4 - LockHolder lockD('D'); - tree.addInterval(2, 4, lockD); - - // Query the intervals owned by A.B,C,D - result = tree.getIntervalSet(2, 11); - assert(result.size () == 4); - assert(popNode(result, lockA) && popNode(result, lockB) && popNode(result, lockC) && popNode(result, lockD)); - -} - - -void testBoundaries() -{ - // 1. Create new lock and acquire lock from 1-10 - IntervalTree tree; - LockHolder lockA('A'); - tree.addInterval(1, 10, lockA); - - // 2. Create lock B on the edge - LockHolder lockB('B'); - tree.addInterval(10, 15, lockB); - - //3. Query the edge - std::list result = tree.getIntervalSet(10, 10); - printResultSet(result); - assert((result.size() == 1) && (result.front() == 'B')); -} - -void testRemoveFromMiddle() -{ - // 1. Create new lock and acquire lock from 1-10 - IntervalTree tree; - LockHolder lockA('A'); - tree.addInterval(1, 10, lockA); - - // 2. Create lock B on the edge - LockHolder lockB('B'); - tree.addInterval(10, 15, lockB); - - // 3. Remove all locks from 6-12 - tree.removeInterval(6, 12); - - //4. Query the removed interval - std::list result = tree.getIntervalSet(6, 11); - assert(result.size() == 0); - - //5. Query the interval locked by A - result = tree.getIntervalSet(2, 5); - assert((result.size() == 1) && (result.front() == 'A')); -} - - -void testIntervalQuery() -{ - int arr[][2] ={ - - {1888,1971}, - {1874,1951}, - {1843,1907}, - {1779,1828}, - {1756,1791}, - {1585, 1672} - - }; - - Node a(1888, 1971); - Node b(1874, 1951); - Node c(1843, 1907); - Node d(1779, 1828); - Node e(1756, 1791); - Node f(1585, 1672); - - IntervalTree tree; - for(size_t i=0; i < ARRAY_SIZE(arr); i++) { - Node nd (arr[i][0], arr[i][1]); - tree.addInterval( arr[i][0], arr[i][1], nd); - } - - - std::list result = tree.getIntervalSet(1843, 1874); - assert(result.size() == 1 && (result.front() == c)); - - result = tree.getIntervalSet(1873, 1974); - assert(result.size() == 3); - assert(popNode(result, c) && popNode(result,b) && popNode(result,a)); - - - result = tree.getIntervalSet(1910, 1910); - assert(result.size() == 2); - assert(popNode(result, b) && popNode(result,a)); - - result = tree.getIntervalSet(1829, 1842); - assert(result.size() == 0); - - result = tree.getIntervalSet(1829, 1845); - assert(result.size() == 1); - assert(popNode(result, c)); -} - -void testRemoveInterval() -{ - int arr[][2] ={ - - {1888,1971}, - {1874,1951}, - {1843,1907}, - {1779,1828}, - {1756,1791}, - {1585, 1672} - - }; - - Node a(1888, 1971); - Node b(1874, 1951); - Node c(1843, 1907); - Node d(1779, 1828); - Node e(1756, 1791); - Node f(1585, 1672); - - IntervalTree tree; - for(size_t i=0; i < ARRAY_SIZE(arr); i++) { - Node nd (arr[i][0], arr[i][1]); - tree.addInterval( arr[i][0], arr[i][1], nd); - } - - printTree(tree); - std::list result; - - { - tree.removeInterval(1951, 1972, a); - result = tree.getIntervalSet(1960, 1970); - assert(result.size() == 0); - } - - { - result = tree.getIntervalSet(1890, 1900); - assert(result.size() == 3); - assert(popNode(result, c) && popNode(result, b) && popNode(result, a)); - } - - { - tree.removeInterval(1875, 1890, c); - result = tree.getIntervalSet(1877, 1889); - assert(!hasNode(result, c)); - } - - { - result = tree.getIntervalSet(1906, 1910); - assert(result.size() == 3); - assert(hasNode(result, a)); - assert(hasNode(result, b)); - assert(hasNode(result, c)); - } - -} - -void testStringIntervals() -{ - IntervalTree tree; - - tree.addInterval('a', 'c', string("ac")); - tree.addInterval('a', 'f', string("af")); - tree.addInterval('d', 'k', string("dk")); - tree.addInterval('d', 'l', string("dl")); - tree.addInterval('d', 'o', string("do")); - tree.addInterval('t', 'z', string("tz")); - - printTree(tree); - std::list result; - - { - result = tree.getIntervalSet('b', 'g'); - assert(result.size() == 5); - assert(!hasNode(result, String(string("tz")))); - } - - { - result = tree.getIntervalSet('k', 'z'); - assert(result.size() == 3); - assert(hasNode(result, String(string("dl")))); - assert(hasNode(result, String(string("do")))); - assert(hasNode(result, String(string("tz")))); - - printResultSet(result); - } - -} - -void testNames() -{ - IntervalTree tree; - - tree.addInterval('j', 'y', string("jojy")); - tree.addInterval('b', 'n', string("brian")); - tree.addInterval('e', 's', string("sage")); - tree.addInterval('f', 'g', string("gregsf")); - tree.addInterval('h', 'y', string("yehudah")); - - printTree(tree); - - std::list result; - { - result = tree.getIntervalSet('b', 'y'); - assert(result.size() == 5); - - printResultSet(result); - } - - { - result = tree.getIntervalSet('j', 'm'); - assert(!hasNode(result, string("gregsf"))); - - printResultSet(result); - } - - { - tree.removeAll("jojy"); - - result = tree.getIntervalSet('b', 'z'); - assert(!hasNode(result, string("jojy"))); - - printResultSet(result); - } -} - -int main() -{ - testIntervalQuery(); - testRemoveInterval(); - testLocks(); - testRemoveFromMiddle(); - testBoundaries(); - testStringIntervals(); - testNames(); -}