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

SMultiPKFileRep.H

Go to the documentation of this file.
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 // SMultiPKFileRep.H -- classes for reading/writing MultiPKFile header records 
00020 
00021 #ifndef _SMULTI_PK_FILE_REP_H
00022 #define _SMULTI_PK_FILE_REP_H
00023 
00024 #include <Basics.H>
00025 #include <FS.H>
00026 #include <Table.H>
00027 #include <FP.H>
00028 #include <BitVector.H>
00029 
00030 #include "SPKFileRep.H"
00031 #include "IntIntTblLR.H"
00032 #include "SPKFile.H"
00033 
00034 class SMultiPKFileRep {
00035 public:
00036   // type for offsets/lengths within a file
00037   typedef unsigned short UShort;
00038   typedef unsigned int UInt;
00039 
00040   // Exceptions
00041   class NotFound {};
00042   class BadMPKFile {}; // the file is not a valid MultiPKFile
00043 
00044   // <HeaderEntry> ----------------------------------------------------------
00045 
00046   class HeaderEntry {
00047   public:
00048     // constructors
00049     HeaderEntry() throw ()
00050       : pk(), offset(0), offsetLoc(0), pkLen(0), pkfile(NULL), pkhdr(NULL),
00051         pkfileModified(false), becameEmpty(false)
00052     { /*SKIP*/ }
00053     HeaderEntry(const FP::Tag &pk) throw ()
00054       : pk(pk), offset(0), offsetLoc(0), pkLen(0), pkfile(NULL),pkhdr(NULL),
00055         pkfileModified(false), becameEmpty(false)
00056     { /*SKIP*/ }
00057     HeaderEntry(std::ifstream &ifs) throw (FS::EndOfFile, FS::Failure)
00058       : pkLen(0), pkfile(NULL),
00059         pkfileModified(false), becameEmpty(false)
00060     { Read(ifs); }
00061     /* REQUIRES FS::Posn(ifs) == ``start of <HeaderEntry>'' */
00062 
00063     // read/write
00064     void Read(std::ifstream &ifs) throw (FS::EndOfFile, FS::Failure);
00065     /* REQUIRES FS::Posn(ifs) == ``start of <HeaderEntry>'' */
00066 
00067     void Write(std::ostream &ofs) throw (FS::Failure);
00068     /* REQUIRES FS::Posn(ofs) == ``start of <HeaderEntry>'' */
00069 
00070     // other methods
00071     static int Size() { return sizeof(FP::Tag) + sizeof(UInt); }
00072     /* Return the size of a "HeaderEntry" on disk. */
00073 
00074     bool SPKFileExists() const throw () { return offset != 0UL; }
00075     /* Return "true" iff this "HeaderEntry" was created for a real SPKFile
00076        in the MultiPKFile using the "HeaderEntry(ifstream)" constructor
00077        or the "Read(ifstream)" method. */
00078 
00079     void Debug(std::ostream &os, bool verbose = false) const throw ();
00080     /* By default, write a one-line elided representation of this
00081        <HeaderEntry> to "os". If "verbose" is true, write a complete,
00082        multi-line representation. */
00083 
00084     // disk data
00085     FP::Tag pk;
00086     UInt offset;                   // start of this PKFile w/in the MultiPKFile
00087 
00088     // auxiliary data -- not written to disk
00089     UInt offsetLoc;            // location of "offset" on disk
00090     UInt pkLen;            // length of this PKFile on disk
00091 
00092     // auxiliary SPKFile data
00093     SPKFile *pkfile;           // the corresponding PKFile...
00094     SPKFileRep::Header *pkhdr; // and its <CFPHeader> (for back-patching)
00095 
00096     /* The auxiliary SPKFile fields are not changed as part of the "Read"
00097        and "Write" methods. */
00098 
00099     // pkfile->Update results
00100     bool pkfileModified;           // was PKFile changed by "pkfile->Update"?
00101     BitVector *exCommonNames;  // ex-common names from updating
00102     BitVector *exUncommonNames;// ex-uncommon names from updating
00103     BitVector *packMask;       // packing bit vector for "allNames" indices
00104     IntIntTblLR *reMap;        // remapping of "allNames" indices
00105     bool becameEmpty;          // were all entries deleted?
00106 
00107     /* The "exCommonNames", "exUncommonNames", "packMask",
00108        "reMap", and "becameEmpty" fields are temporary values used
00109        to store the result of the "pkfile->Update" "OUT"
00110        variables. They are only valid if "pkfileModified" is
00111        true. */
00112   };
00113 
00114   // <Header> ---------------------------------------------------------------
00115 
00116   // dictionary types for Header
00117   typedef Table<FP::Tag,HeaderEntry*>::Default HdrEntryMap;
00118   typedef Table<FP::Tag,HeaderEntry*>::Iterator HdrEntryIter;
00119 
00120   // "Header.type" values
00121   enum HeaderType { HT_List, HT_SortedList, HT_HashTable, HT_Last };
00122 
00123   class Header {
00124   public:
00125     // constructors
00126     Header() throw ()
00127       : version(0), num(0), totalLen(0), type(HT_Last),
00128         lenOffset(0), pksLen(0) { /*SKIP*/ }
00129     Header(std::ifstream &ifs) throw (BadMPKFile, FS::EndOfFile, FS::Failure)
00130     { Read(ifs); }
00131     /* REQUIRES FS::Posn(ifs) == ``start of <Header>'' */
00132 
00133     // methods
00134     bool AppendNewHeaderEntry(const FP::Tag &pk) throw ();
00135     /* If there is no header entry in "pkTbl" under key "pk", create a new
00136        one for "pk", add it to the table, append it to the "pkSeq" array,
00137        and return "false". Otherwise, do nothing and return "true". */ 
00138 
00139     void RemoveHeaderEntry(const FP::Tag &pk) throw ();
00140     /* Remove "pk" from this header's "pkSeq" array, but not from its
00141        "pkTbl". It is a checked run-time error if "pk" does not occur in
00142        "pkSeq". This only modifies the locations of the entries in 
00143        the "pkSeq" array array above the one that is deleted. */
00144 
00145     // reading/writing
00146     void Read(std::ifstream &ifs) throw (BadMPKFile, FS::EndOfFile,FS::Failure);
00147     /* REQUIRES FS::Posn(ifs) == ``start of <Header>'' */
00148     /* Read the "Header" disk data from "ifs", i.e., the fields,
00149        "version", "num", "totalLen", and "type". The value of the
00150        auxilliary fields "lenOffset" and "pksLen" are also set. */ 
00151 
00152     void ReadEntries(std::ifstream &ifs) throw (FS::EndOfFile, FS::Failure);
00153     /* REQUIRES FS::Posn(ifs) == ``start of <TypedHeader>'' */
00154     /* Initialize the auxiliary fields "pkTbl" and "pkSeq" from "ifs" to
00155        contain a representation of this MultiPKFile's <HeaderEntry>
00156        records. This sets the "offsetLoc" and "pkLen" auxiliary fields
00157        of the "HeaderEntry" objects stored in "pkTbl", but not their
00158        "pkfile" or "pkhdr" fields. */ 
00159 
00160     void ReadPKFiles(std::ifstream &ifs) throw (FS::EndOfFile, FS::Failure);
00161     /* REQUIRES FS::Posn(ofs) == ``start of <PKFile>*'' */
00162     /* Read the <PKFile> records into the "pkfile" and "pkhdr" fields of
00163        the "HeaderEntry" records in "pkTbl" in the order specified by the
00164        "pks" array. */
00165 
00166     void Write(std::ostream &ofs) throw (FS::Failure);
00167     /* REQUIRES FS::Posn(ofs) == ``start of <Header>'' */
00168     /* Write the "Header" disk data to "ifs", i.e., the fields,
00169        "version", "num", "totalLen", and "type". The value of "lenOffset"
00170        is set to the location where the "totalLen" field was written. */ 
00171 
00172     void WriteEntries(std::ostream &ofs) throw (FS::Failure);
00173     /* REQUIRES FS::Posn(ofs) == ``start of <TypedHeader>'' */
00174     /* Write this MultiPKFile's <HeaderEntry> records to "ofs" according
00175        to the "pkTbl" and "pkSeq" fields. This may have the side-effect of
00176        permuting the PK's in the "pkSeq" array. It may also change the
00177        values of the "version and "type" fields. */
00178 
00179     void BackPatch(std::ostream &ofs) throw (FS::Failure);
00180     /* Back-patch the offsets and length values in this <Header> by
00181        seeking to their locations and writing their values to "ofs". The
00182        initial position of "ofs" is used as the value for the "totalLen"
00183        field. */
00184 
00185     // other methods
00186     int Size()
00187     { return sizeof(this->version) + sizeof(this->num)
00188         + sizeof(this->totalLen) + sizeof(this->type); }
00189 
00190     void Debug(std::ostream &os, bool verbose = false) const throw ();
00191     /* Write an ASCII representation of this <Header> and its
00192        <HeaderEntry> records to "os". This does not write the PKFile's
00193        themselves. If "verbose" is false, write a concise representation.
00194        Otherwise, write the complete values of the structures. */
00195 
00196     // pointer to a FP::Tag
00197     typedef FP::Tag *FPTagPtr;
00198 
00199     // disk data
00200     UShort version;    // version number of MultiPKFile file format
00201     UShort num;        // number of PKFile's within this MultiPKFile
00202     UInt totalLen;     // must be back-patched
00203     UShort type;       // header entry format type (list, hashtable, etc)
00204 
00205     // auxiliary data -- not written to disk
00206     UInt lenOffset;    // location of "totalLen" field
00207     UShort pksLen;     // size of "pkSeq" array; "pksLen >= num"
00208     FPTagPtr *pkSeq;   // an array of the PK's in "Domain(pkTbl)"
00209     HdrEntryMap pkTbl; // map of this MPKFile's PKFiles: PK -> HeaderEntry
00210 
00211     /* The "pkSeq" array records the *order* in which the <HeaderEntry>
00212        records (and hence the corresponding <PKFile> records) are written
00213        in the MultiPKFile. "pksLen" records the allocated size of the
00214        "pkSeq" array. */
00215 
00216   private:
00217     void ReadListV1(std::ifstream &ifs) throw (FS::EndOfFile, FS::Failure);
00218     /* REQUIRES FS::Posn(ifs) == ``start of <SeqHeader>'' */
00219     /* Read a list of "HeaderEntry"'s into this "Header"'s "pkTbl". */
00220 
00221     void WriteList(std::ostream &ofs) throw (FS::Failure);
00222     /* REQUIRES FS::Posn(ofs) == ``start of <TypedHeader>'' */
00223     /* Write the entries in this "Header"'s "pkTbl" to "ofs" as an
00224        unordered list. */
00225 
00226     void WriteSortedList(std::ostream &ofs) throw (FS::Failure);
00227     /* REQUIRES FS::Posn(ofs) == ``start of <TypedHeader>'' */
00228     /* Write the entries in this "Header"'s "pkTbl" to "ofs" is
00229        sorted order by PK. */
00230   };
00231 };
00232 
00233 #endif // _SMULTI_PK_FILE_REP_H

Generated on Mon May 8 00:48:35 2006 for Vesta by  doxygen 1.4.2