diff options
author | Bernard Normier <bernard@zeroc.com> | 2004-04-19 20:55:36 +0000 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2004-04-19 20:55:36 +0000 |
commit | 8e39b811b7b71c2e5cf2f623b5d108a62d882d5e (patch) | |
tree | 16df76b8ecdd90dae6557b447dcd3847df381757 /cpp/src/Freeze/EvictorI.cpp | |
parent | Changed looking detection policy to DB_LOCK_YOUNGEST (diff) | |
download | ice-8e39b811b7b71c2e5cf2f623b5d108a62d882d5e.tar.bz2 ice-8e39b811b7b71c2e5cf2f623b5d108a62d882d5e.tar.xz ice-8e39b811b7b71c2e5cf2f623b5d108a62d882d5e.zip |
Added keep, keepFacet, remove and removeFacet to Evictor; implemented
IceUtil::Cache properly
Diffstat (limited to 'cpp/src/Freeze/EvictorI.cpp')
-rw-r--r-- | cpp/src/Freeze/EvictorI.cpp | 288 |
1 files changed, 230 insertions, 58 deletions
diff --git a/cpp/src/Freeze/EvictorI.cpp b/cpp/src/Freeze/EvictorI.cpp index c81525ef805..70dd963b0b9 100644 --- a/cpp/src/Freeze/EvictorI.cpp +++ b/cpp/src/Freeze/EvictorI.cpp @@ -322,11 +322,11 @@ Freeze::EvictorI::addFacet(const ObjectPtr& servant, const Identity& ident, cons EvictorElementPtr element = new EvictorElement(*store); element->status = EvictorElement::dead; - pair<EvictorElementPtr, bool> ir = store->insert(ident, element); + EvictorElementPtr oldElt = store->putIfAbsent(ident, element); - if(ir.second == false) + if(oldElt != 0) { - element = ir.first; + element = oldElt; } { @@ -439,11 +439,11 @@ Freeze::EvictorI::createObject(const Identity& ident, const ObjectPtr& servant) EvictorElementPtr element = new EvictorElement(*store); element->status = EvictorElement::dead; - pair<EvictorElementPtr, bool> ir = store->insert(ident, element); + EvictorElementPtr oldElt = store->putIfAbsent(ident, element); - if(ir.second == false) + if(oldElt != 0) { - element = ir.first; + element = oldElt; } { @@ -559,46 +559,62 @@ Freeze::EvictorI::removeFacet(const Identity& ident, const string& facet) } fixEvictPosition(element); - IceUtil::Mutex::Lock lock(element->mutex); - - switch(element->status) { - case EvictorElement::clean: - { - element->status = EvictorElement::destroyed; - element->rec.servant = 0; - addToModifiedQueue(element); - break; - } - case EvictorElement::created: - { - element->status = EvictorElement::dead; - element->rec.servant = 0; - break; - } - case EvictorElement::modified: - { - element->status = EvictorElement::destroyed; - element->rec.servant = 0; - // - // Not necessary to push it on the modified queue, as a modified - // element is either on the queue already or about to be saved - // (at which point it becomes clean) - // - break; - } - case EvictorElement::destroyed: - case EvictorElement::dead: - { - notThere = true; - break; - } - default: + IceUtil::Mutex::Lock lock(element->mutex); + + switch(element->status) { - assert(0); - break; + case EvictorElement::clean: + { + element->status = EvictorElement::destroyed; + element->rec.servant = 0; + addToModifiedQueue(element); + break; + } + case EvictorElement::created: + { + element->status = EvictorElement::dead; + element->rec.servant = 0; + break; + } + case EvictorElement::modified: + { + element->status = EvictorElement::destroyed; + element->rec.servant = 0; + // + // Not necessary to push it on the modified queue, as a modified + // element is either on the queue already or about to be saved + // (at which point it becomes clean) + // + break; + } + case EvictorElement::destroyed: + case EvictorElement::dead: + { + notThere = true; + break; + } + default: + { + assert(0); + break; + } } } + if(element->keepCount > 0) + { + assert(notThere == false); + + element->keepCount = 0; + // + // Add to front of evictor queue + // + // Note that save evicts dead objects + // + _evictorList.push_front(element); + _currentEvictorSize++; + element->evictPosition = _evictorList.begin(); + } } break; // for(;;) } @@ -645,6 +661,156 @@ Freeze::EvictorI::destroyObject(const Identity& ident) } } +void +Freeze::EvictorI::keep(const Identity& ident) +{ + keepFacet(ident, ""); +} + +void +Freeze::EvictorI::keepFacet(const Identity& ident, const string& facet) +{ + bool notThere = false; + + ObjectStore* store = findStore(facet); + if(store == 0) + { + notThere = true; + } + else + { + for(;;) + { + EvictorElementPtr element = store->pin(ident); + if(element == 0) + { + notThere = true; + break; + } + + Lock sync(*this); + if(_deactivated) + { + throw EvictorDeactivatedException(__FILE__, __LINE__); + } + + if(element->stale) + { + // + // try again + // + continue; + } + + + { + IceUtil::Mutex::Lock lockElement(element->mutex); + if(element->status == EvictorElement::destroyed || element->status == EvictorElement::dead) + { + notThere = true; + break; + } + } + + // + // Found! + // + + if(element->keepCount == 0) + { + if(element->usageCount < 0) + { + // + // New object + // + element->usageCount = 0; + } + else + { + _evictorList.erase(element->evictPosition); + _currentEvictorSize--; + } + element->keepCount = 1; + } + else + { + element->keepCount++; + } + break; + } + } + + if(notThere) + { + NotRegisteredException ex(__FILE__, __LINE__); + ex.kindOfObject = "servant"; + ex.id = identityToString(ident); + if(!facet.empty()) + { + ex.id += " -f " + facet; + } + throw ex; + } +} + +void +Freeze::EvictorI::release(const Identity& ident) +{ + releaseFacet(ident, ""); +} + +void +Freeze::EvictorI::releaseFacet(const Identity& ident, const string& facet) +{ + { + Lock sync(*this); + + if(_deactivated) + { + throw EvictorDeactivatedException(__FILE__, __LINE__); + } + + StoreMap::iterator p = _storeMap.find(facet); + if(p != _storeMap.end()) + { + ObjectStore* store = (*p).second; + + EvictorElementPtr element = store->getIfPinned(ident); + if(element != 0) + { + assert(!element->stale); + if(element->keepCount > 0) + { + if(--element->keepCount == 0) + { + // + // Add to front of evictor queue + // + // Note that the element cannot be destroyed or dead since + // its keepCount was > 0. + // + _evictorList.push_front(element); + _currentEvictorSize++; + element->evictPosition = _evictorList.begin(); + } + // + // Success + // + return; + } + } + } + } + + NotRegisteredException ex(__FILE__, __LINE__); + ex.kindOfObject = "servant"; + ex.id = identityToString(ident); + if(!facet.empty()) + { + ex.id += " -f " + facet; + } + throw ex; +} EvictorIteratorPtr Freeze::EvictorI::getIterator(const string& facet, Int batchSize) @@ -692,7 +858,7 @@ Freeze::EvictorI::hasFacet(const Identity& ident, const string& facet) return false; } - ObjectStore* store = (*p).second; + store = (*p).second; EvictorElementPtr element = store->getIfPinned(ident); if(element != 0) @@ -858,7 +1024,7 @@ Freeze::EvictorI::finished(const Current& current, const ObjectPtr& servant, con { addToModifiedQueue(element); } - else + else if(element->usageCount == 0 && element->keepCount == 0) { // // Evict as many elements as necessary. @@ -1230,7 +1396,7 @@ Freeze::EvictorI::run() EvictorElementPtr& element = *q; if(!element->stale) { - if(element->usageCount == 0) + if(element->usageCount == 0 && element->keepCount == 0) { // // Get rid of unused dead elements @@ -1345,6 +1511,7 @@ Freeze::EvictorI::evict() EvictorElementPtr& element = *p; assert(!element->stale); + assert(element->keepCount == 0); if(_trace >= 2 || (_trace >= 1 && _evictorList.size() % 50 == 0)) { @@ -1374,27 +1541,32 @@ void Freeze::EvictorI::fixEvictPosition(const EvictorElementPtr& element) { assert(!element->stale); - if(element->usageCount < 0) - { - // - // New object - // - element->usageCount = 0; - _currentEvictorSize++; - } - else + + if(element->keepCount == 0) { - _evictorList.erase(element->evictPosition); + if(element->usageCount < 0) + { + // + // New object + // + element->usageCount = 0; + _currentEvictorSize++; + } + else + { + _evictorList.erase(element->evictPosition); + } + _evictorList.push_front(element); + element->evictPosition = _evictorList.begin(); } - _evictorList.push_front(element); - element->evictPosition = _evictorList.begin(); } void Freeze::EvictorI::evict(const EvictorElementPtr& element) { assert(!element->stale); - + assert(element->keepCount == 0); + _evictorList.erase(element->evictPosition); _currentEvictorSize--; element->stale = true; |