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 Thu Aug 5 01:44:33 EDT 2004 by ken@xorian.net 00020 // modified on Mon Nov 10 13:11:07 PST 1997 by heydon 00021 00022 // Combine.H -- defines classes for combining a sequence of Fingerprints 00023 00024 #ifndef _COMBINE_H 00025 #define _COMBINE_H 00026 00027 #include <Basics.H> 00028 #include <FS.H> 00029 #include <VestaLog.H> 00030 #include <Recovery.H> 00031 #include <FP.H> 00032 #include <BitVector.H> 00033 00034 #include "IntIntTblLR.H" 00035 00036 namespace Combine 00037 { 00038 /* The first two classes --- "XorTag" and "FPTag" --- are really private 00039 to clients. */ 00040 00041 // XorTag -- The result of XOR'ing together some Fingerprint tags 00042 // 00043 /* The value "w" of an "XorTag" is produced by XOR'ing together a sequence 00044 of Fingerprint tags (wordwise), and then XOR'ing the resulting words 00045 together into a single word. 00046 */ 00047 class XorTag { 00048 public: 00049 // constructors 00050 XorTag() { /*SKIP*/ } 00051 XorTag(const FP::List& pkFPs, BitVector& bv, 00052 const IntIntTblLR *imap = NULL) throw (); 00053 /* Initialize the "XorTag" as the exclusive OR of the fingerprints 00054 "pkFPs.fp[imap(i)]" such that "bv.Read(i)". If "imap" is NULL, 00055 use the identity map. */ 00056 00057 // log/recover 00058 void Log(VestaLog &log) const throw (VestaLog::Error) 00059 { log.write((char *)(&(this->w)), sizeof(this->w)); } 00060 void Recover(RecoveryReader &rd) throw (VestaLog::Error, VestaLog::Eof) 00061 { rd.readAll((char *)(&(this->w)), sizeof(this->w)); } 00062 00063 // write/read 00064 void Write(std::ostream &ofs) const throw (FS::Failure) 00065 { FS::Write(ofs, (char *)(&(this->w)), sizeof(this->w)); } 00066 void Read(std::istream &ifs) throw (FS::EndOfFile, FS::Failure) 00067 { FS::Read(ifs, (char *)(&(this->w)), sizeof(this->w)); } 00068 void Debug(std::ostream &os) const throw (); 00069 00070 // other operators 00071 XorTag& operator ^= (const FP::Tag& fp) throw () 00072 { this->w ^= fp.Hash(); return *this; } 00073 bool operator == (const XorTag& other) throw () 00074 { return this->w == other.w; } 00075 bool operator != (const XorTag& other) throw () 00076 { return this->w != other.w; } 00077 00078 // data 00079 Word w; 00080 }; // XorTag 00081 00082 // "FPTag" -- a combined fingerprint 00083 // 00084 class FPTag : public FP::Tag { 00085 public: 00086 // constructors 00087 FPTag() { /*SKIP*/ } 00088 FPTag(const FP::List& fps, const BitVector& bv, 00089 const IntIntTblLR *imap = NULL) throw (); 00090 /* Initialize this fingerprint to the combined fingerprint of the 00091 words "fps[imap(i)].w" such that "bv.Read(i)". The fingerprint is 00092 combined in the order determined by increasing values of "i". 00093 If "imap == NULL", the identity map is used. */ 00094 }; // FPTag 00095 00096 // XorFPTag -- A combination of an XorTag and an FPTag. 00097 // 00098 /* The "XorFPTag" type is a tag of a sequence of "FP::Tag"'s. An 00099 "XorFPTag" value has two logical fields: an exclusive OR of the 00100 fingerprint word, and the combined fingerprint of the words. Both 00101 are available through methods. 00102 */ 00103 class XorFPTag { 00104 public: 00105 enum { LSB = 0x1 }; 00106 00107 // constructors 00108 XorFPTag() throw () 00109 { /* SKIP */ }; 00110 XorFPTag(RecoveryReader &rd) throw (VestaLog::Error, VestaLog::Eof) 00111 { Recover(rd); } 00112 XorFPTag(const FP::List& fps, const BitVector& bv, 00113 const IntIntTblLR *imap = NULL) throw () 00114 { Init(fps, bv, imap); } 00115 void Zero() throw () { this->xort.w = 0; } 00116 void Init(const FP::List& fps, const BitVector& bv, 00117 const IntIntTblLR *imap = NULL) throw (); 00118 /* Initialize the "xort" field to be the exclusive OR of the words 00119 "fps[imap(i)].w" such that "bv.Read(i)". If "imap == NULL", the 00120 identity map is used. */ 00121 00122 Word Xor() throw () { return this->xort.w | LSB; } 00123 /* Return the "Xor" part of this object. */ 00124 00125 FP::Tag& FPVal(const FP::List &fps, const BitVector &bv, 00126 const IntIntTblLR *imap = NULL) throw (); 00127 /* Return the combined fingerprint of the words "fps[imap(i)].w" such 00128 that "bv.Read(i)". The fingerprint is combined in the order 00129 determined by increasing values of "i". If "imap == NULL", the 00130 identity map is used. If this tag's fingerprint value was lazy, 00131 this method has the benevolent side-effect of unlazying it. */ 00132 00133 void UnlazyFPVal(const FP::List &fps, const BitVector &bv, 00134 const IntIntTblLR *imap = NULL) throw () 00135 { (void) FPVal(fps, bv, imap); } 00136 /* If this tag's fingerprint value is lazy, unlazy it according to 00137 the "FPVal" method above. */ 00138 00139 void InvalidateFPVal() throw () { this->xort.w &= ~LSB; } 00140 /* Invalidate the fingerprint for this tag because the *order* of 00141 the fingerprints used to compute it has changed. */ 00142 00143 bool FPValIsUnlazied() throw () { return this->xort.w & LSB; } 00144 /* Return true iff the combined fingerprint has been computed. */ 00145 00146 void Log(VestaLog &log) const throw (VestaLog::Error); 00147 /* Append this tag to "log", which must be in the "logging" state. */ 00148 00149 void Recover(RecoveryReader &rd) 00150 throw (VestaLog::Error, VestaLog::Eof); 00151 /* Recover this tag from "rd". */ 00152 00153 void Write(std::ostream &ofs) const throw (FS::Failure); 00154 void Read(std::istream &ifs) throw (FS::EndOfFile, FS::Failure); 00155 /* Write/read this XorFPTag to/from "ofs"/"ifs". */ 00156 00157 void Debug(std::ostream &os, int indent = 2) const throw (); 00158 /* Write debugging information to "os"; does not end in newline. */ 00159 00160 private: 00161 XorTag xort; // exclusive OR of fingerprint tags 00162 FP::Tag fp; // combined FP 00163 00164 /* Note: The least-significant bit of "xort.w" is not the XOR, but 00165 instead indicates if "fp" is valid or not. Hence, the "Xor" method 00166 always returns a value that has its least-significant bit set. */ 00167 }; // XorFPTag 00168 } 00169 00170 #endif // _COMBINE_H