ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/src/brains/BlockSnapshotManager.cpp
(Generate patch)

Comparing trunk/OOPSE-2.0/src/brains/BlockSnapshotManager.cpp (file contents):
Revision 2002 by tim, Sun Feb 13 06:57:48 2005 UTC vs.
Revision 2036 by tim, Tue Feb 15 19:39:56 2005 UTC

# Line 40 | Line 40
40   */
41   #include <algorithm>
42   #include "brains/BlockSnapshotManager.hpp"
43 < #include "utlis/physmem.h"
43 > #include "utils/physmem.h"
44 > #include "utils/Algorithm.hpp"
45   #include "brains/SimInfo.hpp"
46   #include "io/DumpReader.hpp"
47  
48   namespace oopse {
49   BlockSnapshotManager::BlockSnapshotManager(SimInfo* info, const std::string& filename,
50      int storageLayout, int blockCapacity)
51 <    : SnapshotManager(storageLayout), info_(info),
52 <      blockCapacity_(blockCapacity), activeBlocks(blockCapacity_, -1) {
51 >    : SnapshotManager(storageLayout), info_(info), blockCapacity_(blockCapacity),
52 >      activeBlocks_(blockCapacity_, -1), activeRefCount_(blockCapacity_, 0) {
53  
54      nAtoms_ = info->getNGlobalAtoms();
55      nRigidBodies_ = info->getNGlobalRigidBodies();
# Line 57 | Line 58 | BlockSnapshotManager::BlockSnapshotManager(SimInfo* in
58      
59      int bytesPerStuntDouble = DataStorage::getBytesPerStuntDouble(storageLayout);
60  
61 <    int bytesPerFrame = nStuntDoubles * bytesPerStuntDouble;
61 >    int bytesPerFrame = (nRigidBodies_ + nAtoms_) * bytesPerStuntDouble;
62  
63      int frameCapacity = int (avalPhysMem / bytesPerFrame);
64      
65      nSnapshotPerBlock_ = frameCapacity /blockCapacity_ ;
66  
67      reader_ = new DumpReader(info, filename);
68 <    nframes_ = reader->getNFrames();
68 >    nframes_ = reader_->getNFrames();
69  
70 <    int nblocks = nframes / nSnapshotPerBlock_;
71 <    if (nframes % nSnapshotPerBlock != 0) {
70 >    int nblocks = nframes_ / nSnapshotPerBlock_;
71 >    if (nframes_ % nSnapshotPerBlock_ != 0) {
72          ++nblocks;
73      }  
74      
75      for (int i = 0; i < nblocks; ++i) {
76 <        blocks_.push_back(SnapshotBlock(i, (i+1)*nSnapshotPerBlock_);    
76 >        blocks_.push_back(SnapshotBlock(i*nSnapshotPerBlock_, (i+1)*nSnapshotPerBlock_));    
77      }
78      //the last block may not have nSnapshotPerBlock frames, we need to consider this special situation
79 <    blocks.back.second = nframes;
79 >    blocks_.back().second = nframes_;
80  
81 <    snapshots_.insert(snapshot_.begin(), nframes, NULL);  
81 >    snapshots_.insert(snapshots_.begin(), nframes_, static_cast<Snapshot*>(NULL));  
82      
83   }
84  
85  
86 < BlockSnapshotMananger::~BlockSnapshotMananger() {
86 > BlockSnapshotManager::~BlockSnapshotManager() {
87      currentSnapshot_ = NULL;
88      previousSnapshot_ = NULL;
89      
90      delete reader_;
91 <    std::for_each(activeBlocks_.begin(), activeBlocks_.end(), unloadBlock);
91 >
92 >    std::vector<int>::iterator i;
93 >    for (i = activeBlocks_.begin(); i != activeBlocks_.end(); ++i) {
94 >        if (*i != -1) {
95 >            unloadBlock(*i);
96 >        }
97 >    }
98   }
99  
100   int BlockSnapshotManager::getNActiveBlocks() {
101 <    return std::count_if(activeBlocks_.begin(), activeBlocks_.end(), std::not);
101 > #ifdef __RWSTD  
102 >    int count = 0;
103 >    std::count_if(activeBlocks_.begin(), activeBlocks_.end(), std::bind2nd(std::not_equal_to<int>(), -1), count);
104 >    return count;
105 > #else
106 >    return std::count_if(activeBlocks_.begin(), activeBlocks_.end(), std::bind2nd(std::not_equal_to<int>(), -1));
107 > #endif
108   }
109  
97 bool BlockSnapshotManager::isBlockActive(int block) {
98    return std::find(activeBlocks_.begin(), activeBlocks_.end(), block) != activeBlocks_.end() ? true : false;
99 }
110  
111 +
112   bool BlockSnapshotManager::loadBlock(int block) {
113 +    std::vector<int>::iterator i = findActiveBlock(block);
114      bool loadSuccess;
115 <    if (isBlockActive(block)) {
115 >    if (i != activeBlocks_.end()) {
116 >        //if block is already in memory, just increast the reference count
117 >        ++activeRefCount_[i - activeBlocks_.begin()];
118          loadSuccess = true;
119      } else if (getNActiveBlocks() < blockCapacity_){
120 <
121 <        for (int i = blocks_[block].first; i < blocks_[block].second; ++i) {
108 <            snapshots_[i] = loadFrame(i);
109 <        }
110 <        
111 <        std::vector<int>::iterator j;
112 <        j = std::find(activeBlocks_.begin(), activeBlocks_.end(), -1);
113 <        assert(j != activeBlocks_.end());
114 <        *j = block;    
120 >        //if number of active blocks is less than the block capacity, just load it
121 >        internalLoad(block);
122          loadSuccess = true;
123 <    }else {
123 >    } else if (hasZeroRefBlock() > 0) {
124 >        //if already reach the block capacity, need to unload a block with 0 reference
125 >        int zeroRefBlock = getFirstZeroRefBlock();
126 >        assert(zeroRefBlock != -1);
127 >        internalUnload(zeroRefBlock);
128 >        internalLoad(block);
129 >    } else {
130 >        //reach the capacity and all blocks in memory are not zero reference
131          loadSuccess = false;
132      }
133 <
133 >    
134      return loadSuccess;
135   }
136  
137   bool BlockSnapshotManager::unloadBlock(int block) {
138      bool unloadSuccess;
139 <    if (!isBlockActive(block)){
140 <        unloadSuccess = false;
141 <    } else {
142 <        for (int i = blocks_[block].first; i < blocks_[block].second; ++i) {
143 <            delete snapshots_[i];
144 <            snapshots_[i] = NULL;
139 >    std::vector<int>::iterator i = findActiveBlock(block);
140 >    
141 >    if (i != activeBlocks_.end()){
142 >        --activeRefCount_[i - activeBlocks_.begin()];
143 >        if (activeRefCount_[i - activeBlocks_.begin()] < 0) {
144 >            //in case, unloadBlock called multiple times
145 >            activeRefCount_[i - activeBlocks_.begin()]  = 0;
146          }
147 <        std::vector<int>::iterator j;
148 <        j = std::find(activeBlocks_.begin(), activeBlocks_.end(), block);
149 <        assert(j != activeBlocks_.end());
150 <        *j = -1;
147 >        
148 >        unloadSuccess = true;
149 >    } else {
150 >        unloadSuccess = false;
151      }
152 +
153 +    return unloadSuccess;
154   }
155  
156 + void BlockSnapshotManager::internalLoad(int block) {
157 +        
158 +    for (int i = blocks_[block].first; i < blocks_[block].second; ++i) {
159 +        snapshots_[i] = loadFrame(i);
160 +    }
161 +    
162 +    std::vector<int>::iterator j;
163 +    j = std::find(activeBlocks_.begin(), activeBlocks_.end(), -1);
164 +    assert(j != activeBlocks_.end());
165 +    *j = block;    
166 +    ++activeRefCount_[j - activeBlocks_.begin()];
167 + }
168 +
169 + void BlockSnapshotManager::internalUnload(int block) {
170 +    for (int i = blocks_[block].first; i < blocks_[block].second; ++i) {
171 +        delete snapshots_[i];
172 +        snapshots_[i] = NULL;
173 +    }
174 +    std::vector<int>::iterator j;
175 +    j = std::find(activeBlocks_.begin(), activeBlocks_.end(), block);
176 +    assert(j != activeBlocks_.end());
177 +    *j = -1;
178 + }
179 +
180 + bool BlockSnapshotManager::hasZeroRefBlock(){
181 +    return std::find(activeRefCount_.begin(), activeRefCount_.end(), 0) != activeRefCount_.end() ?  true : false;
182 + }
183 +
184 + int BlockSnapshotManager::getFirstZeroRefBlock(){
185 +     std::vector<int>::iterator i = std::find(activeRefCount_.begin(), activeRefCount_.end(), 0);
186 +     return i != activeRefCount_.end() ? activeBlocks_[i - activeRefCount_.begin()] : -1;
187 + }
188 +
189   std::vector<int> BlockSnapshotManager::getActiveBlocks() {
190      std::vector<int> result;
191 <    std::copy_if(activeBlocks_.begin(), activeBlocks_.end());
191 >    oopse::copy_if(activeBlocks_.begin(), activeBlocks_.end(), std::back_inserter(result),
192 >        std::bind2nd(std::not_equal_to<int>(), -1));
193 >    return result;    
194   }
195  
196   Snapshot* BlockSnapshotManager::loadFrame(int frame){
197      Snapshot* snapshot = new Snapshot(nAtoms_, nRigidBodies_, getStorageLayout());
198      snapshot->setID(frame);
199 <    setCurrentSnapshot(snapshot);   /** @todo fixed me */
199 >    
200 >    /** @todo fixed me */
201 >    Snapshot* oldSnapshot = currentSnapshot_;
202 >    currentSnapshot_ = snapshot;  
203      reader_->readFrame(frame);
204 +    currentSnapshot_ = oldSnapshot;
205      return snapshot;
206   }
207  
208 + int BlockSnapshotManager::getNFrames() {
209 +    return reader_->getNFrames();
210   }
211 +
212 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines