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

PathDict.hpp

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 // This module contains the path dictionary class
00032 // The path dictionary maps paths into container blocks
00033 // The paths are not actual paths in the XML document, but
00034 // instantiations of the '#' symbols within the FSM for a given
00035 // path in the XML document
00036 
00037 // The path dictionary is implemented as a tree with roots
00038 // for each possible FSM. The roots are children of a node called
00039 // the 'super root node'.
00040 // Edges are labeled with XML label IDs. Each outgoing edge of a parent
00041 // has a distinct ID (i.e. the tree is deterministic)
00042 // To go from one node in the tree to a subnode using a specific label,
00043 // we use a hash table
00044 
00045 #ifndef PATHDICT_HPP
00046 #define PATHDICT_HPP
00047 
00048 #include "Types.hpp"
00049 #include "MemStreamer.hpp"
00050 #include "LabelDict.hpp"
00051 #include "ContMan.hpp"
00052 
00053 // The memory used for allocating nodes in the path dictionary tree
00054 extern MemStreamer *pathdictmem;
00055 
00056 class VPathExpr;
00057 class PathDict;
00058 class CompressContainerBlock;
00059 class UncompressContainerBlock;
00060 
00061 // The size of the hash table
00062 #define PATHDICT_HASHSIZE  512
00063 #define PATHDICT_HASHMASK  511
00064 
00065 
00066 class PathDictNode
00067    // Each node is represented by this structure
00068 {
00069    friend PathDict;
00070 
00071    PathDictNode   *parent; // The parent node.
00072                            // Is NULL for the super root node
00073    union
00074    {
00075       TLabelID       labelid;    // For non-root nodes, we store the label
00076                                  // for the edge from the parent
00077       VPathExpr      *pathexpr;  // For root nodes, we store the FSM info
00078    };
00079 
00080    // For compressor/decompressor, we need to keep track of the actual
00081    // container block used. The container block can be NULL at the beginning
00082    // and be allocated later.
00083    union
00084    {
00085       CompressContainerBlock     *compresscontblock;
00086       UncompressContainerBlock   *uncompresscontblock;
00087    };
00088 
00089    // The next node with the same hash value
00090    PathDictNode   *nextsamehash;
00091 
00092 public:
00093 
00094    void *operator new(size_t size)
00095    {
00096       return pathdictmem->GetByteBlock(size);
00097    }
00098 
00099    CompressContainerBlock *GetCompressContainerBlock()
00100    {
00101       return compresscontblock;
00102    }
00103 
00104    CompressContainerBlock *AssignCompressContainerBlock(unsigned contnum,unsigned userdatasize,VPathExpr *pathexpr)
00105       // If there is no container block yet, then this function allocated
00106       // the container block.
00107    {
00108       compresscontblock=compresscontman.CreateNewContainerBlock(contnum,userdatasize,this,pathexpr);
00109       return compresscontblock;
00110    }
00111 
00112    void PrintInfo(); // Prints the information about the node's container block
00113 
00114    VPathExpr *GetPathExpr()   {  return pathexpr;}
00115 };
00116 
00117 inline unsigned long ComputePathDictHashIdx(PathDictNode *parent,TLabelID labelid)
00118    // Computes the hash index based on the parent node and the label ID
00119    // - This is for non-root nodes
00120 {
00121    return (((unsigned long)parent)+labelid)&PATHDICT_HASHMASK;
00122 }
00123 
00124 inline unsigned long ComputePathDictHashIdx(VPathExpr *pathexpr)
00125    // Computes the hash index based on the path expression
00126    // - This is for root nodes
00127 {
00128    return (((unsigned long)pathexpr)-1)&PATHDICT_HASHMASK;
00129 }
00130 
00131 //***************************************************************************************
00132 
00133 class PathDict
00134    // The actual path dictionary class
00135 {
00136    PathDictNode   *hashtable[PATHDICT_HASHSIZE];   // The hash table
00137    PathDictNode   rootnode;   // The super root node
00138 
00139 #ifdef PROFILE
00140    // Some profiling information
00141    unsigned long  nodecount,lookupcount,hashitercount;
00142 #endif
00143 
00144 public:
00145    void Init()
00146       // Initializes the path dictionary
00147    {
00148       int i;
00149       for(i=0;i<PATHDICT_HASHSIZE;i++)
00150          hashtable[i]=NULL;
00151 #ifdef PROFILE
00152       nodecount=0;
00153       lookupcount=0;
00154       hashitercount=0;
00155 #endif
00156    }
00157 
00158 #ifdef USE_FORWARD_DATAGUIDE
00159    void ResetContBlockPtrs()
00160       // We reset the container block pointers to NULL for all
00161       // nodes
00162    {
00163       for(int i=0;i<PATHDICT_HASHSIZE;i++)
00164       {
00165          PathDictNode *node=hashtable[i];
00166          while(node!=NULL)
00167          {
00168             node->compresscontblock=NULL;
00169             node=node->nextsamehash;
00170          }
00171       }
00172    }
00173 #endif
00174 
00175    PathDict()  {  Init();  }
00176 
00177    PathDictNode *FindOrCreateRootPath(VPathExpr *pathexpr)
00178       // Finds or creates the root node for a specific FSM (i.e. the path expression)
00179    {
00180       unsigned long  hashidx=ComputePathDictHashIdx(pathexpr);
00181       PathDictNode   *node=hashtable[hashidx];
00182 #ifdef PROFILE
00183       lookupcount++;
00184 #endif
00185 
00186       while(node!=NULL)
00187       {
00188 #ifdef PROFILE
00189          hashitercount++;
00190 #endif
00191          if(node->pathexpr==pathexpr)
00192             return node;
00193 
00194          node=node->nextsamehash;
00195       }
00196 
00197       // We must create a new node
00198       node=new PathDictNode();
00199 
00200 #ifdef PROFILE
00201       nodecount++;
00202 #endif
00203 
00204       node->parent=NULL;
00205       node->pathexpr=pathexpr;
00206       node->compresscontblock=NULL;
00207 //      node->labelid=LABEL_UNDEFINED;
00208 
00209       node->nextsamehash=hashtable[hashidx];
00210       hashtable[hashidx]=node;
00211 
00212       return node;
00213    }
00214 
00215    PathDictNode *FindOrCreatePath(PathDictNode *parent,TLabelID labelid)
00216       // Finds or creates a non-root node with parent 'parent' and an
00217       // edge label 'labelid'.
00218    {
00219       unsigned long hashidx=ComputePathDictHashIdx(parent,labelid);
00220       PathDictNode   *node=hashtable[hashidx];
00221 
00222 #ifdef PROFILE
00223       lookupcount++;
00224 #endif
00225 
00226       while(node!=NULL)
00227       {
00228 #ifdef PROFILE
00229          hashitercount++;
00230 #endif
00231 
00232          if((node->parent==parent)&&(node->labelid==labelid))
00233             return node;
00234 
00235          node=node->nextsamehash;
00236       }
00237 
00238       // We must create a new node
00239       node=new PathDictNode();
00240 
00241 #ifdef PROFILE
00242       nodecount++;
00243 #endif
00244 
00245       node->parent=parent;
00246       node->labelid=labelid;
00247       node->compresscontblock=NULL;
00248 
00249       node->nextsamehash=hashtable[hashidx];
00250       hashtable[hashidx]=node;
00251 
00252       return node;
00253    }
00254 
00255 #ifdef PROFILE
00256    void PrintProfile()
00257    {
00258       printf("PathDict: nodecount=%lu  lookupcount=%lu   hashitercount=%lu\n",
00259          nodecount,lookupcount,hashitercount);
00260    }
00261 #endif
00262 
00263 //*******************************************************************************
00264 };
00265 
00266 extern PathDict pathdict;
00267 
00268 #endif

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