| Crates.io | append_kv |
| lib.rs | append_kv |
| version | 0.1.0 |
| created_at | 2026-01-02 07:53:41.010632+00 |
| updated_at | 2026-01-02 07:53:41.010632+00 |
| description | A simple, persistent append-only key-value store built in Rust. |
| homepage | https://github.com/MrGranday/append_kv |
| repository | https://github.com/MrGranday/append_kv |
| max_upload_size | |
| id | 2018132 |
| size | 19,238 |
A robust, single-node key-value store built in Rust. It utilizes an append-only log for data persistence and an in-memory hash map for fast retrieval. This project serves as an educational implementation of storage engine basics, demonstrating crash safety and file handling.
data/kv.log.HashMap index maps keys directly to their file offsets, ensuring O(1) lookup time (excluding disk I/O).To compile the project:
cargo build --release
Run the binary via cargo run (for development) or the built executable.
Stores a value associated with a key. If the key exists, it updates the index to point to the new entry (old entries remain in the log but are ignored).
cargo run -- set <KEY> <VALUE>
# Example
cargo run -- set user:101 "Alice Wonderland"
Retrieves the value for a given key.
cargo run -- get <KEY>
# Example
cargo run -- get user:101
# Output: Alice Wonderland
Removes a key from the store. This appends a "tombstone" record to the log, effectively hiding the key from future lookups.
cargo run -- rm <KEY>
# Example
cargo run -- rm user:101
src/main.rs: The entry point. It uses clap to parse command-line arguments and dispatches commands to the KvStore.src/store.rs: The core storage engine.
KvStore struct.data/kv.log).index.src/utils.rs: A module for utility functions and future extensions (currently a placeholder).data/kv.log)The storage file is a continuous sequence of binary records. Each record has the following format:
| Field | Type | Description |
|---|---|---|
| Key Length | u32 |
Length of the key in bytes (Little Endian). |
| Value Length | u32 |
Length of the value in bytes (Little Endian). |
| Key | [u8] |
The key data (UTF-8 string). |
| Value | [u8] |
The value data (UTF-8 string). |
set(key, value):
key_len, val_len) and then the bodies (key, value).index with the key and the start offset of this new record.get(key):
key in the in-memory index to find the file offset.load_index() (Startup):
index map.The project relies on a few key crates to ensure robustness and code clarity:
anyhow: Provides flexible and easy-to-use error handling. It allows us to attach context to errors (e.g., "Failed to open log file") for better debugging.clap: A powerful command-line argument parser. We use it with the derive feature to define our CLI structure (Set, Get) directly from Rust structs and enums.byteorder: Helpers for reading/writing primitive numbers (like u32) in a specific endianness (Little Endian), ensuring portability of the data file across different systems.