vsdb
vsdbis a high-performance, embedded database with an API similar to Rust's standard collections.
This crate provides high-level, typed data structures that are backed by a persistent key-value store. It is the primary crate for end-users.
Installation
Add this to your Cargo.toml:
[]
= "9.0.0"
Highlights
For more detailed API examples, see API Examples. For the versioned storage architecture with diagrams, see Versioned Module — Architecture & Internals.
- Familiar API: Most APIs are designed to mirror their counterparts in the standard library.
Mapxbehaves likestd::collections::HashMap.MapxOrdbehaves likestd::collections::BTreeMap.
- Persistent Storage: Data is automatically saved to disk and loaded on instantiation.
- Typed Keys and Values: Keys and values are strongly typed and automatically serialized/deserialized.
- Git-Model Versioning:
VerMapprovides branching, commits, three-way merge, rollback, and history — backed by a persistent B+ tree with copy-on-write structural sharing.
Features
Uses RocksDB as the storage backend.
msgpack_codec: (Default) Usermp-serdeas the codec for faster performance.cbor_codec: Useserde_cbor_2as an alternative codec.
msgpack_codec and cbor_codec are mutually exclusive.
To switch from the default MessagePack codec to CBOR, disable default features:
[]
= { = "9.0.0", = false, = ["cbor_codec"] }
Usage
Mapx
Mapx is a persistent, hash map-like data structure.
use Mapx;
let mut map = new;
// Insert some key-value pairs
map.insert;
map.insert;
// Get a value
assert_eq!;
// Check if a key exists
assert!;
// Iterate over the key-value pairs
for in map.iter
// Remove a key-value pair
map.remove;
MapxOrd
MapxOrd is a persistent, B-tree map-like data structure that keeps keys in sorted order.
use MapxOrd;
let mut map = new;
// Insert some key-value pairs
map.insert;
map.insert;
map.insert;
// Get a value
assert_eq!;
// Iterate over the key-value pairs in sorted order
for in map.iter
// Get the first and last key-value pairs
assert_eq!;
assert_eq!;
VerMap
VerMap provides Git-style versioned storage with branching, commits, merge, and rollback.
The typical lifecycle is: create → write → commit → branch → merge → gc.
Merge conflict resolution: source wins on conflicts
merge(source, target) uses three-way merge with the common ancestor.
If only one side changed a key relative to the ancestor, that single-sided
change is preserved. If both sides changed the same key differently, source
wins. A deletion is treated as "assigning ∅", so delete-vs-modify is also
resolved by source priority.
| source | target | result |
|---|---|---|
| unchanged (A) | changed to T | T (target-only change preserved) |
| changed to S | unchanged (A) | S (source-only change preserved) |
| changed to S | changed to T | S (conflict → source wins) |
| deleted (∅) | changed to T | ∅ (conflict → source wins → delete) |
| changed to S | deleted (∅) | S (conflict → source wins → keep) |
The caller controls priority by choosing which branch to pass as source vs target.
use VerMap;
use BranchId;
// 1. Create an empty versioned map (starts with a "main" branch).
let mut m: = new;
let main = m.main_branch;
// 2. Write on the main branch and commit a snapshot.
m.insert.unwrap;
m.commit.unwrap;
// 3. Fork a feature branch — cheap, no data copied.
let feat: BranchId = m.create_branch.unwrap;
m.insert.unwrap;
m.commit.unwrap;
// 4. Branches are isolated.
assert_eq!;
assert_eq!;
// 5. Three-way merge: feature → main (source wins on conflict).
m.merge.unwrap;
assert_eq!;
// 6. Clean up: delete the branch, then garbage-collect unreachable data.
m.delete_branch.unwrap;
m.gc;
Important Notes
- The serialized result of a
vsdbinstance cannot be used for distributed consensus. The serialized data contains meta-information (like storage paths) that may differ across environments. The correct approach is to read the required data and then process the raw content.
License
This project is licensed under the MIT license.