armdb 0.7.2

sharded bitcask key-value storage optimized for NVMe
Documentation
//! Integration with the armour ecosystem (feature `armour`).
//!
//! Provides multi-tree database management, schema-versioned migrations,
//! and a binary RPC server compatible with armour-rpc clients.
//!
//! # Components
//!
//! - [`Db`] — manages a directory of named collections with persistent
//!   metadata ([`DbInfo`]) and sequential ID generation.
//! - [`TreeMeta`] — static descriptor for a collection (name, key scheme, type, version).
//! - [`Db::open_typed_tree`] / [`Db::open_typed_map`] /
//!   [`Db::open_zero_tree`] / [`Db::open_zero_map`] —
//!   open a tree or map with automatic migration when the stored schema version
//!   differs from [`TreeMeta::version`].
//! - [`Db::inspector`] — borrowed in-process read-only diagnostic API over
//!   every collection opened through this [`Db`]. Does not require or alter RPC.
//! - [`Inspector`] — discovery, schema, raw key/value reads, counts, and bounded
//!   scans. Authentication, redaction, JSON, and audit logging stay with the
//!   application.
//! - [`RpcHandler`] — trait for handling binary RPC requests per collection.
//! - [`TypedTreeHandler`] — [`RpcHandler`] implementation that bridges
//!   bytes-level RPC to a [`TypedTree`](crate::TypedTree) via a [`Codec`](crate::Codec).
//! - [`TreeMap`] — `Arc<HashMap<u64, Arc<dyn RpcHandler>>>` routing table
//!   (key = `xxh3(name)`).
//!
//! # Read-only Inspector
//!
//! [`Db::inspector`] returns a borrowed [`Inspector`] tied to the owning `Db`.
//! Only collections opened through that `Db` are visible; directly opened
//! trees and maps are not registered.
//!
//! **Discovery** — [`Inspector::collections`] lists every registered collection
//! sorted by name with [`InspectionCollection`] metadata: [`InspectionSchema`]
//! (version, [`Typ`](armour_core::Typ), [`KeyScheme`](armour_core::KeyScheme),
//! key size, [`InspectionEncoding`](crate::InspectionEncoding)), storage class
//! ([`StorageClass`](armour_core::StorageClass)), optional cheap count,
//! [`ScanCapability`], and [`IterationDirection`] when ordered.
//!
//! **Value encoding** — [`InspectionEncoding::Rapira`] marks Rapira-serialized
//! values suitable for generic decoding; [`InspectionEncoding::RawLayout`] marks
//! a contiguous raw memory image (Zero/Const families); [`InspectionEncoding::Opaque`]
//! declares no generic decoder contract.
//!
//! **Counts** — [`CountMode::Current`] uses the handler's O(1) live-key counter
//! when available; [`CountMode::Exact`] performs a strict key-only scan that
//! includes unreadable values and fails on storage errors (Var/LSM paths
//! propagate failures instead of returning partial results).
//!
//! **Ordered scans** — [`Inspector::range`] and [`Inspector::prefix`] honor the
//! collection's byte order and configured direction. Pass the previous page's
//! `next_key` as `after` to continue in ascending or reversed order. Pagination
//! uses a one-row lookahead so `next_key` is set only when another row exists.
//! Pages are not a cross-shard or cross-page point-in-time snapshot.
//!
//! **Unordered snapshot** — [`Inspector::snapshot_unordered`] walks a
//! non-iterable Map in per-shard unspecified order; it is not a global snapshot.
//!
//! **Map iterability** — whether an iterable Map supports ordered scans is
//! decided at open time (`iterable(true)`); non-iterable Maps expose
//! [`ScanCapability::UnorderedSnapshot`] instead.
//!
//! Inspector exposes no mutation methods. See [`Db::inspector`] for
//! `compile_fail` boundary examples.
//!
//! # Quick start
//!
//! ```ignore
//! use std::sync::Arc;
//! use armdb::armour::{Db, TypedTreeHandler, TreeMap};
//! use armdb::RapiraCodec;
//!
//! let db = Db::open("data/myapp")?;
//! let tree = Arc::new(db.open_typed_tree::<User, _>(RapiraCodec, &[])?);
//!
//! // Register handler and start RPC server
//! let trees: TreeMap = Arc::new(/* hashname -> handler */);
//! db.listen_tcp(trees.clone(), "127.0.0.1:9000");
//! db.listen_uds(trees, "/tmp/myapp.sock");
//! ```
//!
//! # RPC protocol
//!
//! Length-delimited frames over TCP or Unix socket. Each request carries an
//! opcode, a collection hashname (`xxh3` of the collection name), and an
//! operation-specific payload. See [`rpc`] module for codec details.
//!
//! Graceful shutdown: Ctrl-C sends a broadcast via `async_broadcast`;
//! all accept loops and active connections terminate.

pub mod collection;
pub mod db;
#[cfg(feature = "rpc")]
pub mod handler;
#[cfg(not(feature = "rpc"))]
pub(crate) mod handler;
pub mod inspection;
pub mod migration;
pub mod multi_tx;
#[cfg(feature = "rpc")]
pub mod rpc;
pub mod seq;
#[cfg(feature = "rpc")]
pub mod typed_client;

pub use crate::{CollectionMeta, Key, TreeMeta};
pub use collection::Collection;
pub use db::{CollectionInfo, Db, DbInfo, TYP_HASH_MIGRATING};
#[cfg(feature = "rpc")]
pub use handler::{RpcHandler, TypedMapHandler, TypedTreeHandler, ZeroMapHandler, ZeroTreeHandler};
#[cfg(all(feature = "rpc", feature = "var-collections"))]
pub use handler::{VarTypedMapHandler, VarTypedTreeHandler};
pub use inspection::{
    CountMode, InspectionCollection, InspectionEncoding, InspectionEntry, InspectionError,
    InspectionOperation, InspectionPage, InspectionSchema, Inspector, IterationDirection,
    ScanCapability,
};
pub use migration::{TypedMigration, TypedMigrationFn};
pub use multi_tx::{MultiTx, SyncNeeds};
#[cfg(feature = "rpc")]
pub use rpc::TreeMap;
pub use seq::SeqGen;
#[cfg(feature = "rpc")]
pub use typed_client::TypedRpcClient;