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

Comparing trunk/OOPSE-4/src/brains/BlockSnapshotManager.cpp (file contents):
Revision 2031 by tim, Tue Feb 15 17:11:35 2005 UTC vs.
Revision 2035 by tim, Tue Feb 15 19:36:07 2005 UTC

# Line 48 | Line 48 | BlockSnapshotManager::BlockSnapshotManager(SimInfo* in
48   namespace oopse {
49   BlockSnapshotManager::BlockSnapshotManager(SimInfo* info, const std::string& filename,
50      int storageLayout, int blockCapacity)
51 <    : SnapshotManager(storageLayout), info_(info), 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 106 | Line 107 | bool BlockSnapshotManager::isBlockActive(int block) {
107   #endif
108   }
109  
109 bool BlockSnapshotManager::isBlockActive(int block) {
110    return std::find(activeBlocks_.begin(), activeBlocks_.end(), block) != activeBlocks_.end() ? true : false;
111 }
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) {
120 <            snapshots_[i] = loadFrame(i);
121 <        }
122 <        
123 <        std::vector<int>::iterator j;
124 <        j = std::find(activeBlocks_.begin(), activeBlocks_.end(), -1);
125 <        assert(j != activeBlocks_.end());
126 <        *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;
145 <        j = std::find(activeBlocks_.begin(), activeBlocks_.end(), block);
146 <        assert(j != activeBlocks_.end());
147 <        *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);
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      oopse::copy_if(activeBlocks_.begin(), activeBlocks_.end(), std::back_inserter(result),

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines