diff options
Diffstat (limited to 'cpp/src/IceGrid/ObjectCache.cpp')
-rw-r--r-- | cpp/src/IceGrid/ObjectCache.cpp | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/cpp/src/IceGrid/ObjectCache.cpp b/cpp/src/IceGrid/ObjectCache.cpp new file mode 100644 index 00000000000..ef73e7711bc --- /dev/null +++ b/cpp/src/IceGrid/ObjectCache.cpp @@ -0,0 +1,233 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/Random.h> +#include <Ice/Communicator.h> +#include <Ice/LoggerUtil.h> +#include <Ice/LocalException.h> +#include <IceGrid/ObjectCache.h> +#include <IceGrid/NodeSessionI.h> +#include <IceGrid/ServerCache.h> +#include <IceGrid/SessionI.h> + +using namespace std; +using namespace IceGrid; + +pointer_to_unary_function<int, unsigned int> ObjectCache::_rand(IceUtilInternal::random); + +namespace IceGrid +{ + +struct ObjectEntryCI : binary_function<ObjectEntryPtr&, ObjectEntryPtr&, bool> +{ + + bool + operator()(const ObjectEntryPtr& lhs, const ObjectEntryPtr& rhs) + { + return ::Ice::proxyIdentityLess(lhs->getProxy(), rhs->getProxy()); + } +}; + +struct ObjectLoadCI : binary_function<pair<Ice::ObjectPrx, float>&, pair<Ice::ObjectPrx, float>&, bool> +{ + bool operator()(const pair<Ice::ObjectPrx, float>& lhs, const pair<Ice::ObjectPrx, float>& rhs) + { + return lhs.second < rhs.second; + } +}; + +}; + +ObjectCache::TypeEntry::TypeEntry() +{ +} + +void +ObjectCache::TypeEntry::add(const ObjectEntryPtr& obj) +{ + // + // No mutex protection here, this is called with the cache locked. + // + _objects.insert(lower_bound(_objects.begin(), _objects.end(), obj, ObjectEntryCI()), obj); +} + +bool +ObjectCache::TypeEntry::remove(const ObjectEntryPtr& obj) +{ + // + // No mutex protection here, this is called with the cache locked. + // + vector<ObjectEntryPtr>::iterator q = lower_bound(_objects.begin(), _objects.end(), obj, ObjectEntryCI()); + assert(q->get() == obj.get()); + _objects.erase(q); + return _objects.empty(); +} + +ObjectCache::ObjectCache(const Ice::CommunicatorPtr& communicator) : _communicator(communicator) +{ +} + +void +ObjectCache::add(const ObjectInfo& info, const string& application) +{ + const Ice::Identity& id = info.proxy->ice_getIdentity(); + + Lock sync(*this); + if(getImpl(id)) + { + Ice::Error out(_communicator->getLogger()); + out << "can't add duplicate object `" << _communicator->identityToString(id) << "'"; + return; + } + + ObjectEntryPtr entry = new ObjectEntry(*this, info, application); + addImpl(id, entry); + + map<string, TypeEntry>::iterator p = _types.find(entry->getType()); + if(p == _types.end()) + { + p = _types.insert(p, map<string, TypeEntry>::value_type(entry->getType(), TypeEntry())); + } + p->second.add(entry); + + if(_traceLevels && _traceLevels->object > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->objectCat); + out << "added object `" << _communicator->identityToString(id) << "'"; + } +} + +ObjectEntryPtr +ObjectCache::get(const Ice::Identity& id) const +{ + Lock sync(*this); + ObjectEntryPtr entry = getImpl(id); + if(!entry) + { + throw ObjectNotRegisteredException(id); + } + return entry; +} + +void +ObjectCache::remove(const Ice::Identity& id) +{ + Lock sync(*this); + ObjectEntryPtr entry = getImpl(id); + if(!entry) + { + Ice::Error out(_communicator->getLogger()); + out << "can't remove unknown object `" << _communicator->identityToString(id) << "'"; + return; + } + removeImpl(id); + + map<string, TypeEntry>::iterator p = _types.find(entry->getType()); + assert(p != _types.end()); + if(p->second.remove(entry)) + { + _types.erase(p); + } + + if(_traceLevels && _traceLevels->object > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->objectCat); + out << "removed object `" << _communicator->identityToString(id) << "'"; + } +} + +Ice::ObjectProxySeq +ObjectCache::getObjectsByType(const string& type) +{ + Lock sync(*this); + Ice::ObjectProxySeq proxies; + map<string, TypeEntry>::const_iterator p = _types.find(type); + if(p == _types.end()) + { + return proxies; + } + const vector<ObjectEntryPtr>& objects = p->second.getObjects(); + for(vector<ObjectEntryPtr>::const_iterator q = objects.begin(); q != objects.end(); ++q) + { + proxies.push_back((*q)->getProxy()); + } + return proxies; +} + +ObjectInfoSeq +ObjectCache::getAll(const string& expression) +{ + Lock sync(*this); + ObjectInfoSeq infos; + for(map<Ice::Identity, ObjectEntryPtr>::const_iterator p = _entries.begin(); p != _entries.end(); ++p) + { + if(expression.empty() || IceUtilInternal::match(_communicator->identityToString(p->first), expression, true)) + { + infos.push_back(p->second->getObjectInfo()); + } + } + return infos; +} + +ObjectInfoSeq +ObjectCache::getAllByType(const string& type) +{ + Lock sync(*this); + ObjectInfoSeq infos; + map<string, TypeEntry>::const_iterator p = _types.find(type); + if(p == _types.end()) + { + return infos; + } + + const vector<ObjectEntryPtr>& objects = p->second.getObjects(); + for(vector<ObjectEntryPtr>::const_iterator q = objects.begin(); q != objects.end(); ++q) + { + infos.push_back((*q)->getObjectInfo()); + } + return infos; +} + +ObjectEntry::ObjectEntry(ObjectCache& cache, const ObjectInfo& info, const string& application) : + _cache(cache), + _info(info), + _application(application) +{ +} + +Ice::ObjectPrx +ObjectEntry::getProxy() const +{ + return _info.proxy; +} + +string +ObjectEntry::getType() const +{ + return _info.type; +} + +string +ObjectEntry::getApplication() const +{ + return _application; +} + +const ObjectInfo& +ObjectEntry::getObjectInfo() const +{ + return _info; +} + +bool +ObjectEntry::canRemove() +{ + return true; +} + |