Identify files in object cache by filename and optional provided options.
Objects with the same filename may be different from others based on the provided plugin options. Using filename *and* the provided options as object cache key helps to avoid fetching the wrong object.
This commit is contained in:
parent
3816e4c76e
commit
85cd1c456f
@ -50,16 +50,16 @@ class OSGDB_EXPORT ObjectCache : public osg::Referenced
|
||||
void addObjectCache(ObjectCache* object);
|
||||
|
||||
/** Add a filename,object,timestamp triple to the Registry::ObjectCache.*/
|
||||
void addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp = 0.0);
|
||||
void addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp = 0.0, const Options *options = NULL);
|
||||
|
||||
/** Remove Object from cache.*/
|
||||
void removeFromObjectCache(const std::string& fileName);
|
||||
void removeFromObjectCache(const std::string& fileName, const Options *options = NULL);
|
||||
|
||||
/** Get an Object from the object cache*/
|
||||
osg::Object* getFromObjectCache(const std::string& fileName);
|
||||
osg::Object* getFromObjectCache(const std::string& fileName, const Options *options = NULL);
|
||||
|
||||
/** Get an ref_ptr<Object> from the object cache*/
|
||||
osg::ref_ptr<osg::Object> getRefFromObjectCache(const std::string& fileName);
|
||||
osg::ref_ptr<osg::Object> getRefFromObjectCache(const std::string& fileName, const Options *options = NULL);
|
||||
|
||||
/** call rleaseGLObjects on all objects attached to the object cache.*/
|
||||
void releaseGLObjects(osg::State* state);
|
||||
@ -69,7 +69,8 @@ class OSGDB_EXPORT ObjectCache : public osg::Referenced
|
||||
virtual ~ObjectCache();
|
||||
|
||||
typedef std::pair<osg::ref_ptr<osg::Object>, double > ObjectTimeStampPair;
|
||||
typedef std::map<std::string, ObjectTimeStampPair > ObjectCacheMap;
|
||||
typedef std::pair<std::string, osg::ref_ptr<const osgDB::Options> > FileNameOptionsPair;
|
||||
typedef std::map<FileNameOptionsPair, ObjectTimeStampPair > ObjectCacheMap;
|
||||
|
||||
ObjectCacheMap _objectCache;
|
||||
OpenThreads::Mutex _objectCacheMutex;
|
||||
|
@ -255,10 +255,12 @@ class OSGDB_EXPORT Options : public osg::Object
|
||||
/** Get the parentGroup observer_ptr, where the loaded model is intended to be added */
|
||||
const osg::observer_ptr<osg::Group>& getParentGroup() const { return _parentGroup; }
|
||||
|
||||
protected:
|
||||
|
||||
bool operator < (const Options &rhs) const;
|
||||
bool operator == (const Options &rhs) const;
|
||||
virtual ~Options() {}
|
||||
|
||||
protected:
|
||||
|
||||
std::string _str;
|
||||
FilePathList _databasePaths;
|
||||
|
||||
|
@ -452,16 +452,16 @@ class OSGDB_EXPORT Registry : public osg::Referenced
|
||||
void clearObjectCache();
|
||||
|
||||
/** Add a filename,object,timestamp triple to the Registry::ObjectCache.*/
|
||||
void addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp = 0.0);
|
||||
void addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp = 0.0, Options *options = NULL);
|
||||
|
||||
/** Remove Object from cache.*/
|
||||
void removeFromObjectCache(const std::string& fileName);
|
||||
void removeFromObjectCache(const std::string& fileName, Options *options = NULL);
|
||||
|
||||
/** Get an Object from the object cache*/
|
||||
osg::Object* getFromObjectCache(const std::string& fileName);
|
||||
osg::Object* getFromObjectCache(const std::string& fileName, Options *options = NULL);
|
||||
|
||||
/** Get an ref_ptr<Object> from the object cache*/
|
||||
osg::ref_ptr<osg::Object> getRefFromObjectCache(const std::string& fileName);
|
||||
osg::ref_ptr<osg::Object> getRefFromObjectCache(const std::string& fileName, Options *options = NULL);
|
||||
|
||||
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include <osgDB/ObjectCache>
|
||||
#include <osgDB/Options>
|
||||
|
||||
using namespace osgDB;
|
||||
|
||||
@ -39,34 +40,48 @@ void ObjectCache::addObjectCache(ObjectCache* objectCache)
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock1(_objectCacheMutex);
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(objectCache->_objectCacheMutex);
|
||||
|
||||
// OSG_NOTICE<<"Inserting objects to main ObjectCache "<<objectCache->_objectCache.size()<<std::endl;
|
||||
OSG_DEBUG<<"Inserting objects to main ObjectCache "<<objectCache->_objectCache.size()<<std::endl;
|
||||
|
||||
_objectCache.insert(objectCache->_objectCache.begin(), objectCache->_objectCache.end());
|
||||
}
|
||||
|
||||
|
||||
void ObjectCache::addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp)
|
||||
void ObjectCache::addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp, const Options *options)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
|
||||
_objectCache[filename]=ObjectTimeStampPair(object,timestamp);
|
||||
_objectCache[FileNameOptionsPair(filename, osg::clone(options))] = ObjectTimeStampPair(object,timestamp);
|
||||
OSG_DEBUG<<"Adding "<<filename<<" with options '"<<(options ? options->getOptionString() : "")<<"' to ObjectCache "<<this<<std::endl;
|
||||
}
|
||||
|
||||
osg::Object* ObjectCache::getFromObjectCache(const std::string& fileName)
|
||||
osg::Object* ObjectCache::getFromObjectCache(const std::string& fileName, const Options *options)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
|
||||
ObjectCacheMap::iterator itr = _objectCache.find(fileName);
|
||||
if (itr!=_objectCache.end()) return itr->second.first.get();
|
||||
ObjectCacheMap::iterator itr = _objectCache.find(FileNameOptionsPair(fileName, options));
|
||||
if (itr!=_objectCache.end())
|
||||
{
|
||||
osg::ref_ptr<const osgDB::Options> o = itr->first.second;
|
||||
if (o.valid())
|
||||
OSG_DEBUG<<"Found "<<fileName<<" with options '"<< o->getOptionString()<< "' in ObjectCache "<<this<<std::endl;
|
||||
else
|
||||
OSG_DEBUG<<"Found "<<fileName<<" in ObjectCache "<<this<<std::endl;
|
||||
return itr->second.first.get();
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Object> ObjectCache::getRefFromObjectCache(const std::string& fileName)
|
||||
osg::ref_ptr<osg::Object> ObjectCache::getRefFromObjectCache(const std::string& fileName, const Options *options)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
|
||||
ObjectCacheMap::iterator itr = _objectCache.find(fileName);
|
||||
ObjectCacheMap::iterator itr;
|
||||
itr = _objectCache.find(FileNameOptionsPair(fileName, options));
|
||||
if (itr!=_objectCache.end())
|
||||
{
|
||||
// OSG_NOTICE<<"Found "<<fileName<<" in ObjectCache "<<this<<std::endl;
|
||||
return itr->second.first;
|
||||
osg::ref_ptr<const osgDB::Options> o = itr->first.second;
|
||||
if (o.valid())
|
||||
OSG_DEBUG<<"Found "<<fileName<<" with options '"<< o->getOptionString()<< "' in ObjectCache "<<this<<std::endl;
|
||||
else
|
||||
OSG_DEBUG<<"Found "<<fileName<<" in ObjectCache "<<this<<std::endl;
|
||||
return itr->second.first.get();
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
@ -108,10 +123,10 @@ void ObjectCache::removeExpiredObjectsInCache(double expiryTime)
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectCache::removeFromObjectCache(const std::string& fileName)
|
||||
void ObjectCache::removeFromObjectCache(const std::string& fileName, const Options *options)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
|
||||
ObjectCacheMap::iterator itr = _objectCache.find(fileName);
|
||||
ObjectCacheMap::iterator itr = _objectCache.find(FileNameOptionsPair(fileName, options));
|
||||
if (itr!=_objectCache.end()) _objectCache.erase(itr);
|
||||
}
|
||||
|
||||
|
@ -56,3 +56,17 @@ void Options::parsePluginStringData(const std::string& str, char separator1, cha
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Options::operator <(const Options &rhs) const
|
||||
{
|
||||
// TODO add better compare
|
||||
//OSG_DEBUG << "comparing <'" << _str << "' with '" << rhs._str << "'" << std::endl;
|
||||
return _str.compare(rhs._str) < 0;
|
||||
}
|
||||
|
||||
bool Options::operator ==(const Options &rhs) const
|
||||
{
|
||||
// TODO add better compare
|
||||
//OSG_DEBUG << "comparing == '" << _str << "' with '" << rhs._str << "'" << std::endl;
|
||||
return _str.compare(rhs._str) == 0;
|
||||
}
|
||||
|
@ -1250,9 +1250,9 @@ ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& readFun
|
||||
if (useObjectCache)
|
||||
{
|
||||
// search for entry in the object cache.
|
||||
osg::ref_ptr<osg::Object> object = optionsCache ? optionsCache->getRefFromObjectCache(file) : 0;
|
||||
osg::ref_ptr<osg::Object> object = optionsCache ? optionsCache->getRefFromObjectCache(file, options) : 0;
|
||||
|
||||
if (!object && _objectCache.valid()) object = _objectCache->getRefFromObjectCache(file);
|
||||
if (!object && _objectCache.valid()) object = _objectCache->getRefFromObjectCache(file, options);
|
||||
|
||||
if (object.valid())
|
||||
{
|
||||
@ -1264,7 +1264,7 @@ ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& readFun
|
||||
if (rr.validObject())
|
||||
{
|
||||
// search AGAIN for entry in the object cache.
|
||||
object = _objectCache->getRefFromObjectCache(file);
|
||||
object = _objectCache->getRefFromObjectCache(file, options);
|
||||
if (object.valid())
|
||||
{
|
||||
if (readFunctor.isValid(object.get())) return ReaderWriter::ReadResult(object.get(), ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
|
||||
@ -1275,8 +1275,8 @@ ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& readFun
|
||||
}
|
||||
|
||||
// update cache with new entry.
|
||||
if (optionsCache) optionsCache->addEntryToObjectCache(file, rr.getObject(), 0.0);
|
||||
else if (_objectCache.valid()) _objectCache->addEntryToObjectCache(file, rr.getObject(), 0.0);
|
||||
if (optionsCache) optionsCache->addEntryToObjectCache(file, rr.getObject(), 0.0, options);
|
||||
else if (_objectCache.valid()) _objectCache->addEntryToObjectCache(file, rr.getObject(), 0.0, options);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1597,19 +1597,19 @@ ReaderWriter::WriteResult Registry::writeScriptImplementation(const Script& imag
|
||||
return result;
|
||||
}
|
||||
|
||||
void Registry::addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp)
|
||||
void Registry::addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp, Options *options)
|
||||
{
|
||||
if (_objectCache.valid()) _objectCache->addEntryToObjectCache(filename, object, timestamp);
|
||||
if (_objectCache.valid()) _objectCache->addEntryToObjectCache(filename, object, timestamp, options);
|
||||
}
|
||||
|
||||
osg::Object* Registry::getFromObjectCache(const std::string& filename)
|
||||
osg::Object* Registry::getFromObjectCache(const std::string& filename, Options *options)
|
||||
{
|
||||
return _objectCache.valid() ? _objectCache->getFromObjectCache(filename) : 0;
|
||||
return _objectCache.valid() ? _objectCache->getFromObjectCache(filename, options) : 0;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Object> Registry::getRefFromObjectCache(const std::string& filename)
|
||||
osg::ref_ptr<osg::Object> Registry::getRefFromObjectCache(const std::string& filename, Options *options)
|
||||
{
|
||||
return _objectCache.valid() ? _objectCache->getRefFromObjectCache(filename) : 0;
|
||||
return _objectCache.valid() ? _objectCache->getRefFromObjectCache(filename, options) : 0;
|
||||
}
|
||||
|
||||
void Registry::updateTimeStampOfObjectsInCacheWithExternalReferences(const osg::FrameStamp& frameStamp)
|
||||
@ -1623,9 +1623,9 @@ void Registry::removeExpiredObjectsInCache(const osg::FrameStamp& frameStamp)
|
||||
if (_objectCache.valid()) _objectCache->removeExpiredObjectsInCache(expiryTime);
|
||||
}
|
||||
|
||||
void Registry::removeFromObjectCache(const std::string& filename)
|
||||
void Registry::removeFromObjectCache(const std::string& filename, Options *options)
|
||||
{
|
||||
if (_objectCache.valid()) _objectCache->removeFromObjectCache(filename);
|
||||
if (_objectCache.valid()) _objectCache->removeFromObjectCache(filename, options);
|
||||
}
|
||||
|
||||
void Registry::clearObjectCache()
|
||||
|
Loading…
Reference in New Issue
Block a user