00001 // Copyright (C) 2001, Compaq Computer Corporation 00002 // 00003 // This file is part of Vesta. 00004 // 00005 // Vesta is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 // 00010 // Vesta is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with Vesta; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 // Last modified on Tue Aug 3 13:59:25 EDT 2004 by ken@xorian.net 00020 // modified on Wed May 13 16:08:16 PDT 1998 by heydon 00021 // modified on Wed Mar 18 12:04:09 PST 1998 by yuanyu 00022 00023 #ifndef _PREFIX_TBL_H 00024 #define _PREFIX_TBL_H 00025 00026 /* A "PrefixTbl" is a data structure for representing a set 00027 of pathnames. If the pathnames in the set share common 00028 prefixes, the "PrefixTbl" representation is quite compact. 00029 Each pathname in the table is identified by a non-negative 00030 integer. */ 00031 00032 #include <Basics.H> 00033 #include <Generics.H> 00034 #include <SRPC.H> 00035 #include <VestaLog.H> 00036 #include <Recovery.H> 00037 #include <FS.H> 00038 #include "FV2.H" 00039 00040 class PrefixTbl { 00041 public: 00042 00043 // This type is thrown as an exception when no more entries can be 00044 // added to a PrefixTbl. 00045 struct Overflow 00046 { 00047 Basics::uint16 numArcs; 00048 Overflow(Basics::uint16 arcs) : numArcs(arcs) { } 00049 }; 00050 00051 // Index value used to mark the end of a chain in a PrefixTbl. 00052 static const Basics::uint16 endMarker = ~0; 00053 00054 PrefixTbl() throw () 00055 /* Construct a new, empty "PrefixTbl". */ 00056 : numArcs(0), maxArcs(0), indexArray(NULL), arcArray(NULL) { /*SKIP*/}; 00057 00058 PrefixTbl(int szHint) throw (); 00059 /* Construct a new, empty "PrefixTbl" with expected size "szHint". */ 00060 00061 PrefixTbl(std::istream &ifs) throw (FS::EndOfFile, FS::Failure) 00062 { this->Read(ifs); } 00063 00064 int PrefixIndex(int idx) const throw () { return this->indexArray[idx]; } 00065 /* Return the index of the prefix of the name with index "idx". */ 00066 00067 Text Arc(int idx) const throw () { return this->arcArray[idx]; } 00068 /* Return the last arc of the pathname with index "idx". */ 00069 00070 int NumArcs() const throw () { return this->numArcs; }; 00071 /* Return the number of pathnames in the table. */ 00072 00073 int Put(const char* path, TextIntTbl /*INOUT*/ &tbl) throw (Overflow); 00074 int Put(const FV2::T& path, TextIntTbl /*INOUT*/ &tbl) throw (Overflow); 00075 /* Insert the pathname "path" into the table, and return its 00076 integer identifier. The "tbl" argument is a table maintained 00077 by the client. Exactly one "tbl" should be used with each 00078 "PrefixTbl". On the first call to "Put", "tbl" should be 00079 empty, and the client should not perform any other modifications 00080 on "tbl" asside from passing it to "Put". Once the client is 00081 done calling "Put", "tbl" can be disposed of. */ 00082 00083 FV2::T *Get(int idx) const throw (); 00084 /* Return the pathname with integer identifier "idx". */ 00085 00086 bool GetString(int idx, char *buff, int buff_len) const throw (); 00087 /* If the pathname with integer identifier "idx" does not exceed 00088 "buff_len" (including the null termination character at the end 00089 of the pathname), write that pathname into "buff" and return 00090 true. Otherwise, return false. In the latter case, some 00091 characters in "buff" may have been modified. */ 00092 00093 int MemorySize() const throw (); 00094 /* Return an upper bound on the size (in bytes) required to store 00095 this table in memory. */ 00096 00097 static int Skip(std::istream &ifs) throw (FS::EndOfFile, FS::Failure); 00098 /* Assumes "ifs" is positioned at a pickled "PrefixTbl". Skips 00099 over the table, and returns the number of bytes skipped. */ 00100 00101 // write/read 00102 void Write(std::ostream &ofs) const throw (FS::Failure); 00103 void Read(std::istream &ifs) throw (FS::EndOfFile, FS::Failure); 00104 00105 // logging/recovery 00106 void Log(VestaLog &log) const throw (VestaLog::Error); 00107 void Recover(RecoveryReader &rd) 00108 throw (VestaLog::Error, VestaLog::Eof); 00109 00110 // send/recv 00111 void Send(SRPC &srpc) const throw (SRPC::failure); 00112 void Recv(SRPC &srpc) throw (SRPC::failure); 00113 00114 // print 00115 void Print(std::ostream &os, int indent = 0) const throw (); 00116 /* Print a representation of this table to "os", indented by "indent" 00117 characters. */ 00118 00119 private: 00120 /* Invariants: 00121 I0. 0 <= numArcs <= maxArcs 00122 I2. maxArcs > 0 => length(indexArray) == length(arcArray) == maxArcs 00123 I3. maxArcs == 0 <==> ((indexArray == NULL) /\ (arcArray == NULL)) 00124 */ 00125 Basics::uint16 numArcs; // number of used table entries 00126 Basics::uint16 maxArcs; // maximum number of table entries 00127 Basics::uint16 *indexArray; // array for prefix indices 00128 Text *arcArray; // array for arcs 00129 00130 int AddArc(const Text& arc) throw (Overflow); 00131 /* Add the arc "arc" to the next position in "arcArray" (growing 00132 both "indexArray" and "arcArray" if necessary), and return its 00133 index in "arcArray". */ 00134 }; 00135 00136 #endif // _PREFIX_TBL_H