rockstr
An embedded RocksDB storage wrapper with typed column-family access, schema migrations, pluggable value codecs, and optimistic/pessimistic transactions.

Features
- Typed column families — compile-time CF, key, and value types; impossible to address the wrong family or pass an unencoded key
- Dual transaction backend — choose
OptimisticTransactionDB (low overhead, commit-time conflict detection) or TransactionDB (pessimistic locking) at construction time
- Pluggable value codec —
PostcardCodec (default, compact binary) or JsonCodec (human-readable), per column family
- Fixed-width & variable-length keys — big-endian key encoding with
#[derive(KeyEncode, KeyDecode)]; String / Vec<u8> supported with length-prefix
- Prefix scans — forward, reverse, cursor-paginated, byte-and-count-bounded
- Schema migrations — version-tracked, atomic, crash-resumable, with eager and chunked backfill modes
- TTL — per-key expiry via
put_with_ttl; expired values invisible to reads and scans
- Non-transactional snapshots — cheap point-in-time consistent reads without transaction overhead
- Escape hatch —
raw_db() gives direct access to the underlying RocksDB engine
Quick example
use rockstr::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(rockstr::KeyEncode, rockstr::KeyDecode)]
struct ChatSeq { chat_id: u64, seq: u32 }
#[derive(Serialize, Deserialize)]
struct Message { text: String }
struct MessagesCf;
impl ColumnFamily for MessagesCf {
const NAME: &'static str = "messages";
type Key = ChatSeq;
type Value = Message;
type Codec = PostcardCodec;
}
// Optimistic backend (zero-cost conflict detection at commit time)
let store: RocksStore<OptimisticTransactionDB> =
RocksStore::builder("/tmp/mydb")
.cf::<MessagesCf>()
.open()?;
// Typed put
store.put::<MessagesCf>(
&ChatSeq { chat_id: 1, seq: 0 },
&Message { text: "Hello!".into() },
)?;
// Transactional read-modify-write with auto-retry
store.transact(8, |txn: &Txn<'_, _>| {
let next = txn.get_for_update::<MessagesCf>(&ChatSeq { chat_id: 1, seq: 0 })?
.is_some() as u32 + 1;
txn.put::<MessagesCf>(
&ChatSeq { chat_id: 1, seq: next },
&Message { text: "Follow-up".into() },
)?;
Ok(())
})?;
Documentation
Crates
| Crate |
Description |
rockstr |
Main library — store, transactions, migrations, codecs |
rockstr-derive |
Proc-macro derive for KeyEncode / KeyDecode |
License
MPL-2.0