Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Multithreaded Key-Value Store

Built this as a learning project to understand how a basic key-value store works under the hood. It's an in-memory hashmap with an LRU cache for faster repeated reads and an append-only log file for persistence across restarts.

What it does

  • Store and retrieve key-value pairs (strings only for now)
  • LRU cache so repeated reads are fast
  • Persists to an append-only log file, recovers on restart
  • Thread safe with a mutex
  • Optional TCP server mode (simple line protocol)

Files

src/
  kv_store.h/cpp  - main store implementation
  lru_cache.h     - cache using list + hashmap trick
  main.cpp        - demo showing basic usage
  tcp_server.h/cpp - minimal TCP server wrapper

tests/
  basic_tests.cpp - unit tests
  stress_test.cpp - hammers it with threads to find bugs

benchmark/
  benchmark.cpp   - measures how fast operations are

How to build

Need g++ with C++11+ (and threading support). I used MinGW-w64 on Windows.

cd "c:\Users\Bhawya Rawal\Documents\Multithreaded Key-Value Store"

# Build main executable
C:\mingw64\bin\g++.exe -std=c++11 -g -o build\kvstore.exe src\main.cpp src\kv_store.cpp src\tcp_server.cpp -lws2_32 -pthread

# Build tests
C:\mingw64\bin\g++.exe -std=c++11 -g -o build\tests.exe tests\basic_tests.cpp src\kv_store.cpp -lws2_32 -pthread

# Build stress test
C:\mingw64\bin\g++.exe -std=c++11 -g -o build\stress.exe tests\stress_test.cpp src\kv_store.cpp -lws2_32 -pthread

# Build benchmark
C:\mingw64\bin\g++.exe -std=c++11 -g -O2 -o build\benchmark.exe benchmark\benchmark.cpp src\kv_store.cpp -lws2_32 -pthread

On Linux/macOS, drop -lws2_32.

How to run

# Run demo
.\build\kvstore.exe

# Run as TCP server (on port 8080)
.\build\kvstore.exe --server 8080

# Run tests
.\build\tests.exe

# Run stress test
.\build\stress.exe

# Run benchmark
.\build\benchmark.exe

Quick example

KVStore store(100, "mydata.log");

store.put("user:1", "john");

bool found;
string name = store.get("user:1", found);
if (found) {
    cout << name << endl;  // prints "john"
}

store.remove("user:1");

TCP server

Start a server on port 8080:

./kvstore.exe --server 8080 data.log

Connect with telnet or any TCP client:

telnet 127.0.0.1 8080

Commands (one per line):

PUT name Bhawya
GET name
DEL name
SIZE
QUIT

Design notes

Why hashmap? O(1) lookups. Could use a tree for sorted keys but didn't need that here.

Why LRU cache? If you keep reading the same keys, they stay in cache and you skip the hashmap lookup entirely. Used the splice trick with std::list to make it O(1).

Why append-only log? Simple crash recovery: append PUT: / DEL: lines, replay on startup.

Thread safety? Uses a single mutex to make operations thread-safe.

Known limitations

  • TCP server is minimal (no auth, no persistence protocol versioning)
  • Values are strings only

Tests

./tests.exe    - 7 tests covering basic ops + concurrency
./stress.exe   - throws 16 threads at it, checks for data corruption

All passing as of last run.

Built a key-value store in C++ with LRU caching and file-based persistence. Used hash maps for O(1) operations. Implemented crash recovery by replaying an append-only log on startup. Added a TCP server for remote client access over a simple line protocol. Wrote unit tests and benchmarks to validate correctness and measure performance.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages