|
osgEarth 2.1.1
|
Inheritance diagram for LayerTable:
Collaboration diagram for LayerTable:Public Member Functions | |
| LayerTable (const MetadataRecord &meta, sqlite3 *db) | |
| sqlite3_int64 | getTableSize (sqlite3 *db) |
| int | getNbEntry (sqlite3 *db) |
| void | checkAndPurgeIfNeeded (sqlite3 *db, unsigned int maxSize) |
| bool | store (const ImageRecord &rec, sqlite3 *db) |
| bool | updateAccessTime (const TileKey &key, int newTimestamp, sqlite3 *db) |
| bool | updateAccessTimePool (const std::string &keyStr, int newTimestamp, sqlite3 *db) |
| bool | load (const TileKey &key, ImageRecord &output, sqlite3 *db) |
| void | displayStats () |
| bool | purge (int utcTimeStamp, int maxToRemove, sqlite3 *db) |
| bool | initialize (sqlite3 *db) |
Public Attributes | |
| std::string | _selectSQL |
| std::string | _insertSQL |
| std::string | _updateTimeSQL |
| std::string | _updateTimePoolSQL |
| std::string | _purgeSelect |
| std::string | _purgeSQL |
| std::string | _purgeLimitSQL |
| MetadataRecord | _meta |
| std::string | _tableName |
| osg::ref_ptr< osgDB::ReaderWriter > | _rw |
| osg::ref_ptr < osgDB::ReaderWriter::Options > | _rwOptions |
| osg::Timer_t | _statsStartTimer |
| osg::Timer_t | _statsLastCheck |
| int | _statsLoaded |
| int | _statsStored |
| int | _statsDeleted |
Database table that holds one record per cached imagery tile in a layer. The layer name is the table name.
Definition at line 361 of file Sqlite3Cache.cpp.
| LayerTable::LayerTable | ( | const MetadataRecord & | meta, |
| sqlite3 * | db | ||
| ) | [inline] |
Definition at line 363 of file Sqlite3Cache.cpp.
: _meta(meta) { _tableName = "layer_" + _meta._layerName; // create the table and load the processors. if ( ! initialize( db ) ) { return; } // initialize the SELECT statement for fetching records std::stringstream buf; #ifdef SPLIT_DB_FILE buf << "SELECT created,accessed,size FROM \"" << tableName << "\" WHERE key = ?"; #else buf << "SELECT created,accessed,data FROM \"" << _tableName << "\" WHERE key = ?"; #endif _selectSQL = buf.str(); // initialize the UPDATE statement for updating the timestamp of an accessed record buf.str(""); buf << "UPDATE \"" << _tableName << "\" SET accessed = ? " << "WHERE key = ?"; _updateTimeSQL = buf.str(); buf.str(""); buf << "UPDATE \"" << _tableName << "\" SET accessed = ? " << "WHERE key in ( ? )"; _updateTimePoolSQL = buf.str(); // initialize the INSERT statement for writing records. buf.str(""); buf << "INSERT OR REPLACE INTO \"" << _tableName << "\" " #ifdef SPLIT_DB_FILE << "(key,created,accessed,size) VALUES (?,?,?,?)"; #else << "(key,created,accessed,data) VALUES (?,?,?,?)"; #endif _insertSQL = buf.str(); // initialize the DELETE statements for purging old records. buf.str(""); buf << "DELETE FROM \"" << _tableName << "\" " << "INDEXED BY \"" << _tableName << "_lruindex\" " << "WHERE accessed < ?"; _purgeSQL = buf.str(); buf.str(""); buf << "DELETE FROM \"" << _tableName << "\" WHERE key in (SELECT key FROM \"" << _tableName << "\" WHERE \"accessed\" < ? limit ?)"; _purgeLimitSQL = buf.str(); buf.str(""); buf << "SELECT key FROM \"" << _tableName << "\" WHERE \"accessed\" < ? limit ?"; _purgeSelect = buf.str(); _statsLoaded = 0; _statsStored = 0; _statsDeleted = 0; }
| void LayerTable::checkAndPurgeIfNeeded | ( | sqlite3 * | db, |
| unsigned int | maxSize | ||
| ) | [inline] |
Definition at line 477 of file Sqlite3Cache.cpp.
{
int size = getTableSize(db);
OE_DEBUG << _meta._layerName << std::dec << " : " << size/1024/1024 << " MB" << std::endl;
if (size < 0 || size < 1.2 * maxSize)
return;
::time_t t = ::time(0L);
int nbElements = getNbEntry(db);
float averageSize = size * 1.0 / nbElements;
float diffSize = size - maxSize;
int maxElementToRemove = static_cast<int>(ceil(diffSize/averageSize));
OE_DEBUG << _meta._layerName << " try to remove " << std::dec << maxElementToRemove << " / " << nbElements << " to save place" << std::endl;
purge(t, maxElementToRemove, db);
}
Here is the call graph for this function:
Here is the caller graph for this function:| void LayerTable::displayStats | ( | ) | [inline] |
Definition at line 749 of file Sqlite3Cache.cpp.
{
osg::Timer_t t = osg::Timer::instance()->tick();
if (osg::Timer::instance()->delta_s( _statsLastCheck, t) > 10.0) {
double d = osg::Timer::instance()->delta_s(_statsStartTimer, t);
OE_DEBUG << _meta._layerName << " time " << d << " stored " << std::dec << _statsStored << " rate " << _statsStored * 1.0 / d << std::endl;
OE_DEBUG << _meta._layerName << " time " << d << " loaded " << std::dec << _statsLoaded << " rate " << _statsLoaded * 1.0 / d << std::endl;
OE_DEBUG << _meta._layerName << " time " << d << " deleted " << std::dec << _statsDeleted << " rate " << _statsDeleted * 1.0 / d << std::endl;
_statsLastCheck = t;
}
}
| int LayerTable::getNbEntry | ( | sqlite3 * | db | ) | [inline] |
Definition at line 453 of file Sqlite3Cache.cpp.
{
std::string query = "select count(*) from \"" + _tableName + "\";";
sqlite3_stmt* select = 0L;
int rc = sqlite3_prepare_v2( db, query.c_str(), query.length(), &select, 0L );
if ( rc != SQLITE_OK )
{
OE_WARN << LC << "Failed to prepare SQL: " << query << "; " << sqlite3_errmsg(db) << std::endl;
return -1;
}
rc = sqlite3_step( select );
if ( rc != SQLITE_ROW)
{
OE_WARN << LC << "SQL QUERY failed for " << query << ": "
<< sqlite3_errmsg( db ) //<< "; tries=" << (1000-tries)
<< ", rc = " << rc << std::endl;
sqlite3_finalize( select );
return -1;
}
int nbItems = sqlite3_column_int(select, 0);
sqlite3_finalize( select );
return nbItems;
}
Here is the caller graph for this function:| sqlite3_int64 LayerTable::getTableSize | ( | sqlite3 * | db | ) | [inline] |
Definition at line 424 of file Sqlite3Cache.cpp.
{
#ifdef SPLIT_DB_FILE
std::string query = "select sum(size) from \"" + _tableName + "\";";
#else
std::string query = "select sum(length(data)) from \"" + _tableName + "\";";
#endif
sqlite3_stmt* select = 0L;
int rc = sqlite3_prepare_v2( db, query.c_str(), query.length(), &select, 0L );
if ( rc != SQLITE_OK )
{
OE_WARN << LC << "Failed to prepare SQL: " << query << "; " << sqlite3_errmsg(db) << std::endl;
return -1;
}
rc = sqlite3_step( select );
if ( rc != SQLITE_ROW)
{
OE_WARN << LC << "SQL QUERY failed for " << query << ": "
<< sqlite3_errmsg( db ) //<< "; tries=" << (1000-tries)
<< ", rc = " << rc << std::endl;
sqlite3_finalize( select );
return -1;
}
sqlite3_int64 size = sqlite3_column_int(select, 0);
sqlite3_finalize( select );
return size;
}
Here is the caller graph for this function:| bool LayerTable::initialize | ( | sqlite3 * | db | ) | [inline] |
Initializes the layer by creating the layer's table (if necessary), loading the appropriate reader-writer for the image data, and initializing the compressor if necessary.
Definition at line 843 of file Sqlite3Cache.cpp.
{
// first create the table if it does not already exist:
std::stringstream buf;
buf << "CREATE TABLE IF NOT EXISTS \"" << _tableName << "\" ("
<< "key char(64) PRIMARY KEY UNIQUE, "
<< "created int, "
<< "accessed int, "
#ifdef SPLIT_DB_FILE
<< "size int )";
#else
<< "data blob )";
#endif
std::string sql = buf.str();
OE_DEBUG << LC << "SQL = " << sql << std::endl;
char* errMsg = 0L;
int rc = sqlite3_exec( db, sql.c_str(), 0L, 0L, &errMsg );
if ( rc != SQLITE_OK )
{
OE_WARN << LC << "Creating layer \"" << _meta._layerName << "\": " << errMsg << std::endl;
sqlite3_free( errMsg );
return false;
}
// create an index on the time-last-accessed column
buf.str("");
buf << "CREATE INDEX IF NOT EXISTS \""
<< _tableName << "_lruindex\" "
<< "ON \"" << _tableName << "\" (accessed)";
sql = buf.str();
OE_DEBUG << LC << "SQL = " << sql << std::endl;
rc = sqlite3_exec( db, sql.c_str(), 0L, 0L, &errMsg );
if ( rc != SQLITE_OK )
{
OE_WARN << LC << "Creating index for layer \"" << _meta._layerName << "\": " << errMsg << std::endl;
sqlite3_free( errMsg );
//return false;
}
// next load the appropriate ReaderWriter:
#if OSG_MIN_VERSION_REQUIRED(2,9,5)
_rw = osgDB::Registry::instance()->getReaderWriterForMimeType( _meta._format );
if ( !_rw.valid() )
#endif
_rw = osgDB::Registry::instance()->getReaderWriterForExtension( _meta._format );
if ( !_rw.valid() )
{
OE_WARN << LC << "Creating layer: Cannot initialize ReaderWriter for format \""
<< _meta._format << "\"" << std::endl;
return false;
}
if ( !_meta._compressor.empty() )
_rwOptions = new osgDB::ReaderWriter::Options( "Compressor=" + _meta._compressor );
_statsLastCheck = _statsStartTimer = osg::Timer::instance()->tick();
return true;
}
| bool LayerTable::load | ( | const TileKey & | key, |
| ImageRecord & | output, | ||
| sqlite3 * | db | ||
| ) | [inline] |
Definition at line 690 of file Sqlite3Cache.cpp.
{
displayStats();
int imageBufLen = 0;
sqlite3_stmt* select = 0L;
int rc = sqlite3_prepare_v2( db, _selectSQL.c_str(), _selectSQL.length(), &select, 0L );
if ( rc != SQLITE_OK )
{
OE_WARN << LC << "Failed to prepare SQL: " << _selectSQL << "; " << sqlite3_errmsg(db) << std::endl;
return false;
}
std::string keyStr = key.str();
sqlite3_bind_text( select, 1, keyStr.c_str(), keyStr.length(), SQLITE_STATIC );
rc = sqlite3_step( select );
if ( rc != SQLITE_ROW ) // == SQLITE_DONE ) // SQLITE_DONE means "no more rows"
{
// cache miss
OE_DEBUG << LC << "Cache MISS on tile " << key.str() << std::endl;
sqlite3_finalize(select);
return false;
}
// copy the timestamps:
output._created = sqlite3_column_int( select, 0 );
output._accessed = sqlite3_column_int( select, 1 );
#ifdef SPLIT_DB_FILE
std::string fname(keyStr);
osgDB::ReaderWriter::ReadResult rr = _rw->readImage( _meta._layerName + "_" +fname+".osgb" );
#else
// the pointer returned from _blob gets freed internally by sqlite, supposedly
const char* data = (const char*)sqlite3_column_blob( select, 2 );
imageBufLen = sqlite3_column_bytes( select, 2 );
// deserialize the image from the buffer:
std::string imageString( data, imageBufLen );
std::stringstream imageBufStream( imageString );
osgDB::ReaderWriter::ReadResult rr = _rw->readImage( imageBufStream );
#endif
if ( rr.error() )
{
OE_WARN << LC << "Failed to read image from database: " << rr.message() << std::endl;
}
else
{
output._image = rr.takeImage();
output._key = key;
OE_DEBUG << LC << "Cache HIT on tile " << key.str() << std::endl;
}
sqlite3_finalize(select);
_statsLoaded++;
return output._image.valid();
}
Here is the call graph for this function:
Here is the caller graph for this function:| bool LayerTable::purge | ( | int | utcTimeStamp, |
| int | maxToRemove, | ||
| sqlite3 * | db | ||
| ) | [inline] |
Definition at line 761 of file Sqlite3Cache.cpp.
{
if ( maxToRemove < 0 )
return false;
sqlite3_stmt* purge = 0L;
int rc;
{
#ifdef SPLIT_DB_FILE
{
std::vector<std::string> deleteFiles;
sqlite3_stmt* selectPurge = 0L;
rc = sqlite3_prepare_v2( db, _purgeSelect.c_str(), _purgeSelect.length(), &selectPurge, 0L);
if ( rc != SQLITE_OK )
{
OE_WARN << LC << "Failed to prepare SQL: " << _purgeSelect << "; " << sqlite3_errmsg(db) << std::endl;
return false;
}
sqlite3_bind_int( selectPurge, 2, maxToRemove );
sqlite3_bind_int( selectPurge, 1, utcTimeStamp );
rc = sqlite3_step( selectPurge );
if ( rc != SQLITE_ROW && rc != SQLITE_DONE)
{
OE_WARN << LC << "SQL QUERY failed for " << _purgeSelect << ": "
<< sqlite3_errmsg( db ) //<< "; tries=" << (1000-tries)
<< ", rc = " << rc << std::endl;
sqlite3_finalize( selectPurge );
return false;
}
while (rc == SQLITE_ROW) {
std::string f((const char*)sqlite3_column_text( selectPurge, 0 ));
deleteFiles.push_back(f);
rc = sqlite3_step( selectPurge );
}
if (rc != SQLITE_DONE) {
OE_WARN << LC << "SQL QUERY failed for " << _purgeSelect << ": "
<< sqlite3_errmsg( db ) //<< "; tries=" << (1000-tries)
<< ", rc = " << rc << std::endl;
sqlite3_finalize( selectPurge );
return false;
}
sqlite3_finalize( selectPurge );
while (!deleteFiles.empty()) {
std::string fname = _meta._layerName + "_" + deleteFiles.back() +".osgb";
int run = unlink(fname.c_str());
if (run) {
OE_WARN << "Error while removing file " << fname << std::endl;
}
deleteFiles.pop_back();
}
}
#endif
rc = sqlite3_prepare_v2( db, _purgeLimitSQL.c_str(), _purgeLimitSQL.length(), &purge, 0L );
if ( rc != SQLITE_OK )
{
OE_WARN << LC << "Failed to prepare SQL: " << _purgeLimitSQL << "; " << sqlite3_errmsg(db) << std::endl;
return false;
}
sqlite3_bind_int( purge, 2, maxToRemove );
}
sqlite3_bind_int( purge, 1, utcTimeStamp );
rc = sqlite3_step( purge );
if ( rc != SQLITE_DONE )
{
// cache miss
OE_DEBUG << LC << "Error purging records from \"" << _meta._layerName << "\"; " << sqlite3_errmsg(db) << std::endl;
sqlite3_finalize(purge);
return false;
}
sqlite3_finalize(purge);
_statsDeleted += maxToRemove;
return true;
}
Here is the call graph for this function:
Here is the caller graph for this function:| bool LayerTable::store | ( | const ImageRecord & | rec, |
| sqlite3 * | db | ||
| ) | [inline] |
Definition at line 493 of file Sqlite3Cache.cpp.
{
displayStats();
sqlite3_stmt* insert = 0L;
int rc = sqlite3_prepare_v2( db, _insertSQL.c_str(), _insertSQL.length(), &insert, 0L );
if ( rc != SQLITE_OK )
{
OE_WARN
<< LC << "Error preparing SQL: "
<< sqlite3_errmsg( db )
<< "(SQL: " << _insertSQL << ")"
<< std::endl;
return false;
}
// bind the key string:
std::string keyStr = rec._key.str();
sqlite3_bind_text( insert, 1, keyStr.c_str(), keyStr.length(), SQLITE_STATIC );
sqlite3_bind_int( insert, 2, rec._created );
sqlite3_bind_int( insert, 3, rec._accessed );
// serialize the image:
#ifdef SPLIT_DB_FILE
std::stringstream outStream;
_rw->writeImage( *rec._image.get(), outStream, _rwOptions.get() );
std::string outBuf = outStream.str();
std::string fname = _meta._layerName + "_" + keyStr+".osgb";
{
std::ofstream file(fname.c_str(), std::ios::out | std::ios::binary);
if (file.is_open()) {
file.write(outBuf.c_str(), outBuf.length());
}
}
sqlite3_bind_int( insert, 4, outBuf.length() );
#else
std::stringstream outStream;
_rw->writeImage( *rec._image.get(), outStream, _rwOptions.get() );
std::string outBuf = outStream.str();
sqlite3_bind_blob( insert, 4, outBuf.c_str(), outBuf.length(), SQLITE_STATIC );
#endif
// write to the database:
rc = sqlite3_step( insert );
if ( rc != SQLITE_DONE )
{
OE_WARN << LC << "SQL INSERT failed for key " << rec._key.str() << ": "
<< sqlite3_errmsg( db ) //<< "; tries=" << (1000-tries)
<< ", rc = " << rc << std::endl;
sqlite3_finalize( insert );
return false;
}
else
{
OE_DEBUG << LC << "cache INSERT tile " << rec._key.str() << std::endl;
sqlite3_finalize( insert );
_statsStored++;
return true;
}
}
Here is the call graph for this function:
Here is the caller graph for this function:| bool LayerTable::updateAccessTime | ( | const TileKey & | key, |
| int | newTimestamp, | ||
| sqlite3 * | db | ||
| ) | [inline] |
Definition at line 640 of file Sqlite3Cache.cpp.
{
sqlite3_stmt* update = 0L;
int rc = sqlite3_prepare_v2( db, _updateTimeSQL.c_str(), _updateTimeSQL.length(), &update, 0L );
if ( rc != SQLITE_OK )
{
OE_WARN << LC << "Failed to prepare SQL " << _updateTimeSQL << "; " << sqlite3_errmsg(db) << std::endl;
return false;
}
bool success = true;
sqlite3_bind_int( update, 1, newTimestamp );
std::string keyStr = key.str();
sqlite3_bind_text( update, 2, keyStr.c_str(), keyStr.length(), SQLITE_STATIC );
rc = sqlite3_step( update );
if ( rc != SQLITE_DONE )
{
OE_WARN << LC << "Failed to update timestamp for " << key.str() << " on layer " << _meta._layerName << " rc = " << rc << std::endl;
success = false;
}
sqlite3_finalize( update );
return success;
}
Here is the call graph for this function:
Here is the caller graph for this function:| bool LayerTable::updateAccessTimePool | ( | const std::string & | keyStr, |
| int | newTimestamp, | ||
| sqlite3 * | db | ||
| ) | [inline] |
Definition at line 665 of file Sqlite3Cache.cpp.
{
//OE_WARN << LC << "update access times " << _meta._layerName << " " << keyStr << std::endl;
sqlite3_stmt* update = 0L;
int rc = sqlite3_prepare_v2( db, _updateTimePoolSQL.c_str(), _updateTimePoolSQL.length(), &update, 0L );
if ( rc != SQLITE_OK )
{
OE_WARN << LC << "Failed to prepare SQL " << _updateTimePoolSQL << "; " << sqlite3_errmsg(db) << std::endl;
return false;
}
bool success = true;
sqlite3_bind_int( update, 1, newTimestamp );
sqlite3_bind_text( update, 2, keyStr.c_str(), keyStr.length(), SQLITE_STATIC );
rc = sqlite3_step( update );
if ( rc != SQLITE_DONE )
{
OE_WARN << LC << "Failed to update timestamp for " << keyStr << " on layer " << _meta._layerName << " rc = " << rc << std::endl;
success = false;
}
sqlite3_finalize( update );
return success;
}
Here is the caller graph for this function:| std::string LayerTable::_insertSQL |
Definition at line 908 of file Sqlite3Cache.cpp.
Definition at line 915 of file Sqlite3Cache.cpp.
| std::string LayerTable::_purgeLimitSQL |
Definition at line 914 of file Sqlite3Cache.cpp.
| std::string LayerTable::_purgeSelect |
Definition at line 912 of file Sqlite3Cache.cpp.
| std::string LayerTable::_purgeSQL |
Definition at line 913 of file Sqlite3Cache.cpp.
| osg::ref_ptr<osgDB::ReaderWriter> LayerTable::_rw |
Definition at line 918 of file Sqlite3Cache.cpp.
| osg::ref_ptr<osgDB::ReaderWriter::Options> LayerTable::_rwOptions |
Definition at line 919 of file Sqlite3Cache.cpp.
| std::string LayerTable::_selectSQL |
Definition at line 907 of file Sqlite3Cache.cpp.
Definition at line 926 of file Sqlite3Cache.cpp.
| osg::Timer_t LayerTable::_statsLastCheck |
Definition at line 922 of file Sqlite3Cache.cpp.
Definition at line 924 of file Sqlite3Cache.cpp.
| osg::Timer_t LayerTable::_statsStartTimer |
Definition at line 921 of file Sqlite3Cache.cpp.
Definition at line 925 of file Sqlite3Cache.cpp.
| std::string LayerTable::_tableName |
Definition at line 916 of file Sqlite3Cache.cpp.
| std::string LayerTable::_updateTimePoolSQL |
Definition at line 910 of file Sqlite3Cache.cpp.
| std::string LayerTable::_updateTimeSQL |
Definition at line 909 of file Sqlite3Cache.cpp.
1.7.3