00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <Basics.H>
00023 #include <FS.H>
00024 #include <VestaLog.H>
00025 #include <Recovery.H>
00026 #include <FP.H>
00027 #include <BitVector.H>
00028 #include <Model.H>
00029 #include <CacheIndex.H>
00030 #include <VestaVal.H>
00031
00032 #include "IntIntTblLR.H"
00033 #include "Combine.H"
00034 #include "CacheEntry.H"
00035
00036 using std::istream;
00037 using std::ostream;
00038 using std::ifstream;
00039 using std::cout;
00040 using std::endl;
00041
00042
00043
00044
00045 static const CacheEntry::Index Index_MSB =
00046 (1 << ((sizeof(CacheEntry::Index) * 8) - 1));
00047
00048 CE::T::T(CacheEntry::Index ci, BitVector *uncommonNames, FP::List* fps,
00049 IntIntTblLR *imap, VestaVal::T *value, CacheEntry::Indices *kids,
00050 Model::T model) throw ()
00051
00052 : ci(ci), uncommonNames(uncommonNames), value(value), kids(kids),
00053 model(model), imap(imap), fps(fps)
00054 {
00055
00056 uncommonTag = Combine::XorFPTag(*fps, *uncommonNames, imap);
00057 }
00058
00059 CE::T::T(const T *ce) throw ()
00060
00061 : ci(ce->ci), uncommonTag(ce->uncommonTag), value(ce->value),
00062 kids(ce->kids), model(ce->model), fps(ce->fps)
00063 {
00064 this->uncommonNames = NEW_CONSTR(BitVector, (ce->uncommonNames));
00065 this->imap = (ce->imap == NULL) ? NULL : NEW_CONSTR(IntIntTblLR, (ce->imap));
00066 }
00067
00068 bool CE::T::FPMatch(const FP::List& pkFPs) throw ()
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 {
00082
00083 if (this->uncommonNames->Size() == 0) {
00084 return true;
00085 }
00086
00087
00088 Combine::XorFPTag tag(pkFPs, *(this->uncommonNames));
00089 if (tag.Xor() != this->uncommonTag.Xor()) {
00090
00091 return false;
00092 }
00093
00094
00095 if (tag.FPVal(pkFPs, *(this->uncommonNames)) !=
00096 uncommonTag.FPVal(*(this->fps), *(this->uncommonNames), this->imap)) {
00097
00098 return false;
00099 }
00100
00101
00102 return true;
00103 }
00104
00105 void CE::T::Pack(const BitVector *packMask, const IntIntTblLR *reMap) throw ()
00106
00107
00108 {
00109 assert((packMask == (BitVector *)NULL) == (reMap == (IntIntTblLR *)NULL));
00110 if (packMask != (BitVector *)NULL) {
00111
00112 uncommonNames->Pack(*packMask);
00113
00114
00115 if (this->imap != (IntIntTblLR *)NULL) {
00116 IntIntTblLR *imap2 = NEW_CONSTR(IntIntTblLR,
00117 (this->imap->ArraySize()));
00118 IntIntTblIter it(this->imap);
00119 short k, v, newK;
00120 while (it.Next( k, v)) {
00121 bool inTbl = reMap->Get(k, newK); assert(inTbl);
00122 inTbl = imap2->Put(newK, v); assert(!inTbl);
00123 }
00124 this->imap = imap2;
00125 imap2 = (IntIntTblLR *)NULL;
00126
00127
00128 int mapSz = this->imap->Size();
00129 for (k = 0; k < mapSz; k++) {
00130 if ((!(this->imap->Get(k, v))) || (k != v))
00131
00132 break;
00133 }
00134 if (k == mapSz) {
00135
00136 this->imap = (IntIntTblLR *)NULL;
00137 }
00138 }
00139 }
00140 }
00141
00142 void CE::T::CycleNames(const BitVector &delBV,
00143 const IntIntTblLR &delMap) throw ()
00144
00145 {
00146 assert((uncommonNames != NULL) && (!delBV.IsEmpty()));
00147
00148
00149 if (this->imap == (IntIntTblLR *)NULL) {
00150 this->imap = NEW_CONSTR(IntIntTblLR, (fps->len));
00151 for (short k = 0; k < fps->len; k++) {
00152 bool inTbl = this->imap->Put(k, k); assert(!inTbl);
00153 }
00154 }
00155
00156
00157 BVIter it(&delBV); int oldBx; short newBx;
00158 while (it.Next( oldBx)) {
00159
00160 bool inTbl = delMap.Get(oldBx, newBx); assert(inTbl);
00161 bool set = this->uncommonNames->Reset(oldBx); assert(set);
00162 set = this->uncommonNames->Set(newBx); assert(!set);
00163
00164
00165 short fpIndex;
00166 inTbl = this->imap->Delete(oldBx, fpIndex); assert(inTbl);
00167 inTbl = this->imap->Put(newBx, fpIndex); assert(!inTbl);
00168 }
00169
00170
00171
00172
00173
00174 this->uncommonTag.InvalidateFPVal();
00175 }
00176
00177 void CE::T::Update(const BitVector *exCommonNames,
00178 const BitVector *exUncommonNames, const BitVector *packMask,
00179 const IntIntTblLR *reMap) throw ()
00180
00181
00182 {
00183 if (exCommonNames != NULL || exUncommonNames != NULL) {
00184
00185 if (exCommonNames != (BitVector *)NULL)
00186 *(this->uncommonNames) |= *exCommonNames;
00187 if (exUncommonNames != (BitVector *)NULL)
00188 *(this->uncommonNames) -= *exUncommonNames;
00189
00190
00191 this->uncommonTag.Init(*(this->fps),
00192 *(this->uncommonNames), this->imap);
00193 }
00194
00195
00196 Pack(packMask, reMap);
00197 }
00198
00199 void CE::T::XorUncommonNames(const BitVector &mask) throw ()
00200
00201 {
00202 *(this->uncommonNames) ^= mask;
00203 this->uncommonTag.Init(*(this->fps), *(this->uncommonNames), this->imap);
00204 }
00205
00206
00207
00208
00209 bool CE::T::CheckUsedNames(const BitVector *commonNames,
00210 const BitVector *uncommonNames,
00211 const IntIntTblLR* imap,
00212 const FP::List *fps,
00213 unsigned int &missing)
00214 throw ()
00215 {
00216 if(imap != 0)
00217 {
00218 IntIntTblIter it(imap);
00219 short k, v;
00220 while (it.Next( k, v))
00221 {
00222
00223
00224 if(((commonNames == 0) || !commonNames->Read(k)) &&
00225 ((uncommonNames == 0) || !uncommonNames->Read(k)))
00226 {
00227 missing = k;
00228 return true;
00229 }
00230 }
00231 }
00232
00233
00234 else if(fps != 0)
00235 {
00236 for(unsigned int i = 0; i < fps->len; i++)
00237 {
00238
00239
00240 if(((commonNames == 0) || !commonNames->Read(i)) &&
00241 ((uncommonNames == 0) || !uncommonNames->Read(i)))
00242 {
00243 missing = i;
00244 return true;
00245 }
00246 }
00247 }
00248
00249
00250 return false;
00251 }
00252
00253 void CE::T::Log(VestaLog& log) const
00254 throw (VestaLog::Error)
00255
00256 {
00257 log.write((char *)(&(this->ci)), sizeof(this->ci));
00258 this->uncommonNames->Log(log);
00259 if (this->uncommonNames->Size() > 0) {
00260 this->uncommonTag.Log(log);
00261 }
00262 this->value->Log(log);
00263 this->kids->Log(log);
00264 Model::Log(this->model, log);
00265 if (this->imap == (IntIntTblLR *)NULL) {
00266 IntIntTblLR empty;
00267 empty.Log(log);
00268 } else {
00269 this->imap->Log(log);
00270 }
00271 this->fps->Log(log);
00272 }
00273
00274 void CE::T::Recover(RecoveryReader &rd)
00275 throw (VestaLog::Error, VestaLog::Eof)
00276
00277 {
00278 rd.readAll((char *)(&(this->ci)), sizeof(this->ci));
00279 this->uncommonNames = NEW_CONSTR(BitVector, (rd));
00280 if (this->uncommonNames->Size() > 0) {
00281 this->uncommonTag.Recover(rd);
00282 } else {
00283 this->uncommonTag.Zero();
00284 }
00285 this->value = NEW_CONSTR(VestaVal::T, (rd));
00286 this->kids = NEW_CONSTR(CacheEntry::Indices, (rd));
00287 Model::Recover( this->model, rd);
00288 this->imap = NEW_CONSTR(IntIntTblLR, (rd));
00289 if (this->imap->Size() == 0) {
00290
00291 this->imap = (IntIntTblLR *)NULL;
00292 }
00293 this->fps = NEW_CONSTR(FP::List, (rd));
00294 }
00295
00296 void CE::T::Write(ostream &ofs, ifstream *ifs) const throw (FS::Failure)
00297
00298 {
00299
00300 CacheEntry::Index ciToWrite = this->ci;
00301 if (ciToWrite & Index_MSB) {
00302
00303 ciToWrite &= (~Index_MSB);
00304 }
00305 assert(!(ciToWrite & Index_MSB));
00306 FS::Write(ofs, (char *)(&ciToWrite), sizeof(ciToWrite));
00307 this->uncommonNames->Write(ofs);
00308 if (this->uncommonNames->Size() > 0) {
00309 this->uncommonTag.Write(ofs);
00310 }
00311 if (this->ci & Index_MSB) {
00312
00313 assert(ifs != (ifstream *)NULL);
00314 ((ImmutableVal *)(this->value))->Copy(*ifs, ofs);
00315 ((ImmutableVal *)(this->kids))->Copy(*ifs, ofs);
00316 } else {
00317
00318 this->value->Write(ofs);
00319 this->kids->Write(ofs);
00320 }
00321 Model::Write(this->model, ofs);
00322 }
00323
00324 void CE::T::Read(istream &ifs, bool readImmutable)
00325 throw (FS::EndOfFile, FS::Failure)
00326
00327 {
00328
00329 FS::Read(ifs, (char *)(&(this->ci)), sizeof(this->ci));
00330 this->uncommonNames = NEW_CONSTR(BitVector, (ifs));
00331 if (this->uncommonNames->Size() > 0) {
00332 this->uncommonTag.Read(ifs);
00333 } else {
00334 this->uncommonTag.Zero();
00335 }
00336 if (readImmutable) {
00337 this->value = NEW_CONSTR(VestaVal::T, (ifs));
00338 this->kids = NEW_CONSTR(CacheEntry::Indices, (ifs));
00339 } else {
00340 assert(!(this->ci & Index_MSB));
00341 this->ci |= Index_MSB;
00342 this->value = (VestaVal::T *)(VestaVal::T::ReadImmutable(ifs));
00343 this->kids = (CacheEntry::Indices *)
00344 (CacheEntry::Indices::ReadImmutable(ifs));
00345 }
00346 Model::Read( this->model, ifs);
00347
00348
00349 this->imap = (IntIntTblLR *)NULL;
00350 this->fps = (FP::List *)NULL;
00351 }
00352
00353 void CE::T::WriteExtras(ostream &ofs) const throw (FS::Failure)
00354
00355 {
00356 if (this->imap == (IntIntTblLR *)NULL) {
00357 IntIntTblLR empty;
00358 empty.Write(ofs);
00359 } else {
00360 this->imap->Write(ofs);
00361 }
00362 this->fps->Write(ofs);
00363 }
00364
00365 void CE::T::ReadExtras(istream &ifs) throw (FS::EndOfFile, FS::Failure)
00366
00367 {
00368 this->imap = NEW_CONSTR(IntIntTblLR, (ifs));
00369 if (this->imap->Size() == 0) {
00370
00371 this->imap = (IntIntTblLR *)NULL;
00372 }
00373 this->fps = NEW_CONSTR(FP::List, (ifs));
00374 }
00375
00376 inline void Indent(ostream &os, int indent) throw ()
00377 {
00378 for (int i = 0; i < indent; i++) os << " ";
00379 }
00380
00381 void CE::T::Debug(ostream &os, int indent) const throw ()
00382
00383 {
00384 Indent(os, indent); os << "ci = " << this->ci << endl;
00385 Indent(os, indent); os << "unFVs = {" << endl;
00386 this->uncommonNames->PrintAll(cout, indent+4);
00387 Indent(os, indent); os << " } ("
00388 << this->uncommonNames->Cardinality() << " total)"
00389 << endl;
00390 if (this->uncommonNames->Size() > 0) {
00391 Indent(os, indent);
00392 os << "unTag =" << endl; this->uncommonTag.Debug(os, indent+2);
00393 os << endl;
00394 }
00395 Indent(os, indent);
00396 os << "value =" << endl; this->value->Print(os, indent + 2);
00397 Indent(os, indent); os << "kids = "; this->kids->Print(os, indent + 2);
00398 Indent(os, indent); os << "model = " << this->model << endl;
00399 }
00400
00401 void CE::T::DebugExtras(ostream &os, int indent) const throw ()
00402
00403 {
00404 Indent(os, indent); os << "imap = ";
00405 if (this->imap == (IntIntTblLR *)NULL) {
00406 os << "<identity-map>" << endl;
00407 } else {
00408 this->imap->Print(os, indent+2);
00409 }
00410 Indent(os, indent);
00411 os << "fps =" << endl; this->fps->Print(os, indent + 2);
00412 }
00413
00414 unsigned CE::List::Length(const List *list) throw ()
00415 {
00416 unsigned res = 0;
00417 for (; list != (List *)NULL; list = list->tail) res++;
00418 return res;
00419 }