Skip to content

Latest commit

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Build Your Own Redis (Java)

A lightweight, concurrent Redis server implementation written in pure Java (JDK 17+) adhering strictly to the Redis Serialization Protocol (RESP) specification and CodeCrafters challenge requirements.


🚀 Features & Stages Implemented

  • Pure Java Standard Library: Zero external third-party dependencies (java.net, java.io, java.util.concurrent).
  • Stage 1 & 2 (Server Initialization & PING):
    • Binds to port 6379 with setReuseAddress(true).
    • Responds to PING with simple string +PONG\r\n or custom arguments as bulk strings.
  • Stage 3 & 4 (Concurrent Clients & ECHO):
    • Multi-threaded client handling using virtual threads (Executors.newVirtualThreadPerTaskExecutor()) with fallback to cached thread pool.
    • Implements ECHO <message> command returning Bulk String format ($<length>\r\n<arg>\r\n).
  • Stage 5 (SET & GET Commands):
    • Thread-safe storage with ConcurrentHashMap<String, ValueEntry>.
    • Implements SET <key> <value> replying with +OK\r\n.
    • Implements GET <key> replying with Bulk String or Null Bulk String ($-1\r\n) if key is absent.
  • Stage 6 (Key Expiry with PX):
    • Supports SET <key> <value> [PX <expiry_in_millis>] and [EX <expiry_in_seconds>].
    • Passive eviction: On GET, evaluates if TTL has expired and evicts atomically.
    • Active eviction: Background daemon executor periodically cleans expired keys.
  • Robust RESP Protocol Engine:
    • Handles streaming TCP input, fragmented packets, and pipelining.
    • Supports RESP Arrays (*), Bulk Strings ($), Simple Strings (+), Integers (:), and Errors (-).
    • Supports raw inline command input from telnet / netcat.

📁 Project Structure

redis-java-clone/
├── src/
│ ├── main/
│ │ └── java/
│ │ ├── Main.java # CodeCrafters entry point
│ │ └── com/codecrafters/redis/
│ │ ├── Server.java # TCP Server & connection accept loop
│ │ ├── ClientHandler.java # Per-connection read/eval/write loop
│ │ ├── protocol/
│ │ │ ├── RespType.java # RESP type definitions
│ │ │ ├── RespValue.java # Immutable RESP value model & encoder
│ │ │ ├── RespReader.java # Streaming RESP parser
│ │ │ └── RespWriter.java # Low-overhead RESP output writer
│ │ ├── storage/
│ │ │ ├── ValueEntry.java # Key value + TTL metadata
│ │ │ └── RedisStore.java # Thread-safe in-memory store
│ │ └── command/
│ │ ├── Command.java # Parsed command representation
│ │ └── CommandHandler.java # Command dispatcher & executor
│ └── test/
│ └── java/
│ └── com/codecrafters/redis/
│ └── RedisServerTest.java # Comprehensive test suite (37+ tests)
├── spawn_redis_server.sh # CodeCrafters runner script
└── pom.xml # Standard Maven POM

🛠️ Building and Running

Using the CodeCrafters runner script:

./spawn_redis_server.sh [--port <port>]

Running the built-in test suite:

mkdir -p /tmp/test-classes
javac -d /tmp/test-classes $(find src -name "*.java")
java -cp /tmp/test-classes com.codecrafters.redis.RedisServerTest

Connecting with redis-cli:

redis-cli -p 6379 PING
redis-cli -p 6379 ECHO "Hello World"
redis-cli -p 6379 SET mykey myvalue PX 5000
redis-cli -p 6379 GET mykey

About

Concurrent Redis server clone built from scratch in pure Java (JDK 17+) implementing the Redis Serialization Protocol (RESP).

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages