Significantly optimize LevelDB database backend

This commit is contained in:
ShadowNinja
2014-03-28 16:47:19 -04:00
parent 6e565e93d1
commit 5905c34ec0
6 changed files with 61 additions and 49 deletions

View File

@ -17,46 +17,56 @@ inline std::string i64tos(int64_t i) {
DBLevelDB::DBLevelDB(const std::string &mapdir) {
leveldb::Options options;
posCacheLoaded = false;
options.create_if_missing = false;
leveldb::Status status = leveldb::DB::Open(options, mapdir + "map.db", &m_db);
leveldb::Status status = leveldb::DB::Open(options, mapdir + "map.db", &db);
if(!status.ok())
throw std::runtime_error("Failed to open Database");
}
DBLevelDB::~DBLevelDB() {
delete m_db;
delete db;
}
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;
loadPosCache();
return posCache;
}
DBBlockList DBLevelDB::getBlocksOnZ(int zPos)
{
void DBLevelDB::loadPosCache() {
if (posCacheLoaded) {
return;
}
leveldb::Iterator * it = db->NewIterator(leveldb::ReadOptions());
for (it->SeekToFirst(); it->Valid(); it->Next()) {
posCache.push_back(stoi64(it->key().ToString()));
}
delete it;
posCacheLoaded = true;
}
DBBlockList DBLevelDB::getBlocksOnZ(int zPos) {
DBBlockList blocks;
std::string datastr;
leveldb::Status status;
int64_t psMin;
int64_t psMax;
psMin = (zPos * 16777216l) - 0x800000;
psMax = (zPos * 16777216l) + 0x7fffff;
int64_t psMin = (zPos * 16777216L) - 0x800000;
int64_t psMax = (zPos * 16777216L) + 0x7fffff;
for(int64_t i = psMin; i <= psMax; i++) { // FIXME: This is still very very inefficent (even with m_bpcache)
if(m_bpcache.find(i) == m_bpcache.end())
for (std::vector<int64_t>::iterator it = posCache.begin(); it != posCache.end(); ++it) {
int64_t i = *it;
if (i < psMin || i > psMax) {
continue;
status = m_db->Get(leveldb::ReadOptions(), i64tos(i), &datastr);
if(status.ok())
blocks.push_back( DBBlock( i, std::basic_string<unsigned char>( (const unsigned char*) datastr.c_str(), datastr.size() ) ) );
}
status = db->Get(leveldb::ReadOptions(), i64tos(i), &datastr);
if (status.ok()) {
blocks.push_back(
DBBlock(i,
std::basic_string<unsigned char>((const unsigned char*) datastr.data(), datastr.size())
)
);
}
}
return blocks;