00001
00002
00003 #define ENABLE_PERSISTANCE
00004
00005 #include "persistance.h"
00006
00009 PersistantStore :: PersistantStore() : current_view_(0), popping_(false)
00010 {
00011 }
00012
00016 int PersistantStore::add_checkpoint()
00017 {
00018 assert(viewing_current());
00019 assert(!popping_);
00020 modifications_.push_back(ModifySet());
00021 births_.push_back(ModifySet());
00022 current_view_ = modifications_.size();
00023 return current_view_;
00024 }
00025
00029 void PersistantStore::set_view(int idx) {
00030 assert(idx >= 0); assert(idx <= (signed)modifications_.size());
00031 assert(!popping_);
00032 current_view_ = idx;
00033 }
00034
00038 void PersistantStore::set_view_current() {
00039 assert(!popping_);
00040 current_view_ = modifications_.size();
00041 }
00042
00043
00047 void PersistantStore::undo()
00048 {
00049 assert(!popping_);
00050 assert(viewing_current());
00051 assert(logging());
00052 popping_ = true;
00053
00054 assert(died_in_pop_.empty());
00055 for(ModifySet::iterator it = modifications_.back().begin();
00056 it != modifications_.back().end(); ++it) {
00057 if (died_in_pop_.count(*it) == 0) {
00058 (*it)->undo();
00059 }
00060 }
00061
00062 died_in_pop_.clear();
00063 modifications_.pop_back();
00064 births_.pop_back();
00065 current_view_--;
00066 popping_ = false;
00067 }
00068
00074 void PersistantStore::commit()
00075 {
00076 assert(!popping_);
00077 assert(viewing_current());
00078 assert(logging());
00079 popping_ = true;
00080
00081 assert(died_in_pop_.empty());
00082 for(ModifySet::iterator it = modifications_.back().begin();
00083 it != modifications_.back().end(); ++it) {
00084 if (died_in_pop_.count(*it) == 0) {
00085 (*it)->commit();
00086 }
00087 }
00088 for(ModifySet::iterator it = births_.back().begin();
00089 it != births_.back().end(); ++it) {
00090 if (died_in_pop_.count(*it) == 0) {
00091 (*it)->preincarnate();
00092 }
00093 }
00094 if (logging_after_pop()) {
00095
00096
00097 for(ModifySet::iterator it = modifications_.back().begin();
00098 it != modifications_.back().end(); ++it) {
00099 assert(births_.back().count(*it) == 0);
00100 if (births_[births_.size() - 2].count(*it) == 0) {
00101 modifications_[modifications_.size() - 2].insert(*it);
00102 }
00103 }
00104
00105 births_[births_.size() - 2].insert(
00106 births_.back().begin(), births_.back().end());
00107 }
00108
00109 died_in_pop_.clear();
00110 modifications_.pop_back();
00111 births_.pop_back();
00112 current_view_--;
00113 popping_ = false;
00114 }
00115
00119 int PersistantStore::get_time() const {
00120 return current_view_;
00121 }
00122
00126 bool PersistantStore::viewing_current() const {
00127 return get_time() == (signed)modifications_.size();
00128 }
00129
00133 bool PersistantStore::logging() const {
00134 return modifications_.size() >= 1;
00135 }
00136
00140 bool PersistantStore::logging_after_pop() const {
00141 return modifications_.size() - 1 >= 1;
00142 }
00143
00144
00149 void PersistantStore::notify_access(PersistantObject* data)
00150 {
00151 assert(!popping_);
00152 assert(viewing_current());
00153
00154
00155 if(logging()) {
00156 assert(births_.back().count(data) == 0);
00157 bool didinsert;
00158 didinsert = modifications_.back().insert(data).second;
00159 assert(didinsert);
00160 }
00161 }
00162
00165 void PersistantStore::notify_born(PersistantObject* data)
00166 {
00167 assert(!popping_);
00168 assert(viewing_current());
00169 if (logging()) {
00170 bool didinsert;
00171 didinsert = births_.back().insert(data).second;
00172 assert(didinsert);
00173 }
00174 }
00175
00183 void PersistantStore::notify_died(PersistantObject* data)
00184 {
00185 assert(viewing_current());
00186 if (logging()) {
00187 bool found;
00188 found = births_.back().erase(data);
00189 if (!found) {
00190 assert(popping_);
00191 if (logging_after_pop()) {
00192 found = births_[births_.size() - 2].erase(data);
00193 assert(found);
00194 } else {
00195
00196
00197 }
00198
00199
00200 died_in_pop_.insert(data);
00201 }
00202 }
00203 }