leveldbfm format for reading leveldb maps from freeminer

This commit is contained in:
proller 2014-05-23 21:40:11 +04:00
parent dff4589152
commit 3661c9f352
7 changed files with 96 additions and 3 deletions

View File

@ -106,6 +106,7 @@ set(mapper_SRCS
if(USE_LEVELDB)
set(mapper_SRCS ${mapper_SRCS} db-leveldb.cpp)
set(mapper_SRCS ${mapper_SRCS} db-leveldbfm.cpp)
endif(USE_LEVELDB)
if(USE_REDIS)

View File

@ -16,6 +16,7 @@
#include "db-sqlite3.h"
#if USE_LEVELDB
#include "db-leveldb.h"
#include "db-leveldbfm.h"
#endif
#if USE_REDIS
#include "db-redis.h"
@ -294,6 +295,8 @@ void TileGenerator::openDb(const std::string &input)
#if USE_LEVELDB
else if(m_backend == "leveldb")
m_db = new DBLevelDB(input);
else if(m_backend == "leveldbfm")
m_db = new DBLevelDBFM(input);
#endif
#if USE_REDIS
else if(m_backend == "redis")

View File

@ -28,7 +28,8 @@ DBLevelDB::DBLevelDB(const std::string &mapdir)
throw std::runtime_error(std::string("Failed to open Database: ") + status.ToString());
}
loadPosCache();
if(!no_load)
loadPosCache();
}

View File

@ -6,13 +6,14 @@
class DBLevelDB : public DB {
public:
DBLevelDB(const std::string &mapdir);
DBLevelDB(const std::string &mapdir, bool no_load = 0);
virtual std::vector<BlockPos> getBlockPos();
virtual void getBlocksOnZ(std::map<int16_t, BlockList> &blocks, int16_t zPos);
~DBLevelDB();
private:
void loadPosCache();
protected:
std::vector<BlockPos> posCache;
leveldb::DB *db;

69
db-leveldbfm.cpp Normal file
View File

@ -0,0 +1,69 @@
#include <sstream>
#include "db-leveldbfm.h"
#include "types.h"
static inline int64_t stoi64(const std::string &s)
{
std::stringstream tmp(s);
int64_t t;
tmp >> t;
return t;
}
DBLevelDBFM::DBLevelDBFM(const std::string &mapdir) : DBLevelDB(mapdir, 1)
{
loadPosCache();
}
DBLevelDBFM::~DBLevelDBFM()
{
}
std::string getBlockAsString(const BlockPos &pos) {
std::ostringstream os;
os << "a" << pos.x << "," << pos.y << "," << pos.z;
return os.str().c_str();
}
BlockPos DBLevelDBFM::getStringAsBlock(const std::string &i) {
std::istringstream is(i);
BlockPos pos;
char c;
if (i[0] == 'a') {
is >> c; // 'a'
is >> pos.x;
is >> c; // ','
is >> pos.y;
is >> c; // ','
is >> pos.z;
} else { // old format
return decodeBlockPos(stoi64(i));
}
return pos;
}
void DBLevelDBFM::loadPosCache()
{
leveldb::Iterator * it = db->NewIterator(leveldb::ReadOptions());
for (it->SeekToFirst(); it->Valid(); it->Next()) {
posCache.push_back(getStringAsBlock(it->key().ToString()));
}
delete it;
}
void DBLevelDBFM::getBlocksOnZ(std::map<int16_t, BlockList> &blocks, int16_t zPos)
{
std::string datastr;
leveldb::Status status;
for (std::vector<BlockPos>::iterator it = posCache.begin(); it != posCache.end(); ++it) {
if (it->z != zPos) {
continue;
}
status = db->Get(leveldb::ReadOptions(), getBlockAsString(*it), &datastr);
if (status.ok()) {
Block b(*it, ustring((const unsigned char *) datastr.data(), datastr.size()));
blocks[b.first.x].push_back(b);
}
}
}

18
db-leveldbfm.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef DB_LEVELDBFM_HEADER
#define DB_LEVELDBFM_HEADER
#include "db-leveldb.h"
#include <leveldb/db.h>
class DBLevelDBFM : public DBLevelDB {
public:
DBLevelDBFM(const std::string &mapdir);
virtual void getBlocksOnZ(std::map<int16_t, BlockList> &blocks, int16_t zPos);
~DBLevelDBFM();
protected:
BlockPos getStringAsBlock(const std::string &i);
virtual void loadPosCache();
};
#endif // DB_LEVELDBFM_HEADER

View File

@ -34,7 +34,7 @@ void usage()
" --noshading\n"
" --min-y <y>\n"
" --max-y <y>\n"
" --backend <sqlite3/leveldb/redis>\n"
" --backend <sqlite3/leveldb/leveldbfm/redis>\n"
" --geometry x:y+w+h\n"
"Color format: '#000000'\n";
std::cout << usage_text;