mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-02 16:38:41 +00:00
Avoid duplication of mod metadata in memory (#12562)
Co-authored-by: sfan5 <sfan5@live.de>
This commit is contained in:
parent
03428d9825
commit
f4a01f3a5d
37 changed files with 527 additions and 272 deletions
|
@ -92,6 +92,32 @@ bool Database_Dummy::getModEntries(const std::string &modname, StringMap *storag
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Database_Dummy::getModEntry(const std::string &modname,
|
||||
const std::string &key, std::string *value)
|
||||
{
|
||||
auto mod_pair = m_mod_meta_database.find(modname);
|
||||
if (mod_pair == m_mod_meta_database.end())
|
||||
return false;
|
||||
const StringMap &meta = mod_pair->second;
|
||||
|
||||
auto pair = meta.find(key);
|
||||
if (pair != meta.end()) {
|
||||
*value = pair->second;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Database_Dummy::hasModEntry(const std::string &modname, const std::string &key)
|
||||
{
|
||||
auto mod_pair = m_mod_meta_database.find(modname);
|
||||
if (mod_pair == m_mod_meta_database.end())
|
||||
return false;
|
||||
const StringMap &meta = mod_pair->second;
|
||||
|
||||
return meta.find(key) != meta.cend();
|
||||
}
|
||||
|
||||
bool Database_Dummy::setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value)
|
||||
{
|
||||
|
@ -112,6 +138,16 @@ bool Database_Dummy::removeModEntry(const std::string &modname, const std::strin
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Database_Dummy::removeModEntries(const std::string &modname)
|
||||
{
|
||||
auto mod_pair = m_mod_meta_database.find(modname);
|
||||
if (mod_pair != m_mod_meta_database.end() && !mod_pair->second.empty()) {
|
||||
mod_pair->second.clear();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Database_Dummy::listMods(std::vector<std::string> *res)
|
||||
{
|
||||
for (const auto &pair : m_mod_meta_database) {
|
||||
|
|
|
@ -38,9 +38,13 @@ public:
|
|||
void listPlayers(std::vector<std::string> &res);
|
||||
|
||||
bool getModEntries(const std::string &modname, StringMap *storage);
|
||||
bool getModEntry(const std::string &modname,
|
||||
const std::string &key, std::string *value);
|
||||
bool hasModEntry(const std::string &modname, const std::string &key);
|
||||
bool setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value);
|
||||
bool removeModEntry(const std::string &modname, const std::string &key);
|
||||
bool removeModEntries(const std::string &modname);
|
||||
void listMods(std::vector<std::string> *res);
|
||||
|
||||
void beginSave() {}
|
||||
|
|
|
@ -396,6 +396,26 @@ bool ModMetadataDatabaseFiles::getModEntries(const std::string &modname, StringM
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ModMetadataDatabaseFiles::getModEntry(const std::string &modname,
|
||||
const std::string &key, std::string *value)
|
||||
{
|
||||
Json::Value *meta = getOrCreateJson(modname);
|
||||
if (!meta)
|
||||
return false;
|
||||
|
||||
if (meta->isMember(key)) {
|
||||
*value = (*meta)[key].asString();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModMetadataDatabaseFiles::hasModEntry(const std::string &modname, const std::string &key)
|
||||
{
|
||||
Json::Value *meta = getOrCreateJson(modname);
|
||||
return meta && meta->isMember(key);
|
||||
}
|
||||
|
||||
bool ModMetadataDatabaseFiles::setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value)
|
||||
{
|
||||
|
@ -424,6 +444,17 @@ bool ModMetadataDatabaseFiles::removeModEntry(const std::string &modname,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ModMetadataDatabaseFiles::removeModEntries(const std::string &modname)
|
||||
{
|
||||
Json::Value *meta = getOrCreateJson(modname);
|
||||
if (!meta || meta->empty())
|
||||
return false;
|
||||
|
||||
meta->clear();
|
||||
m_modified.insert(modname);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModMetadataDatabaseFiles::beginSave()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -79,9 +79,13 @@ public:
|
|||
virtual ~ModMetadataDatabaseFiles() = default;
|
||||
|
||||
virtual bool getModEntries(const std::string &modname, StringMap *storage);
|
||||
virtual bool getModEntry(const std::string &modname,
|
||||
const std::string &key, std::string *value);
|
||||
virtual bool hasModEntry(const std::string &modname, const std::string &key);
|
||||
virtual bool setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value);
|
||||
virtual bool removeModEntry(const std::string &modname, const std::string &key);
|
||||
virtual bool removeModEntries(const std::string &modname);
|
||||
virtual void listMods(std::vector<std::string> *res);
|
||||
|
||||
virtual void beginSave();
|
||||
|
|
|
@ -770,9 +770,12 @@ ModMetadataDatabaseSQLite3::ModMetadataDatabaseSQLite3(const std::string &savedi
|
|||
|
||||
ModMetadataDatabaseSQLite3::~ModMetadataDatabaseSQLite3()
|
||||
{
|
||||
FINALIZE_STATEMENT(m_stmt_remove_all)
|
||||
FINALIZE_STATEMENT(m_stmt_remove)
|
||||
FINALIZE_STATEMENT(m_stmt_set)
|
||||
FINALIZE_STATEMENT(m_stmt_has)
|
||||
FINALIZE_STATEMENT(m_stmt_get)
|
||||
FINALIZE_STATEMENT(m_stmt_get_all)
|
||||
}
|
||||
|
||||
void ModMetadataDatabaseSQLite3::createDatabase()
|
||||
|
@ -792,31 +795,74 @@ void ModMetadataDatabaseSQLite3::createDatabase()
|
|||
|
||||
void ModMetadataDatabaseSQLite3::initStatements()
|
||||
{
|
||||
PREPARE_STATEMENT(get, "SELECT `key`, `value` FROM `entries` WHERE `modname` = ?");
|
||||
PREPARE_STATEMENT(get_all, "SELECT `key`, `value` FROM `entries` WHERE `modname` = ?");
|
||||
PREPARE_STATEMENT(get,
|
||||
"SELECT `value` FROM `entries` WHERE `modname` = ? AND `key` = ? LIMIT 1");
|
||||
PREPARE_STATEMENT(has,
|
||||
"SELECT 1 FROM `entries` WHERE `modname` = ? AND `key` = ? LIMIT 1");
|
||||
PREPARE_STATEMENT(set,
|
||||
"REPLACE INTO `entries` (`modname`, `key`, `value`) VALUES (?, ?, ?)");
|
||||
PREPARE_STATEMENT(remove, "DELETE FROM `entries` WHERE `modname` = ? AND `key` = ?");
|
||||
PREPARE_STATEMENT(remove_all, "DELETE FROM `entries` WHERE `modname` = ?");
|
||||
}
|
||||
|
||||
bool ModMetadataDatabaseSQLite3::getModEntries(const std::string &modname, StringMap *storage)
|
||||
{
|
||||
verifyDatabase();
|
||||
|
||||
str_to_sqlite(m_stmt_get, 1, modname);
|
||||
while (sqlite3_step(m_stmt_get) == SQLITE_ROW) {
|
||||
const char *key_data = (const char *) sqlite3_column_blob(m_stmt_get, 0);
|
||||
size_t key_len = sqlite3_column_bytes(m_stmt_get, 0);
|
||||
const char *value_data = (const char *) sqlite3_column_blob(m_stmt_get, 1);
|
||||
size_t value_len = sqlite3_column_bytes(m_stmt_get, 1);
|
||||
str_to_sqlite(m_stmt_get_all, 1, modname);
|
||||
while (sqlite3_step(m_stmt_get_all) == SQLITE_ROW) {
|
||||
const char *key_data = (const char *) sqlite3_column_blob(m_stmt_get_all, 0);
|
||||
size_t key_len = sqlite3_column_bytes(m_stmt_get_all, 0);
|
||||
const char *value_data = (const char *) sqlite3_column_blob(m_stmt_get_all, 1);
|
||||
size_t value_len = sqlite3_column_bytes(m_stmt_get_all, 1);
|
||||
(*storage)[std::string(key_data, key_len)] = std::string(value_data, value_len);
|
||||
}
|
||||
sqlite3_vrfy(sqlite3_errcode(m_database), SQLITE_DONE);
|
||||
|
||||
sqlite3_reset(m_stmt_get);
|
||||
sqlite3_reset(m_stmt_get_all);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModMetadataDatabaseSQLite3::getModEntry(const std::string &modname,
|
||||
const std::string &key, std::string *value)
|
||||
{
|
||||
verifyDatabase();
|
||||
|
||||
str_to_sqlite(m_stmt_get, 1, modname);
|
||||
SQLOK(sqlite3_bind_blob(m_stmt_get, 2, key.data(), key.size(), NULL),
|
||||
"Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__));
|
||||
bool found = sqlite3_step(m_stmt_get) == SQLITE_ROW;
|
||||
if (found) {
|
||||
const char *value_data = (const char *) sqlite3_column_blob(m_stmt_get, 0);
|
||||
size_t value_len = sqlite3_column_bytes(m_stmt_get, 0);
|
||||
value->assign(value_data, value_len);
|
||||
sqlite3_step(m_stmt_get);
|
||||
}
|
||||
|
||||
sqlite3_reset(m_stmt_get);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool ModMetadataDatabaseSQLite3::hasModEntry(const std::string &modname,
|
||||
const std::string &key)
|
||||
{
|
||||
verifyDatabase();
|
||||
|
||||
str_to_sqlite(m_stmt_has, 1, modname);
|
||||
SQLOK(sqlite3_bind_blob(m_stmt_has, 2, key.data(), key.size(), NULL),
|
||||
"Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__));
|
||||
bool found = sqlite3_step(m_stmt_has) == SQLITE_ROW;
|
||||
if (found)
|
||||
sqlite3_step(m_stmt_has);
|
||||
|
||||
sqlite3_reset(m_stmt_has);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool ModMetadataDatabaseSQLite3::setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value)
|
||||
{
|
||||
|
@ -850,6 +896,19 @@ bool ModMetadataDatabaseSQLite3::removeModEntry(const std::string &modname,
|
|||
return changes > 0;
|
||||
}
|
||||
|
||||
bool ModMetadataDatabaseSQLite3::removeModEntries(const std::string &modname)
|
||||
{
|
||||
verifyDatabase();
|
||||
|
||||
str_to_sqlite(m_stmt_remove_all, 1, modname);
|
||||
sqlite3_vrfy(sqlite3_step(m_stmt_remove_all), SQLITE_DONE);
|
||||
int changes = sqlite3_changes(m_database);
|
||||
|
||||
sqlite3_reset(m_stmt_remove_all);
|
||||
|
||||
return changes > 0;
|
||||
}
|
||||
|
||||
void ModMetadataDatabaseSQLite3::listMods(std::vector<std::string> *res)
|
||||
{
|
||||
verifyDatabase();
|
||||
|
|
|
@ -240,9 +240,13 @@ public:
|
|||
virtual ~ModMetadataDatabaseSQLite3();
|
||||
|
||||
virtual bool getModEntries(const std::string &modname, StringMap *storage);
|
||||
virtual bool getModEntry(const std::string &modname,
|
||||
const std::string &key, std::string *value);
|
||||
virtual bool hasModEntry(const std::string &modname, const std::string &key);
|
||||
virtual bool setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value);
|
||||
virtual bool removeModEntry(const std::string &modname, const std::string &key);
|
||||
virtual bool removeModEntries(const std::string &modname);
|
||||
virtual void listMods(std::vector<std::string> *res);
|
||||
|
||||
virtual void beginSave() { Database_SQLite3::beginSave(); }
|
||||
|
@ -253,7 +257,10 @@ protected:
|
|||
virtual void initStatements();
|
||||
|
||||
private:
|
||||
sqlite3_stmt *m_stmt_get_all = nullptr;
|
||||
sqlite3_stmt *m_stmt_get = nullptr;
|
||||
sqlite3_stmt *m_stmt_has = nullptr;
|
||||
sqlite3_stmt *m_stmt_set = nullptr;
|
||||
sqlite3_stmt *m_stmt_remove = nullptr;
|
||||
sqlite3_stmt *m_stmt_remove_all = nullptr;
|
||||
};
|
||||
|
|
|
@ -92,8 +92,12 @@ public:
|
|||
virtual ~ModMetadataDatabase() = default;
|
||||
|
||||
virtual bool getModEntries(const std::string &modname, StringMap *storage) = 0;
|
||||
virtual bool hasModEntry(const std::string &modname, const std::string &key) = 0;
|
||||
virtual bool getModEntry(const std::string &modname,
|
||||
const std::string &key, std::string *value) = 0;
|
||||
virtual bool setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value) = 0;
|
||||
virtual bool removeModEntry(const std::string &modname, const std::string &key) = 0;
|
||||
virtual bool removeModEntries(const std::string &modname) = 0;
|
||||
virtual void listMods(std::vector<std::string> *res) = 0;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue