目标:(二十一)中的问题66
继承关系:
osgEarth::Cache
osgEarth::MemCache
cache中的数据是通过cachebin来实现存放的,cachebin有两种,继承关系为:
osgEarth::CacheBin
MemCacheBin(osgEarth/MemCache.cpp)
在osgEarth::Cache中有维护这osgEarth::CacheBin的map表,osgEarth::CacheBin其实就是最终的缓存数据,具体数据由其成员osg::ref_ptr<osg::Referenced> _metadata来存放。
osgEarth::MemCache中的CacheBin本质上是MemCacheBin,具体数据是在其MemCacheLRU _lru中存放,MemCacheLRU(typedef LRUCache<std::string, MemCacheEntry> MemCacheLRU)是一个osgEarth::LRUCache(Least-recently-used最近最少使用缓存类,很多操作系统中都有此种缓存类),值得注意的是LRUCache中既有map又有list,他们存放的数据是相同的,只所以要这样做,是因为map方便查找和存放,list方便定位较早的元素。
osgEarth/MemCache.cpp
typedef std::pair<osg::ref_ptr<const osg::Object>, Config> MemCacheEntry;
typedef LRUCache<std::string, MemCacheEntry> MemCacheLRU;
struct MemCacheBin : public CacheBin
{
MemCacheLRU _lru;
};
缓存的默认大小为16.
在osgDB::DatabasePager::DatabaseThread::run中处理请求时,会往图层的缓存中写入瓦片信息,在创建瓦片模型时会从缓存中读取缓存信息。
写入缓存过程
osgDB/DatabasePager.cpp
void DatabasePager::DatabaseThread::run()
{
// assume that readNode is thread safe...
ReaderWriter::ReadResult rr = readFromFileCache ?
fileCache->readNode(fileName, dr_loadOptions.get(), false) :
Registry::instance()->readNode(fileName, dr_loadOptions.get(), false);
}
osgEarth/MemCache.cpp
bool write( const std::string& key, const osg::Object* object, const Config& meta, const osgDB::Options* writeOptions)
{
if ( object )
{
osg::ref_ptr<const osg::Object> cloned = osg::clone(object, osg::CopyOp::DEEP_COPY_ALL);
_lru.insert( key, std::make_pair(cloned.get(), meta) );
return true;
}
else
return false;
}
读取缓存过程
osgDB/DatabasePager.cpp
void DatabasePager::DatabaseThread::run()
{
// assume that readNode is thread safe...
ReaderWriter::ReadResult rr = readFromFileCache ?
fileCache->readNode(fileName, dr_loadOptions.get(), false) :
Registry::instance()->readNode(fileName, dr_loadOptions.get(), false);
}
osgEarth/MemCache.cpp
ReadResult readObject(const std::string& key, const osgDB::Options*)
{
MemCacheLRU::Record rec;
_lru.get(key, rec);
// clone required since the cache is in memory
if ( rec.valid() )
{
//OE_INFO << LC << "hits: " << _lru.getStats()._hitRatio*100.0f << "%" << std::endl;
return ReadResult(
osg::clone(rec.value().first.get(), osg::CopyOp::DEEP_COPY_ALL),
rec.value().second );
}
else
{
//OE_INFO << LC << "hits: " << _lru.getStats()._hitRatio*100.0f << "%" << std::endl;
return ReadResult();
}
}
这个缓存和文件系统缓存还不一样,这里缓存在内存里,因而速度会更快。
缓存MemCacheBin在rex引擎的setMap中会间接创建
待继续分析列表:
9、earth文件中都有哪些options((九)中问题)
10、如何根据earth文件options创建不同的地理信息引擎节点((九)中问题)
11、rex地理信息引擎的四梁八柱((九)中问题)
12、osgEarth::TerrainEngineNode中setMap方法作用((十二)中问题)
13、RexTerrainEngineNode中_mapFrame的作用((十二)中问题)
14、地形变形(Terrain morphing)((十二)中问题)
15、地球瓦片过期门限的含义((十二)中问题)
16、高分辨率优先的含义((十二)中问题)
17、OSGEARTH_DEBUG_NORMALS环境变量的作用((十二)中问题)
18、活跃瓦片寄存器的作用((十二)中问题)
19、资源释放器子节点的作用((十二)中问题)
20、共享几何图形池子节点的作用((十二)中问题)
21、分页瓦片加载器子节点的作用((十二)中问题)
22、分页瓦片卸载器子节点的作用((十二)中问题)
23、栅格化器子节点的作用((十二)中问题)
24、地形子节点的作用((十二)中问题)
25、绑定渲染器的作用((十二)中问题)
26、地图回调函数的作用((十二)中问题)
27、如何将地图图层添加到rex引擎中((十二)中问题)
28、选择信息的作用((十二)中问题)
29、瓦片包围盒修改回调函数的作用((十二)中问题)
30、刷新rex引擎((十二)中问题)
31、刷新边界作用((十二)中问题)
32、osgEarth::Metrics类的意义((十四)中问题)
33、请求合并队列_mergeQueue((十四)中问题)
34、分页瓦片加载器在更新遍历时对请求处理过程((十四)中问题)
35、分页瓦片加载器在更新遍历时对已处理请求裁剪过程((十四)中问题)
36、已处理的请求队列_requests((十四)中问题)
37、DatabasePager中的_fileRequestQueue和_httpRequestQueue((十六)中问题)
38、瓦片请求的生成到处理过程详解((十六)中问题)
39、瓦片节点TileNode的创建过程((十七)中问题)
40、request请求加载瓦片优先级的含义((十七)中问题)
41、request的_internalHandle的作用((十七)中问题)
42、DatabaseRequest中_objectCache含义((十七)中问题)
42、osgEarth的多线程分析((十七)中问题)
43、osgEarth的缓存及其结构((十七)中问题)
44、DatabaseThread从缓存加载数据过程((十七)中问题)
45、DatabaseThread从文件加载数据过程((十七)中问题)
46、决定创建TileNode的时机条件((十七)中问题)
47、TerrainEngineNode的createTileModel过程详解((十七)中问题)
48、DatabaseThread中CompileSet的含义((十七)中问题)
48、PagerLoader的traverse过程详解((十七)中问题)
49、DatabaseThread的run过程详解((十七)中问题)
50、LoadTileData的invoke过程详解((十七)中问题)
51、TileNode的cull过程详解((十七)中问题)
52、遮罩生成器osgEarth::Drivers::RexTerrainEngine::MaskGenerator((十八)中问题)
53、RexTerrainEngineNode::traverse过程详解((十八)中问题)
54、TileNode节点下的场景树分析((十八)中问题)
55、地形瓦片大小尺寸和LOD的关系((十八)中问题)
56、TileNode的_tileKeyValue作用((十八)中问题)
57、TileNode的_morphConstants作用((十八)中问题)
58、TileNode的_stitchNormalMap作用((十八)中问题)
59、TileNode的_renderModel作用((十八)中问题)
60、初始化高程栅格过程详解((十八)中问题)
61、LoadTileData中的CreateTileModelFilter作用((十八)中问题)
62、TileNode节点何时会从场景树中移除((十八)中问题)
63、osgEarth::Map的Profile创建过程((二十)中问题)
64、osgEarth::TerrainTileModelFactory添加颜色层和影像层的区别((二十一)中问题)
65、osgEarth::PatchLayer修补层的作用((二十一)中问题)
66、osgEarth::TerrainLayer中的_memCache(osgEarth::MemCache)详解((二十一)中问题)
67、osgEarth::Layer::RenderType图层渲染类型的作用((二十一)中问题)
68、osgEarth::TerrainLayer中TileSource的作用((二十一)中问题)
69、earth文件没有设置高程图层会不会有默认高程层(高程均为0)((二十一)中问题)
70、TerrainTileModelFactory::addColorLayers过程详解((二十一)中问题)
71、TerrainTileModelFactory::addElevation过程详解((二十一)中问题)
72、osgearth中可能用到的几个全局实例对象(osgDB::Registry osgEarth::Registry osg::Timer osg::DisplaySetting)((二十三)中问题)
73、osgEarth::Map::addLayer过程详解((二十三)中问题)
74、TileNode::setDirty过程详解((二十三)中问题)
75、请求四个状态的含义(IDLE RUNNING MERGING FINISHED)((二十三)中问题)
76、什么时候删除TileNode节点,不会一直增加吧((二十三)中问题)
77、寄存器中请求状态活动记录的含义Registry::instance()->endActivity( req->getName() )((二十三)中问题)
78、瓦片TileNode的生命周期流程详解((二十三)中问题)
79、rex引擎如何将瓦片构造成地球形状((二十五)中问题)
80、高程、影像文件格式详解((二十五)中问题)
81、TileNode的merge过程详解((二十六)中问题)
82、osgEarth支持的空间参考坐标系详解(osgEarth::SpatialReference、osgEarth::CubeSpatialReference、osgEarth::TangentPlaneSpatialReference)((二十九)中问题)
83、osgEarth地球椭球体ellipsoid 大地基准面datum 地图投影Projection详解((二十九)中问题)
84、空间参考坐标系和坐标系统类型的关系(geocentric projected)((二十九)中问题)
85、proj4是什么((二十九)中问题)
86、为什么要删除设置过的垂直水准面((二十九)中问题)
87、osgEarth如何对投影坐标系和大地坐标系进行显示处理的((二十九)中问题)
88、TileNode的节点构成,一个surface、tilenode((三十)中问题)
89、MapFram和MapInfo的关系((三十)中问题)
90、ModifyBoundingBoxCallback的使用时机和场合((三十)中问题)
91、MapFrame为什么要单独存放高程层_elevationLayers,而不是放在图层_layers中((三十)中问题)
92、MapFrame和Map中高程池的作用osg::ref_ptr<ElevationPool> _elevationPool((三十)中问题)
93、osgEarth::Drivers::RexTerrainEngine::TileDrawable分析((三十)中问题)