DatabasePager加载数据的过程:

多线程 使用DatabasePager加载数据的流程:

左侧的图框表示数据的检索和输入, 中间的白色框表示用于数据存储的内存空间,而右边的图框表示存储数据的输出。此外,蓝色图框表示可以在DatabaseThread线程中完成的工作, 而橙色图框表示由线程之外的函数完成的工作。

 void DatabasePager::DatabaseThread::run()
{
OSG_INFO<<_name<<": DatabasePager::DatabaseThread::run"<<std::endl; bool firstTime = true; osg::ref_ptr<DatabasePager::ReadQueue> read_queue;
osg::ref_ptr<DatabasePager::ReadQueue> out_queue; switch(_mode)
{
case(HANDLE_ALL_REQUESTS):
read_queue = _pager->_fileRequestQueue;
break;
case(HANDLE_NON_HTTP):
read_queue = _pager->_fileRequestQueue;
out_queue = _pager->_httpRequestQueue;
break;
case(HANDLE_ONLY_HTTP):
read_queue = _pager->_httpRequestQueue;
break;
} do
{
_active = false; read_queue->block(); if (_done)
{
break;
} _active = true; OSG_INFO<<_name<<": _pager->size()= "<<read_queue->size()<<" to delete = "<<read_queue->_childrenToDeleteList.size()<<std::endl; //
// delete any children if required.
//
if (_pager->_deleteRemovedSubgraphsInDatabaseThread/* && !(read_queue->_childrenToDeleteList.empty())*/)
{
ObjectList deleteList;
{
// Don't hold lock during destruction of deleteList
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(read_queue->_requestMutex);
if (!read_queue->_childrenToDeleteList.empty())
{
deleteList.swap(read_queue->_childrenToDeleteList);
read_queue->updateBlock();
}
}
} //
// load any subgraphs that are required.
//
osg::ref_ptr<DatabaseRequest> databaseRequest;
read_queue->takeFirst(databaseRequest); bool readFromFileCache = false; osg::ref_ptr<FileCache> fileCache = osgDB::Registry::instance()->getFileCache();
osg::ref_ptr<FileLocationCallback> fileLocationCallback = osgDB::Registry::instance()->getFileLocationCallback();
osg::ref_ptr<Options> dr_loadOptions;
std::string fileName;
int frameNumberLastRequest = ;
bool cacheNodes = false;
if (databaseRequest.valid())
{
{
OpenThreads::ScopedLock<OpenThreads::Mutex> drLock(_pager->_dr_mutex);
dr_loadOptions = databaseRequest->_loadOptions.valid() ? databaseRequest->_loadOptions->cloneOptions() : new osgDB::Options;
dr_loadOptions->setTerrain(databaseRequest->_terrain);
dr_loadOptions->setParentGroup(databaseRequest->_group);
fileName = databaseRequest->_fileName;
frameNumberLastRequest = databaseRequest->_frameNumberLastRequest;
} if (dr_loadOptions->getFileCache()) fileCache = dr_loadOptions->getFileCache();
if (dr_loadOptions->getFileLocationCallback()) fileLocationCallback = dr_loadOptions->getFileLocationCallback(); // disable the FileCache if the fileLocationCallback tells us that it isn't required for this request.
if (fileLocationCallback.valid() && !fileLocationCallback->useFileCache()) fileCache = ; cacheNodes = (dr_loadOptions->getObjectCacheHint() & osgDB::Options::CACHE_NODES)!=;
if (cacheNodes)
{
//OSG_NOTICE<<"Checking main ObjectCache"<<std::endl;
// check the object cache to see if the file we want has already been loaded.
osg::ref_ptr<osg::Object> objectFromCache = osgDB::Registry::instance()->getRefFromObjectCache(fileName); // if no object with fileName in ObjectCache then try the filename appropriate for fileCache
if (!objectFromCache && (fileCache.valid() && fileCache->isFileAppropriateForFileCache(fileName)))
{
if (fileCache->existsInCache(fileName))
{
objectFromCache = osgDB::Registry::instance()->getRefFromObjectCache(fileCache->createCacheFileName(fileName));
}
} osg::Node* modelFromCache = dynamic_cast<osg::Node*>(objectFromCache.get());
if (modelFromCache)
{
//OSG_NOTICE<<"Found object in cache "<<fileName<<std::endl; // assign the cached model to the request
{
OpenThreads::ScopedLock<OpenThreads::Mutex> drLock(_pager->_dr_mutex);
databaseRequest->_loadedModel = modelFromCache;
} // move the request to the dataToMerge list so it can be merged during the update phase of the frame.
{
OpenThreads::ScopedLock<OpenThreads::Mutex> listLock( _pager->_dataToMergeList->_requestMutex);
_pager->_dataToMergeList->addNoLock(databaseRequest.get());
databaseRequest = ;
} // skip the rest of the do/while loop as we have done all the processing we need to do.
continue;
}
else
{
//OSG_NOTICE<<"Not Found object in cache "<<fileName<<std::endl;
} // need to disable any attempt to use the cache when loading as we're handle this ourselves to avoid threading conflicts
{
OpenThreads::ScopedLock<OpenThreads::Mutex> drLock(_pager->_dr_mutex);
databaseRequest->_objectCache = new ObjectCache;
dr_loadOptions->setObjectCache(databaseRequest->_objectCache.get());
}
} // check if databaseRequest is still relevant
if ((_pager->_frameNumber-frameNumberLastRequest)<=)
{ // now check to see if this request is appropriate for this thread
switch(_mode)
{
case(HANDLE_ALL_REQUESTS):
{
// do nothing as this thread can handle the load
if (fileCache.valid() && fileCache->isFileAppropriateForFileCache(fileName))
{
if (fileCache->existsInCache(fileName))
{
readFromFileCache = true;
}
}
break;
}
case(HANDLE_NON_HTTP):
{
// check the cache first
bool isHighLatencyFileRequest = false; if (fileLocationCallback.valid())
{
isHighLatencyFileRequest = fileLocationCallback->fileLocation(fileName, dr_loadOptions.get()) == FileLocationCallback::REMOTE_FILE;
}
else if (fileCache.valid() && fileCache->isFileAppropriateForFileCache(fileName))
{
isHighLatencyFileRequest = true;
} if (isHighLatencyFileRequest)
{
if (fileCache.valid() && fileCache->existsInCache(fileName))
{
readFromFileCache = true;
}
else
{
OSG_INFO<<_name<<": Passing http requests over "<<fileName<<std::endl;
out_queue->add(databaseRequest.get());
databaseRequest = ;
}
}
break;
}
case(HANDLE_ONLY_HTTP):
{
// accept all requests, as we'll assume only high latency requests will have got here.
break;
}
}
}
else
{
databaseRequest = ;
}
} if (databaseRequest.valid())
{ // load the data, note safe to write to the databaseRequest since once
// it is created this thread is the only one to write to the _loadedModel pointer.
//OSG_NOTICE<<"In DatabasePager thread readNodeFile("<<databaseRequest->_fileName<<")"<<std::endl;
//osg::Timer_t before = osg::Timer::instance()->tick(); // 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); osg::ref_ptr<osg::Node> loadedModel;
if (rr.validNode()) loadedModel = rr.getNode();
if (rr.error()) OSG_WARN<<"Error in reading file "<<fileName<<" : "<<rr.message() << std::endl;
if (rr.notEnoughMemory()) OSG_INFO<<"Not enought memory to load file "<<fileName << std::endl; if (loadedModel.valid() &&
fileCache.valid() &&
fileCache->isFileAppropriateForFileCache(fileName) &&
!readFromFileCache)
{
fileCache->writeNode(*(loadedModel), fileName, dr_loadOptions.get());
} {
OpenThreads::ScopedLock<OpenThreads::Mutex> drLock(_pager->_dr_mutex);
if ((_pager->_frameNumber-databaseRequest->_frameNumberLastRequest)>)
{
OSG_INFO<<_name<<": Warning DatabaseRquest no longer required."<<std::endl;
loadedModel = ;
}
} //OSG_NOTICE<<" node read in "<<osg::Timer::instance()->delta_m(before,osg::Timer::instance()->tick())<<" ms"<<std::endl; if (loadedModel.valid())
{
loadedModel->getBound(); bool loadedObjectsNeedToBeCompiled = false;
osg::ref_ptr<osgUtil::IncrementalCompileOperation::CompileSet> compileSet = ;
if (!rr.loadedFromCache())
{
// find all the compileable rendering objects
DatabasePager::FindCompileableGLObjectsVisitor stateToCompile(_pager, _pager->getMarkerObject());
loadedModel->accept(stateToCompile); loadedObjectsNeedToBeCompiled = _pager->_doPreCompile &&
_pager->_incrementalCompileOperation.valid() &&
_pager->_incrementalCompileOperation->requiresCompile(stateToCompile); // move the databaseRequest from the front of the fileRequest to the end of
// dataToCompile or dataToMerge lists.
if (loadedObjectsNeedToBeCompiled)
{
// OSG_NOTICE<<"Using IncrementalCompileOperation"<<std::endl; compileSet = new osgUtil::IncrementalCompileOperation::CompileSet(loadedModel.get());
compileSet->buildCompileMap(_pager->_incrementalCompileOperation->getContextSet(), stateToCompile);
compileSet->_compileCompletedCallback = new DatabasePagerCompileCompletedCallback(_pager, databaseRequest.get());
_pager->_incrementalCompileOperation->add(compileSet.get(), false);
}
}
else
{
OSG_NOTICE<<"Loaded from ObjectCache"<<std::endl;
} {
OpenThreads::ScopedLock<OpenThreads::Mutex> drLock(_pager->_dr_mutex);
databaseRequest->_loadedModel = loadedModel;
databaseRequest->_compileSet = compileSet;
}
// Dereference the databaseRequest while the queue is
// locked. This prevents the request from being
// deleted at an unpredictable time within
// addLoadedDataToSceneGraph.
if (loadedObjectsNeedToBeCompiled)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> listLock(
_pager->_dataToCompileList->_requestMutex);
_pager->_dataToCompileList->addNoLock(databaseRequest.get());
databaseRequest = ;
}
else
{
OpenThreads::ScopedLock<OpenThreads::Mutex> listLock(
_pager->_dataToMergeList->_requestMutex);
_pager->_dataToMergeList->addNoLock(databaseRequest.get());
databaseRequest = ;
} } // _pager->_dataToCompileList->pruneOldRequestsAndCheckIfEmpty();
}
else
{
OpenThreads::Thread::YieldCurrentThread();
} // go to sleep till our the next time our thread gets scheduled. if (firstTime)
{
// do a yield to get round a peculiar thread hang when testCancel() is called
// in certain circumstances - of which there is no particular pattern.
YieldCurrentThread();
firstTime = false;
} } while (!testCancel() && !_done);
}

[osg][osgearth]osg的分页加载,代码和结构图的更多相关文章

  1. java攻城狮之路(Android篇)--widget_webview_metadata_popupwindow_tabhost_分页加载数据_菜单

    一.widget:桌面小控件1 写一个类extends AppWidgetProvider 2 在清单文件件中注册: <receiver android:name=".ExampleA ...

  2. Android基本控件之listView(三)<用ListView实现分页加载>

    我们之前讨论了ListView的基本使用方法和ListView的优化 今天我们再来讨论一个关于ListView的一个新的东西~就是分页加载.那么什么是分页加载呢?简单点说,就是"下拉刷新&q ...

  3. ListView实现分页加载(三)实现分页加载

    在上一篇中,我们实现了底部布局(即带上了进度条).没有读过的朋友可以点击下面的链接: http://www.cnblogs.com/fuly550871915/p/4866966.html 但是进度条 ...

  4. ListView实现分页加载(一)制作Demo

    一.什么是分页加载 在下面的文章中,我们来讲解LitView分页加载的实现.什么是分页加载呢?我们先看几张效果图吧,如下:                                       ...

  5. android中滑动SQLite数据库分页加载

    今天用到了android中滑动SQlit数据库分页加载技术,写了个测试工程,将代码贴出来和大家交流一下: MainActivity package com.example.testscrollsqli ...

  6. iOS 高效的分页加载(TableView、CollectionView)

    一.tableview的分页加载的代码对比 没有优化之前的代码如下 [strongSelf.tableView.mj_footer endRefreshing]: [strongSelf.articl ...

  7. 微信小程序云开发-列表数据分页加载显示

    一.准备工作 1.创建数据库nums,向数据库中导入108条数据 2.修改数据库表nums的权限 二.新建页面ListPaginated 1.wxml文件 <!-- 显示列表数据 --> ...

  8. Android ListView分页加载时图片显示问题

    场景:Android ListView需要分页加载,每个item中会有图片,图片又是从网络下载的. 问题:在滑动加载下一页时,上一页的图片明明已经下载完成了,但是无法显示出来. Bug重现: 1,加载 ...

  9. Android中ListView分页加载数据

    public class MainActivity extends Activity { private ListView listView=null; //listview的数据填充器 privat ...

  10. Android动态加载代码技术

    Android动态加载代码技术 在开发Android App的过程当中,可能希望实现插件式软件架构,将一部分代码以另外一个APK的形式单独发布,而在主程序中加载并执行这个APK中的代码. 实现这个任务 ...

随机推荐

  1. mac java环境变量配置

    在终端输入java -version命令,如果没安装系统会自动弹出个东西让你安装,下载完之后打开,再点java -version,如果有显示就说明安装成功了. 在终端输入  ç 可以得到JAVA_HO ...

  2. MYSQL-max_binlog_cache_size参数

    max_binlog_cache_size 解释:这是设置最大二进制日志的缓存区大小的变量.若处理多语句事务时需要的内存大小比设置值大的话就会提示一个error:Multi-statement tra ...

  3. UUID的定义以及作用

    UUID含义是通用唯一识别码 (Universally Unique Identifier),这 是一个软件建构的标准,也是被开源软件基金会 (Open Software Foundation, OS ...

  4. MySQL监控、性能分析——工具篇(转载)

    MySQL越来越被更多企业接受,随着企业发展,MySQL存储数据日益膨胀,MySQL的性能分析.监控预警.容量扩展议题越来越多.“工欲善其事,必先利其器”,那么我们如何在进行MySQL性能分析.监控预 ...

  5. Composer 添加 Laravel-china 的国内源

    不知道由于什么原因,原来的 Composer 的国内镜像 https://pkg.phpcomposer.com/ 不能正常使用,经常连不上. 找了半天,发现还有一个 laravel-china 的国 ...

  6. hdu2196 Computer【树形DP】【换根法】

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  7. CMDB经验分享之 – 剖析CMDB的设计过程

    作为IT管理的核心,CMDB逐渐成为系统管理项目实施的热点.在很多的案例中,由于忽视了CMDB的因素,ITIL的深入应用受到了极大的挑战.同时,由于CMDB是IT管理信息的集中,CMDB也是一个重要的 ...

  8. Flask wtform组件

    Wtforms简介 WTForms是一个支持多个web框架的form组件 主要能够帮助我们生成html标签 对数据进行验证 安装 pip install wtforms Wtforms的使用 这里借助 ...

  9. day15(Mysql学习)

      day15-MySQL   数据库   1 数据库概念(了解) 1.1 什么是数据库 数据库就是用来存储和管理数据的仓库! 数据库存储数据的优先: 可存储大量数据: 方便检索: 保持数据的一致性. ...

  10. java-基础-【三】try/catch/finally

    原文地址: https://my.oschina.net/bieber/blog/703251 一.单层的try/catch public int test(int a,int b){ try{ re ...