X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fdatabase-leveldb.cpp;h=4a4904c6a0b122f58a5ee217577236b22cf767fb;hb=d382483fa76028c2d34f75067bff45306c6da34e;hp=cb0101a811f7ce46bb2f23d672b4b5e3c8bed86a;hpb=f1e4a671dc524430cae0dc66fd774858842a3067;p=dragonfireclient.git diff --git a/src/database-leveldb.cpp b/src/database-leveldb.cpp index cb0101a81..4a4904c6a 100644 --- a/src/database-leveldb.cpp +++ b/src/database-leveldb.cpp @@ -1,163 +1,101 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + #include "config.h" #if USE_LEVELDB -/* -LevelDB databases -*/ +#include "database-leveldb.h" -#include "map.h" -#include "mapsector.h" -#include "mapblock.h" -#include "main.h" -#include "filesys.h" -#include "voxel.h" -#include "porting.h" -#include "mapgen.h" -#include "nodemetadata.h" -#include "settings.h" #include "log.h" -#include "profiler.h" -#include "nodedef.h" -#include "gamedef.h" -#include "util/directiontables.h" -#include "rollback_interface.h" +#include "filesys.h" +#include "exceptions.h" +#include "util/string.h" -#include "database-leveldb.h" #include "leveldb/db.h" -Database_LevelDB::Database_LevelDB(ServerMap *map, std::string savedir) + +#define ENSURE_STATUS_OK(s) \ + if (!(s).ok()) { \ + throw DatabaseException(std::string("LevelDB error: ") + \ + (s).ToString()); \ + } + + +Database_LevelDB::Database_LevelDB(const std::string &savedir) { leveldb::Options options; options.create_if_missing = true; - leveldb::Status status = leveldb::DB::Open(options, savedir + DIR_DELIM + "map.db", &m_database); - assert(status.ok()); - srvmap = map; + leveldb::Status status = leveldb::DB::Open(options, + savedir + DIR_DELIM + "map.db", &m_database); + ENSURE_STATUS_OK(status); } -int Database_LevelDB::Initialized(void) +Database_LevelDB::~Database_LevelDB() { - return 1; + delete m_database; } -void Database_LevelDB::beginSave() {} -void Database_LevelDB::endSave() {} - -void Database_LevelDB::saveBlock(MapBlock *block) +bool Database_LevelDB::saveBlock(const v3s16 &pos, const std::string &data) { - DSTACK(__FUNCTION_NAME); - /* - Dummy blocks are not written - */ - if(block->isDummy()) - { - return; + leveldb::Status status = m_database->Put(leveldb::WriteOptions(), + i64tos(getBlockAsInteger(pos)), data); + if (!status.ok()) { + warningstream << "saveBlock: LevelDB error saving block " + << PP(pos) << ": " << status.ToString() << std::endl; + return false; } - // Format used for writing - u8 version = SER_FMT_VER_HIGHEST_WRITE; - // Get destination - v3s16 p3d = block->getPos(); - - /* - [0] u8 serialization version - [1] data - */ - - std::ostringstream o(std::ios_base::binary); - o.write((char*)&version, 1); - // Write basic data - block->serialize(o, version, true); - // Write block to database - std::string tmp = o.str(); + return true; +} - m_database->Put(leveldb::WriteOptions(), i64tos(getBlockAsInteger(p3d)), tmp); +void Database_LevelDB::loadBlock(const v3s16 &pos, std::string *block) +{ + std::string datastr; + leveldb::Status status = m_database->Get(leveldb::ReadOptions(), + i64tos(getBlockAsInteger(pos)), &datastr); - // We just wrote it to the disk so clear modified flag - block->resetModified(); + *block = (status.ok()) ? datastr : ""; } -MapBlock* Database_LevelDB::loadBlock(v3s16 blockpos) +bool Database_LevelDB::deleteBlock(const v3s16 &pos) { - v2s16 p2d(blockpos.X, blockpos.Z); + leveldb::Status status = m_database->Delete(leveldb::WriteOptions(), + i64tos(getBlockAsInteger(pos))); + if (!status.ok()) { + warningstream << "deleteBlock: LevelDB error deleting block " + << PP(pos) << ": " << status.ToString() << std::endl; + return false; + } - std::string datastr; - leveldb::Status s = m_database->Get(leveldb::ReadOptions(), i64tos(getBlockAsInteger(blockpos)), &datastr); - - if(s.ok()) { - /* - Make sure sector is loaded - */ - MapSector *sector = srvmap->createSector(p2d); - - try { - std::istringstream is(datastr, 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"); - - MapBlock *block = NULL; - bool created_new = false; - block = sector->getBlockNoCreateNoEx(blockpos.Y); - if(block == NULL) - { - block = sector->createBlankBlockNoInsert(blockpos.Y); - created_new = true; - } - // Read basic data - block->deSerialize(is, version, true); - // 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) - // Only save if asked to; no need to update version - //if(save_after_load) - // saveBlock(block); - // We just loaded it from, so it's up-to-date. - block->resetModified(); - - } - catch(SerializationError &e) - { - errorstream<<"Invalid block data in database" - <<" ("<getBool("ignore_world_load_errors")){ - errorstream<<"Ignoring block load error. Duck and cover! " - <<"(ignore_world_load_errors)"<getBlockNoCreateNoEx(blockpos); // should not be using this here - } - return(NULL); + return true; } -void Database_LevelDB::listAllLoadableBlocks(std::list &dst) +void Database_LevelDB::listAllLoadableBlocks(std::vector &dst) { leveldb::Iterator* it = m_database->NewIterator(leveldb::ReadOptions()); for (it->SeekToFirst(); it->Valid(); it->Next()) { dst.push_back(getIntegerAsBlock(stoi64(it->key().ToString()))); } - assert(it->status().ok()); // Check for any errors found during the scan + ENSURE_STATUS_OK(it->status()); // Check for any errors found during the scan delete it; } -Database_LevelDB::~Database_LevelDB() -{ - delete m_database; -} -#endif +#endif // USE_LEVELDB +