目标:(十七)中问题43
1、缓存分两类
(1)文件缓存
osgDB::FileCache、FileSystemCache(位于osgEarthDrivers/cache_filesystem/FileSystemCache),osgDB::FileCache主要用于网络数据读写,FileSystemCache主要用于高程、影像数据读写。
(2)内存缓存
osgEarth::MemCache,主要用于高程、影像数据读写,具体见osgEarth::ImageLayer、osgEarth::TileSource。这里存在一个问题,在请求一个瓦片时,该瓦片会存在多个缓存中,比如影像瓦片在osgEarth::ImageLayer、osgEarth::TileSource的缓存中都会存在。
2、文件缓存
2.1osgDB::FileCache
这个是osg提供的缓存,需要提供通过环境变量OSG_FILE_CACHE提供缓存路径才能创建,该缓存是全局的通过osg::Registry创建和使用。osgEarth一般不使用该缓存。
(1)缓存的创建
osgDB/Registry.cpp
Registry::Registry()
{
const char* fileCachePath = getenv("OSG_FILE_CACHE");
if (fileCachePath)
{
_fileCache = new FileCache(fileCachePath);
}
}
(2)缓存的使用
osgDB/DatabasePager.cpp
void DatabasePager::DatabaseThread::run()
{
osg::ref_ptr<FileCache> fileCache = osgDB::Registry::instance()->getFileCache();
fileCache->readNode(fileName, dr_loadOptions.get(), false);
fileCache->writeNode(*(loadedModel), fileName, dr_loadOptions.get())
}
osgDB/FileCache.cpp
ReaderWriter::ReadResult FileCache::readNode(const std::string& originalFileName, const osgDB::Options* options, bool buildKdTreeIfRequired) const
{
std::string cacheFileName = createCacheFileName(originalFileName);
if (!cacheFileName.empty() && osgDB::fileExists(cacheFileName))
{
OSG_INFO<<"FileCache::readNodeFromCache("<<originalFileName<<") as "<<cacheFileName<<std::endl;
return osgDB::Registry::instance()->readNode(cacheFileName, options, buildKdTreeIfRequired);
}
else
{
return 0;
}
}
ReaderWriter::WriteResult FileCache::writeNode(const osg::Node& node, const std::string& originalFileName, const osgDB::Options* options) const
{
std::string cacheFileName = createCacheFileName(originalFileName);
if (!cacheFileName.empty())
{
std::string path = osgDB::getFilePath(cacheFileName);
if (!osgDB::fileExists(path) && !osgDB::makeDirectory(path))
{
OSG_NOTICE<<"Could not create cache directory: "<<path<<std::endl;
return ReaderWriter::WriteResult::ERROR_IN_WRITING_FILE;
}
OSG_INFO<<"FileCache::writeNodeToCache("<<originalFileName<<") as "<<cacheFileName<<std::endl;
ReaderWriter::WriteResult result = osgDB::Registry::instance()->writeNode(node, cacheFileName, options);
if (result.success())
{
removeFileFromBlackListed(originalFileName);
}
return result;
}
return ReaderWriter::WriteResult::FILE_NOT_HANDLED;
}
2.2FileSystemCache
该缓存依附于高程、影像图层,辅助瓦片数据的快速读写,该缓存的创建需要在earth文件中设置cache属性(见后)。
(1)缓存的创建
(2)缓存的使用
(3)缓存路径和文件名的设置
std::string cacheKey = Stringify() << key.str() << "_" << key.getProfile()->getHorizSignature();
比如“0/0/0_344562d1”
URI fileURI( getHashedKey(key), _metaPath );
这里的key就是上面的cacheKey,_metaPath为D:/OSG_OAGEARTH_x86/data/test_cache\cc245f0f\osgearth_cacheinfo.json。变换完后为:"D:/OSG_OAGEARTH_x86/data/test_cache/cc245f0f/7db/16a/c8"。
std::string filename = fileURI.full() + OSG_EXT;
比如"D:/OSG_OAGEARTH_x86/data/test_cache/cc245f0f/7db/16a/c8.osgb"
3、内存缓存
该缓存依附于高程、影像图层,辅助瓦片数据的快速读写,该缓存的创建是强制的,只要图层创建就会创建配套的缓存。
(1)缓存的创建
MemCache创建,默认缓存大小为16,若要修改,有两种方式:一是设置earth文件图层的l2_cache_size属性(见后);二是设置环境变量OSGEARTH_L2_CACHE_SIZE。
MemCacheBin、LRUCache创建
(2)缓存的使用
影像缓存的保存、提取过程
osgEarth/ImageLayer.cpp
GeoImage
ImageLayer::createImageInKeyProfile(const TileKey& key,
ProgressCallback* progress)
{
//读缓存
if ( _memCache.valid() )
{
CacheBin* bin = _memCache->getOrCreateDefaultBin();
ReadResult result = bin->readObject(cacheKey, 0L);
if ( result.succeeded() )
return G