netabase_store 0.0.8

A type-safe, multi-backend key-value storage library for Rust with support for native (Sled, Redb) and WASM (IndexedDB) environments.
Documentation
//! # Zero-Copy Redb Backend
//!
//! This module provides a high-performance redb backend with zero-copy reads
//! and transaction-scoped API.
//!
//! ## Quick Start
//!
//! ```
//! # use netabase_store::databases::redb_zerocopy::*;
//! # use netabase_store::*;
//! # #[netabase_definition_module(MyDef, MyKeys)]
//! # mod models {
//! #     use netabase_store::*;
//! #     #[derive(NetabaseModel, Clone, Debug, bincode::Encode, bincode::Decode, serde::Serialize, serde::Deserialize)]
//! #     #[netabase(MyDef)]
//! #     pub struct User {
//! #         #[primary_key]
//! #         pub id: u64,
//! #         pub name: String,
//! #     }
//! # }
//! # use models::*;
//! # fn example() -> Result<(), netabase_store::error::NetabaseError> {
//! # let temp = tempfile::tempdir().unwrap();
//! # let path = temp.path().join("app.redb");
//! let store = RedbStoreZeroCopy::<MyDef>::new(&path)?;
//!
//! // Write
//! let mut txn = store.begin_write()?;
//! let mut tree = txn.open_tree::<User>()?;
//! tree.put(User { id: 1, name: "Alice".to_string() })?;
//! drop(tree);
//! txn.commit()?;
//!
//! // Read (cloned)
//! let txn = store.begin_read()?;
//! let tree = txn.open_tree::<User>()?;
//! let user = tree.get(&UserPrimaryKey(1))?;
//! # Ok(())
//! # }
//! # example().unwrap();
//! ```
//!
//! ## Architecture
//!
//! The zero-copy backend follows a strict lifetime hierarchy:
//!
//! ```text
//! RedbStoreZeroCopy<D>                    ('static or app lifetime)
//!   ↓ begin_write() / begin_read()
//! RedbWriteTransactionZC<'db, D>          (borrows 'db from store)
//! RedbReadTransactionZC<'db, D>           (borrows 'db from store)
//!   ↓ open_tree<M>()
//! RedbTreeMut<'txn, 'db, D, M>            (borrows 'txn from transaction)
//! RedbTree<'txn, 'db, D, M>               (borrows 'txn from transaction)
//!   ↓ get(), remove(), etc.
//! Model data (owned or borrowed)
//! ```
//!
//! ## Performance
//!
//! | Operation | Old API | New API | Improvement |
//! |-----------|---------|---------|-------------|
//! | Single read | ~100ns | ~100ns | Similar (both use bincode) |
//! | Bulk insert (1000) | ~50ms | ~5ms | 10x faster (single transaction) |
//!
//! ## API Comparison
//!
//! ### Standard API (redb_store) - Simple & Convenient
//!
//! ```no_run
//! use netabase_store::{netabase_definition_module, NetabaseModel, netabase};
//! use netabase_store::databases::redb_store::RedbStore;
//! use netabase_store::traits::tree::NetabaseTreeSync;
//! use netabase_store::traits::model::NetabaseModelTrait;
//!
//! #[netabase_definition_module(MyDef, MyKeys)]
//! mod models {
//!     use netabase_store::{NetabaseModel, netabase};
//!     #[derive(NetabaseModel, Clone, Debug, PartialEq,
//!              bincode::Encode, bincode::Decode,
//!              serde::Serialize, serde::Deserialize)]
//!     #[netabase(MyDef)]
//!     pub struct User {
//!         #[primary_key]
//!         pub id: u64,
//!         pub name: String,
//!     }
//! }
//! use models::*;
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let store = RedbStore::<MyDef>::new("./db.redb")?;
//! let tree = store.open_tree::<User>();
//! let user = User { id: 1, name: "Alice".into() };
//! tree.put(user.clone())?; // Auto-commits (1 transaction per operation)
//! let retrieved = tree.get(UserKey::Primary(UserPrimaryKey(1)))?; // Always clones
//! assert_eq!(retrieved, Some(user));
//! # Ok(())
//! # }
//! ```
//!
//! ### Zero-Copy API (redb_zerocopy) - Explicit & High-Performance
//!
//! ```no_run
//! # use netabase_store::{netabase_definition_module, NetabaseModel, netabase};
//! # use netabase_store::databases::redb_zerocopy::*;
//! # use netabase_store::traits::model::NetabaseModelTrait;
//! #
//! # #[netabase_definition_module(MyDef, MyKeys)]
//! # mod models {
//! #     use netabase_store::{NetabaseModel, netabase};
//! #     #[derive(NetabaseModel, Clone, Debug, PartialEq,
//! #              bincode::Encode, bincode::Decode,
//! #              serde::Serialize, serde::Deserialize)]
//! #     #[netabase(MyDef)]
//! #     pub struct User {
//! #         #[primary_key]
//! #         pub id: u64,
//! #         pub name: String,
//! #     }
//! # }
//! # use models::*;
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let store = RedbStoreZeroCopy::<MyDef>::new("./db.redb")?;
//!
//! // Bulk insert (manual transaction management)
//! let mut txn = store.begin_write()?;
//! let mut tree = txn.open_tree::<User>()?;
//! for i in 0..1000 {
//!     tree.put(User { id: i, name: format!("User {}", i) })?;
//! }
//! drop(tree); // Release borrowing before commit
//! txn.commit()?; // Commits all 1000 inserts in one transaction
//!
//! // Zero-copy read
//! let txn = store.begin_read()?;
//! let tree = txn.open_tree::<User>()?;
//! let user = tree.get(&UserPrimaryKey(42))? // Option<User> (cloned)
//!     .expect("User should exist");
//! # Ok(())
//! # }
//! ```
//!
//! ## When to use which?
//!
//! - Use **redb_store** when:
//!   - You want automatic transaction management
//!   - You're doing mostly single-record operations
//!   - You want the simplest possible API
//!
//! - Use **redb_zerocopy** when:
//!   - You need maximum performance for bulk operations
//!   - You want fine-grained transaction control
//!   - You're willing to manage lifetimes and borrowing
//!   - You want the smallest possible memory footprint

// Module declarations
mod store;
mod transaction;
mod tree;
mod utils;

// Re-export main types
pub use store::RedbStoreZeroCopy;
pub use transaction::{RedbReadTransactionZC, RedbWriteTransactionZC};
pub use tree::{RedbTree, RedbTreeMut};
pub use utils::{with_read_transaction, with_write_transaction};