Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

PathTree.cpp

Go to the documentation of this file.
00001 /*
00002 This product contains certain software code or other information
00003 ("AT&T Software") proprietary to AT&T Corp. ("AT&T").  The AT&T
00004 Software is provided to you "AS IS".  YOU ASSUME TOTAL RESPONSIBILITY
00005 AND RISK FOR USE OF THE AT&T SOFTWARE.  AT&T DOES NOT MAKE, AND
00006 EXPRESSLY DISCLAIMS, ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND
00007 WHATSOEVER, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00008 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, WARRANTIES OF
00009 TITLE OR NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS, ANY
00010 WARRANTIES ARISING BY USAGE OF TRADE, COURSE OF DEALING OR COURSE OF
00011 PERFORMANCE, OR ANY WARRANTY THAT THE AT&T SOFTWARE IS "ERROR FREE" OR
00012 WILL MEET YOUR REQUIREMENTS.
00013 
00014 Unless you accept a license to use the AT&T Software, you shall not
00015 reverse compile, disassemble or otherwise reverse engineer this
00016 product to ascertain the source code for any AT&T Software.
00017 
00018 (c) AT&T Corp. All rights reserved.  AT&T is a registered trademark of AT&T Corp.
00019 
00020 ***********************************************************************
00021 
00022 History:
00023 
00024       24/11/99  - initial release by Hartmut Liefke, liefke@seas.upenn.edu
00025                                      Dan Suciu,      suciu@research.att.com
00026 */
00027 
00028 
00029 //***********************************************************************
00030 //***********************************************************************
00031 
00032 // This module contains the backward data guide
00033 // The backward data guide maps paths into path dictionary (see PathDict.hpp)
00034 // nodes. Each path in the backward data guide represents a
00035 // path in the XML document that is *backward* - i.e. from
00036 // the leaf (i.e. a leaf node with some string value) toward
00037 // the root of the XML document.
00038 
00039 // The backward dataguide is implemented as a tree.
00040 
00041 
00042 #include "PathTree.hpp"
00043 #include "ContMan.hpp"
00044 
00045 #ifdef USE_FORWARD_DATAGUIDE
00046 MemStreamer    mypathtreemem(5);
00047 MemStreamer    *pathtreemem=&mypathtreemem;
00048 #else
00049 MemStreamer    *pathtreemem=&blockmem;
00050 #endif
00051 
00052 
00053 //*****************************************************************************
00054 //*****************************************************************************
00055 
00056 #ifdef USE_FORWARD_DATAGUIDE
00057 inline void PathTreeNode::ComputePathDictNode(FSMManStateItem *stateitem)
00058 {
00059    PathDictNode   *mypathdictnode=pathdict.FindOrCreateRootPath(stateitem->pathexpr);
00060    FSMState       *curstate=stateitem->pathexpr->GetReverseFSMStartState();
00061    char           overpoundedge;
00062 
00063    PathTreeNode *curpathtreenode=this;
00064 
00065    while((curpathtreenode->labelid!=LABEL_UNDEFINED)&&
00066          (curstate->HasPoundsAhead()))
00067 
00068    {
00069       curstate=curstate->GetNextState(curpathtreenode->labelid,&overpoundedge);
00070 
00071       // Did we jump over a pound-edge ?
00072       // ==> We must advance the 'pathdictnode' item
00073       if(overpoundedge)
00074          mypathdictnode=pathdict.FindOrCreatePath(mypathdictnode,curpathtreenode->labelid);
00075 
00076       curpathtreenode=curpathtreenode->parent;
00077    }
00078    stateitem->pathdictnode=mypathdictnode;
00079 }
00080 #endif
00081 
00082 inline void PathTreeNode::ComputeInitStateList(unsigned char *isaccepting)
00083    // Computes the list of initial FSM states for this node
00084    // The state must be the root node!
00085 {
00086    VPathExpr         *pathexpr=pathexprman.GetVPathExprs();
00087    FSMManStateItem   **statelistref=&fsmstatelist;
00088 
00089    *isaccepting=1;
00090 
00091    // We consider all path expressions
00092    while(pathexpr!=NULL)
00093    {
00094 #ifdef PROFILE
00095       pathtree.fsmstatecount++;
00096 #endif
00097 
00098       // Let's create a new FSM state reference for each FSM
00099       *statelistref=new FSMManStateItem();
00100 
00101       (*statelistref)->pathexpr     =pathexpr;
00102 
00103 #ifndef USE_FORWARD_DATAGUIDE
00104       // We annotate the state with the start state of the reverse FSM
00105       (*statelistref)->curstate    =pathexpr->GetReverseFSMStartState();
00106       // We also find (or create) the corresponding root node from the
00107       // path dictionary
00108       (*statelistref)->pathdictnode=pathdict.FindOrCreateRootPath(pathexpr);
00109 #else
00110       (*statelistref)->curstate    =pathexpr->GetForwardFSMStartState();
00111       ComputePathDictNode(*statelistref);
00112 #endif
00113 
00114       // If one of the FSM states is not accepting, then the *entire*
00115       // dataguide state is not accepting.
00116       if((*statelistref)->curstate->IsAccepting()==0)
00117          *isaccepting=0;
00118 
00119       statelistref=&((*statelistref)->next);
00120       pathexpr=pathexpr->GetNext();
00121    }
00122    *statelistref=NULL;
00123 }
00124 
00125 inline void PathTreeNode::ComputeNextStateList(TLabelID labelid,unsigned char *isaccepting)
00126    // Given a new label and a list of existing states,
00127    // this function produces a list of successor states
00128 {
00129    FSMManStateItem   *newstatelist=NULL,**newstatelistref=&fsmstatelist,
00130                      *newfsmstate;
00131    FSMState          *nextstate;
00132    char              overpoundedge;
00133 
00134    // Let's find the previous set of FSM states
00135    FSMManStateItem   *prevstatelist=parent->fsmstatelist;
00136    
00137    *isaccepting=1;
00138 
00139    // We conside all FSM states of the parent node
00140    while(prevstatelist!=NULL)
00141    {
00142       // Can we find a successor state over 'labelid'?
00143       nextstate=prevstatelist->curstate->GetNextState(labelid,&overpoundedge);
00144       if(nextstate==NULL)
00145          // There is no following state, i.e. the automaton does not
00146          // accept that word
00147       {
00148          prevstatelist=prevstatelist->next;
00149          continue;
00150       }
00151 
00152 #ifdef PROFILE
00153       pathtree.fsmstatecount++;
00154 #endif
00155 
00156       newfsmstate=new FSMManStateItem();
00157 
00158       newfsmstate->pathexpr      =prevstatelist->pathexpr;
00159       newfsmstate->curstate      =nextstate;
00160 
00161 #ifndef USE_FORWARD_DATAGUIDE
00162       // If we have a pound edge, we need to maintain this information,
00163       // since pound edges must be instantiated to labels 
00164       newfsmstate->overpoundedge =(unsigned long)overpoundedge;
00165 
00166       // If we have a '#' edge, then we need to go to some child node
00167       // in the path dictionary that is reachable of the labelid
00168       if(overpoundedge)
00169          newfsmstate->pathdictnode=pathdict.FindOrCreatePath(prevstatelist->pathdictnode,labelid);
00170       else
00171          // Otherwise, we stay in the same path dictionary node
00172          newfsmstate->pathdictnode=prevstatelist->pathdictnode;
00173 #else
00174       if(nextstate->IsFinal())
00175          ComputePathDictNode(newfsmstate);
00176       else
00177          newfsmstate->pathdictnode=NULL;
00178 #endif
00179 
00180       // If one of the next states is not accepting,
00181       // then the entire state is not accepting
00182       if(nextstate->IsAccepting()==0)
00183          *isaccepting=0;
00184 
00185       *newstatelistref=newfsmstate;
00186       newstatelistref=&(newfsmstate->next);
00187 
00188       prevstatelist=prevstatelist->next;
00189    }
00190    *newstatelistref=NULL;
00191 }
00192 
00193 //*****************************************************************************
00194 
00195 void PathTree::CreateRootNode()
00196    // Creates the root node
00197 {
00198    unsigned char isaccepting;
00199 
00200    rootnode.parent=NULL;
00201    rootnode.labelid=LABEL_UNDEFINED;
00202 #ifdef PROFILE
00203    nodecount=0;
00204    lookupcount=0;
00205    hashitercount=0;
00206    fsmstatecount=0;
00207 #endif
00208 
00209 //   rootnode.fsmstatelist=pathexprman.CreateInitStateList(&isaccepting);
00210    rootnode.ComputeInitStateList(&isaccepting);
00211 
00212    rootnode.isaccepting=isaccepting;
00213 }
00214 
00215 // Computes the hash index for a parent node and a label id
00216 #define ComputePathTreeHashIdx(node,labelid) ((((unsigned long)(node))+(labelid))&PATHTREE_HASHMASK)
00217 
00218 PathTreeNode *PathTree::ExtendCurPath(PathTreeNode *curnode,TLabelID labelid)
00219    // This important function extends the dataguide from the
00220    // current node 'curnode' by adding an edge with label 'labelid'
00221    // It also computes the corresponding FSM state annotations
00222    // If such an edge already exists, the function simply returns
00223    // the existing child node
00224 {
00225    unsigned char  isaccepting;
00226    PathTreeNode   *node;
00227 
00228 #ifndef USE_NO_DATAGUIDE
00229    unsigned long  hashidx=ComputePathTreeHashIdx(curnode,labelid);
00230 
00231 #ifdef PROFILE
00232    lookupcount++;
00233 #endif
00234 
00235    // First, we check whether we already have an edge with the
00236    // same label.
00237    node=pathtreehashtable[hashidx];
00238 
00239    while(node!=NULL)
00240    {
00241 #ifdef PROFILE
00242       hashitercount++;
00243 #endif
00244 
00245       if((node->parent==curnode)&&
00246          (node->labelid==labelid))
00247          break;
00248       node=node->nextsamehash;
00249    }
00250 
00251    if(node!=NULL)
00252       // if an edge with the label already exists ? ==> We return it
00253       return node;
00254 
00255 #ifdef PROFILE
00256    nodecount++;
00257 #endif
00258 
00259 #endif // USE_NO_DATAGUIDE
00260 
00261    // If we don't have an edge with the label, we create a new dataguide node
00262    node=new PathTreeNode();
00263    node->parent=curnode;
00264    node->labelid=labelid;
00265 
00266    // ... and compute the set of FSM states for that node
00267    node->ComputeNextStateList(labelid,&isaccepting);
00268 
00269    node->isaccepting=isaccepting;
00270 
00271 #ifndef USE_NO_DATAGUIDE
00272    node->nextsamehash=pathtreehashtable[hashidx];
00273    pathtreehashtable[hashidx]=node;
00274 #endif
00275 
00276    return node;
00277 }
00278 
00279 void PathTree::ReleaseMemory()
00280 {
00281 //   pathtreemem->ReleaseMemory();
00282 //   pathtreemem.Initialize(5);
00283 //   Init();
00284 
00285    for(int i=0;i<PATHTREE_HASHSIZE;i++)
00286       pathtreehashtable[i]=NULL;
00287 }

Generated on Sat Oct 13 16:08:39 2001 for XMILL by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001