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 <VestaLog.H>
00025 #include <Recovery.H>
00026 #include <FP.H>
00027 #include <CacheConfig.H>
00028 #include <CacheIntf.H>
00029 #include <PKEpoch.H>
00030 #include <Debug.H>
00031
00032 #include "EmptyPKLog.H"
00033
00034 using std::fstream;
00035 using std::cout;
00036 using std::endl;
00037
00038
00039
00040
00041
00042 EmptyPKLog::EmptyPKLog(Basics::mutex *mu, CacheIntf::DebugLevel debug,
00043 bool readonly)
00044 throw (VestaLog::Error)
00045
00046 : mu(mu), debug(debug)
00047 {
00048 this->log = NEW(VestaLog);
00049 this->log->open(Config_EmptyPKLogPath.chars(), -1, readonly);
00050 this->rd = NEW_CONSTR(RecoveryReader, (this->log));
00051 this->oldEmptyPKTbl = NULL;
00052 this->emptyPKTbl = NEW(EmptyPKLog::PKEpochTbl);
00053 }
00054
00055 void EmptyPKLog::Read( FP::Tag &pk, PKFile::Epoch &pkEpoch)
00056 throw (VestaLog::Error, VestaLog::Eof)
00057
00058 {
00059
00060 pk.Recover(*(this->rd));
00061 this->rd->readAll((char *)(&pkEpoch), sizeof(pkEpoch));
00062
00063
00064 PKFile::Epoch tblEpoch;
00065 bool inTbl = this->emptyPKTbl->Get(pk, tblEpoch);
00066
00067 assert(!inTbl || pkEpoch > tblEpoch);
00068 bool inTbl2 = this->emptyPKTbl->Put(pk, pkEpoch);
00069 assert(inTbl == inTbl2);
00070 }
00071
00072 void EmptyPKLog::CheckpointBegin()
00073 throw (FS::Failure, VestaLog::Error)
00074
00075 {
00076 this->mu->lock();
00077 try {
00078 fstream *chkptFile = this->log->checkpointBegin();
00079
00080 FS::Close(*chkptFile);
00081 this->oldEmptyPKTbl = this->emptyPKTbl;
00082 this->emptyPKTbl = NEW(EmptyPKLog::PKEpochTbl);
00083 } catch (...) { this->mu->unlock(); throw; }
00084 this->mu->unlock();
00085 }
00086
00087 void EmptyPKLog::CheckpointEnd() throw (VestaLog::Error)
00088
00089 {
00090 this->mu->lock();
00091 try {
00092 this->log->checkpointEnd();
00093 this->log->prune( 1);
00094 delete this->oldEmptyPKTbl;
00095 this->oldEmptyPKTbl = NULL;
00096 } catch (...) { this->mu->unlock(); throw; }
00097 this->mu->unlock();
00098 }
00099
00100 void EmptyPKLog::Write(const FP::Tag &pk, PKFile::Epoch pkEpoch)
00101 throw (VestaLog::Error)
00102
00103 {
00104 this->mu->lock();
00105 PKFile::Epoch tblEpoch = 0;
00106 if (this->emptyPKTbl->Get(pk, tblEpoch)) {
00107 assert(pkEpoch >= tblEpoch);
00108 }
00109 if (pkEpoch > tblEpoch) {
00110 if (this->debug >= CacheIntf::LogFlush) {
00111 Debug::Lock();
00112 cout << Debug::Timestamp() << "Writing entry to EmptyPKLog" <<endl;
00113 cout << " pk = " << pk << endl;
00114 cout << " pkEpoch = " << pkEpoch << endl;
00115 cout << endl;
00116 Debug::Unlock();
00117 }
00118 (void)this->emptyPKTbl->Put(pk, pkEpoch);
00119 try {
00120 this->log->start();
00121 pk.Log(*(this->log));
00122 this->log->write((char *)(&pkEpoch), sizeof(pkEpoch));
00123 this->log->commit();
00124 }
00125 catch (...) {
00126 this->mu->unlock();
00127 throw;
00128 }
00129 }
00130 this->mu->unlock();
00131 }
00132
00133 bool EmptyPKLog::GetEpoch0(const FP::Tag &pk, PKFile::Epoch &pkEpoch)
00134 throw ()
00135
00136 {
00137 if (this->emptyPKTbl->Get(pk, pkEpoch)) return true;
00138 if (this->oldEmptyPKTbl == NULL) return false;
00139 return this->oldEmptyPKTbl->Get(pk, pkEpoch);
00140 }
00141
00142 bool EmptyPKLog::GetEpoch(const FP::Tag &pk, PKFile::Epoch &pkEpoch)
00143 throw ()
00144
00145 {
00146 this->mu->lock();
00147 bool res = this->GetEpoch0(pk, pkEpoch);
00148 this->mu->unlock();
00149 return res;
00150 }