Netabase Store
A type-safe, multi-backend key-value storage library for Rust with support for native (Sled, Redb) and WASM (IndexedDB) environments.
This crate is still in early development and will change frequently as it stabalises. It is not advised to use this in a production environment until it stabalises.
Features
Current Features
-
Multi-Backend Support:
- Sled: High-performance embedded database for native platforms
- Redb: Memory-efficient embedded database with ACID guarantees
- IndexedDB: Browser-based storage for WASM applications
-
Type-Safe Schema Definition:
- Derive macros for automatic schema generation
- Primary and secondary key support
- Compile-time type checking for all database operations
-
Cross-Platform:
- Unified API across native and WASM targets
- Feature flags for platform-specific backends
-
Zero-Copy Deserialization: Efficient data access with minimal overhead
-
Secondary Key Indexing: Fast lookups using secondary keys
-
Iterators: Efficient iteration over stored data
-
Benchmarking: Comprehensive benchmarks for performance analysis
-
libp2p Integration: Optional record store for distributed systems (via
record-storefeature)
TODO for 1.0.0
-
Default Profiles/Modes:
- Simple mode: Pre-configured for common use cases with sensible defaults
- Performance mode: Optimized for high-throughput applications
- Compact mode: Optimized for minimal storage footprint
-
Migration Tools:
- Schema migration utilities
- Data import/export functionality
- Backend conversion tools
-
Query Builder:
- Fluent API for complex queries
- Compound secondary key queries
- Range queries on ordered keys
-
Transaction Support:
- Multi-operation ACID transactions
- Batch operations for improved performance
-
Async API:
- Fully async/await compatible operations
- Non-blocking I/O for all backends
-
Compression:
- Optional transparent compression
- Configurable compression algorithms
-
Encryption:
- At-rest encryption support
- Transparent encryption/decryption
Installation
Add to your Cargo.toml:
[]
= "0.0.1"
= "0.0.1"
# Required dependencies for macros to work
= { = "2.0", = ["serde"] }
= { = "1.0", = ["derive"] }
= { = "0.27.2", = ["derive"] }
= { = "2.0.1", = ["from", "try_into", "into"] }
= "1.0" # For error handling
# For WASM
# netabase_store = { version = "0.0.1", features = ["wasm"] }
# netabase_deps = "0.0.1"
Why so many dependencies? The procedural macros generate code that uses these crates. Due to Rust's macro hygiene rules, they must be available in your dependency list.
Quick Start
Define Your Schema
use netabase_definition_module;
use NetabaseModelTrait;
use *;
Use with Sled (Native)
use SledStore;
Use with Redb (Native)
use RedbStore;
Use with IndexedDB (WASM)
use IndexedDbStore;
async
Advanced Usage
Secondary Keys
Secondary keys enable efficient lookups on non-primary fields:
// Define a model with secondary keys
// Query by secondary key
let published_articles = article_tree
.get_by_secondary_key?;
let tech_articles = article_tree
.get_by_secondary_key?;
Multiple Models in One Store
let store = new?;
// Different trees for different models
let user_tree = store.;
let post_tree = store.;
// Each tree is independent but shares the same underlying database
user_tree.put?;
post_tree.put?;
Benchmarks
Run benchmarks to compare backend performance:
# Sled benchmarks
# Redb benchmarks
Benchmark categories:
- Insert performance
- Get performance
- Iteration performance
- Secondary key lookup performance
Architecture
Backend Abstraction
Each backend implements a common set of operations:
put(model): Insert or update a modelget(primary_key): Retrieve a model by primary keyremove(primary_key): Delete a modeliter(): Iterate over all modelsget_by_secondary_key(key): Query by secondary keylen(): Get count of stored modelsis_empty(): Check if store is emptyclear(): Remove all models
Type Safety
The library uses Rust's type system to ensure:
- Keys match their models
- Secondary keys exist for the model
- Backend stores only hold their defined models
- Compile-time verification of all operations
Feature Flags
native(default): Enable sled and redb backendswasm: Enable IndexedDB backendlibp2p: Enable libp2p integrationrecord-store: Enable record store for distributed systems (requireslibp2p)
Examples
See the examples/ directory for complete examples:
basic_store.rs: Basic CRUD operations- More examples coming in 1.0.0
Testing
# Run all tests
# Run native tests only
# Run WASM tests (requires wasm-pack)
Performance
Netabase Store is designed for high performance:
- Minimal overhead over raw backend operations (typically <5%)
- Zero-copy deserialization where possible
- Efficient secondary key indexing
- Batch operation support (coming in 1.0.0)
Performance Considerations
Abstraction Overhead: While netabase_store provides a powerful type-safe abstraction layer over multiple database backends, this abstraction does come with some overhead. The cost primarily comes from:
- Type conversions between models and the underlying storage format
- The
RecordStoretrait implementation which adds indirection - Automatic secondary key indexing which requires additional storage operations
For most applications, this overhead is minimal (typically <5-10%) and well worth the benefits of type safety, portability, and developer ergonomics. However, for extremely performance-critical applications that need to squeeze out every last bit of performance, direct use of the underlying backends (Sled, Redb) without the abstraction layer may be preferred.
Future Optimizations: We plan to reduce this overhead in future releases through:
- Direct backend integration for Redb: Currently in research phase. The challenge is maintaining the
RecordStoretrait abstraction while allowing for more direct access patterns. - Compile-time optimization: Leveraging Rust's zero-cost abstractions more aggressively
- Lazy secondary key updates: Optional deferred indexing for write-heavy workloads
- Custom serialization strategies: Per-backend optimized serialization paths
Distributed Systems Support
P2P Networking Plans: We are actively developing enhanced support for decentralized peer-to-peer applications:
- Configurable profiles and modes: Simple presets for different use cases (local-only, DHT-backed, full replication, etc.)
- Network protocols abstraction: Making it easier to use netabase_store over libp2p, WebRTC, or other transport layers
- Distributed RecordStore: Currently in development - will provide automatic record distribution and discovery across peers
- Conflict resolution strategies: Pluggable CRDT and last-write-wins implementations for eventual consistency
The vision is to make it trivial to build distributed applications where your local database automatically synchronizes with peers without complex manual synchronization logic.
License
This project is licensed under the GNU Apache License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines (coming in 1.0.0).