ShardCache is a high-performance, ultra-low-latency in-memory key-value store built from scratch in C++. Designed for systems-programming tracking, it bypasses high-level abstractions to interact cleanly with Linux system resources.
The architecture utilizes an asynchronous, event-driven networking layer paired with a custom cache-friendly data structure and sharded concurrency mechanics to maximize throughput and minimize P99 latency spikes.
- Asynchronous I/O Multiplexing: Built on Linux native
epollusing Edge-Triggered (EPOLLET) mode and non-blocking sockets to manage thousands of concurrent client connections within a single network thread. - Cache-Friendly Storage: Replaces standard node-based structures (pointer chasing) with a custom Open Addressing Hash Map using Linear Probing allocated inside a contiguous memory array to eliminate CPU cache misses.
- Low-Contention Concurrency: Implements a multi-threaded Lock Sharding architecture dividing the keyspace into 16 distinct sectors, reducing thread lock contention by ~93%.
- Pre-Warmed Thread Pool: Utilizes a fixed task queue and worker thread pool to completely eliminate thread-creation overhead on the request path.
- High-Speed Hashing: Employs the bitwise FNV-1a algorithm for rapid, deterministic key distribution.
├── hash_map.hpp # Custom open-addressing linear probing hash map
├── server_concurrent.cpp # Integrated epoll loop, thread pool, and sharded logic
└── README.md # Project documentation and usage guide
HOW TO RUN THIS PROJECT?
1. make sure you are on wsl or linux system
2. mount to directory where you cloned this project.
3. g++ -O3 -std=c++17 server_concurrent.cpp -o concurrent_server -lpthread
4. ./server_concurrent
5. open another window, say window B (just for naming) on ubuntu itself and run this command: nc localhost 8080
6. On window B, you can run these following commands to access the hash map functions:
SET smit 100
GET smit
DEL smit
Performance Considerations:
No Dynamic Allocation on Hot Path: The underlying hash table vector is pre-allocated at startup. This prevents memory fragmentation and avoids systemic allocator latency drops during execution.
Tombstone Deletions: Deleted slots are marked with a DELETED state rather than being cleared entirely. This preserves the probing continuity for keys that encountered collisions during insertion, maintaining absolute lookup correctness.