Changeset 3e4fb6


Ignore:
Timestamp:
Dec 28, 2011, 3:27:49 PM (13 years ago)
Author:
Frederik Heber <heber@…>
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:
53c7fc
Parents:
401f90
git-author:
Frederik Heber <heber@…> (12/23/11 14:48:37)
git-committer:
Frederik Heber <heber@…> (12/28/11 15:27:49)
Message:

Added template class IdPool used by World to manage defragmentable id pool.

  • this is stuff from World factored into own class (was doubly present in World anyway).
  • added short documentation to constructs/world.
Location:
src
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • src/Makefile.am

    r401f90 r3e4fb6  
    196196  config.hpp \
    197197  Formula.hpp \
     198  IdPool.hpp \
     199  IdPool_impl.hpp \
    198200  linkedcell.hpp \
    199201  MoleculeLeafClass.hpp \
  • src/World.cpp

    r401f90 r3e4fb6  
    4545#include "WorldTime.hpp"
    4646
     47#include "IdPool_impl.hpp"
     48
    4749#include "CodePatterns/Singleton_impl.hpp"
    4850#include "CodePatterns/ObservedContainer_impl.hpp"
    4951
    5052using namespace MoleCuilder;
    51 
    52 const unsigned int MAX_POOL_FRAGMENTATION=20;
    53 const unsigned int MAX_FRAGMENTATION_SKIPS=100;
    5453
    5554/******************************* Notifications ************************/
     
    188187  molecule *mol = NULL;
    189188  mol = NewMolecule();
    190   moleculeId_t id = getNextMoleculeId();
     189  moleculeId_t id = moleculeIdPool.getNextId();
    191190  ASSERT(!molecules.count(id),"proposed id did not specify an unused ID");
    192191  mol->setId(id);
     
    218217    selectedMolecules.erase(id);
    219218  molecules.erase(id);
    220   releaseMoleculeId(id);
     219  moleculeIdPool.releaseId(id);
    221220}
    222221
    223222atom *World::createAtom(){
    224223  OBSERVE;
    225   atomId_t id = getNextAtomId();
     224  atomId_t id = atomIdPool.getNextId();
    226225  ASSERT(!atoms.count(id),"proposed id did not specify an unused ID");
    227226  atom *res = NewAtom(id);
     
    237236int World::registerAtom(atom *atom){
    238237  OBSERVE;
    239   atomId_t id = getNextAtomId();
     238  atomId_t id = atomIdPool.getNextId();
    240239  atom->setId(id);
    241240  atom->setWorld(this);
     
    262261    selectedAtoms.erase(id);
    263262  atoms.erase(id);
    264   releaseAtomId(id);
     263  atomIdPool.releaseId(id);
    265264}
    266265
     
    275274  }
    276275  else{
    277     if(reserveAtomId(newId)){
     276    if(atomIdPool.reserveId(newId)){
    278277      atoms.erase(oldId);
    279278      atoms.insert(pair<atomId_t,atom*>(newId,target));
     
    296295  }
    297296  else{
    298     if(reserveMoleculeId(newId)){
     297    if(moleculeIdPool.reserveId(newId)){
    299298      molecules.erase(oldId);
    300299      molecules.insert(pair<moleculeId_t,molecule*>(newId,target));
     
    326325  proc->signOff(this);
    327326}
    328 /******************************* IDManagement *****************************/
    329 
    330 // Atoms
    331 
    332 atomId_t World::getNextAtomId(){
    333   // try to find an Id in the pool;
    334   if(!atomIdPool.empty()){
    335     atomIdPool_t::iterator iter=atomIdPool.begin();
    336     atomId_t id = iter->first;
    337     range<atomId_t> newRange = makeRange(id+1,iter->last);
    338     // we wont use this iterator anymore, so we don't care about invalidating
    339     atomIdPool.erase(iter);
    340     if(newRange.first<newRange.last){
    341       atomIdPool.insert(newRange);
    342     }
    343     return id;
    344   }
    345   // Nothing in the pool... we are out of luck
    346   return currAtomId++;
    347 }
    348 
    349 void World::releaseAtomId(atomId_t id){
    350   atomIdPool.insert(makeRange(id,id+1));
    351   defragAtomIdPool();
    352 }
    353 
    354 bool World::reserveAtomId(atomId_t id){
    355   if(id>=currAtomId ){
    356     range<atomId_t> newRange = makeRange(currAtomId,id);
    357     if(newRange.first<newRange.last){
    358       atomIdPool.insert(newRange);
    359     }
    360     currAtomId=id+1;
    361     defragAtomIdPool();
    362     return true;
    363   }
    364   // look for a range that matches the request
    365   for(atomIdPool_t::iterator iter=atomIdPool.begin();iter!=atomIdPool.end();++iter){
    366     if(iter->isBefore(id)){
    367       // we have covered all available ranges... nothing to be found here
    368       break;
    369     }
    370     // no need to check first, since it has to be <=id, since otherwise we would have broken out
    371     if(!iter->isBeyond(id)){
    372       // we found a matching range... get the id from this range
    373 
    374       // split up this range at the point of id
    375       range<atomId_t> bottomRange = makeRange(iter->first,id);
    376       range<atomId_t> topRange = makeRange(id+1,iter->last);
    377       // remove this range
    378       atomIdPool.erase(iter);
    379       if(bottomRange.first<bottomRange.last){
    380         atomIdPool.insert(bottomRange);
    381       }
    382       if(topRange.first<topRange.last){
    383         atomIdPool.insert(topRange);
    384       }
    385       defragAtomIdPool();
    386       return true;
    387     }
    388   }
    389   // this ID could not be reserved
    390   return false;
    391 }
    392 
    393 void World::defragAtomIdPool(){
    394   // check if the situation is bad enough to make defragging neccessary
    395   if((numAtomDefragSkips<MAX_FRAGMENTATION_SKIPS) &&
    396      (atomIdPool.size()<lastAtomPoolSize+MAX_POOL_FRAGMENTATION)){
    397     ++numAtomDefragSkips;
    398     return;
    399   }
    400   for(atomIdPool_t::iterator iter = atomIdPool.begin();iter!=atomIdPool.end();){
    401     // see if this range is adjacent to the next one
    402     atomIdPool_t::iterator next = iter;
    403     next++;
    404     if(next!=atomIdPool.end() && (next->first==iter->last)){
    405       // merge the two ranges
    406       range<atomId_t> newRange = makeRange(iter->first,next->last);
    407       atomIdPool.erase(iter);
    408       atomIdPool.erase(next);
    409       pair<atomIdPool_t::iterator,bool> res = atomIdPool.insert(newRange);
    410       ASSERT(res.second,"Id-Pool was confused");
    411       iter=res.first;
    412       continue;
    413     }
    414     ++iter;
    415   }
    416   if(!atomIdPool.empty()){
    417     // check if the last range is at the border
    418     atomIdPool_t::iterator iter = atomIdPool.end();
    419     iter--;
    420     if(iter->last==currAtomId){
    421       currAtomId=iter->first;
    422       atomIdPool.erase(iter);
    423     }
    424   }
    425   lastAtomPoolSize=atomIdPool.size();
    426   numAtomDefragSkips=0;
    427 }
    428 
    429 // Molecules
    430 
    431 moleculeId_t World::getNextMoleculeId(){
    432   // try to find an Id in the pool;
    433   if(!moleculeIdPool.empty()){
    434     moleculeIdPool_t::iterator iter=moleculeIdPool.begin();
    435     moleculeId_t id = iter->first;
    436     range<moleculeId_t> newRange = makeRange(id+1,iter->last);
    437     // we wont use this iterator anymore, so we don't care about invalidating
    438     moleculeIdPool.erase(iter);
    439     if(newRange.first<newRange.last){
    440       moleculeIdPool.insert(newRange);
    441     }
    442     return id;
    443   }
    444   // Nothing in the pool... we are out of luck
    445   return currMoleculeId++;
    446 }
    447 
    448 void World::releaseMoleculeId(moleculeId_t id){
    449   moleculeIdPool.insert(makeRange(id,id+1));
    450   defragMoleculeIdPool();
    451 }
    452 
    453 bool World::reserveMoleculeId(moleculeId_t id){
    454   if(id>=currMoleculeId ){
    455     range<moleculeId_t> newRange = makeRange(currMoleculeId,id);
    456     if(newRange.first<newRange.last){
    457       moleculeIdPool.insert(newRange);
    458     }
    459     currMoleculeId=id+1;
    460     defragMoleculeIdPool();
    461     return true;
    462   }
    463   // look for a range that matches the request
    464   for(moleculeIdPool_t::iterator iter=moleculeIdPool.begin();iter!=moleculeIdPool.end();++iter){
    465     if(iter->isBefore(id)){
    466       // we have coverd all available ranges... nothing to be found here
    467       break;
    468     }
    469     // no need to check first, since it has to be <=id, since otherwise we would have broken out
    470     if(!iter->isBeyond(id)){
    471       // we found a matching range... get the id from this range
    472 
    473       // split up this range at the point of id
    474       range<moleculeId_t> bottomRange = makeRange(iter->first,id);
    475       range<moleculeId_t> topRange = makeRange(id+1,iter->last);
    476       // remove this range
    477       moleculeIdPool.erase(iter);
    478       if(bottomRange.first<bottomRange.last){
    479         moleculeIdPool.insert(bottomRange);
    480       }
    481       if(topRange.first<topRange.last){
    482         moleculeIdPool.insert(topRange);
    483       }
    484       defragMoleculeIdPool();
    485       return true;
    486     }
    487   }
    488   // this ID could not be reserved
    489   return false;
    490 }
    491 
    492 void World::defragMoleculeIdPool(){
    493   // check if the situation is bad enough to make defragging neccessary
    494   if((numMoleculeDefragSkips<MAX_FRAGMENTATION_SKIPS) &&
    495      (moleculeIdPool.size()<lastMoleculePoolSize+MAX_POOL_FRAGMENTATION)){
    496     ++numMoleculeDefragSkips;
    497     return;
    498   }
    499   for(moleculeIdPool_t::iterator iter = moleculeIdPool.begin();iter!=moleculeIdPool.end();){
    500     // see if this range is adjacent to the next one
    501     moleculeIdPool_t::iterator next = iter;
    502     next++;
    503     if(next!=moleculeIdPool.end() && (next->first==iter->last)){
    504       // merge the two ranges
    505       range<moleculeId_t> newRange = makeRange(iter->first,next->last);
    506       moleculeIdPool.erase(iter);
    507       moleculeIdPool.erase(next);
    508       pair<moleculeIdPool_t::iterator,bool> res = moleculeIdPool.insert(newRange);
    509       ASSERT(res.second,"Id-Pool was confused");
    510       iter=res.first;
    511       continue;
    512     }
    513     ++iter;
    514   }
    515   if(!moleculeIdPool.empty()){
    516     // check if the last range is at the border
    517     moleculeIdPool_t::iterator iter = moleculeIdPool.end();
    518     iter--;
    519     if(iter->last==currMoleculeId){
    520       currMoleculeId=iter->first;
    521       moleculeIdPool.erase(iter);
    522     }
    523   }
    524   lastMoleculePoolSize=moleculeIdPool.size();
    525   numMoleculeDefragSkips=0;
    526 }
    527 
    528327/******************************* Iterators ********************************/
    529328
     
    823622    atoms(this),
    824623    selectedAtoms(this),
    825     currAtomId(0),
    826     lastAtomPoolSize(0),
    827     numAtomDefragSkips(0),
     624    atomIdPool(0, 20, 100),
    828625    molecules(this),
    829626    selectedMolecules(this),
    830     currMoleculeId(0),
    831     lastMoleculePoolSize(0),
    832     numMoleculeDefragSkips(0),
     627    moleculeIdPool(0, 20,100),
    833628    molecules_deprecated(new MoleculeListClass(this))
    834629{
     
    873668// Explicit instantiation of the singleton mechanism at this point
    874669
     670// moleculeId_t und atomId_t sind gleicher Basistyp, deswegen nur einen von beiden konstruieren
     671CONSTRUCT_IDPOOL(moleculeId_t)
     672
    875673CONSTRUCT_SINGLETON(World)
    876674
  • src/World.hpp

    r401f90 r3e4fb6  
    99#define WORLD_HPP_
    1010
     11// include config.h
     12#ifdef HAVE_CONFIG_H
     13#include <config.h>
     14#endif
     15
    1116/*********************************************** includes ***********************************/
    1217
     
    1823#include <boost/shared_ptr.hpp>
    1924
    20 #include "types.hpp"
    2125#include "Actions/ActionTrait.hpp"
     26#include "AtomSet.hpp"
    2227#include "Descriptors/SelectiveIterator.hpp"
    2328#include "CodePatterns/Observer.hpp"
     
    2631#include "CodePatterns/ObservedContainer.hpp"
    2732#include "CodePatterns/Range.hpp"
    28 #include "AtomSet.hpp"
    29 
    30 // include config.h
    31 #ifdef HAVE_CONFIG_H
    32 #include <config.h>
    33 #endif
     33#include "IdPool.hpp"
     34#include "types.hpp"
    3435
    3536// forward declarations
     
    443444  AtomSet atoms;
    444445  AtomSet selectedAtoms;
    445   typedef std::set<range<atomId_t> > atomIdPool_t;
    446446  /**
    447447   * stores the pool for all available AtomIds below currAtomId
     
    449449   * The pool contains ranges of free ids in the form [bottom,top).
    450450   */
    451   atomIdPool_t atomIdPool;
    452   atomId_t currAtomId; //!< stores the next available Id for atoms
    453   size_t lastAtomPoolSize; //!< size of the pool after last defrag, to skip some defrags
    454   unsigned int numAtomDefragSkips;
     451  IdPool<atomId_t> atomIdPool;
    455452
    456453  MoleculeSet molecules;
    457454  MoleculeSet selectedMolecules;
    458   typedef std::set<range<atomId_t> > moleculeIdPool_t;
    459455  /**
    460456   * stores the pool for all available AtomIds below currAtomId
     
    462458   * The pool contains ranges of free ids in the form [bottom,top).
    463459   */
    464   moleculeIdPool_t moleculeIdPool;
    465   moleculeId_t currMoleculeId;
    466   size_t lastMoleculePoolSize; //!< size of the pool after last defrag, to skip some defrags
    467   unsigned int numMoleculeDefragSkips;
     460  IdPool<moleculeId_t> moleculeIdPool;
     461
    468462private:
    469463  /**
  • src/documentation/constructs/world.dox

    r401f90 r3e4fb6  
    108108 * respectively.
    109109 *
     110 * \subsection world-internals-notes Notes on internals of the World
     111 *
     112 * \paragraph world-internals-notes-idpool
     113 *
     114 * The World has an idpool to manage the ids of atoms and molecules, i.e. such
     115 * that they are:
     116 * -# unique
     117 * -# not loosely spread over the whole range of possible, but tightly packed
     118 *
     119 * For the latter to work we have a class IdPool that manages the ids and
     120 * defragments the pool from time to time by combining ranges of released ids.
    110121 *
    111122 * \date 2011-10-31
Note: See TracChangeset for help on using the changeset viewer.