Skip to content

v0.0.2-alpha

Choose a tag to compare

@barddoo barddoo released this 08 Oct 14:26
· 84 commits to main since this release

Major Features

Append-Only File (AOF) Persistence

  • New Module: Added src/aof/aof.zig with AOF reader and writer functionality
  • AOF writer captures all write commands and persists them to disk
  • AOF reader replays commands on server startup for data recovery
  • Integrated with server initialization for automatic persistence
  • Added comprehensive AOF tests for read/write operations

Enhanced String Command Support

Added 10 new Redis-compatible string commands (increasing coverage from 23% to 36%):

  • APPEND - Concatenate value to existing key
  • STRLEN - Get length of value stored in key
  • GETSET - Atomically set key and return old value
  • MGET - Get values of multiple keys in single operation
  • MSET - Set multiple key-value pairs atomically
  • SETEX - Set key with expiration time
  • SETNX - Set key only if it doesn't exist
  • INCRBY - Increment key by specific integer amount
  • DECRBY - Decrement key by specific integer amount
  • INCRBYFLOAT - Increment key by floating point number (17 decimal precision, Redis-compatible)

Architecture Improvements

Decoupled Command Architecture

  • Decoupled commands from Client: Commands now only require their minimum dependencies (writer, store, args)
  • Commands can be invoked from non-client contexts (e.g., AOF replay)
  • Introduced three ClientHandler types: Default, Client, and Store
  • Commands no longer require network stream, only a generic writer

Centralized Error Handling

  • Moved error-to-RESP message mapping from individual commands to registry
  • Expanded CommandError with specific error types (WrongType, ValueNotInteger, InvalidFloat, etc.)
  • Added handleCommandError() function in registry for consistent error responses
  • Commands now return typed errors instead of writing RESP errors directly

Modular RESP Protocol Layer

  • Created dedicated src/commands/resp.zig module for RESP protocol writing
  • Decoupled RESP writing from client/network layer
  • Generic writer interface allows RESP output to any destination
  • Improved writeInt() to accept any integer type via compile-time generics

Parser Improvements

  • Decoupled parser from network streams - now only requires a generic reader
  • Parser can consume from any source (network, file, buffer)
  • Fixed memory leak in parser
  • More flexible command parsing for AOF and testing scenarios

Performance Optimizations

Short String Optimization (SSO)

  • Implemented inline storage for strings ≤23 bytes (no heap allocation)
  • Added ShortString type with efficient fromSlice() and asSlice() methods
  • Automatic type selection in Store.set() based on string length
  • Significant memory savings for small strings (keys, common values)

Safe Memory Pool

  • Added src/safe_memory_pool.zig for optimized allocations
  • Pre-allocated pools for common string lengths
  • Reduced allocation overhead for frequently-used sizes
  • Integrated with store operations for better memory management

Testing Improvements

Refactored Test Architecture

  • Removed MockClient dependency: Tests now call command functions directly
  • Implemented fixed buffer writer pattern (std.Io.Writer.fixed(&buffer))
  • More idiomatic Zig testing with stack-allocated buffers
  • Cleaner test implementation without heap allocations
  • Refactored all 31 string tests to use direct command calls
  • Refactored all 30 list tests to use direct command calls

Enhanced Test Coverage

  • Added comprehensive tests for 10 new string commands
  • Expanded edge case testing (error conditions, boundary cases)
  • Added AOF read/write tests
  • Improved test utilities in src/test_utils.zig

Bug Fixes

  • Fixed short_string handling in incrDecr() function - now properly parses integers from SSO strings
  • Fixed parser memory leak
  • Improved error handling for out-of-range operations
  • Better type checking in store operations

Code Quality

  • Simplified RESP command responses throughout codebase
  • More consistent error handling patterns
  • Reduced code duplication in command implementations
  • Better separation of concerns (commands, parsing, protocol, persistence)
  • Improved code documentation and inline comments

Refactoring

  • Consolidated command argument handling
  • Streamlined store interface
  • Reduced client.zig complexity (103 lines removed)
  • Reorganized command registry with better type safety
  • Cleaned up pubsub and RDB integration points

Statistics

  • Redis Command Coverage: 23% → 36% (string commands)

Breaking Changes

  • Command function signatures changed to require writer and store instead of Client
  • Error handling now returns typed errors instead of writing RESP directly
  • Test utilities restructured (MockClient usage patterns changed)

Deprecations

  • Removed benchmark results until async I/O work is complete