From 86dbb1f942515b23cb0dffeffc457ebf84bc59c9 Mon Sep 17 00:00:00 2001 From: g2px1 Date: Mon, 21 Apr 2025 12:08:27 +0300 Subject: [PATCH] update protocol description & added more settings to toml --- CMakeLists.txt | 2 ++ README.md | 51 +++++++++++++++++++++++++++++- core/DatabaseManager.cpp | 5 +-- core/Memtable.h | 6 ++-- core/UDB.cpp | 8 ++--- core/UDB.h | 5 ++- utils/config/GlobalConfig.cpp | 58 +++++++++++++++++++++++++++++++++++ utils/config/GlobalConfig.h | 29 ++++++++++++++++++ 8 files changed, 152 insertions(+), 12 deletions(-) create mode 100644 utils/config/GlobalConfig.cpp create mode 100644 utils/config/GlobalConfig.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 085d0ed..bce5289 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,8 @@ add_executable(sharedMemoryKeyDB core/UDB.h core/DatabaseManager.cpp core/DatabaseManager.h + utils/config/GlobalConfig.h + utils/config/GlobalConfig.cpp ) add_executable(sharedMemoryKeyDB_client diff --git a/README.md b/README.md index 29b7789..a704399 100644 --- a/README.md +++ b/README.md @@ -210,4 +210,53 @@ response = read_bytes(ptr, offset + 1050, response_size) - После обработки команды — инкрементировать `tail` мод capacity. - Ответ через `response` + `response_size` + `response_ready` только для `FIND`. ---- \ No newline at end of file +--- + +# Конфиг +Пример: +```toml +# Список баз данных +[[database]] +name = "rates1" + +[[database]] +name = "test" + +# Настройки базы rates1 +[databases.rates1] +shm_queue_capacity = 2048 # Размер очереди команд в shared memory (количество команд) +max_memtable_size = 2097152 # Максимальный размер активной Memtable в байтах (до сброса на диск) +l0_queue_capacity = 2048 # Размер очереди для фоновой компакции L0 SSTables +estimated_element_size = 256 # Оценка среднего размера одного элемента в Memtable в байтах + +# Настройки базы test +[databases.test] +shm_queue_capacity = 1024 +max_memtable_size = 1048576 +l0_queue_capacity = 1024 +estimated_element_size = 128 +``` + +## Замечания: +Если параметры не заданы для конкретной базы, используются значения по умолчанию: +```cpp +shm_queue_capacity = 1024 +max_memtable_size = 1048576 +l0_queue_capacity = 1024 +estimated_element_size = 128 +``` + +> Все размеры (max_memtable_size, estimated_element_size) указываются в байтах. + +> Shared Memory для каждой базы будет создана с именем /shm_<имя_базы>. + +> Очереди (l0_queue, shm_queue) построены на lock-free кольцевых буферах. + +## Полное описание параметров конфига + +| Параметр | Тип | Описание | +| :----------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `shm_queue_capacity` | `size_t` | **Размер очереди команд в shared memory**.
Это количество слотов команд (PUT/DELETE/FIND), которые могут одновременно находиться в памяти. Если очередь заполнится — новые команды временно не смогут быть отправлены.
**Важно**: shared memory выделяется исходя из этого размера, поэтому очередь большого размера требует больше памяти. | +| `max_memtable_size` | `size_t` | **Максимальный размер активной Memtable в байтах**.
Когда объем данных в Memtable превышает это значение, Memtable сбрасывается на диск в SSTable-файл.
**Если значение маленькое** — будет много мелких SSTable-файлов.
**Если значение большое** — реже будет происходить сброс, но потребление оперативной памяти будет выше. | +| `l0_queue_capacity` | `size_t` | **Размер очереди файлов для компакции L0 уровня**.
Когда Memtable сбрасывается в SSTable, файл ставится в очередь на компакцию. Этот параметр задает максимальное количество файлов, которые можно держать в очереди одновременно.
**Если значение маленькое** — компакция будет происходить чаще.
**Если большое** — будет задержка в обработке компакции при большом потоке вставок. | +| `estimated_element_size` | `size_t` | **Оценка среднего размера одного элемента в Memtable**.
Используется для **приближенного** расчета реального размера Memtable. Нужно, чтобы **не замерять точно каждый вставленный элемент**, а быстро определять когда пора сбрасывать Memtable.
**Типичный случай**: текстовые значения без больших вложений имеют размер 64-256 байт. | \ No newline at end of file diff --git a/core/DatabaseManager.cpp b/core/DatabaseManager.cpp index 0c5b75b..6e71fa0 100644 --- a/core/DatabaseManager.cpp +++ b/core/DatabaseManager.cpp @@ -4,7 +4,6 @@ #include "DatabaseManager.h" - namespace usub::core { DatabaseManager::DatabaseManager(const std::string& config_path) @@ -34,8 +33,10 @@ namespace usub::core { throw std::runtime_error("Database entry must be a table"); } + utils::load_global_config(config); + auto& database_settings = utils::database_settings_map.at(db_name); bool create_new = !SharedMemoryManager::exists("shm_" + db_name); - auto udb = std::make_unique(db_name, "shm_" + db_name, 1024, 1024 * 1024, create_new); + auto udb = std::make_unique(db_name, "shm_" + db_name, database_settings, create_new); this->databases_.push_back(DatabaseInstance{std::move(udb), {}}); } } diff --git a/core/Memtable.h b/core/Memtable.h index c8d6a0a..4367c2b 100644 --- a/core/Memtable.h +++ b/core/Memtable.h @@ -10,6 +10,7 @@ #include #include "utils/io/Wal.h" #include "utils/io/VersionManager.h" +#include "utils/config/GlobalConfig.h" namespace usub::shared_storage { @@ -19,7 +20,7 @@ namespace usub::shared_storage class MemTableManager { public: - MemTableManager(const std::string& wal_file, size_t max_size, utils::VersionManager& vm); + MemTableManager(const std::string& wal_file, size_t max_size, size_t estimated_element_size, utils::VersionManager& vm); ~MemTableManager(); @@ -41,6 +42,7 @@ namespace usub::shared_storage std::vector> write_batch; std::atomic flushing{false}; VersionManager& version_manager; + size_t estimated_element_size; private: size_t estimate_memtable_size() const; @@ -49,7 +51,7 @@ namespace usub::shared_storage }; template - MemTableManager::MemTableManager(const std::string& wal_file, size_t max_size, VersionManager& vm) + MemTableManager::MemTableManager(const std::string& wal_file, size_t max_size, size_t estimated_element_size, VersionManager& vm) : wal(wal_file), max_memtable_size(max_size), version_manager(vm) { this->active_memtable.store(new SkipList(this->version_manager)); diff --git a/core/UDB.cpp b/core/UDB.cpp index 05cab13..0e1a77e 100644 --- a/core/UDB.cpp +++ b/core/UDB.cpp @@ -7,14 +7,14 @@ namespace usub::core { UDB::UDB(const std::string& db_name, const std::string& shm_name, - size_t shm_queue_capacity, size_t max_memtable_size, bool create_new) + utils::DatabaseSettings settings, bool create_new) : db_name_(db_name), shm_name_(shm_name), - shm_queue_capacity_(shm_queue_capacity), - max_memtable_size_(max_memtable_size), + shm_queue_capacity_(settings.shm_queue_capacity), + max_memtable_size_(settings.max_memtable_size), shm_manager_(shm_name, sizeof(SharedCommandQueue), create_new), version_manager_(db_name), - memtable_manager_(db_name + "_wal", max_memtable_size, this->version_manager_), + memtable_manager_(db_name + "_wal", settings.max_memtable_size, settings.estimated_element_size, this->version_manager_), compactor_(this->version_manager_), running_(true) { diff --git a/core/UDB.h b/core/UDB.h index 8a85fab..ac5a3d7 100644 --- a/core/UDB.h +++ b/core/UDB.h @@ -25,14 +25,14 @@ #include "Memtable.h" #include "utils/io/RecoveryLog.h" #include "utils/io/Compactor.h" +#include "utils/config/GlobalConfig.h" namespace usub::core { class UDB { public: - UDB(const std::string& db_name, const std::string& shm_name, size_t shm_queue_capacity = 1024, - size_t max_memtable_size = 1024 * 1024, bool create_new = true); + UDB(const std::string& db_name, const std::string& shm_name, utils::DatabaseSettings settings, bool create_new = true); ~UDB(); @@ -65,4 +65,3 @@ namespace usub::core } #endif // UDB_H - diff --git a/utils/config/GlobalConfig.cpp b/utils/config/GlobalConfig.cpp new file mode 100644 index 0000000..b86c492 --- /dev/null +++ b/utils/config/GlobalConfig.cpp @@ -0,0 +1,58 @@ +// +// Created by Kirill Zhukov on 21.04.2025. +// +#include "GlobalConfig.h" +#include +#include "utils/toml/toml.hpp" + +namespace usub::utils +{ + std::unordered_map database_settings_map; + + void load_global_config(toml::parse_result& path) + { + try + { + if (auto databases = path["databases"].as_table()) + { + for (const auto& db : *databases) + { + const auto& db_name = db.first; + const auto& db_config = db.second; + + if (!db_config.is_table()) + continue; + + DatabaseSettings settings; + + const auto& table = *db_config.as_table(); + + if (auto val = table[toml::path("shm_queue_capacity")].value()) + settings.shm_queue_capacity = *val; + + if (auto val = table[toml::path("max_memtable_size")].value()) + settings.max_memtable_size = *val; + + if (auto val = table[toml::path("l0_queue_capacity")].value()) + settings.l0_queue_capacity = *val; + + if (auto val = table[toml::path("estimated_element_size")].value()) + settings.estimated_element_size = *val; + + database_settings_map.emplace(db_name.str(), settings); + + std::cout << "[Config] Loaded for DB '" << db_name << "': " + << "shm_queue_capacity=" << settings.shm_queue_capacity + << ", max_memtable_size=" << settings.max_memtable_size + << ", l0_queue_capacity=" << settings.l0_queue_capacity + << ", estimated_element_size=" << settings.estimated_element_size + << "\n"; + } + } + } + catch (const std::exception& ex) + { + std::cerr << "[Config] Failed to load config: " << ex.what() << "\n"; + } + } +} diff --git a/utils/config/GlobalConfig.h b/utils/config/GlobalConfig.h new file mode 100644 index 0000000..a49f43f --- /dev/null +++ b/utils/config/GlobalConfig.h @@ -0,0 +1,29 @@ +// +// Created by Kirill Zhukov on 21.04.2025. +// + +#ifndef GLOBAL_CONFIG_H +#define GLOBAL_CONFIG_H + +#include +#include +#include + +#include "utils/toml/toml.hpp" + +namespace usub::utils +{ + struct DatabaseSettings + { + size_t shm_queue_capacity = 1024; + size_t max_memtable_size = 1024 * 1024; + size_t l0_queue_capacity = 1024; + size_t estimated_element_size = 128; + }; + + extern std::unordered_map database_settings_map; + + void load_global_config(toml::parse_result& path); +} + +#endif //GLOBAL_CONFIG_H