feat: switch to hashmap

This commit is contained in:
Xory 2026-04-10 14:28:55 +03:00
parent b4c7068c30
commit b2f7ee3a9d
3 changed files with 23 additions and 41 deletions

1
.gitignore vendored
View file

@ -2,3 +2,4 @@ a.out
flake.lock flake.lock
db.json db.json
/.ccls-cache /.ccls-cache
compile_commands.json

View file

@ -17,7 +17,7 @@
#include <thread> #include <thread>
#include <boost/asio.hpp> #include <boost/asio.hpp>
using Db = std::vector<std::vector<std::string>>; using Db = std::unordered_map<std::string, std::string>;
Db database; Db database;
void save_database(std::string file_name) { void save_database(std::string file_name) {
@ -73,7 +73,7 @@ using asio::use_awaitable;
boost::asio::io_context io_context; boost::asio::io_context io_context;
asio::awaitable<void> handle_client(tcp::socket client_socket) { asio::awaitable<void> handle_client(tcp::socket client_socket) {
char buffer[4096]; char buffer[4096]; // this looks like a buffer overflow waiting to happen ngl :P
try { try {
while (true) { while (true) {
@ -83,45 +83,24 @@ asio::awaitable<void> handle_client(tcp::socket client_socket) {
std::vector<std::string> parsed = parse_resp_request(buffer); std::vector<std::string> parsed = parse_resp_request(buffer);
if (parsed[0] == "GET") { if (parsed[0] == "GET") {
bool found = false; auto it = database.find(parsed[1]);
if (it != database.end()) {
for (const auto& inner_vec: database) { // Iterate through DB and find the required item std::string found_object = it->second;
if (!inner_vec.empty() && inner_vec[0] == parsed[1]) { std::string return_string = std::format("${}\r\n{}\r\n", found_object.length(), found_object); // Serialise to RESP
int length = inner_vec[1].length(); co_await asio::async_write(client_socket, asio::buffer(return_string.data(), return_string.length()), use_awaitable);
std::string return_string = std::format("${}\r\n{}\r\n", length, inner_vec[1]); // Serialise to RESP
std::cout << "[d] Sending: " << return_string << std::endl;
co_await asio::async_write(client_socket, asio::buffer(return_string.data(), return_string.length()), use_awaitable);
found = true;
}
}
if (!found) {
co_await asio::async_write(client_socket, asio::buffer("$-1\r\n", strlen("$-1\r\n")), use_awaitable); // Not found
}
} else if (parsed[0] == "SET") {
bool found = false; // Avoids SEGFAULT
for (auto& inner_vec: database) {
if (!inner_vec.empty() && inner_vec[0] == parsed[1]) {
inner_vec[1] = parsed[2];
co_await asio::async_write(client_socket, asio::buffer("+OK\r\n", strlen("+OK\r\n")), use_awaitable);
found = true;
}
if (!found) {
std::vector<std::string> new_kv = { parsed[1], parsed[2] };
database.push_back(new_kv);
co_await asio::async_write(client_socket, asio::buffer("+OK\r\n", strlen("+OK\r\n")), use_awaitable);
found = true;
}
}
} else { } else {
co_await asio::async_write(client_socket, asio::buffer("+OK\r\n", strlen("+OK\r\n")), use_awaitable); // Temporary catch-all (for more advanced handshake) co_await asio::async_write(client_socket, asio::buffer("$-1\r\n", strlen("$-1\r\n")), use_awaitable); // Not found
} }
} else if (parsed[0] == "SET") {
database.insert_or_assign(parsed[1], parsed[2]); // it's as shrimple as that
co_await asio::async_write(client_socket, asio::buffer("+OK\r\n", strlen("+OK\r\n")), use_awaitable);
} else {
co_await asio::async_write(client_socket, asio::buffer("+OK\r\n", strlen("+OK\r\n")), use_awaitable); // "Temporary" catch-all (for more advanced handshake)
} }
} catch (const std::exception& e) {
std::cout << "[i] Client session ened/error" << e.what() << std::endl;
} }
} catch (const std::exception& e) {
std::cout << "[i] Client session end/error: " << e.what() << std::endl;
}
} }
@ -143,6 +122,7 @@ asio::awaitable<void> shutdown_handler(asio::io_context& io_context, tcp::accept
asio::signal_set signals(io_context, SIGINT, SIGTERM); asio::signal_set signals(io_context, SIGINT, SIGTERM);
co_await signals.async_wait(use_awaitable); co_await signals.async_wait(use_awaitable);
std::cout << "[i] Stopping blueis server..." << std::endl; std::cout << "[i] Stopping blueis server..." << std::endl;
save_database("db.json");
acceptor.cancel(); acceptor.cancel();
acceptor.close(); acceptor.close();
@ -170,7 +150,7 @@ int main() {
); );
for (int i = 0; i < N_THREADS - 1; i++) { for (int i = 0; i < N_THREADS - 1; i++) {
threads.emplace_back([&io_context] { threads.emplace_back([] {
io_context.run(); io_context.run();
}); });
} }

View file

@ -1,8 +1,9 @@
{ pkgs ? import <nixpkgs> }: { pkgs ? import <nixpkgs> {} }:
with pkgs; pkgs.mkShell {
mkShell {
buildInputs = with pkgs; [ buildInputs = with pkgs; [
gcc gcc
ccls ccls
bear
boost
]; ];
} }