persistance.C

Go to the documentation of this file.
00001 
00002 /* Unconditionally enable persistance here. */
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     /* Copy all the modifications back, except those that correspond
00096        to things just born. */
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     /* Copy all the births back to keep track of them. */
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   /* if we are logging, then remember this change; otherwise, it doesn't
00154      matter. */
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         /* we're returning to an unlogged time: we have no birth certificates
00196            anymore. */
00197       }
00198       /* 'data' may be deallocated, but the pointer value is still valid,
00199          and it's illegal to add new objects during a pop. */
00200       died_in_pop_.insert(data);
00201     }
00202   }
00203 }

Generated on Mon May 24 09:53:30 2010 for TUMBLE by  doxygen 1.5.2