00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <Basics.H>
00024 #include <IntKey.H>
00025 #include <FS.H>
00026 #include <Sequence.H>
00027 #include <Generics.H>
00028
00029
00030 #include <SRPC.H>
00031
00032
00033 #include <FP.H>
00034
00035
00036 #include <PKPrefix.H>
00037 #include <BitVector.H>
00038 #include <CacheIntf.H>
00039 #include <Debug.H>
00040 #include <CacheState.H>
00041 #include <Model.H>
00042 #include <PKEpoch.H>
00043 #include <CacheIndex.H>
00044 #include <FV.H>
00045 #include <VestaVal.H>
00046
00047
00048 #include "CacheConfigServer.H"
00049 #include "IntIntTblLR.H"
00050 #include "Combine.H"
00051 #include "CacheEntry.H"
00052 #include "VPKFileChkPt.H"
00053 #include "SPKFile.H"
00054 #include "VPKFile.H"
00055 #include "SMultiPKFile.H"
00056
00057 using std::streampos;
00058 using std::ifstream;
00059 using std::cerr;
00060 using std::cout;
00061 using std::endl;
00062
00063 VPKFile::VPKFile(const FP::Tag &pk,
00064 PKFile::Epoch newPKEpoch, FV::Epoch newNamesEpoch) throw (FS::Failure)
00065 : SPKFile(pk), newUncommon((CE::List *)NULL), freePKFileEpoch(-1),
00066 evicted(false)
00067 {
00068 try {
00069
00070 this->ReadPKFHeaderTail(pk);
00071
00072
00073 for (int i = 0; i < this->allNames.len; i++) {
00074 bool inMap = this->nameMap.Put(this->allNames.name[i], i);
00075 assert(!inMap);
00076 }
00077 this->isEmpty = false;
00078 }
00079 catch (SMultiPKFileRep::NotFound) {
00080
00081 this->pkEpoch = newPKEpoch;
00082 this->namesEpoch = newNamesEpoch;
00083 this->isEmpty = true;
00084 }
00085 }
00086
00087 void VPKFile::ReadPKFHeaderTail(const FP::Tag &pk)
00088 throw (FS::Failure, SMultiPKFileRep::NotFound)
00089 {
00090 PKPrefix::T pfx(pk);
00091 try {
00092
00093 ifstream ifs;
00094 SMultiPKFile::OpenRead(pfx, ifs);
00095 int version;
00096 try {
00097 streampos origin =
00098 SMultiPKFile::SeekToPKFile(ifs, pk, version);
00099
00100
00101 SPKFileRep::Header *dummy;
00102 this->Read(ifs, origin, version,
00103 dummy, false);
00104 } catch (...) { FS::Close(ifs); throw; }
00105 FS::Close(ifs);
00106 }
00107 catch (FS::EndOfFile) {
00108
00109 cerr << "Fatal error: premature EOF in MultiPKFile " << pfx
00110 << "; crashing..." << endl;
00111 assert(false);
00112 }
00113 }
00114
00115 bool VPKFile::IsEmpty() throw ()
00116
00117 {
00118 bool res;
00119 this->mu.lock();
00120 res = ((this->oldEntries.Size() == 0) && (this->newCommon.Size() == 0)
00121 && (this->newUncommon == (CE::List *)NULL));
00122 this->mu.unlock();
00123 return res;
00124 }
00125
00126 static void Etp_CacheS_FreeVariables(int num_names, int sz) throw ()
00127
00128
00129
00130
00131 { }
00132
00133 void VPKFile::SendAllNames(SRPC *srpc, bool debug)
00134 throw (SRPC::failure, PrefixTbl::Overflow)
00135
00136 {
00137 this->mu.lock();
00138
00139
00140 if (debug) {
00141 Debug::Lock();
00142 cout << Debug::Timestamp() << "RETURNED -- FreeVariables" << endl;
00143 cout << " epoch = " << this->namesEpoch << endl;
00144 cout << " isEmpty = " << BoolName[this->isEmpty] << endl;
00145 cout << " names =" << endl; this->allNames.Print(cout, 4);
00146 cout << endl;
00147 Debug::Unlock();
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 Etp_CacheS_FreeVariables(this->allNames.len, this->allNames.CheapSize());
00160
00161
00162 try {
00163 srpc->send_int((int)this->isEmpty);
00164 this->allNames.Send(*srpc);
00165 srpc->send_int((int)this->namesEpoch);
00166 } catch (...) { this->mu.unlock(); throw; }
00167 this->mu.unlock();
00168 }
00169
00170 CacheIntf::LookupRes VPKFile::Lookup(FV::Epoch id, const FP::List &fps,
00171 CacheEntry::Index &ci, const VestaVal::T* &value,
00172 CacheIntf::LookupOutcome &outcome) throw (FS::Failure)
00173
00174 {
00175 CacheIntf::LookupRes res = CacheIntf::Miss;
00176 CE::T *ce = (CE::T *)NULL;
00177
00178
00179 outcome = CacheIntf::AllMisses;
00180
00181
00182 if (namesEpoch != id) {
00183
00184 res = (namesEpoch < id)
00185 ? CacheIntf::BadLookupArgs
00186 : CacheIntf::FVMismatch;
00187 outcome = CacheIntf::NoOutcome;
00188 } else if (fps.len != allNames.len) {
00189
00190 outcome = CacheIntf::NoOutcome;
00191 res = CacheIntf::BadLookupArgs;
00192 } else {
00193
00194 CE::List *list;
00195 Combine::FPTag commonTag(fps, this->commonNames);
00196
00197 if (this->newCommon.Get(commonTag, list)
00198 && ((ce = LookupInList(list, fps)) != NULL)) {
00199 outcome = CacheIntf::NewHits;
00200 res = CacheIntf::Hit;
00201 }
00202
00203 else if ((ce = LookupInList(this->newUncommon, fps)) != NULL) {
00204 outcome = CacheIntf::NewHits;
00205 res = CacheIntf::Hit;
00206 }
00207
00208 else if (this->oldEntries.Get(commonTag, list)
00209 && ((ce = LookupInList(list, fps)) != NULL)) {
00210 outcome = CacheIntf::WarmHits;
00211 res = CacheIntf::Hit;
00212 }
00213
00214 else {
00215 PKPrefix::T pfx(pk);
00216 try {
00217
00218 ifstream ifs;
00219 SMultiPKFile::OpenRead(pfx, ifs);
00220 int version;
00221 try {
00222 streampos origin =
00223 SMultiPKFile::SeekToPKFile(ifs, pk, version);
00224 ce = SPKFile::Lookup(ifs, origin, version, commonTag, fps);
00225 } catch (...) { FS::Close(ifs); throw; }
00226 FS::Close(ifs);
00227
00228 if (ce != (CE::T *)NULL) {
00229 outcome = CacheIntf::DiskHits;
00230 res = CacheIntf::Hit;
00231
00232
00233 this->AddEntryToTable( this->oldEntries,
00234 commonTag, ce);
00235 }
00236 }
00237 catch (SMultiPKFileRep::NotFound) {
00238
00239
00240 }
00241 catch (FS::EndOfFile) {
00242
00243 cerr << "Fatal error: premature EOF in MultiPKFile " << pfx
00244 << "; crashing..." << endl;
00245 assert(false);
00246 }
00247 }
00248 if (res == CacheIntf::Hit) {
00249
00250 assert(ce != (CE::T *)NULL);
00251 ci = ce->CI();
00252 value = ce->Value();
00253 }
00254 }
00255
00256 return res;
00257 }
00258
00259 CE::T* VPKFile::LookupInList(const CE::List *entries, const FP::List &fps)
00260 throw ()
00261
00262 {
00263 for (const CE::List *curr = entries; curr != NULL; curr = curr->Tail()) {
00264 CE::T *ce = curr->Head();
00265 if (ce->FPMatch(fps)) {
00266 return ce;
00267 }
00268 }
00269 return (CE::T *)NULL;
00270 }
00271
00272 CE::T* VPKFile::NewEntry(CacheEntry::Index ci, FV::List* names, FP::List *fps,
00273 VestaVal::T* value, Model::T model, CacheEntry::Indices* kids,
00274 FP::Tag* &commonFP)
00275 throw (DuplicateNames)
00276
00277 {
00278 assert(names->len == fps->len);
00279 bool newNames = false;
00280
00281
00282 BitVector *namesBV = NEW_CONSTR(BitVector,
00283 ( this->allNames.len));
00284
00285
00286
00287
00288 IntIntTblLR *imap = (IntIntTblLR *)NULL;
00289
00290
00291
00292
00293
00294
00295
00296 for (int i = 0; i < names->len; i++) {
00297 int index;
00298 FV::T *name = &(names->name[i]);
00299 if (!(this->nameMap.Get(*name, index))) {
00300
00301 index = this->allNames.Append(*name);
00302 newNames = true;
00303 bool inMap = this->nameMap.Put(*name, index); assert(!inMap);
00304 }
00305 if (namesBV->Set(index)) throw DuplicateNames();
00306 if ((imap == (IntIntTblLR *)NULL) && (index != i)) {
00307
00308 imap = NEW_CONSTR(IntIntTblLR, (names->len));
00309 for (short k = 0; k < i; k++) {
00310 bool inMap = imap->Put(k, k); assert(!inMap);
00311 }
00312 }
00313 if (imap != (IntIntTblLR *)NULL) {
00314 bool inMap = imap->Put(index, i); assert(!inMap);
00315 }
00316 }
00317
00318
00319 if (newNames) {
00320 this->namesEpoch++;
00321 }
00322
00323
00324 delete names;
00325
00326
00327 BitVector *uncommonNames = NEW_CONSTR(BitVector, (namesBV));
00328 commonFP = (FP::Tag *)NULL;
00329 if (this->IsCommon(*uncommonNames)) {
00330 *uncommonNames -= this->commonNames;
00331 commonFP = NEW_PTRFREE_CONSTR(Combine::FPTag, (*fps, this->commonNames, imap));
00332 }
00333
00334
00335 return NEW_CONSTR(CE::T,
00336 (ci, uncommonNames, fps, imap, value, kids, model));
00337 }
00338
00339 void VPKFile::AddEntry(const Text* sourceFunc, CE::T* ce, FP::Tag* commonFP,
00340 PKFile::Epoch newPKEpoch) throw ()
00341
00342 {
00343
00344 if (newPKEpoch != -1) {
00345 assert(newPKEpoch >= this->pkEpoch);
00346 this->pkEpoch = newPKEpoch;
00347 }
00348
00349
00350 if (this->sourceFunc == (Text *)NULL) {
00351 this->sourceFunc = sourceFunc;
00352 }
00353
00354
00355 if (commonFP == (FP::Tag*)NULL) {
00356 this->newUncommon = NEW_CONSTR(CE::List, (ce, this->newUncommon));
00357 } else {
00358 this->AddEntryToTable( this->newCommon, *commonFP, ce);
00359 }
00360
00361
00362 this->isEmpty = false;
00363 }
00364
00365 static CE::List* VPKFile_ChkptEntryList(CE::List *entries) throw ()
00366
00367 {
00368 CE::List *res = (CE::List *)NULL;
00369 for (CE::List *curr = entries; curr != NULL; curr = curr->Tail()) {
00370 CE::T *newCE = NEW_CONSTR(CE::T, (curr->Head()));
00371 res = NEW_CONSTR(CE::List, (newCE, res));
00372 }
00373 return res;
00374 }
00375
00376 static void VPKFile_ChkptEntryTbl(const SPKFile::CFPEntryMap &inTbl,
00377 SPKFile::CFPEntryMap &outTbl) throw ()
00378 {
00379 FP::Tag cfp;
00380 CE::List *oldEntries;
00381 SPKFile::CFPEntryIter it(&inTbl);
00382 while (it.Next( cfp, oldEntries)) {
00383 CE::List *newEntries = VPKFile_ChkptEntryList(oldEntries);
00384 bool inTbl = outTbl.Put(cfp, newEntries, false);
00385 assert(!inTbl);
00386 }
00387 outTbl.Resize();
00388 }
00389
00390 VPKFileChkPt *VPKFile::CheckPoint() throw ()
00391
00392 {
00393 this->mu.lock();
00394
00395 VPKFileChkPt *res = SPKFile::CheckPoint();
00396
00397
00398 res->newUncommon = VPKFile_ChkptEntryList(this->newUncommon);
00399 if (this->newCommon.Size() > 0) {
00400 VPKFile_ChkptEntryTbl(this->newCommon, res->newCommon);
00401 }
00402 res->newUncommonHead = this->newUncommon;
00403 res->newCommonHeads = this->newCommon;
00404 res->hasNewEntries = this->HasNewEntries();
00405
00406
00407
00408 this->pkEpoch++;
00409 this->mu.unlock();
00410 return res;
00411 }
00412
00413
00414
00415 void VPKFile::Update(const SPKFile &pf,
00416 const VPKFileChkPt &chkpt, const BitVector *toDelete,
00417 const BitVector *exCommonNames, const BitVector *exUncommonNames,
00418 BitVector *packMask, IntIntTblLR *reMap, bool becameEmpty,
00419 EntryState &state) throw ()
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 {
00481
00482 if (chkpt.hasNewEntries) {
00483 DeleteCheckpointedEntries(chkpt, state);
00484 }
00485
00487
00488
00489
00490
00491 if (packMask != (BitVector *)NULL) {
00492
00493
00494 if (this->allNames.len > chkpt.allNamesLen) {
00495
00496 int lastBx = packMask->MSB();
00497 packMask->SetInterval(chkpt.allNamesLen, this->allNames.len-1);
00498
00499
00500 assert(reMap != (IntIntTblLR *)NULL);
00501 short nextBx = -1;
00502 (void) reMap->Get(lastBx, nextBx); nextBx++;
00503 for (int i = chkpt.allNamesLen; i < this->allNames.len; i++) {
00504 bool inTbl = reMap->Put(i, nextBx++); assert(!inTbl);
00505 }
00506 }
00507 }
00508
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 IntIntTbl keepCIs( 0, true);
00520
00521
00522 if (Config_KeepNewOnFlush && chkpt.hasNewEntries) {
00523 RecordCIsFromList(chkpt.newUncommon, keepCIs);
00524 RecordCIsFromTbl(chkpt.newCommon, keepCIs);
00525 }
00526
00527
00528 if (Config_KeepOldOnFlush) {
00529 RecordCIsFromTbl(this->oldEntries, keepCIs);
00530 }
00531
00532
00533
00534 int sizeHint = max(this->oldEntries.Size(), keepCIs.Size());
00535 this->DeleteOldEntries(sizeHint, state);
00536 if (keepCIs.Size() > 0) {
00537 this->CopyByCIs(pf.OldEntries(), keepCIs, state);
00538 }
00539
00541
00542 bool commonNamesChanged = ((exCommonNames != (BitVector *)NULL)
00543 || (exUncommonNames != (BitVector *)NULL));
00544 if (commonNamesChanged || (toDelete != (BitVector *)NULL)) {
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 if (this->newCommon.Size() > 0) {
00565
00566
00567
00568 MoveCommonToUncommon(this->commonNames);
00569 }
00570
00571 if (commonNamesChanged) {
00572
00573 if (exCommonNames != (BitVector *)NULL)
00574 this->commonNames ^= *exCommonNames;
00575 if (exUncommonNames != (BitVector *)NULL)
00576 this->commonNames ^= *exUncommonNames;
00577 }
00578 if (packMask != (BitVector *)NULL) {
00579
00580 BitVector temp(&(this->commonNames)); temp -= *packMask;
00581 assert(temp.IsEmpty());
00582 }
00583
00584
00585
00586
00587
00588
00589 if (this->newUncommon != (CE::List *)NULL) {
00590 UpdateUncommonList(chkpt.sourceFunc, packMask,
00591 reMap, false);
00592 }
00593
00594
00595 this->commonNames.Pack(packMask);
00596 assert(this->commonNames == pf.CommonNames());
00597
00598
00599 if (packMask != (BitVector *)NULL) {
00600 this->allNames.Pack(*packMask);
00601 this->namesEpoch++;
00602
00603
00604 this->nameMap.Init( this->allNames.len);
00605 for (int i = 0; i < this->allNames.len; i++) {
00606 bool inTbl = nameMap.Put(this->allNames.name[i], i);
00607 assert(!inTbl);
00608 }
00609 }
00610 }
00611
00613
00614
00615 if(becameEmpty && !this->HasNewEntries())
00616 {
00617
00618 this->isEmpty = true;
00619
00620
00621 assert(toDelete != (BitVector *)NULL);
00622
00623
00624 assert(this->oldEntries.Size() == 0);
00625 }
00626
00627 }
00628
00629 static void VPKFile_TruncateList( CE::List* &head,
00630 const CE::List *tail, EntryState &state) throw ()
00631
00632
00633
00634
00635
00636
00637 {
00638 if (tail != (CE::List *)NULL) {
00639
00640 assert(head != (CE::List *)NULL);
00641 CE::List *curr, *prev = (CE::List *)NULL;
00642 for (curr = head; curr != tail; curr = curr->Tail()) {
00643 prev = curr;
00644 }
00645
00646
00647 if (prev == (CE::List *)NULL) {
00648 assert(head == tail);
00649 head = (CE::List *)NULL;
00650 } else {
00651 prev->SetTail((CE::List *)NULL);
00652 }
00653
00654
00655 for (; curr != (CE::List *)NULL; curr = curr->Tail()) {
00656 state.newEntryCnt--;
00657 state.newPklSize -= curr->Head()->Value()->len;
00658 }
00659 }
00660 }
00661
00662 void VPKFile::DeleteCheckpointedEntries(const VPKFileChkPt &chkpt,
00663 EntryState &state) throw ()
00664
00665 {
00666
00667 VPKFile_TruncateList(this->newUncommon,
00668 chkpt.newUncommonHead, state);
00669
00670
00671 if (chkpt.newCommonHeads.Size() > 0) {
00672
00673
00674
00675 CFPEntryIter iter(&(chkpt.newCommonHeads));
00676 FP::Tag key; CE::List *tail;
00677 while (iter.Next( key, tail)) {
00678 CE::List *head;
00679 bool inTbl = this->newCommon.Get(key, head);
00680 assert(inTbl && head != (CE::List *)NULL);
00681 VPKFile_TruncateList( head, tail, state);
00682 if (head == (CE::List *)NULL) {
00683 this->newCommon.Delete(key, tail, false);
00684 assert(inTbl);
00685 }
00686 }
00687 this->newCommon.Resize();
00688 }
00689 }
00690
00691 void VPKFile::DeleteOldEntries(int sizeHint, EntryState &state)
00692 throw ()
00693
00694 {
00695
00696 CFPEntryIter iter(&(this->oldEntries));
00697 FP::Tag key; CE::List *curr;
00698 while (iter.Next( key, curr)) {
00699 for (; curr != (CE::List *)NULL; curr = curr->Tail()) {
00700 state.oldEntryCnt--;
00701 state.oldPklSize -= curr->Head()->Value()->len;
00702 }
00703 }
00704
00705
00706 this->oldEntries.Init(sizeHint);
00707 }
00708
00709 void VPKFile::MoveCommonToUncommon(const BitVector &oldCommon) throw ()
00710
00711 {
00712
00713 assert(this->newCommon.Size() > 0);
00714 SPKFile::CFPEntryIter it(&(this->newCommon));
00715 FP::Tag cfp; CE::List *head;
00716 while (it.Next( cfp, head)) {
00717 MoveCommonListToUncommon(head, oldCommon);
00718 }
00719
00720
00721 newCommon.Init( newCommon.Size());
00722 }
00723
00724 void VPKFile::MoveCommonListToUncommon(CE::List *head,
00725 const BitVector &oldCommon) throw ()
00726
00727
00728 {
00729 assert(head != (CE::List *)NULL);
00730 CE::List *curr, *prev;
00731 for (curr = head; curr != (CE::List *)NULL;
00732 prev = curr, curr = curr->Tail()) {
00733 CE::T *ce = curr->Head();
00734 ce->XorUncommonNames(oldCommon);
00735 }
00736 prev->SetTail(this->newUncommon);
00737 this->newUncommon = head;
00738 }
00739
00740 void VPKFile::UpdateUncommonList(const Text* sourceFunc,
00741 BitVector *packMask, IntIntTblLR *reMap,
00742 bool unlazyTag) throw ()
00743
00744 {
00745 CE::List *curr = this->newUncommon;
00746 this->newUncommon = (CE::List *)NULL;
00747
00748 if (packMask != (BitVector *)NULL) {
00749 assert(reMap != (IntIntTblLR *)NULL);
00750 CycleDeletedNamesInList(curr, *packMask, *reMap);
00751 }
00752
00753 for (; curr != (CE::List *)NULL; curr = curr->Tail()) {
00754 CE::T *ce = curr->Head();
00755
00756
00757 FP::Tag *commonFP = (FP::Tag *)NULL;
00758 if (this->IsCommon(ce->UncommonNames())) {
00759 ce->XorUncommonNames(commonNames);
00760 commonFP = CommonFP(*ce);
00761 }
00762
00763
00764
00765
00766
00767
00768 AddEntry(sourceFunc, ce, commonFP);
00769
00770
00771 ce->Pack(packMask, reMap);
00772
00773
00774 if (unlazyTag) ce->UnlazyUncommonFP();
00775 }
00776 }
00777
00778 void VPKFile::RecordCIsFromList(const CE::List *ents,
00779 IntIntTbl& keep) const throw ()
00780
00781 {
00782 for (const CE::List *curr = ents; curr != NULL; curr = curr->Tail()) {
00783 IntKey key(curr->Head()->CI());
00784 bool inTbl = keep.Put(IntKey(key), 0); assert(!inTbl);
00785 }
00786 }
00787
00788 void VPKFile::RecordCIsFromTbl(const CFPEntryMap& tbl,
00789 IntIntTbl& keep) const throw ()
00790 {
00791 if (tbl.Size() > 0) {
00792 CFPEntryIter it(&tbl);
00793 FP::Tag cfp; CE::List *head;
00794 while (it.Next( cfp, head)) {
00795 RecordCIsFromList(head, keep);
00796 }
00797 }
00798 }
00799
00800 void VPKFile::CopyByCIs(const CFPEntryMap& source,
00801 IntIntTbl& cis, EntryState & state) throw ()
00802
00803 {
00804 if (source.Size() > 0 && cis.Size() > 0) {
00805 CFPEntryIter it(&source);
00806 FP::Tag cfp; CE::List *head, *curr;
00807 while (it.Next( cfp, head)) {
00808 for (curr = head; curr != NULL; curr = curr->Tail()) {
00809 CE::T *ce = curr->Head();
00810 int cnt;
00811 if (cis.Get(ce->CI(), cnt)) {
00812
00813 assert(cnt == 0);
00814 (void) cis.Put(ce->CI(), cnt+1);
00815
00816
00817 this->AddEntryToTable(this->oldEntries, cfp, ce);
00818
00819
00820 state.oldEntryCnt++;
00821 state.oldPklSize += ce->Value()->len;
00822 }
00823 }
00824 }
00825 }
00826 }
00827
00828 void VPKFile::CycleDeletedNamesInList(CE::List *curr,
00829 BitVector &packMask, IntIntTblLR &reMap) throw ()
00830
00831 {
00832
00833 short lastBx = packMask.MSB(), nextBx = -1;
00834 (void) reMap.Get(lastBx, nextBx);
00835 nextBx++;
00836
00837
00838
00839 IntIntTblLR delMap(reMap.ArraySize());
00840
00841 for (; curr != (CE::List *)NULL; curr = curr->Tail()) {
00842 CE::T *ce = curr->Head();
00843 BitVector delBV(ce->UncommonNames());
00844 delBV -= packMask;
00845 if (!(delBV.IsEmpty())) {
00846
00847 BVIter it(&delBV); int oldBx; short newBx;
00848 while (it.Next( oldBx)) {
00849 if (!delMap.Get(oldBx, newBx)) {
00850
00851 FV::T *name = &(this->allNames.name[oldBx]);
00852 newBx = this->allNames.Append(*name);
00853 bool inTbl = delMap.Put(oldBx, newBx); assert(!inTbl);
00854
00855
00856 inTbl = this->nameMap.Put(*name, newBx); assert(inTbl);
00857
00858
00859 bool set = packMask.Set(newBx); assert(!set);
00860
00861
00862 inTbl = reMap.Put(newBx, nextBx++);
00863 assert(!inTbl);
00864 }
00865 }
00866
00867
00868 ce->CycleNames(delBV, delMap);
00869 }
00870 }
00871 }
00872
00873 bool VPKFile::ReadyForPurgeWarm(int latestEpoch) const throw()
00874
00875 {
00876
00877
00878
00879
00880
00881
00882
00883
00884 return ((this->freePKFileEpoch <= (latestEpoch -
00885 Config_PurgeWarmPeriodCnt)) &&
00886 !this->HasNewEntries() &&
00887 (this->OldEntries()->Size() > 0));
00888 }
00889
00890 bool VPKFile::ReadyForEviction(int latestEpoch) const throw()
00891
00892 {
00893
00894
00895
00896
00897
00898
00899
00900
00901 return ((this->freePKFileEpoch <= (latestEpoch -
00902 Config_EvictPeriodCnt)) &&
00903 !this->HasNewEntries() &&
00904 (this->OldEntries()->Size() == 0));
00905 }