cpp_server/kv_store.hpp

100 lines
2.4 KiB
C++

#pragma once
#include <unordered_map>
#include <mutex>
#include <fstream>
#include <optional>
#include <string>
#include <variant>
#include <sstream>
using std::string;
class KeyValueStore {
public:
using Value = std::variant<int, double, string, bool>;
void set(const string& key, const Value& value) {
std::lock_guard<std::mutex> lock(mutex_);
data_[key] = value;
}
template<typename T>
std::optional<T> get(const string& key) {
std::lock_guard<std::mutex> lock(mutex_);
auto it = data_.find(key);
if (it == data_.end()) return std::nullopt;
if (auto* ptr = std::get_if<T>(&it->second)) {
return *ptr;
}
return std::nullopt;
}
bool del(const string& key) {
std::lock_guard<std::mutex> lock(mutex_);
return data_.erase(key) > 0;
}
size_t size() {
std::lock_guard<std::mutex> lock(mutex_);
return data_.size();
}
void set_file(const string& filename) {
filename_ = filename;
}
void load() {
std::ifstream file(filename_);
if (!file.is_open()) return;
std::lock_guard<std::mutex> lock(mutex_);
string line;
while (std::getline(file, line)) {
size_t eq = line.find('=');
if (eq == string::npos || eq < 2) continue;
string key = line.substr(2, eq - 2);
string val_str = line.substr(eq + 1);
char type = line[0];
switch (type) {
case 'i': data_[key] = std::stoi(val_str); break;
case 'd': data_[key] = std::stod(val_str); break;
case 's': data_[key] = val_str; break;
case 'b': data_[key] = (val_str == "1"); break;
}
}
}
void save() {
std::lock_guard<std::mutex> lock(mutex_);
std::ofstream file(filename_);
if (!file.is_open()) return;
for (const auto& [key, value] : data_) {
file << serialize_entry(key, value) << "\n";
}
}
private:
string serialize_entry(const string& key, const Value& value) {
return std::visit([&key](const auto& val) -> string {
using T = std::decay_t<decltype(val)>;
if constexpr (std::is_same_v<T, int>) {
return "i:" + key + "=" + std::to_string(val);
} else if constexpr (std::is_same_v<T, double>) {
return "d:" + key + "=" + std::to_string(val);
} else if constexpr (std::is_same_v<T, string>) {
return "s:" + key + "=" + val;
} else if constexpr (std::is_same_v<T, bool>) {
return "b:" + key + "=" + (val ? "1" : "0");
}
}, value);
}
std::unordered_map<string, Value> data_;
mutable std::mutex mutex_;
string filename_ = "store.txt";
};