From d1a16f24cfb360a0a6e60fc76ea87d7c4cf24618 Mon Sep 17 00:00:00 2001 From: JacobF Date: Fri, 2 Sep 2011 19:07:14 -0400 Subject: Initial sqlite3 maps. * The map will reside in world/map.sqlite * It will load from the sectors folder but will not save there --- src/map.cpp | 251 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 242 insertions(+), 9 deletions(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index 27a491428..41c4e17d2 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -29,12 +29,21 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapgen.h" #include "nodemetadata.h" -extern "C" { - #include "sqlite3.h" -} /* SQLite format specification: - Initially only replaces sectors/ and sectors2/ + + If map.sqlite does not exist in the save dir + or the block was not found in the database + the map will try to load from sectors folder. + In either case, map.sqlite will be created + and all future saves will save there. + + Structure of map.sqlite: + Tables: + blocks + (PK) INT pos + BLOB data */ /* @@ -1408,6 +1417,8 @@ void Map::timerUpdate(float dtime, float unload_timeout, core::list blocks; sector->getBlocks(blocks); + + beginSave(); for(core::list::Iterator i = blocks.begin(); i != blocks.end(); i++) { @@ -1440,6 +1451,7 @@ void Map::timerUpdate(float dtime, float unload_timeout, all_blocks_deleted = false; } } + endSave(); if(all_blocks_deleted) { @@ -1873,7 +1885,10 @@ void Map::nodeMetadataStep(float dtime, ServerMap::ServerMap(std::string savedir): Map(dout_server), m_seed(0), - m_map_metadata_changed(true) + m_map_metadata_changed(true), + m_database(NULL), + m_database_read(NULL), + m_database_write(NULL) { dstream<<__FUNCTION_NAME<::Iterator i = m_sectors.getIterator(); for(; i.atEnd() == false; i++) { @@ -2876,6 +2971,8 @@ void ServerMap::save(bool only_changed) core::list blocks; sector->getBlocks(blocks); core::list::Iterator j; + + //sqlite3_exec(m_database, "BEGIN;", NULL, NULL, NULL); for(j=blocks.begin(); j!=blocks.end(); j++) { MapBlock *block = *j; @@ -2894,8 +2991,10 @@ void ServerMap::save(bool only_changed) <getPos().Z<<")" <getPos(); + +#if 0 v2s16 p2d(p3d.X, p3d.Z); std::string sectordir = getSectorDir(p2d); @@ -3182,11 +3295,16 @@ void ServerMap::saveBlock(MapBlock *block) std::ofstream o(fullpath.c_str(), std::ios_base::binary); if(o.good() == false) throw FileNotGoodException("Cannot open block data"); - +#endif /* [0] u8 serialization version [1] data */ + + verifyDatabase(); + + std::ostringstream o(std::ios_base::binary); + o.write((char*)&version, 1); // Write basic data @@ -3194,7 +3312,23 @@ void ServerMap::saveBlock(MapBlock *block) // Write extra data stored on disk block->serializeDiskExtra(o, version); - + + // Write block to database + + std::string tmp = o.str(); + const char *bytes = tmp.c_str(); + + if(sqlite3_bind_int(m_database_write, 1, getBlockAsInteger(p3d)) != SQLITE_OK) + dstream<<"WARNING: Block position failed to bind: "<resetModified(); } @@ -3275,12 +3409,111 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto } } +void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load) +{ + DSTACK(__FUNCTION_NAME); + + try { + std::istringstream is(*blob, std::ios_base::binary); + + u8 version = SER_FMT_VER_INVALID; + is.read((char*)&version, 1); + + if(is.fail()) + throw SerializationError("ServerMap::loadBlock(): Failed" + " to read MapBlock version"); + + /*u32 block_size = MapBlock::serializedLength(version); + SharedBuffer data(block_size); + is.read((char*)*data, block_size);*/ + + // This will always return a sector because we're the server + //MapSector *sector = emergeSector(p2d); + + MapBlock *block = NULL; + bool created_new = false; + block = sector->getBlockNoCreateNoEx(p3d.Y); + if(block == NULL) + { + block = sector->createBlankBlockNoInsert(p3d.Y); + created_new = true; + } + + // Read basic data + block->deSerialize(is, version); + + // Read extra data stored on disk + block->deSerializeDiskExtra(is, version); + + // If it's a new block, insert it to the map + if(created_new) + sector->insertBlock(block); + + /* + Save blocks loaded in old format in new format + */ + + if(version < SER_FMT_VER_HIGHEST || save_after_load) + { + saveBlock(block); + } + + // We just loaded it from, so it's up-to-date. + block->resetModified(); + + } + catch(SerializationError &e) + { + dstream<<"WARNING: Invalid block data in database " + <<" (SerializationError). " + <<"what()="< Date: Sun, 4 Sep 2011 17:01:28 -0400 Subject: These numbers were well exceeding 2^32... --- src/map.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index 41c4e17d2..46ee5b53f 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2849,8 +2849,9 @@ bool ServerMap::loadFromFolders() { return false; } -int ServerMap::getBlockAsInteger(const v3s16 pos) { - return (pos.Z+2048)*16777216 + (pos.Y+2048)*4096 + pos.X; +sqlite3_int64 ServerMap::getBlockAsInteger(const v3s16 pos) { + return (sqlite3_int64)pos.Z*16777216 + + (sqlite3_int64)pos.Y*4096 + (sqlite3_int64)pos.X; } void ServerMap::createDirs(std::string path) @@ -3318,7 +3319,7 @@ void ServerMap::saveBlock(MapBlock *block) std::string tmp = o.str(); const char *bytes = tmp.c_str(); - if(sqlite3_bind_int(m_database_write, 1, getBlockAsInteger(p3d)) != SQLITE_OK) + if(sqlite3_bind_int64(m_database_write, 1, getBlockAsInteger(p3d)) != SQLITE_OK) dstream<<"WARNING: Block position failed to bind: "<