diff --git a/src/persist/api/Recoverable.cpp b/src/persist/api/Recoverable.cpp index 07340ca..e283a7c 100644 --- a/src/persist/api/Recoverable.cpp +++ b/src/persist/api/Recoverable.cpp @@ -28,10 +28,9 @@ Recoverable::Recoverable(GlobalTestConfig* gtc){ gtc->setEnv("Liveness", "Blocking"); _esys = new pds::EpochSys(gtc); } - auto recovered = _esys->get_recovered(); - if (recovered) { - last_recovered = recovered->size(); - recover(recovered, false); + auto recovered_pblks = _esys->get_recovered(); + if (recovered_pblks) { + last_recovered_cnt = recovered_pblks->size(); } } Recoverable::~Recoverable(){ @@ -39,6 +38,9 @@ Recoverable::~Recoverable(){ delete pending_allocs; delete pending_retires; delete epochs; + if (recovered_pblks) { + delete recovered_pblks; + } Persistent::finalize(); } void Recoverable::init_thread(GlobalTestConfig*, LocalTestConfig* ltc){ diff --git a/src/persist/api/Recoverable.hpp b/src/persist/api/Recoverable.hpp index 0c2f0c3..4b6aa31 100644 --- a/src/persist/api/Recoverable.hpp +++ b/src/persist/api/Recoverable.hpp @@ -66,11 +66,13 @@ class Recoverable{ padded>* pending_allocs = nullptr; // pending retires; each pair is padded>>* pending_retires = nullptr; + // pointer to recovered PBlks from EpochSys + std::unordered_map* recovered_pblks = nullptr; // count of last recovered PBlks from EpochSys - uint64_t last_recovered = 0; + uint64_t last_recovered_cnt = 0; public: // return num of blocks recovered. - virtual int recover(std::unordered_map* recovered, bool simulated = false) { + virtual int recover() { errexit("recover() not implemented. Implement recover() or delete existing persistent heap file."); return 0; } @@ -289,8 +291,11 @@ class Recoverable{ assert(epochs[pds::EpochSys::tid].ui != NULL_EPOCH); return _esys->openwrite_pblk(b, epochs[pds::EpochSys::tid].ui); } - std::unordered_map* recover_pblks(const int rec_thd=10){ - return _esys->recover(rec_thd); + std::unordered_map* get_recovered_pblks(){ + return recovered_pblks; + } + uint64_t get_last_recovered_cnt() { + return last_recovered_cnt; } void sync(){ assert(epochs[pds::EpochSys::tid].ui == NULL_EPOCH); @@ -308,9 +313,6 @@ class Recoverable{ } // _esys->flush(); } - uint64_t get_last_recovered_cnt() { - return last_recovered; - } pds::sc_desc_t* get_dcss_desc(){ return _esys->get_dcss_desc(); diff --git a/src/persist/api/montage_global_api.hpp b/src/persist/api/montage_global_api.hpp index dabeae6..ac87acc 100644 --- a/src/persist/api/montage_global_api.hpp +++ b/src/persist/api/montage_global_api.hpp @@ -10,23 +10,9 @@ namespace pds{ class GlobalRecoverable: public Recoverable{ - std::unordered_map* recovered_pblks = nullptr; public: GlobalRecoverable(GlobalTestConfig* gtc): Recoverable(gtc){} - ~GlobalRecoverable(){ - if (recovered_pblks){ - delete recovered_pblks; - } - } - int recover(bool simulated){ - // TODO: handle simulated situation here? - recovered_pblks = recover_pblks(); - // TODO: return number of blocks here? - return 0; - } - std::unordered_map* get_recovered(){ - return recovered_pblks; - } + ~GlobalRecoverable(){} }; extern GlobalRecoverable* global_recoverable; @@ -117,9 +103,8 @@ namespace pds{ // delete(b); // }}) - inline std::unordered_map* recover(const int rec_thd=10){ - global_recoverable->recover(rec_thd); - return global_recoverable->get_recovered(); + inline std::unordered_map* get_recovered_pblks(){ + return global_recoverable->get_recovered_pblks(); } inline void flush(){ diff --git a/src/rideables/HOHHashTable.hpp b/src/rideables/HOHHashTable.hpp index b349284..60b6de6 100644 --- a/src/rideables/HOHHashTable.hpp +++ b/src/rideables/HOHHashTable.hpp @@ -58,7 +58,7 @@ class HOHHashTable : public RMap, public Recoverable{ } } - int recover(bool simulated){ + int recover(){ errexit("recover of HOHHashTable not implemented"); } diff --git a/src/rideables/MontageGraph.hpp b/src/rideables/MontageGraph.hpp index 5aa3c89..4e96fed 100644 --- a/src/rideables/MontageGraph.hpp +++ b/src/rideables/MontageGraph.hpp @@ -126,6 +126,11 @@ class MontageGraph : public RGraph, public Recoverable{ }; MontageGraph(GlobalTestConfig* gtc) : Recoverable(gtc), gtc(gtc) { + if (get_recovered_pblks()) { + recover(); + return; + } + size_t sz = numVertices; this->vMeta = new VertexMeta[numVertices]; std::mt19937_64 gen(time(NULL)); @@ -168,7 +173,9 @@ class MontageGraph : public RGraph, public Recoverable{ if(gtc->verbose) std::cout << "Filled mean edges per vertex" << std::endl; } - ~MontageGraph() {} + ~MontageGraph() { + delete vMeta; + } // Obtain statistics of graph (|V|, |E|, average degree, vertex degrees) // Not concurrent safe... @@ -329,35 +336,23 @@ class MontageGraph : public RGraph, public Recoverable{ return ret; } - int recover(bool simulated) { + int recover() { struct RelationWrapper{ int v1; int v2; Relation* e; } __attribute__((aligned(CACHE_LINE_SIZE))); - // assert(0&&"recover() not implemented!"); - if (simulated) { - recover_mode(); - delete vMeta; - vMeta = new VertexMeta[numVertices]; - // #pragma omp parallel for - for (size_t i = 0; i < numVertices; i++) { - vertex(i) = nullptr; - } - online_mode(); + vMeta = new VertexMeta[numVertices]; + for (size_t i = 0; i < numVertices; i++) { + vertex(i) = nullptr; } - int rec_thd = gtc->task_num; int block_cnt = 0; - auto begin = chrono::high_resolution_clock::now(); - std::unordered_map* recovered = recover_pblks(); - auto end = chrono::high_resolution_clock::now(); - auto dur = end - begin; - auto dur_ms = std::chrono::duration_cast(dur).count(); - std::cout << "Spent " << dur_ms << "ms getting PBlk(" << recovered->size() << ")" << std::endl; + std::unordered_map* recovered = get_recovered_pblks(); + assert(recovered); - begin = chrono::high_resolution_clock::now(); + auto begin = chrono::high_resolution_clock::now(); std::vector relationVector; std::vector vertexVector; { @@ -389,9 +384,9 @@ class MontageGraph : public RGraph, public Recoverable{ } } } - end = chrono::high_resolution_clock::now(); - dur = end - begin; - dur_ms = std::chrono::duration_cast(dur).count(); + auto end = chrono::high_resolution_clock::now(); + auto dur = end - begin; + auto dur_ms = std::chrono::duration_cast(dur).count(); std::cout << "Spent " << dur_ms << "ms gathering vertices(" << vertexVector.size() << ") and edges(" << relationVector.size() << ")..." << std::endl; begin = chrono::high_resolution_clock::now(); diff --git a/src/rideables/MontageHashTable.hpp b/src/rideables/MontageHashTable.hpp index 1d51dce..2ccc060 100644 --- a/src/rideables/MontageHashTable.hpp +++ b/src/rideables/MontageHashTable.hpp @@ -62,7 +62,11 @@ class MontageHashTable : public RMap, public Recoverable{ std::hash hash_fn; Bucket buckets[idxSize]; GlobalTestConfig* gtc; - MontageHashTable(GlobalTestConfig* gtc_): Recoverable(gtc_), gtc(gtc_){}; + MontageHashTable(GlobalTestConfig* gtc_): Recoverable(gtc_), gtc(gtc_){ + if (get_recovered_pblks()) { + recover(); + } + }; void init_thread(GlobalTestConfig* gtc, LocalTestConfig* ltc){ Recoverable::init_thread(gtc, ltc); @@ -200,14 +204,8 @@ class MontageHashTable : public RMap, public Recoverable{ } - int recover(std::unordered_map* recovered, bool simulated){ - if (simulated){ - recover_mode(); // PDELETE --> noop - // clear transient structures. - clear(); - online_mode(); // re-enable PDELETE. - } - + int recover(){ + std::unordered_map* recovered = get_recovered_pblks(); assert(recovered); int rec_cnt = 0; diff --git a/src/rideables/MontageLfHashTable.hpp b/src/rideables/MontageLfHashTable.hpp index 058df9f..b0d58ea 100644 --- a/src/rideables/MontageLfHashTable.hpp +++ b/src/rideables/MontageLfHashTable.hpp @@ -95,8 +95,16 @@ class MontageLfHashTable : public RMap, public Recoverable{ } public: MontageLfHashTable(GlobalTestConfig* gtc) : Recoverable(gtc), tracker(gtc->task_num, 100, 1000, true), gtc(gtc) { + if (get_recovered_pblks()) { + recover(); + } + }; + ~MontageLfHashTable(){ + recover_mode(); // PDELETE --> noop + // clear transient structures. + clear(); + online_mode(); // re-enable PDELETE. }; - ~MontageLfHashTable(){}; void init_thread(GlobalTestConfig* gtc, LocalTestConfig* ltc){ Recoverable::init_thread(gtc, ltc); @@ -114,35 +122,25 @@ class MontageLfHashTable : public RMap, public Recoverable{ buckets[i].ui.ptr.store(this,nullptr); } } - int recover(bool simulated){ - if (simulated){ - recover_mode(); // PDELETE --> noop - // clear transient structures. - clear(); - online_mode(); // re-enable PDELETE. - } - + int recover(){ int rec_cnt = 0; int rec_thd = gtc->task_num; if (gtc->checkEnv("RecoverThread")){ rec_thd = stoi(gtc->getEnv("RecoverThread")); } - auto begin = chrono::high_resolution_clock::now(); - std::unordered_map* recovered = recover_pblks(rec_thd); - auto end = chrono::high_resolution_clock::now(); - auto dur = end - begin; - auto dur_ms = std::chrono::duration_cast(dur).count(); - std::cout << "Spent " << dur_ms << "ms getting PBlk(" << recovered->size() << ")" << std::endl; + std::unordered_map* recovered = get_recovered_pblks(); + assert(recovered); + std::vector payloadVector; payloadVector.reserve(recovered->size()); - begin = chrono::high_resolution_clock::now(); + auto begin = chrono::high_resolution_clock::now(); for (auto itr = recovered->begin(); itr != recovered->end(); itr++){ rec_cnt++; Payload* payload = reinterpret_cast(itr->second); payloadVector.push_back(payload); } - end = chrono::high_resolution_clock::now(); - dur = end - begin; + auto end = chrono::high_resolution_clock::now(); + auto dur = end - begin; auto dur_ms_vec = std::chrono::duration_cast(dur).count(); std::cout << "Spent " << dur_ms_vec << "ms building vector" << std::endl; begin = chrono::high_resolution_clock::now(); @@ -187,7 +185,6 @@ class MontageLfHashTable : public RMap, public Recoverable{ dur = end - begin; auto dur_ms_ins = std::chrono::duration_cast(dur).count(); std::cout << "Spent " << dur_ms_ins << "ms inserting(" << recovered->size() << ")" << std::endl; - std::cout << "Total time to recover: " << dur_ms+dur_ms_vec+dur_ms_ins << "ms" << std::endl; delete recovered; return rec_cnt; } diff --git a/src/rideables/MontageLfSkipList.hpp b/src/rideables/MontageLfSkipList.hpp index 1e1c14f..3cffc56 100644 --- a/src/rideables/MontageLfSkipList.hpp +++ b/src/rideables/MontageLfSkipList.hpp @@ -149,8 +149,15 @@ class MontageLfSkipList : public RMap, public Recoverable { int bg_tid = gtc->task_num; bg_state.store(background_state::RUNNING); background_thread = std::move(std::thread(&MontageLfSkipList::bg_loop, this, bg_tid)); + if (get_recovered_pblks()) { + recover(); + } }; ~MontageLfSkipList(){ + recover_mode(); // PDELETE --> noop + // clear transient structures. + clear(); + online_mode(); // re-enable PDELETE. bg_state.store(background_state::FINISHED); background_thread.join(); }; @@ -180,14 +187,7 @@ class MontageLfSkipList : public RMap, public Recoverable { head.ptr.store(initialHeadNode); } - int recover(bool simulated){ - if (simulated){ - recover_mode(); // PDELETE --> noop - // clear transient structures. - clear(); - online_mode(); // re-enable PDELETE. - } - + int recover(){ should_cas_verify.store(false); int rec_cnt = 0; @@ -195,23 +195,18 @@ class MontageLfSkipList : public RMap, public Recoverable { if (gtc->checkEnv("RecoverThread")){ rec_thd_count = stoi(gtc->getEnv("RecoverThread")); } - auto begin = chrono::high_resolution_clock::now(); - std::unordered_map* recovered = recover_pblks(rec_thd_count); - auto end = chrono::high_resolution_clock::now(); - auto dur = end - begin; - auto dur_ms = std::chrono::duration_cast(dur).count(); - std::cout << "Spent " << dur_ms << "ms getting PBlk(" << recovered->size() << ")" << std::endl; + std::unordered_map* recovered = get_recovered_pblks(); std::vector payloadVector; payloadVector.reserve(recovered->size()); - begin = chrono::high_resolution_clock::now(); + auto begin = chrono::high_resolution_clock::now(); for (auto itr = recovered->begin(); itr != recovered->end(); itr++){ rec_cnt++; Payload* payload = reinterpret_cast(itr->second); payloadVector.push_back(payload); } - end = chrono::high_resolution_clock::now(); - dur = end - begin; + auto end = chrono::high_resolution_clock::now(); + auto dur = end - begin; auto dur_ms_vec = std::chrono::duration_cast(dur).count(); std::cout << "Spent " << dur_ms_vec << "ms building vector" << std::endl; @@ -253,7 +248,6 @@ class MontageLfSkipList : public RMap, public Recoverable { dur = end - begin; auto dur_ms_ins = std::chrono::duration_cast(dur).count(); std::cout << "Spent " << dur_ms_ins << "ms inserting(" << recovered->size() << ")" << std::endl; - std::cout << "Total time to recover: " << dur_ms+dur_ms_vec+dur_ms_ins << "ms" << std::endl; should_cas_verify.store(true); delete recovered; diff --git a/src/rideables/MontageMSQueue.hpp b/src/rideables/MontageMSQueue.hpp index 1710f0d..46e0424 100644 --- a/src/rideables/MontageMSQueue.hpp +++ b/src/rideables/MontageMSQueue.hpp @@ -71,7 +71,7 @@ class MontageMSQueue : public RQueue, public Recoverable{ Recoverable::init_thread(gtc, ltc); } - int recover(bool simulated){ + int recover(){ errexit("recover of MontageMSQueue not implemented."); return 0; } diff --git a/src/rideables/MontageNatarajanTree.hpp b/src/rideables/MontageNatarajanTree.hpp index 0ba5b6f..ee9c2c1 100644 --- a/src/rideables/MontageNatarajanTree.hpp +++ b/src/rideables/MontageNatarajanTree.hpp @@ -163,7 +163,7 @@ class MontageNatarajanTree : public RMap, public Recoverable{ Recoverable::init_thread(gtc, ltc); } - int recover(bool simulated){ + int recover(){ errexit("recover of MontageNatarajanTree not implemented."); return 0; } diff --git a/src/rideables/MontageQueue.hpp b/src/rideables/MontageQueue.hpp index 4896aa7..10feab7 100644 --- a/src/rideables/MontageQueue.hpp +++ b/src/rideables/MontageQueue.hpp @@ -76,7 +76,7 @@ class MontageQueue : public RQueue, public Recoverable{ Recoverable::init_thread(gtc, ltc); } - int recover(bool simulated){ + int recover(){ errexit("recover of MontageQueue not implemented."); return 0; } diff --git a/src/rideables/MontageSSHashTable.hpp b/src/rideables/MontageSSHashTable.hpp index 4e189aa..9dfa3f7 100644 --- a/src/rideables/MontageSSHashTable.hpp +++ b/src/rideables/MontageSSHashTable.hpp @@ -124,7 +124,7 @@ class MontageSSHashTable : public RMap, public Recoverable { Recoverable::init_thread(gtc, ltc); } - int recover(bool simulated){ + int recover(){ errexit("recover of MontageSSHashTable not implemented."); return 0; } diff --git a/src/rideables/UnbalancedTree.hpp b/src/rideables/UnbalancedTree.hpp index ff4a5bc..3d0a966 100644 --- a/src/rideables/UnbalancedTree.hpp +++ b/src/rideables/UnbalancedTree.hpp @@ -68,7 +68,7 @@ class UnbalancedTree : public RMap, public Recoverable{ root = nullptr; } - int recover(bool simulated){ + int recover(){ errexit("recover of UnbalancedTree not implemented"); return 0; } diff --git a/src/tests/AllocTest.hpp b/src/tests/AllocTest.hpp index 13fb61f..465317b 100644 --- a/src/tests/AllocTest.hpp +++ b/src/tests/AllocTest.hpp @@ -25,7 +25,7 @@ class DummyObject : public pds::PBlk { }; struct MontageDummy : public Recoverable { - int recover(bool simulated) { return 0; } + int recover() { return 0; } MontageDummy(GlobalTestConfig *gtc) : Recoverable(gtc) {} ~MontageDummy() {} diff --git a/src/tests/RecoverVerifyTest.hpp b/src/tests/RecoverVerifyTest.hpp index 773bffc..8904dcf 100644 --- a/src/tests/RecoverVerifyTest.hpp +++ b/src/tests/RecoverVerifyTest.hpp @@ -126,7 +126,7 @@ int RecoverVerifyTest::execute(GlobalTestConfig* gtc, LocalTestConfig* ltc) prepareRideable(); std::cout<<"recover returned."<get_last_recovered_cnt(); - if (rec_cnt == (int)reference.size()){ + if (rec_cnt == reference.size()){ std::cout<<"rec_cnt currect."<