Expand description
§scoped-heed
A library providing Redis-like database isolation for LMDB via the heed wrapper.
§Scope Isolation Model
This library implements complete scope isolation similar to Redis databases:
- Each scope acts as an independent database within the same LMDB environment
- Operations are strictly confined to a single scope
- No cross-scope queries or operations are possible
- Keys can be identical across different scopes without collision
- Clearing a scope only affects that specific scope’s data
This design is perfect for:
- Multi-tenant applications requiring data isolation
- Test scenarios where each test needs its own database
- Modular systems with independent components
§Example
ⓘ
use scoped_heed::{scoped_database_options, ScopedDbError, Scope};
use heed::EnvOpenOptions;
// Open environment
let env = unsafe {
EnvOpenOptions::new()
.map_size(10 * 1024 * 1024)
.max_dbs(3)
.open("./my_db")?
};
// Create a scoped database
let mut wtxn = env.write_txn()?;
let db = scoped_database_options(&env)
.types::<String, String>()
.name("my_data")
.create(&mut wtxn)?;
wtxn.commit()?;
// Use different scopes for different tenants
let mut wtxn = env.write_txn()?;
let tenant1 = Scope::named("tenant1")?;
let tenant2 = Scope::named("tenant2")?;
db.put(&mut wtxn, &tenant1, &"key1".to_string(), &"value1".to_string())?;
db.put(&mut wtxn, &tenant2, &"key1".to_string(), &"value2".to_string())?;
wtxn.commit()?;
// Each scope is completely isolated
let rtxn = env.read_txn()?;
let val1 = db.get(&rtxn, &tenant1, &"key1".to_string())?; // Some("value1")
let val2 = db.get(&rtxn, &tenant2, &"key1".to_string())?; // Some("value2")
§Database Types
The library provides three database implementations optimized for different use cases:
-
Generic Database (
ScopedDatabase<K, V>
)- Supports any Serde-compatible types for keys and values
- Most flexible option
- Suitable for complex data structures
-
Bytes Key Database (
ScopedBytesKeyDatabase<V>
)- Uses raw byte slices for keys, serialized values
- Optimized for byte-based keys (hashes, IDs)
- ~38x faster key decoding than generic version
-
Raw Bytes Database (
ScopedBytesDatabase
)- Both keys and values are raw bytes
- Maximum performance with zero serialization
- ~1.8x faster writes than generic version
§Key Encoding
Scoped entries use different key encoding strategies depending on the database type:
§Generic Database (ScopedDatabase<K,V>
)
- Default scope: keys are stored using the
K
codec directly - Named scopes: Keys are stored as a serialized
ScopedKey<K>
struct containing:struct ScopedKey<K> { scope_hash: u32, // 32-bit xxHash of the scope name key: K, // The original key }
§Bytes Key Databases (ScopedBytesKeyDatabase<V>
and ScopedBytesDatabase
)
- Default scope: raw byte keys are stored as-is
- Named scopes: Keys use the following binary format:where:
[scope_hash_le: 4 bytes][key_len_le: 8 bytes][original_key_data]
scope_hash_le
: 32-bit xxHash of the scope name (little-endian)key_len_le
: 64-bit length of the original key (little-endian)original_key_data
: The original key bytes
This specialized binary format in the byte databases provides substantial performance improvements over the generic encoding, particularly for key decoding operations.
Re-exports§
pub use builder::scoped_database_options;
pub use global_registry::GlobalScopeRegistry;
pub use global_registry::ScopeEmptinessChecker;
pub use scope::Scope;
pub use scoped_bytes_database::ScopedBytesDatabase;
pub use scoped_bytes_key_database::ScopedBytesKeyDatabase;
pub use scoped_database::ScopedDatabase;
pub use utils::HeedRangeAdapter;
pub use utils::ScopedBytesCodec;
Modules§
Structs§
- Scoped
Key - Tuple type for scoped keys: (scope_hash, original_key)
Enums§
- Scoped
DbError - Error type for scoped database operations.
Type Aliases§
- Bytes
Iter Result - Iterator result type for bytes database operations
- Bytes
KeyIter Result - Iterator result type for bytes key database operations
- Iter
Result - Iterator result type for generic database operations, returning key-value pairs