RKVS - Rust Key-Value Storage
A high-performance, namespace-based key-value storage system built in Rust. RKVS provides persistent storage with configurable limits, async operations, and atomic batch processing.
Features
- 🚀 High Performance: Optimized for speed with async operations and efficient data structures
- 📁 Namespace Support: Organize data into isolated namespaces with individual configurations
- ⚡ Atomic Operations: Batch operations with all-or-nothing semantics
- 💾 Persistence: Optional file-based persistence with automatic serialization
- 🔒 Thread-Safe: Built on Tokio's async primitives for concurrent access
- 📊 Rich Metadata: Track key counts, sizes, and namespace statistics
- 🎯 Configurable Limits: Set per-namespace limits for keys and value sizes
- 🔄 Atomic Consume: Get and delete operations in a single atomic step
Quick Start
Add RKVS to your Cargo.toml:
[]
= "0.2.0"
= { = "1.0", = ["full"] }
Basic Usage
use ;
async
Batch Operations
RKVS supports efficient batch operations for processing multiple key-value pairs:
use ;
async
Configuration
Configure storage and namespace limits:
use ;
// Global storage configuration
let storage_config = StorageConfig ;
// Per-namespace configuration
let namespace_config = NamespaceConfig ;
let storage = builder
.with_config
.with_persistence
.build;
Performance
RKVS is designed for high performance with the following characteristics:
- Get: ~134ns
- Set: ~482ns
- Delete - ~160ns
- Exists - ~122ns
- consume - ~160ns
- Batch Operations: Tests show 30% more efficient Get and negligible Set
- Concurrent Access: Optimized for read-heavy workloads with RwLock-based synchronization
See the benchmark results for detailed performance metrics.
API Reference
Core Types
StorageManager: Main entry point for managing namespacesNamespace: Handle for working with a specific namespaceNamespaceConfig: Configuration for namespace limitsStorageConfig: Global storage configurationBatchResult<T>: Result of batch operations with metadata
Key Methods
StorageManager
create_namespace(name, config)- Create a new namespace, returns namespace namenamespace(name)- Get a namespace handle using namespace namedelete_namespace(name)- Remove a namespace using namespace namelist_namespaces()- List all namespace namessave()- Save all data to disk (if persistence enabled)initialize()- Initialize storage and load from disk (if persistence enabled)
Namespace
set(key, value)- Store a key-value pairget(key)- Retrieve a valuedelete(key)- Remove a keyexists(key)- Check if key existsconsume(key)- Atomically get and deleteset_multiple(items)- Batch set operationget_multiple(keys)- Batch get operationdelete_multiple(keys)- Batch delete operationconsume_multiple(keys)- Batch consume operation
Error Handling
RKVS uses a unified error type RkvsError with the following variants:
Storage: File I/O and storage-related errorsSerialization: Data serialization/deserialization errorsInternal: Internal system errors
use ;
async
Thread Safety
RKVS is fully thread-safe and designed for concurrent access:
- All operations are async and can be safely called from multiple tasks
- Read operations can run concurrently within a namespace
- Write operations are serialized per namespace
- Batch operations provide atomicity guarantees
Persistence
RKVS supports optional file-based persistence:
let storage = builder
.with_persistence
.build;
// Save all data to disk
storage.save.await?;
// Initialize storage (loads data from disk if persistence is enabled)
storage.initialize.await?;
Data is automatically serialized using bincode for efficient storage.
Migration Guide
Upgrading from v0.1.0 to v0.2.0
The main breaking change is the switch from hash-based namespace identifiers to string-based namespace IDs:
Before (v0.1.0):
let ns_hash = storage.create_namespace.await?;
let namespace = storage.namespace.await?; // ns_hash was [u8; 32]
After (v0.2.0):
storage.create_namespace.await?;
storage.namespace.await?; // namespace_id is String
Key Changes:
create_namespace()now returns Ok(()) or Err() instead of[u8; 32]namespace()method now takes&strinstead of[u8; 32]- All other methods (
delete_namespace,get_namespace_stats, etc.) now use&strfor namespace identification - No more manual hash conversion needed
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Changelog
v0.2.0 (Latest)
- Breaking Change: Updated API to use string-based namespace IDs instead of hash values
- Performance: Switched from
MutextoRwLockfor better concurrent read performance, removed pointless hashing and data duplication - API Improvements: Simplified namespace ID handling - no more manual hash conversion needed
- Documentation: Updated all examples and documentation to reflect new API
- Concurrency: Improved read performance with multiple concurrent readers support
v0.1.0
- Initial release
- Namespace-based storage
- Async operations
- Batch processing
- File persistence
- Comprehensive benchmarking