Skip to content

Commit

Permalink
perf: configmanager cache (opentibiabr#3232)
Browse files Browse the repository at this point in the history
This introduces a performance enhancement by implementing a cache within the ConfigManager. This change reduces the overhead associated with accessing standard configuration variables, leading to more efficient retrieval and improved overall performance.
  • Loading branch information
dudantas authored and vllworldbuilding committed Jan 30, 2025
1 parent ef190ec commit b15ff62
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 11 deletions.
67 changes: 57 additions & 10 deletions src/config/configmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,10 @@ bool ConfigManager::load() {
}

bool ConfigManager::reload() {
m_configString.clear();
m_configInteger.clear();
m_configBoolean.clear();
m_configFloat.clear();
const bool result = load();
if (transformToSHA1(getString(SERVER_MOTD)) != g_game().getMotdHash()) {
g_game().incrementMotdNum();
Expand Down Expand Up @@ -437,34 +441,77 @@ float ConfigManager::loadFloatConfig(lua_State* L, const ConfigKey_t &key, const
}

const std::string &ConfigManager::getString(const ConfigKey_t &key, const std::source_location &location /*= std::source_location::current()*/) const {
static const std::string dummyStr;
if (configs.contains(key) && std::holds_alternative<std::string>(configs.at(key))) {
return std::get<std::string>(configs.at(key));
auto itCache = m_configString.find(key);
if (itCache != m_configString.end()) {
return itCache->second;
}

auto it = configs.find(key);
if (it != configs.end()) {
if (const auto* value = std::get_if<std::string>(&it->second)) {
m_configString[key] = *value;
return *value;
}
}

static const std::string staticEmptyString;
g_logger().warn("[{}] accessing invalid or wrong type index: {}[{}]. Called line: {}:{}, in {}", __FUNCTION__, magic_enum::enum_name(key), fmt::underlying(key), location.line(), location.column(), location.function_name());
return dummyStr;
return staticEmptyString;
}

int32_t ConfigManager::getNumber(const ConfigKey_t &key, const std::source_location &location /*= std::source_location::current()*/) const {
if (configs.contains(key) && std::holds_alternative<int32_t>(configs.at(key))) {
return std::get<int32_t>(configs.at(key));
auto itCache = m_configInteger.find(key);
if (itCache != m_configInteger.end()) {
return itCache->second;
}

auto it = configs.find(key);
if (it != configs.end()) {
if (std::holds_alternative<int32_t>(it->second)) {
const auto value = std::get<int32_t>(it->second);
m_configInteger[key] = value;
return value;
}
}

g_logger().warn("[{}] accessing invalid or wrong type index: {}[{}]. Called line: {}:{}, in {}", __FUNCTION__, magic_enum::enum_name(key), fmt::underlying(key), location.line(), location.column(), location.function_name());
return 0;
}

bool ConfigManager::getBoolean(const ConfigKey_t &key, const std::source_location &location /*= std::source_location::current()*/) const {
if (configs.contains(key) && std::holds_alternative<bool>(configs.at(key))) {
return std::get<bool>(configs.at(key));
auto itCache = m_configBoolean.find(key);
if (itCache != m_configBoolean.end()) {
return itCache->second;
}

auto it = configs.find(key);
if (it != configs.end()) {
if (std::holds_alternative<bool>(it->second)) {
const auto value = std::get<bool>(it->second);
m_configBoolean[key] = value;
return value;
}
}

g_logger().warn("[{}] accessing invalid or wrong type index: {}[{}]. Called line: {}:{}, in {}", __FUNCTION__, magic_enum::enum_name(key), fmt::underlying(key), location.line(), location.column(), location.function_name());
return false;
}

float ConfigManager::getFloat(const ConfigKey_t &key, const std::source_location &location /*= std::source_location::current()*/) const {
if (configs.contains(key) && std::holds_alternative<float>(configs.at(key))) {
return std::get<float>(configs.at(key));
auto itCache = m_configFloat.find(key);
if (itCache != m_configFloat.end()) {
return itCache->second;
}

auto it = configs.find(key);
if (it != configs.end()) {
if (std::holds_alternative<float>(it->second)) {
const auto value = std::get<float>(it->second);
m_configFloat[key] = value;
return value;
}
}

g_logger().warn("[{}] accessing invalid or wrong type index: {}[{}]. Called line: {}:{}, in {}", __FUNCTION__, magic_enum::enum_name(key), fmt::underlying(key), location.line(), location.column(), location.function_name());
return 0.0f;
}
7 changes: 6 additions & 1 deletion src/config/configmanager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ class ConfigManager {
[[nodiscard]] float getFloat(const ConfigKey_t &key, const std::source_location &location = std::source_location::current()) const;

private:
phmap::flat_hash_map<ConfigKey_t, ConfigValue> configs;
mutable std::unordered_map<ConfigKey_t, std::string> m_configString;
mutable std::unordered_map<ConfigKey_t, bool> m_configBoolean;
mutable std::unordered_map<ConfigKey_t, int32_t> m_configInteger;
mutable std::unordered_map<ConfigKey_t, float> m_configFloat;

std::unordered_map<ConfigKey_t, ConfigValue> configs;
std::string loadStringConfig(lua_State* L, const ConfigKey_t &key, const char* identifier, const std::string &defaultValue);
int32_t loadIntConfig(lua_State* L, const ConfigKey_t &key, const char* identifier, const int32_t &defaultValue);
bool loadBoolConfig(lua_State* L, const ConfigKey_t &key, const char* identifier, const bool &defaultValue);
Expand Down

0 comments on commit b15ff62

Please sign in to comment.