Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

classicfp.cpp

Go to the documentation of this file.
00001 
00009 #include "common.hpp"
00010 #include "common/log.h"
00011 #include "io/input/transaction_reader/TransactionReader.hpp"
00012 #include "fpgrowth/buildfptree.hpp"
00013 
00014 
00015 namespace bracz {
00016 
00018   typedef struct node_t {
00019     node_t *parent;
00020     item_t item;
00021     counter_t counter;
00022     node_t *headerlink;
00023   } node_t;
00024 
00025 
00034   template<class INPUT,class BUILDTREE, FirstLevel FIRSTLEVEL, bool TD, bool SINGLE> class ClassicFPStructure {
00035   private:
00036 
00037   public:
00039     typedef struct fptree_t {
00040       counter_t *freqs;
00041       node_t **headertable;
00042       counter_t rootfreq;
00043       counter_t DINLINE getFrequency(item_t i) {
00044         return freqs[i];
00045       }
00046 
00047       counter_t DINLINE getRootFrequency() {
00048         return rootfreq;
00049       }
00050     } fptree_t;
00051 
00052 
00053     counter_t getTransactionCount() {
00054       return transaction_count;
00055     }
00056 
00057   private:
00058 
00060     INPUT *inp;
00061     
00062   protected:
00063 
00064     fptree_t fulltree;
00065 
00066     std::vector<fptree_t> l1trees;
00067 
00068     // used when per-item trees are built
00069     counter_t transaction_count;
00070 
00072     singleualloc<node_t, 10*1024> nodeallocator;
00074     singlesalloc<fptree_t,100> treealloc;
00075 
00076     //these will be unused if operating TD mode
00078     blockstack<stackmultiblock<node_t*,false,stacksingleblock<counter_t,false> > > treecontentalloc;
00079 
00080 
00081     void reccopytree(fptree_t *target,TYPENAME BUILDTREE::nodeptr_t node, node_t *parent) {
00082       //target->counters[nodeidx]=node->getCounter();
00083       for(TYPENAME BUILDTREE::nodeiter_t i=node->childrenBegin();
00084           i!=node->childrenEnd();
00085           ++i) {
00086         //item_t (*i).first
00087         //
00088         node_t *newnode=nodeallocator.allocate();
00089         newnode->parent=parent;
00090         newnode->item=(*i).first;
00091         newnode->counter=(*i).second->getCounter();
00092         newnode->headerlink=target->headertable[(*i).first];
00093         target->headertable[(*i).first]=newnode;
00094         target->freqs[(*i).first]+=(*i).second->getCounter();
00095 
00096         reccopytree(target,TYPENAME BUILDTREE::nodeptr_t((*i).second),newnode);
00097       }
00098     }
00099 
00100     void copyBuildTreeToFinalTree(TYPENAME BUILDTREE::buildtree_t &buildtree,fptree_t &fulltree,item_t maxitem) {
00101       alignalloc::allocz(fulltree.freqs,maxitem);
00102       alignalloc::allocz(fulltree.headertable,maxitem);
00103       fulltree.rootfreq=buildtree.getRoot()->getCounter();
00104       reccopytree(&fulltree,(buildtree.getRoot()),NULL);
00105     }
00106 
00108     void buildTree(item_t maxitem) {
00109       bracz::nullTreeAnn treeann;
00110       BUILDTREE btr;
00111       typename BUILDTREE::buildtree_t buildtree;
00112       btr.initBuildTree(buildtree,maxitem,treeann);
00113 
00114       log_status(0,"Building temporary FP tree.");
00115       //build the trie
00116       std::vector<item_t> trans;
00117       inp->rewind();
00118       //    size_t singlec=0;
00119       transaction_count=0;
00120       while (counter_t count=inp->nextTransactionBIS(trans)) {
00121         transaction_count+=count;
00122         btr.addTransToTree(trans,trans.size(),buildtree,count,treeann);
00123       }
00124       copyBuildTreeToFinalTree(buildtree,fulltree,maxitem);
00125     }
00126 
00127 
00129     void buildAllL1Trees(item_t maxitem) {
00130       BUILDTREE btr;
00131       // holds the number of nodes for each item id
00132       bracz::nullTreeAnn treeann;
00133       std::vector<typename BUILDTREE::buildtree_t> trees;
00134       trees.resize(maxitem);
00135       log_status(0,"Initializing FP tree.");
00136       for(item_t i=0;i<maxitem;++i) {
00137         btr.initBuildTree(trees[i],i,treeann);
00138       }
00139       log_status(0,"Building temporary FP trees.");
00140       //build the trie
00141       std::vector<item_t> trans;
00142       inp->rewind();
00143       //    size_t singlec=0;
00144       transaction_count=0;
00145       while (counter_t count=inp->nextTransactionBIS(trans)) {
00146         transaction_count+=count;
00147         for (size_t itemidx=0;itemidx<trans.size();++itemidx) {
00148           btr.addTransToTree(trans,itemidx,trees[trans[itemidx]],count,treeann);
00149         }
00150       }
00151       l1trees.resize(maxitem);
00152       for(item_t i=0;i<maxitem;++i) {
00153         copyBuildTreeToFinalTree(trees[i],l1trees[i],i);
00154       }
00155     }
00156 
00157   public:
00158     class SinglePathIterator {
00159     private:
00160       node_t *c;
00161     public:
00162       void DINLINE increment(fptree_t *) {
00163         c=c->parent;
00164       }
00165       bool DINLINE atEnd(fptree_t *) {
00166         return !c;
00167       }
00168       item_t DINLINE getCurrItem(fptree_t *) {
00169         return c->item;
00170       }
00171       SinglePathIterator(node_t *_c): c(_c){}
00172     };//class SinglePathIterator
00173 
00174     SinglePathIterator getSinglePathIterator(fptree_t *t,item_t curritem) {
00175       return SinglePathIterator(t->headertable[curritem]);
00176     }
00177 
00184     ClassicFPStructure(INPUT *_inp, item_t maxitem) {
00185       inp=_inp;
00186       switch(FIRSTLEVEL) {
00187       case FLBuildSingleTree: {
00188         buildTree(maxitem);
00189         break;
00190       }
00191       case FLBuildAllL1Trees: {
00192         buildAllL1Trees(maxitem);
00193         break;
00194       }
00195       case FLSimultProject: {
00196         log_err(0,"Simultaneous projection is not implemented in ClassicFpTree yet.");
00197         exit(1);
00198         break;
00199       }
00200       }
00201     }
00202 
00203     fptree_t * getFullTree() {
00204       if (FIRSTLEVEL != FLBuildSingleTree) {
00205         log_err(0,"Requested full tree when per-item trees are calculated!");
00206         return NULL;
00207       } else 
00208         return &fulltree;
00209     }
00210 
00211     fptree_t * getProjTree(item_t item) {
00212       if (FIRSTLEVEL == FLBuildSingleTree) {
00213         log_err(0,"Requested per-item tree when only unconditional tree is calculated!");
00214         return NULL;
00215       } else 
00216         return &(l1trees[item]);
00217     }
00218 
00219 
00220     item_t DINLINE checkSinglePath(fptree_t *t, item_t curritem, item_t spdepth) {
00221       if (!SINGLE) {
00222         return 0;
00223       } else {
00224         while ((spdepth<curritem) && ((!t->headertable[spdepth]) || (!t->headertable[spdepth]->headerlink)))
00225           spdepth++;
00226         return spdepth;
00227       }
00228     }
00229 
00230     template <class O_M> void DINLINE handleSinglePath(fptree_t *t, item_t curritem, O_M *out) {
00231     
00232     }
00233 
00234     void DINLINE zeroDataDense(fptree_t *intr, item_t curritem) {
00235       //partial erase on the `data' part of the tree
00236       alignalloc::zerola(intr->freqs,curritem);
00237       //zero the counters above the current item
00238       /*for (item_t i=0;i<curritem;++i) {
00239         for(node_t *cnode=intr->headertable[i];cnode;cnode=cnode->headerlink) {
00240           cnode->counter=0;
00241         }
00242         }*/
00243       intr->rootfreq=0;
00244     }
00245 
00246     void DINLINE aggregateDense(fptree_t *intr, item_t curritem) {
00247       for (node_t *cnode=intr->headertable[curritem];cnode;cnode=cnode->headerlink) {
00248         counter_t c=cnode->counter;
00249         intr->rootfreq+=c;
00250         node_t *nnode=cnode->parent;
00251         while (nnode) {
00252           nnode->counter+=c;
00253           intr->freqs[nnode->item]+=c;
00254           nnode=nnode->parent;
00255         }
00256       }
00257       
00258     }
00259 
00260     fptree_t * DINLINE projectTree(fptree_t *intr,item_t curritem) {
00261       if (TD) {
00262         zeroDataDense(intr,curritem);
00263         aggregateDense(intr,curritem);
00264         return intr;
00265       } else {
00266         /*        fptree_t *nftree = treealloc.allocate();
00267         nftree->parents=intr->parents;
00268         nftree->itemstarts=intr->itemstarts;
00269         nftree->counters=NULL;
00270         nodealloc.pushAndGetBlock(nftree->itemstarts[curritem],nftree->counters);
00271         nftree->freqs=NULL;
00272         headeralloc.pushAndGetBlock(curritem,nftree->freqs);
00273         zeroDataADense(nftree,curritem);
00274         aggregateDense(nftree->itemstarts,nftree->parents,nftree->freqs,intr->counters,nftree->counters,curritem);
00275         if (PROJECT) {
00276           compactTree(nftree,curritem);
00277         }
00278         return nftree;*/
00279       }
00280     }
00281 
00282     void DINLINE deallocTree(fptree_t *t, fptree_t *parent, item_t projitem) {
00283       //in case of TD de clean up the nonzer counters in the tree
00284       if (TD) {
00285         for (node_t *cnode=t->headertable[projitem];cnode;cnode=cnode->headerlink) {
00286           node_t *pnode=cnode;
00287           while (pnode && pnode->counter) {
00288             pnode->counter=0;
00289             pnode=pnode->parent;
00290           }
00291         }
00292       }
00293     }
00294 
00295   }; //class ClassicFPStructure
00296 
00297 }//namespace bracz

Generated on Sun Sep 17 17:50:38 2006 for FIM environment by  doxygen 1.4.4