From 2caf1628ca902f9cd359c9097600e1488baf4fa9 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Fri, 11 Apr 1997 20:53:38 +0000 Subject: [PATCH] added b-tree templ --- src/cxxTemplates/test/Makefile.Host | 2 +- src/cxxTemplates/test/tsBTreeBench.cc | 83 ++++++ src/cxxTemplates/test/tsBTreeTest.cc | 80 ++++++ src/cxxTemplates/tsBTree.h | 253 +++++++++++++++++++ src/libCom/cxxTemplates/test/tsBTreeBench.cc | 83 ++++++ src/libCom/cxxTemplates/test/tsBTreeTest.cc | 80 ++++++ src/libCom/cxxTemplates/tsBTree.h | 253 +++++++++++++++++++ 7 files changed, 833 insertions(+), 1 deletion(-) create mode 100644 src/cxxTemplates/test/tsBTreeBench.cc create mode 100644 src/cxxTemplates/test/tsBTreeTest.cc create mode 100644 src/cxxTemplates/tsBTree.h create mode 100644 src/libCom/cxxTemplates/test/tsBTreeBench.cc create mode 100644 src/libCom/cxxTemplates/test/tsBTreeTest.cc create mode 100644 src/libCom/cxxTemplates/tsBTree.h diff --git a/src/cxxTemplates/test/Makefile.Host b/src/cxxTemplates/test/Makefile.Host index 9b4111099..9453b5774 100644 --- a/src/cxxTemplates/test/Makefile.Host +++ b/src/cxxTemplates/test/Makefile.Host @@ -5,7 +5,7 @@ include $(TOP)/config/CONFIG_BASE CXXCMPLR = STRICT TESTPROD := resourceLibTest tsDLListBench tsDLListTest tsDLListTest \ - tsSLListBench tsSLListTest minmaxTest + tsSLListBench tsSLListTest minmaxTest tsBTreeBench tsBTreeTest include $(TOP)/config/RULES.Host diff --git a/src/cxxTemplates/test/tsBTreeBench.cc b/src/cxxTemplates/test/tsBTreeBench.cc new file mode 100644 index 000000000..15a07301f --- /dev/null +++ b/src/cxxTemplates/test/tsBTreeBench.cc @@ -0,0 +1,83 @@ + +#include +#include +#include +#include + +#include "tsBTree.h" +#include "tsSLList.h" + +class A : public tsBTreeNode, public tsSLNode { +public: + A() + { + key = (unsigned) rand(); + } + + btCmp tsBTreeCompare(const A &item) const + { + if (this->key<=item.key) { + return btLessOrEqual; + } + else { + return btGreater; + } + } + + void show() + { + printf("A: %u\n", key); + } +private: + unsigned key; +}; + +#define LOOPCOUNT 10000u + +main () +{ + unsigned i; + tsBTree tree; + tsSLList list; + A *pA; + A a; + clock_t clk; + clock_t diff; + double delay; + + tree.insert(a); + list.add(a); + + for (i=0u; i +#include + +#include "tsBTree.h" + +class A : public tsBTreeNode { +public: + A(const char *pNameIn) : pName(pNameIn) {} + + btCmp tsBTreeCompare(const A &item) const + { + int cmp = strcmp(this->pName, item.pName); + if (cmp<=0) { + return btLessOrEqual; + } + else { + return btGreater; + } + } + + void show() + { + printf("A: %s\n", pName); + } +private: + const char *pName; +}; + +main () +{ + tsBTree tree; + A a0("fred"); + A a1("jane"); + A a2("jane0"); + A a3("bill"); + A a4("jane"); + A a5("dan"); + A a6("joe"); + + tree.insert(a0); + tree.insert(a1); + tree.insert(a2); + tree.insert(a3); + tree.insert(a4); + tree.insert(a5); + + tree.traverse(A::show); + + assert(!tree.remove(a6)); + tree.insert(a6); + assert(tree.remove(a6)); + assert(tree.remove(a5)); + assert(!tree.remove(a5)); + assert(!tree.verify(a5)); + assert(tree.verify(a4)); + assert(tree.remove(a0)); + assert(!tree.verify(a0)); + assert(!tree.remove(a0)); + tree.insert(a5); + assert(tree.verify(a5)); + assert(tree.verify(a2)); + assert(tree.remove(a2)); + assert(!tree.verify(a2)); + assert(!tree.remove(a2)); + assert(tree.verify(a5)); + assert(tree.remove(a5)); + assert(!tree.remove(a5)); + assert(!tree.remove(a0)); + assert(tree.remove(a4)); + assert(tree.remove(a3)); + assert(!tree.remove(a4)); + assert(tree.remove(a1)); + + tree.traverse(A::show); + + return 0; +} + + diff --git a/src/cxxTemplates/tsBTree.h b/src/cxxTemplates/tsBTree.h new file mode 100644 index 000000000..575028a89 --- /dev/null +++ b/src/cxxTemplates/tsBTree.h @@ -0,0 +1,253 @@ + +#include + +// +// tsBTreeRMRet +// +template +class tsBTreeRMRet { +public: + tsBTreeRMRet (unsigned foundItIn, T *pNewSegIn) : + foundIt(foundItIn), pNewSeg(pNewSegIn) {} + + const unsigned foundIt; + T * const pNewSeg; +}; + +// +// tsBTreeNode +// +template +class tsBTreeNode +{ +friend class tsBTree; +public: + // + // when someone copies into a class deriving from this + // do _not_ change the node pointers + // + void operator = (tsBTreeNode &) {} + + enum btCmp {btGreater, btLessOrEqual}; + + // + // class T must supply this member function which + // comapres *this with item + // + // returns: + // btGreater *this is greater than item + // btLessOrEqual *this is less than or equal to item + // + // btCmp tsBTreeCompare(const T &item) const; + // + +private: + T *pLeft; + T *pRight; + + static void traverse(T &self, void (T::*pCB)()) + { + if (self.tsBTreeNode::pLeft) { + tsBTreeNode::traverse + (*self.tsBTreeNode::pLeft, pCB); + } + (self.*pCB)(); + if (self.tsBTreeNode::pRight) { + tsBTreeNode::traverse + (*self.tsBTreeNode::pRight, pCB); + } + } + + // + // NOTE: + // no change to item.pLeft and item.pRight here + // so that an segment of a tree can be inserted + // + static void insert(T &self, T &item) + { + btCmp result = item.tsBTreeCompare(self); + if (result==btLessOrEqual) { + if (self.tsBTreeNode::pLeft) { + tsBTreeNode::insert + (*self.tsBTreeNode::pLeft, item); + } + else { + self.tsBTreeNode::pLeft = &item; + } + } + else if(result==btGreater) { + if (self.tsBTreeNode::pRight) { + tsBTreeNode::insert + (*self.tsBTreeNode::pRight, item); + } + else { + self.tsBTreeNode::pRight = &item; + } + } + else { + assert(0); + } + } + + // + // remove() + // returns pointer to modified tree and found/not found + // (NULL if this portion of the tree is empty) + // + static tsBTreeRMRet remove(T &self, T &item) + { + if (&self == &item) { + if (self.tsBTreeNode::pLeft) { + if (self.tsBTreeNode::pRight) { + T *pR = self.tsBTreeNode::pLeft->tsBTreeNode::pRight; + if (pR) { + tsBTreeNode::insert + (*pR, *self.tsBTreeNode::pRight); + } + else { + self.tsBTreeNode::pLeft->tsBTreeNode::pRight = + self.tsBTreeNode::pRight; + } + } + return tsBTreeRMRet(1u, self.tsBTreeNode::pLeft); // found it + } + else { + return tsBTreeRMRet(1u, self.tsBTreeNode::pRight); // found it + } + } + + btCmp result = item.tsBTreeCompare(self); + if (result==btLessOrEqual) { + if (self.tsBTreeNode::pLeft) { + tsBTreeRMRet ret = tsBTreeNode:: + remove(*self.tsBTreeNode::pLeft, item); + if (ret.foundIt) { + self.tsBTreeNode::pLeft= ret.pNewSeg; + return tsBTreeRMRet(1u,&self); // TRUE - found it + } + } + return tsBTreeRMRet(0u, 0u); // not found + } + else if(result==btGreater) { + if (self.tsBTreeNode::pRight) { + tsBTreeRMRet ret = tsBTreeNode:: + remove(*self.tsBTreeNode::pRight, item); + if (ret.foundIt) { + self.tsBTreeNode::pRight = ret.pNewSeg; + return tsBTreeRMRet(1u,&self); // TRUE - found it + } + } + return tsBTreeRMRet(0u, 0u); // not found + } + else { + assert(0); + } + } + // + // verify + // + static unsigned verify(const T &self, const T &item) + { + if (&self == &item) { + return 1u; // TRUE -item is present + } + btCmp result = item.tsBTreeCompare(self); + if (result==btLessOrEqual) { + if (self.tsBTreeNode::pLeft) { + return tsBTreeNode::verify + (*self.tsBTreeNode::pLeft, item); + } + else { + return 0u; // FALSE - not found + } + } + else if(result==btGreater) { + if (self.tsBTreeNode::pRight) { + return tsBTreeNode::verify + (*self.tsBTreeNode::pRight, item); + } + else { + return 0u; // FALSE - not found + } + } + else { + assert(0); + } + } +}; + +// +// tsBTree +// +template +class tsBTree +{ +public: + tsBTree() : pRoot(0u) {} + +// ~tsBTree() +// { +// this->traverse(T::~T); +// } + + void insert(T &item) + { + item.tsBTreeNode::pLeft = 0; + item.tsBTreeNode::pRight = 0; + if (this->pRoot) { + tsBTreeNode::insert(*this->pRoot, item); + } + else { + this->pRoot = &item; + } + } + // + // remove item from the tree + // + // returns true if item was in the tree + // (otherwise FALSE) + // + unsigned remove(T &item) + { + if (this->pRoot) { + tsBTreeRMRet ret = + tsBTreeNode::remove(*this->pRoot, item); + if (ret.foundIt) { + this->pRoot = ret.pNewSeg; + return 1u; // TRUE - found it + } + } + return 0u; // FALSE - not found + } + // + // verify that item is in the tree + // + // returns true if item is in the tree + // (otherwise FALSE) + // + unsigned verify(T &item) const + { + if (this->pRoot) { + return tsBTreeNode::verify(*this->pRoot, item); + } + else { + return 0u; // FALSE - not found + } + } + // + // Call (pT->*pCB) () for each item in the table + // + // where pT is a pointer to type T and pCB is + // a pointer to a memmber function of T with + // no parameters and returning void + // + void traverse(void (T::*pCB)()) + { + if (this->pRoot) { + tsBTreeNode::traverse(*this->pRoot, pCB); + } + } +private: + T *pRoot; +}; + diff --git a/src/libCom/cxxTemplates/test/tsBTreeBench.cc b/src/libCom/cxxTemplates/test/tsBTreeBench.cc new file mode 100644 index 000000000..15a07301f --- /dev/null +++ b/src/libCom/cxxTemplates/test/tsBTreeBench.cc @@ -0,0 +1,83 @@ + +#include +#include +#include +#include + +#include "tsBTree.h" +#include "tsSLList.h" + +class A : public tsBTreeNode, public tsSLNode { +public: + A() + { + key = (unsigned) rand(); + } + + btCmp tsBTreeCompare(const A &item) const + { + if (this->key<=item.key) { + return btLessOrEqual; + } + else { + return btGreater; + } + } + + void show() + { + printf("A: %u\n", key); + } +private: + unsigned key; +}; + +#define LOOPCOUNT 10000u + +main () +{ + unsigned i; + tsBTree tree; + tsSLList list; + A *pA; + A a; + clock_t clk; + clock_t diff; + double delay; + + tree.insert(a); + list.add(a); + + for (i=0u; i +#include + +#include "tsBTree.h" + +class A : public tsBTreeNode { +public: + A(const char *pNameIn) : pName(pNameIn) {} + + btCmp tsBTreeCompare(const A &item) const + { + int cmp = strcmp(this->pName, item.pName); + if (cmp<=0) { + return btLessOrEqual; + } + else { + return btGreater; + } + } + + void show() + { + printf("A: %s\n", pName); + } +private: + const char *pName; +}; + +main () +{ + tsBTree tree; + A a0("fred"); + A a1("jane"); + A a2("jane0"); + A a3("bill"); + A a4("jane"); + A a5("dan"); + A a6("joe"); + + tree.insert(a0); + tree.insert(a1); + tree.insert(a2); + tree.insert(a3); + tree.insert(a4); + tree.insert(a5); + + tree.traverse(A::show); + + assert(!tree.remove(a6)); + tree.insert(a6); + assert(tree.remove(a6)); + assert(tree.remove(a5)); + assert(!tree.remove(a5)); + assert(!tree.verify(a5)); + assert(tree.verify(a4)); + assert(tree.remove(a0)); + assert(!tree.verify(a0)); + assert(!tree.remove(a0)); + tree.insert(a5); + assert(tree.verify(a5)); + assert(tree.verify(a2)); + assert(tree.remove(a2)); + assert(!tree.verify(a2)); + assert(!tree.remove(a2)); + assert(tree.verify(a5)); + assert(tree.remove(a5)); + assert(!tree.remove(a5)); + assert(!tree.remove(a0)); + assert(tree.remove(a4)); + assert(tree.remove(a3)); + assert(!tree.remove(a4)); + assert(tree.remove(a1)); + + tree.traverse(A::show); + + return 0; +} + + diff --git a/src/libCom/cxxTemplates/tsBTree.h b/src/libCom/cxxTemplates/tsBTree.h new file mode 100644 index 000000000..575028a89 --- /dev/null +++ b/src/libCom/cxxTemplates/tsBTree.h @@ -0,0 +1,253 @@ + +#include + +// +// tsBTreeRMRet +// +template +class tsBTreeRMRet { +public: + tsBTreeRMRet (unsigned foundItIn, T *pNewSegIn) : + foundIt(foundItIn), pNewSeg(pNewSegIn) {} + + const unsigned foundIt; + T * const pNewSeg; +}; + +// +// tsBTreeNode +// +template +class tsBTreeNode +{ +friend class tsBTree; +public: + // + // when someone copies into a class deriving from this + // do _not_ change the node pointers + // + void operator = (tsBTreeNode &) {} + + enum btCmp {btGreater, btLessOrEqual}; + + // + // class T must supply this member function which + // comapres *this with item + // + // returns: + // btGreater *this is greater than item + // btLessOrEqual *this is less than or equal to item + // + // btCmp tsBTreeCompare(const T &item) const; + // + +private: + T *pLeft; + T *pRight; + + static void traverse(T &self, void (T::*pCB)()) + { + if (self.tsBTreeNode::pLeft) { + tsBTreeNode::traverse + (*self.tsBTreeNode::pLeft, pCB); + } + (self.*pCB)(); + if (self.tsBTreeNode::pRight) { + tsBTreeNode::traverse + (*self.tsBTreeNode::pRight, pCB); + } + } + + // + // NOTE: + // no change to item.pLeft and item.pRight here + // so that an segment of a tree can be inserted + // + static void insert(T &self, T &item) + { + btCmp result = item.tsBTreeCompare(self); + if (result==btLessOrEqual) { + if (self.tsBTreeNode::pLeft) { + tsBTreeNode::insert + (*self.tsBTreeNode::pLeft, item); + } + else { + self.tsBTreeNode::pLeft = &item; + } + } + else if(result==btGreater) { + if (self.tsBTreeNode::pRight) { + tsBTreeNode::insert + (*self.tsBTreeNode::pRight, item); + } + else { + self.tsBTreeNode::pRight = &item; + } + } + else { + assert(0); + } + } + + // + // remove() + // returns pointer to modified tree and found/not found + // (NULL if this portion of the tree is empty) + // + static tsBTreeRMRet remove(T &self, T &item) + { + if (&self == &item) { + if (self.tsBTreeNode::pLeft) { + if (self.tsBTreeNode::pRight) { + T *pR = self.tsBTreeNode::pLeft->tsBTreeNode::pRight; + if (pR) { + tsBTreeNode::insert + (*pR, *self.tsBTreeNode::pRight); + } + else { + self.tsBTreeNode::pLeft->tsBTreeNode::pRight = + self.tsBTreeNode::pRight; + } + } + return tsBTreeRMRet(1u, self.tsBTreeNode::pLeft); // found it + } + else { + return tsBTreeRMRet(1u, self.tsBTreeNode::pRight); // found it + } + } + + btCmp result = item.tsBTreeCompare(self); + if (result==btLessOrEqual) { + if (self.tsBTreeNode::pLeft) { + tsBTreeRMRet ret = tsBTreeNode:: + remove(*self.tsBTreeNode::pLeft, item); + if (ret.foundIt) { + self.tsBTreeNode::pLeft= ret.pNewSeg; + return tsBTreeRMRet(1u,&self); // TRUE - found it + } + } + return tsBTreeRMRet(0u, 0u); // not found + } + else if(result==btGreater) { + if (self.tsBTreeNode::pRight) { + tsBTreeRMRet ret = tsBTreeNode:: + remove(*self.tsBTreeNode::pRight, item); + if (ret.foundIt) { + self.tsBTreeNode::pRight = ret.pNewSeg; + return tsBTreeRMRet(1u,&self); // TRUE - found it + } + } + return tsBTreeRMRet(0u, 0u); // not found + } + else { + assert(0); + } + } + // + // verify + // + static unsigned verify(const T &self, const T &item) + { + if (&self == &item) { + return 1u; // TRUE -item is present + } + btCmp result = item.tsBTreeCompare(self); + if (result==btLessOrEqual) { + if (self.tsBTreeNode::pLeft) { + return tsBTreeNode::verify + (*self.tsBTreeNode::pLeft, item); + } + else { + return 0u; // FALSE - not found + } + } + else if(result==btGreater) { + if (self.tsBTreeNode::pRight) { + return tsBTreeNode::verify + (*self.tsBTreeNode::pRight, item); + } + else { + return 0u; // FALSE - not found + } + } + else { + assert(0); + } + } +}; + +// +// tsBTree +// +template +class tsBTree +{ +public: + tsBTree() : pRoot(0u) {} + +// ~tsBTree() +// { +// this->traverse(T::~T); +// } + + void insert(T &item) + { + item.tsBTreeNode::pLeft = 0; + item.tsBTreeNode::pRight = 0; + if (this->pRoot) { + tsBTreeNode::insert(*this->pRoot, item); + } + else { + this->pRoot = &item; + } + } + // + // remove item from the tree + // + // returns true if item was in the tree + // (otherwise FALSE) + // + unsigned remove(T &item) + { + if (this->pRoot) { + tsBTreeRMRet ret = + tsBTreeNode::remove(*this->pRoot, item); + if (ret.foundIt) { + this->pRoot = ret.pNewSeg; + return 1u; // TRUE - found it + } + } + return 0u; // FALSE - not found + } + // + // verify that item is in the tree + // + // returns true if item is in the tree + // (otherwise FALSE) + // + unsigned verify(T &item) const + { + if (this->pRoot) { + return tsBTreeNode::verify(*this->pRoot, item); + } + else { + return 0u; // FALSE - not found + } + } + // + // Call (pT->*pCB) () for each item in the table + // + // where pT is a pointer to type T and pCB is + // a pointer to a memmber function of T with + // no parameters and returning void + // + void traverse(void (T::*pCB)()) + { + if (this->pRoot) { + tsBTreeNode::traverse(*this->pRoot, pCB); + } + } +private: + T *pRoot; +}; +