Added the option to bulk load and cache entire world rows at a time when using sqlite. Caching is implemented in the database class this time around. Enabled using --sqlite-cacheworldrow on the command line. This is essentially re-introduces the database access strategy that was used originally, but as an option. Currently, one block is read at a time from the database. The original behavior was to read and cache one entire world row at a time, irrespective of whether or not only a (small) subsection of the world was being mapped. Under some circumstances, in particular if the entire world is mapped or a relatively large percentage of it (blocks-wise), the bulk loading and caching may outperform the one-by-one strategy, even though it usually loads many more blocks than are actually needed. It seems that leveldb won't benefit from any kind of caching or bulk loading of blocks, so none was implemented. Leveldb does compile now. Still not tested on a database :-( Improved the database statistics (printed with --verbose).
83 lines
1.8 KiB
C++
83 lines
1.8 KiB
C++
#include "db-leveldb.h"
|
|
#include <stdexcept>
|
|
#include <sstream>
|
|
|
|
inline int64_t stoi64(const std::string &s) {
|
|
std::stringstream tmp(s);
|
|
long long t;
|
|
tmp >> t;
|
|
return t;
|
|
}
|
|
|
|
inline std::string i64tos(int64_t i) {
|
|
std::ostringstream o;
|
|
o<<i;
|
|
return o.str();
|
|
}
|
|
|
|
DBLevelDB::DBLevelDB(const std::string &mapdir) :
|
|
m_blocksReadCount(0),
|
|
m_blocksCachedCount(0),
|
|
m_blocksUnCachedCount(0)
|
|
{
|
|
leveldb::Options options;
|
|
options.create_if_missing = false;
|
|
leveldb::Status status = leveldb::DB::Open(options, mapdir + "map.db", &m_db);
|
|
if(!status.ok())
|
|
throw std::runtime_error("Failed to open Database");
|
|
}
|
|
|
|
DBLevelDB::~DBLevelDB() {
|
|
delete m_db;
|
|
}
|
|
|
|
int DBLevelDB::getBlocksReadCount(void)
|
|
{
|
|
return m_blocksReadCount;
|
|
}
|
|
|
|
int DBLevelDB::getBlocksCachedCount(void)
|
|
{
|
|
return m_blocksCachedCount;
|
|
}
|
|
|
|
int DBLevelDB::getBlocksUnCachedCount(void)
|
|
{
|
|
return m_blocksUnCachedCount;
|
|
}
|
|
|
|
std::vector<int64_t> DBLevelDB::getBlockPos() {
|
|
std::vector<int64_t> vec;
|
|
std::set<int64_t> s;
|
|
leveldb::Iterator* it = m_db->NewIterator(leveldb::ReadOptions());
|
|
for (it->SeekToFirst(); it->Valid(); it->Next()) {
|
|
vec.push_back(stoi64(it->key().ToString()));
|
|
s.insert(stoi64(it->key().ToString()));
|
|
}
|
|
delete it;
|
|
m_bpcache = s;
|
|
return vec;
|
|
}
|
|
|
|
DBBlock DBLevelDB::getBlockOnPos(int x, int y, int z)
|
|
{
|
|
int64_t iPos;
|
|
DBBlock block(0,(const unsigned char *)"");
|
|
std::string datastr;
|
|
leveldb::Status status;
|
|
|
|
iPos = static_cast<int64_t>(x);
|
|
iPos += static_cast<int64_t>(y) << 12;
|
|
iPos += static_cast<int64_t>(z) << 24;
|
|
|
|
status = m_db->Get(leveldb::ReadOptions(), i64tos(iPos), &datastr);
|
|
if(status.ok()) {
|
|
block = DBBlock( iPos, std::basic_string<unsigned char>( (const unsigned char*) datastr.c_str(), datastr.size() ) );
|
|
m_blocksReadCount++;
|
|
m_blocksUnCachedCount++;
|
|
}
|
|
|
|
return block;
|
|
}
|
|
|