Changeset 052b8d0 for src/Patterns
- Timestamp:
- Mar 19, 2010, 4:40:04 PM (15 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
- Children:
- 4fb5a3
- Parents:
- 5be0eb
- git-author:
- Tillmann Crueger <crueger@…> (03/19/10 15:50:01)
- git-committer:
- Tillmann Crueger <crueger@…> (03/19/10 16:40:04)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Patterns/Cacheable.hpp
r5be0eb r052b8d0 11 11 #include "Patterns/Observer.hpp" 12 12 #include <boost/function.hpp> 13 #include <boost/shared_ptr.hpp> 14 #include <iostream> 15 16 #include "Helpers/Assert.hpp" 13 17 14 18 #ifndef NO_CACHING … … 17 21 class Cacheable : public Observer 18 22 { 23 // we define the states of the cacheable so we can do very fast state-checks 24 class State{ 25 public: 26 State(Cacheable *_owner) : 27 owner(_owner), 28 busy(false) 29 {} 30 virtual T& getValue()=0; 31 virtual void invalidate()=0; 32 virtual bool isValid()=0; 33 virtual void enter()=0; 34 bool isBusy(){ 35 return busy; 36 } 37 protected: 38 bool busy; 39 Cacheable *owner; 40 }; 41 42 class InvalidState : public State{ 43 public: 44 InvalidState(Cacheable *_owner): 45 State(_owner) 46 {} 47 48 virtual T& getValue(){ 49 // set the state to valid 50 State::owner->switchState(State::owner->validState); 51 // get the value from the now valid state 52 return State::owner->state->getValue(); 53 } 54 55 virtual void invalidate(){ 56 // nothing to do on this message 57 } 58 59 virtual bool isValid(){ 60 return false; 61 } 62 63 virtual void enter(){ 64 // nothing to do when entering this 65 } 66 }; 67 68 class ValidState : public State{ 69 public: 70 ValidState(Cacheable *_owner) : 71 State(_owner) 72 {} 73 74 virtual T& getValue(){ 75 return content; 76 } 77 78 virtual void invalidate(){ 79 State::owner->switchState(State::owner->invalidState); 80 } 81 82 virtual bool isValid(){ 83 return true; 84 } 85 86 virtual void enter(){ 87 State::busy= true; 88 // as soon as we enter the valid state we recalculate 89 content = State::owner->recalcMethod(); 90 State::busy = false; 91 } 92 private: 93 T content; 94 }; 95 96 class DestroyedState : public State { 97 public: 98 DestroyedState(Cacheable *_owner) : 99 State(_owner) 100 {} 101 102 virtual T& getValue(){ 103 ASSERT(0,"Cannot get a value from a Cacheable after it's Observable has died"); 104 // we have to return a grossly invalid reference, because no value can be produced anymore 105 return *(static_cast<T*>(0)); 106 } 107 108 virtual void invalidate(){ 109 ASSERT(0,"Cannot invalidate a Cacheable after it's Observable has died"); 110 } 111 112 virtual bool isValid(){ 113 ASSERT(0,"Cannot check validity of a Cacheable after it's Observable has died"); 114 return false; 115 } 116 117 virtual void enter(){ 118 // nothing to do when entering this state 119 } 120 }; 121 122 123 typedef boost::shared_ptr<State> state_ptr; 124 19 125 public: 20 126 Cacheable(Observable *_owner, boost::function<T()> _recalcMethod); 21 127 virtual ~Cacheable(); 22 128 23 const bool isValid(); 24 const T& operator*(); 25 const bool operator==(const T&); 26 const bool operator!=(const T&); 129 const bool isValid() const; 130 const T& operator*() const; 27 131 28 132 // methods implemented for base-class Observer … … 30 134 void subjectKilled(Observable *subject); 31 135 private: 32 void checkValid(); 33 34 T content; 136 137 void switchState(state_ptr newState); 138 139 mutable state_ptr state; 140 // pre-defined state so we don't have to construct to much 141 state_ptr invalidState; 142 state_ptr validState; 143 // destroyed state is not predefined, because we rarely enter that state and never leave 144 35 145 Observable *owner; 36 bool valid; 37 bool canBeUsed; 146 38 147 boost::function<T()> recalcMethod; 148 149 // de-activated copy constructor 150 Cacheable(const Cacheable&); 39 151 }; 40 152 … … 43 155 Cacheable<T>::Cacheable(Observable *_owner, boost::function<T()> _recalcMethod) : 44 156 owner(_owner), 45 valid(false),46 canBeUsed(true),47 157 recalcMethod(_recalcMethod) 48 158 { 159 // create all states needed for this object 160 invalidState = state_ptr(new InvalidState(this)); 161 validState = state_ptr(new ValidState(this)); 162 state = invalidState; 49 163 // we sign on with the best(=lowest) priority, so cached values are recalculated before 50 164 // anybody else might ask for updated values … … 52 166 } 53 167 54 template<typename T> 55 const T& Cacheable<T>::operator*(){ 56 checkValid(); 57 return content; 58 } 59 60 template<typename T> 61 const bool Cacheable<T>::operator==(const T& rval){ 62 checkValid(); 63 return (content == rval); 64 } 65 66 template<typename T> 67 const bool Cacheable<T>::operator!=(const T& rval){ 68 checkValid(); 69 return (content != rval); 168 // de-activated copy constructor 169 template<typename T> 170 Cacheable<T>::Cacheable(const Cacheable&){ 171 ASSERT(0,"Cacheables should never be copied"); 172 } 173 174 template<typename T> 175 const T& Cacheable<T>::operator*() const{ 176 return state->getValue(); 70 177 } 71 178 … … 77 184 78 185 template<typename T> 79 const bool Cacheable<T>::isValid() {80 return valid;186 const bool Cacheable<T>::isValid() const{ 187 return state->isValid(); 81 188 } 82 189 83 190 template<typename T> 84 191 void Cacheable<T>::update(Observable *subject) { 85 valid = false;192 state->invalidate(); 86 193 } 87 194 88 195 template<typename T> 89 196 void Cacheable<T>::subjectKilled(Observable *subject) { 90 valid = false;91 canBeUsed = false;92 } 93 94 template<typename T> 95 void Cacheable<T>:: checkValid(){96 assert(canBeUsed && "Cacheable used after owner was deleted");97 if(!isValid()){98 content = recalcMethod();99 100 } 197 state_ptr destroyed = state_ptr(new DestroyedState(this)); 198 switchState(destroyed); 199 } 200 201 template<typename T> 202 void Cacheable<T>::switchState(state_ptr newState){ 203 ASSERT(!state->isBusy(),"LOOP DETECTED: Cacheable state switched while recalculating.\nDid the recalculation trigger the Observable?"); 204 state = newState; 205 state->enter(); 206 } 207 101 208 #else 102 209 template<typename T> … … 107 214 virtual ~Cacheable(); 108 215 109 const bool isValid(); 110 const T& operator*(); 111 const bool operator==(const T&); 112 const bool operator!=(const T&); 216 const bool isValid() const; 217 const T& operator*() const; 113 218 114 219 // methods implemented for base-class Observer … … 126 231 127 232 template<typename T> 128 const T& Cacheable<T>::operator*() {233 const T& Cacheable<T>::operator*() const{ 129 234 return recalcMethod(); 130 }131 132 template<typename T>133 const bool Cacheable<T>::operator==(const T& rval){134 return (recalcMethod() == rval);135 }136 137 template<typename T>138 const bool Cacheable<T>::operator!=(const T& rval){139 return (recalcMethod() != rval);140 235 } 141 236 … … 145 240 146 241 template<typename T> 147 const bool Cacheable<T>::isValid() {242 const bool Cacheable<T>::isValid() const{ 148 243 return true; 149 244 } … … 151 246 template<typename T> 152 247 void Cacheable<T>::update(Observable *subject) { 153 assert(0 &&"Cacheable::update should never be called when caching is disabled");154 } 155 156 template<typename T> 157 void Cacheable<T>::subjectKilled(Observable *subject) 158 assert(0 &&"Cacheable::subjectKilled should never be called when caching is disabled");248 ASSERT(0, "Cacheable::update should never be called when caching is disabled"); 249 } 250 251 template<typename T> 252 void Cacheable<T>::subjectKilled(Observable *subject){ 253 ASSERT(0, "Cacheable::subjectKilled should never be called when caching is disabled"); 159 254 } 160 255 #endif
Note:
See TracChangeset
for help on using the changeset viewer.