00001 #ifndef BuildTreeDBCache_HPP
00002 #define BuildTreeDBCache_HPP
00003
00008 #include <vector>
00009 #include <set>
00010 #include <map>
00011
00012
00013 #include "fpgrowth/buildfptree.hpp"
00014
00015 namespace bracz
00016 {
00017 template <class T_R, class BIS, class BuildTree, bool ENDONLY=true, bool SORT_NEEDED=false>
00018 class BuildTreeDBCache : public T_R, public BuildTree
00019 {
00020 public:
00021 typedef typename T_R::params_t params_t;
00022 typedef typename BuildTree::nodeiter_t nodeiter_t;
00023 typedef typename BuildTree::nodeptr_t nodeptr_t;
00024
00025 BuildTreeDBCache( const params_t* par ) : T_R(par), BuildTree(){
00026 nullTreeAnn treeann;
00027 T_R::rewind();
00028 BuildTree::initBuildTree(tree,this->getLargestItem()+1,treeann);
00029 BIS trans;
00030 while (counter_t count=T_R::nextTransactionBIS(trans)) {
00031 BuildTree::addTransToTree(trans,trans.size(),tree,count,treeann);
00032 }
00033 if(SORT_NEEDED)
00034 sortEdgeList(tree.getRoot());
00035 }
00036
00037 void insert( const BIS& transaction,
00038 const counter_t multiplicity )
00039 {
00040 nullTreeAnn treeann;
00041 BuildTree::addTransToTree(
00042 transaction, transaction.size(),
00043 tree, multiplicity, treeann);
00044 }
00045 void clear()
00046 {}
00047
00048 counter_t nextTransactionBIS(BIS& transaction ) {
00049 while ((!curriters.empty()) && (curriters.top()==enditers.top())) {
00050 curriters.pop();
00051 enditers.pop();
00052 currtrans.pop_back();
00053 if (!curriters.empty()) {
00054 ++(curriters.top());
00055 }
00056 }
00057 if (curriters.empty()) {
00058 return 0;
00059 }
00060 while (true) {
00061 std::pair<item_t,nodeptr_t> p=*(curriters.top());
00062 currtrans.push_back(p.first);
00063 curriters.push((*p.second).childrenBegin());
00064 enditers.push((*p.second).childrenEnd());
00065 counter_t r=(*p.second).getCounter();
00066 if(!ENDONLY)
00067 {
00068 for( nodeiter_t child_iter = (*p.second).childrenBegin();
00069 child_iter != (*p.second).childrenEnd(); ++child_iter )
00070 r -= (*child_iter).second->getCounter();
00071 }
00072 if (r) {
00073 transaction=currtrans;
00074 return r;
00075 }
00076 }
00077 }
00078 nodeptr_t getRoot()
00079 {
00080 return tree.getRoot();
00081 }
00082
00083 template <class UAC> counter_t nextTransactionUAC(UAC& transaction ) { exit(1);}
00084
00085 void rewind()
00086 {
00087 currtrans.clear();
00088 while (!curriters.empty())
00089 curriters.pop();
00090 while (!enditers.empty())
00091 enditers.pop();
00092 nodeptr_t r=tree.getRoot();
00093 curriters.push((*r).childrenBegin());
00094 enditers.push((*r).childrenEnd());
00095 }
00096 protected:
00097 typename BuildTree::buildtree_t tree;
00098 std::stack<nodeiter_t> curriters,enditers;
00099 BIS currtrans;
00100
00101 void sortEdgeList(nodeptr_t subtrie)
00102 {
00103 typename BuildTree::childmap_t* children = subtrie->getChildren();
00104 if(children)
00105 {
00106 children->sort< std::less<typename BuildTree::childmap_t::value_type> >();
00107 for( nodeiter_t patr_iter = subtrie->childrenBegin();
00108 patr_iter != subtrie->childrenEnd(); ++patr_iter)
00109 sortEdgeList((*patr_iter).second);
00110 }
00111 }
00112 };
00113
00114 }
00115 #endif