summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpp/CHANGES4
-rw-r--r--cpp/src/Freeze/EvictorI.cpp159
-rw-r--r--cpp/src/Freeze/EvictorI.h4
-rw-r--r--cpp/test/Freeze/evictor/Client.cpp31
4 files changed, 148 insertions, 50 deletions
diff --git a/cpp/CHANGES b/cpp/CHANGES
index da56c27eda9..f126548a137 100644
--- a/cpp/CHANGES
+++ b/cpp/CHANGES
@@ -1,6 +1,10 @@
Changes since version 2.0.0
---------------------------
+- Added ice_ping optimization in the Freeze evictor: for operation
+ "ice_ping", the object is not loaded in the cache, Freeze only
+ checks if the object is in the cache or the database.
+
- Fixed a slice2cpp failure when the --output-dir option specified a
directory containing backslashes.
diff --git a/cpp/src/Freeze/EvictorI.cpp b/cpp/src/Freeze/EvictorI.cpp
index 5ae651a2166..a02a34753c8 100644
--- a/cpp/src/Freeze/EvictorI.cpp
+++ b/cpp/src/Freeze/EvictorI.cpp
@@ -286,7 +286,8 @@ Freeze::EvictorI::EvictorI(const ObjectAdapterPtr& adapter,
_dbEnv(SharedDbEnv::get(_communicator, envName, dbEnv)),
_filename(filename),
_createDb(createDb),
- _trace(0)
+ _trace(0),
+ _pingObject(new Ice::Object)
{
_trace = _communicator->getProperties()->getPropertyAsInt("Freeze.Trace.Evictor");
_deadlockWarning = (_communicator->getProperties()->getPropertyAsInt("Freeze.Warn.Deadlocks") != 0);
@@ -1022,9 +1023,18 @@ Freeze::EvictorI::hasObject(const Identity& ident)
bool
Freeze::EvictorI::hasFacet(const Identity& ident, const string& facet)
{
- checkIdentity(ident);
DeactivateController::Guard deactivateGuard(_deactivateController);
+ return hasFacetImpl(ident, facet);
+}
+bool
+Freeze::EvictorI::hasFacetImpl(const Identity& ident, const string& facet)
+{
+ //
+ // Must be called with _deactivateController locked.
+ //
+
+ checkIdentity(ident);
ObjectStore* store = 0;
{
@@ -1051,66 +1061,125 @@ Freeze::EvictorI::hasFacet(const Identity& ident, const string& facet)
return store->dbHasObject(ident);
}
-
-ObjectPtr
-Freeze::EvictorI::locate(const Current& current, LocalObjectPtr& cookie)
+bool
+Freeze::EvictorI::hasAnotherFacet(const Identity& ident, const string& facet)
{
//
- // If only Ice calls locate/finished/deactivate, then it cannot be deactivated.
+ // Must be called with _deactivateController locked.
//
- DeactivateController::Guard deactivateGuard(_deactivateController);
- ObjectPtr result = locateImpl(current, cookie);
-
- if(result == 0)
+ //
+ // If the object exists in another store, throw FacetNotExistException
+ // instead of returning 0 (== ObjectNotExistException)
+ //
+ StoreMap storeMapCopy;
+ {
+ Lock sync(*this);
+ storeMapCopy = _storeMap;
+ }
+
+ for(StoreMap::iterator p = storeMapCopy.begin(); p != storeMapCopy.end(); ++p)
{
//
- // If the object exists in another store, throw FacetNotExistException
- // instead of returning 0 (== ObjectNotExistException)
- //
- StoreMap storeMapCopy;
- {
- Lock sync(*this);
- storeMapCopy = _storeMap;
- }
- for(StoreMap::iterator p = storeMapCopy.begin(); p != storeMapCopy.end(); ++p)
- {
- //
- // Do not check again the current facet
- //
- if((*p).first != current.facet)
- {
- ObjectStore* store = (*p).second;
-
- bool inCache = false;
+ // Do not check again the given facet
+ //
+ if((*p).first != facet)
+ {
+ ObjectStore* store = (*p).second;
+
+ bool inCache = false;
+ {
+ Lock sync(*this);
+
+ EvictorElementPtr element = store->getIfPinned(ident);
+ if(element != 0)
{
- Lock sync(*this);
+ inCache = true;
+ assert(!element->stale);
- EvictorElementPtr element = store->getIfPinned(current.id);
- if(element != 0)
+ IceUtil::Mutex::Lock lock(element->mutex);
+ if(element->status != EvictorElement::dead &&
+ element->status != EvictorElement::destroyed)
{
- inCache = true;
- assert(!element->stale);
-
- IceUtil::Mutex::Lock lock(element->mutex);
- if(element->status != EvictorElement::dead &&
- element->status != EvictorElement::destroyed)
- {
- throw FacetNotExistException(__FILE__, __LINE__);
- }
+ return true;
}
}
- if(!inCache)
+ }
+ if(!inCache)
+ {
+ if(store->dbHasObject(ident))
{
- if(store->dbHasObject(current.id))
- {
- throw FacetNotExistException(__FILE__, __LINE__);
- }
+ return true;
}
}
}
}
+ return false;
+}
+
+ObjectPtr
+Freeze::EvictorI::locate(const Current& current, LocalObjectPtr& cookie)
+{
+ //
+ // We need this guard because the application may call locate/finished/deactivate
+ // directly.
+ //
+ DeactivateController::Guard deactivateGuard(_deactivateController);
+
+ //
+ // Special ice_ping() handling
+ //
+ if(current.operation == "ice_ping")
+ {
+ assert(current.mode == Nonmutating);
+
+ if(hasFacetImpl(current.id, current.facet))
+ {
+ if(_trace >= 3)
+ {
+ Trace out(_communicator->getLogger(), "Freeze.Evictor");
+ out << "ice_ping found \"" << identityToString(current.id)
+ << "\" with facet \"" << current.facet + "\"";
+ }
+
+ cookie = 0;
+ return _pingObject;
+ }
+ else if(hasAnotherFacet(current.id, current.facet))
+ {
+ if(_trace >= 3)
+ {
+ Trace out(_communicator->getLogger(), "Freeze.Evictor");
+ out << "ice_ping raises FacetNotExistException for \"" << identityToString(current.id)
+ << "\" with facet \"" << current.facet + "\"";
+ }
+ throw FacetNotExistException(__FILE__, __LINE__);
+ }
+ else
+ {
+ if(_trace >= 3)
+ {
+ if(_trace >= 3)
+ {
+ Trace out(_communicator->getLogger(), "Freeze.Evictor");
+ out << "ice_ping will raise ObjectNotExistException for \"" << identityToString(current.id)
+ << "\" with facet \"" << current.facet + "\"";
+ }
+ }
+ return 0;
+ }
+ }
+
+ ObjectPtr result = locateImpl(current, cookie);
+
+ if(result == 0)
+ {
+ if(hasAnotherFacet(current.id, current.facet))
+ {
+ throw FacetNotExistException(__FILE__, __LINE__);
+ }
+ }
return result;
}
diff --git a/cpp/src/Freeze/EvictorI.h b/cpp/src/Freeze/EvictorI.h
index 8a5a9b92e85..d16be2e37bd 100644
--- a/cpp/src/Freeze/EvictorI.h
+++ b/cpp/src/Freeze/EvictorI.h
@@ -177,6 +177,8 @@ public:
private:
Ice::ObjectPtr locateImpl(const Ice::Current&, Ice::LocalObjectPtr&);
+ bool hasFacetImpl(const Ice::Identity&, const std::string&);
+ bool hasAnotherFacet(const Ice::Identity&, const std::string&);
void evict();
void evict(const EvictorElementPtr&);
@@ -236,6 +238,8 @@ private:
IceUtil::Time _savePeriod;
bool _deadlockWarning;
+
+ Ice::ObjectPtr _pingObject;
};
diff --git a/cpp/test/Freeze/evictor/Client.cpp b/cpp/test/Freeze/evictor/Client.cpp
index a7f525fa600..c1b54141376 100644
--- a/cpp/test/Freeze/evictor/Client.cpp
+++ b/cpp/test/Freeze/evictor/Client.cpp
@@ -303,8 +303,22 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
for(i = 0; i < size; i++)
{
servants.push_back(evictor->createServant(i, i));
+ servants[i]->ice_ping();
+
+ Test::FacetPrx facet1 = Test::FacetPrx::uncheckedCast(servants[i], "facet1");
+ try
+ {
+ facet1->ice_ping();
+ test(false);
+ }
+ catch(const Ice::FacetNotExistException&)
+ {
+ // Expected
+ }
+
servants[i]->addFacet("facet1", "data");
- Test::FacetPrx facet1 = Test::FacetPrx::checkedCast(servants[i], "facet1");
+ facet1->ice_ping();
+ facet1 = Test::FacetPrx::checkedCast(servants[i], "facet1");
test(facet1);
facet1->setValue(10 * i);
facet1->addFacet("facet2", "moreData");
@@ -425,7 +439,7 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
servants[i]->removeFacet("facet1");
servants[i]->removeFacet("facet2");
}
-
+
//
// Check they are all gone
//
@@ -437,12 +451,9 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
test(facet2 == 0);
}
-
evictor->setSize(0);
evictor->setSize(size);
-
-
for(i = 0; i < size; i++)
{
test(servants[i]->getValue() == i + 300);
@@ -466,6 +477,16 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
{
// Expected
}
+
+ try
+ {
+ servants[i]->ice_ping();
+ test(false);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ // Expected
+ }
}
//