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