How ad4rsh2701/riri works
1. Overall shape
- RiRi is a C++23 in-process, static key-value library, not a server or distributed system.
- The architecture is split into a public API layer, a core storage engine, command wrappers, a persistence subsystem, and a small CLI entrypoint used for local interaction/testing.
2. Public API boundary
- The exported surface lives under include/riri and is aggregated by include/riri.hpp.
- This is the boundary consumers link against: Commands, Parser, Persistence, RapidResponse, RapidTypes, and utils.
- The design suggests a deliberate separation between stable user-facing headers and implementation details in src/.
3. Data model
- The core payload type is RapidDataType, a variant-like type supporting string, integer, double, and bool.
- RapidNode pairs a string key with a typed value, and most API calls accept either a single node/key-value or a span/array of nodes for bulk operations.
- This model drives the response and validation system, so typed values are preserved end-to-end rather than normalized into strings.
4. Command layer
- Commands.hpp is the main user-level API, exposing CRUD-style operations such as SET, GET, DELETE, UPDATE, and CLEAR.
- The implementation is split in src/commands/*.cpp, which likely act as thin orchestration wrappers over the core store.
- The commands support both single-item “lazy” calls and batched bulk calls, which is a key architectural feature of the library.
5. Core storage engine
- The actual in-memory store appears to be centered on src/core/DataManager.cpp and src/core/MemoryMaps.cpp.
- MemoryMaps likely owns the key-value containers, while DataManager coordinates mutations, reads, and store-level invariants.
- The presence of ankerl::unordered_dense in src/include/ankerl/ indicates the project uses a high-performance hash map implementation for the main store, consistent with the performance focus.
6. Validation and response flow
- A significant part of the architecture is the response system in RapidResponse and the status_to_string helper.
- Commands do not just return raw values; they return structured responses with per-operation status codes, especially for batched requests.
- This means the data flow is: input nodes/keys → validation → store operation → typed response/status aggregation.
7. Batched operations
- Bulk calls are a distinct path in the design, not just repeated single calls.
- The README and tests show two batched styles: one that returns a capped error batch and one that returns an uncapped mixed result set.
- This implies the architecture has an internal distinction between single-status responses and collection responses with partial success handling.
8. Persistence subsystem
- Persistence is already represented structurally, even though the README marks it as future roadmap.
- src/core/persistence/{Persistence,Loader,Dumper}.cpp suggests a classic split: serialize store state, deserialize/recover state, and a top-level coordinator.
- The public headers under include/riri/Persistence.hpp indicate persistence is intended to be part of the library boundary, even if not yet the primary focus.
9. CLI boundary
- src/cli/Main.cpp and src/cli/Parser.cpp form a separate executable-facing layer.
- This is likely a thin adapter that translates command-line input into the same command/data-manager flow used by the library API.
- The CLI is therefore a consumer of the core library, not a parallel implementation.
10. Utility and support code
- src/utils/RapidLogger.h and helpers under src/utils/helpers provide cross-cutting support, probably for diagnostics and status formatting.
- The include/riri/utils and include/riri/utils/Accessors.hpp headers show some utility functions are part of the public API rather than internal-only helpers.
- RiRiMacros.h suggests compile-time configuration or export/annotation macros are centralized in the internal headers.
11. Testing architecture
- Tests are organized by feature area: commands, response/status behavior, core behavior, and utils.
- This mirrors the runtime architecture and is a useful signal for drawing the diagram: the project is validated at the command boundary and at the response semantics boundary, not just at low-level storage functions.
- The presence of doctest.h indicates a lightweight embedded test framework.
12. Build, packaging, and dependency boundaries
- The project is built with CMake and targets Clang++ / C++23.
- It is consumed as a library via FetchContent, so the repo is structured as a distributable dependency rather than an application.
- External third-party code is minimal and vendored: ankerl::unordered_dense for the hash map and doctest for tests.
13. Practical architecture summary
- The main runtime path is: public API / CLI input → command layer → data manager / memory map → response/status generation.
- Optional persistence sits alongside the core store and can serialize or restore state.
- The important diagram boundary is between the stable header-only interface and the compiled implementation in src/, with commands acting as the main orchestration layer over the in-memory store.
Main entry points: riri.hpp riri.hpp · DataManager.cpp DataManager · set.cpp Command impls · MemoryMaps.cpp MemoryMaps
Components 20
Public API
Stable headers consumed by library users
- riri.hpp · Top-level public include that aggregates the API surface
include/riri.hpp - Commands · User-facing CRUD and batch command interface
include/riri/Commands.hpp - Parser · Public parsing boundary for command/input handling
include/riri/Parser.hpp - Persistence · Public persistence boundary for save/restore operations
include/riri/Persistence.hpp - RapidResponse · Structured statuses and result aggregation returned by commands
include/riri/RapidResponse.hpp - RapidTypes · Typed key-value model including nodes and variant-like values
include/riri/RapidTypes.hpp - utils · Public utility helpers and accessors
include/riri/utils.hpp - Accessors · Public accessor utilities for the data model
include/riri/utils/Accessors.hpp
Core Engine
In-memory storage and persistence internals
- DataManager · Coordinates reads, writes, validation, and invariants
src/core/DataManager.cpp - MemoryMaps · Owns the underlying key-value containers
src/core/MemoryMaps.cpp - Command impls · Thin command wrappers for set, get, delete, update, and clear
src/commands/set.cpp - Persistence core · Top-level persistence orchestration
src/core/persistence/Persistence.cpp - Loader · Deserializes and restores stored state
src/core/persistence/Loader.cpp - Dumper · Serializes store state for persistence
src/core/persistence/Dumper.cpp
CLI
Command-line entrypoint and parsing
- Main · CLI entrypoint for local interaction and testing
src/cli/Main.cpp - CLI parser · Translates command-line input into library calls
src/cli/Parser.cpp
Support
Cross-cutting utilities and helpers
- RapidLogger · Diagnostic logging support used across the implementation
src/utils/RapidLogger.h - status text · Converts status codes into readable strings
src/utils/helpers/status_to_string.hpp
Third Party
Vendored external dependencies
- unordered_dense · Vendored high-performance hash map dependency
src/include/ankerl/unordered_dense.h - doctest · Embedded unit test framework
tests/doctest.h
Connections 26
- riri.hpp → Commands: aggregates · Umbrella header exposes the command API
- riri.hpp → Parser: aggregates · Umbrella header exposes parsing boundary
- riri.hpp → Persistence: aggregates · Umbrella header exposes persistence API
- riri.hpp → RapidResponse: aggregates · Umbrella header exposes responses
- riri.hpp → RapidTypes: aggregates · Umbrella header exposes typed data model
- riri.hpp → utils: aggregates · Umbrella header exposes utilities
- utils → Accessors: includes · Utility facade includes accessor helpers
- Commands → RapidTypes: uses · Commands operate on typed nodes and values
- Commands → RapidResponse: returns · Commands return structured statuses and results
- Parser → RapidTypes: parses · Parser converts input into typed nodes
- Command impls → DataManager: orchestrates · Command wrappers delegate core mutations and reads
- Command impls → RapidResponse: builds · Command layer assembles operation responses
- DataManager → MemoryMaps: stores in · Data manager coordinates the underlying in-memory maps
- DataManager → status text: formats · Uses status helpers for readable results
- MemoryMaps → unordered_dense: backed by · Main storage uses vendored dense hash maps
- Persistence core → Loader: loads via · Persistence coordinator restores state through loader
- Persistence core → Dumper: saves via · Persistence coordinator snapshots state through dumper
- Loader → MemoryMaps: restores · Loader repopulates the in-memory store
- Dumper → MemoryMaps: reads · Dumper serializes current store state
- Main → CLI parser: uses · CLI entrypoint consumes parsed input
- CLI parser → Command impls: invokes · CLI adapter routes requests into command execution
- RapidLogger → DataManager: supports · Logging aids core execution and diagnostics
- RapidLogger → Command impls: supports · Logging aids command orchestration
- doctest → Command impls: tests · Unit tests validate command behavior
- doctest → DataManager: tests · Unit tests validate core store behavior
- doctest → status text: tests · Unit tests validate response/status helpers