#![warn(clippy::unwrap_used)]
#![cfg_attr(
all(
test,
not(all(
feature = "parking_lot",
feature = "rapira-codec",
feature = "var-collections",
feature = "rpc"
))
),
allow(dead_code)
)]
#[cfg(feature = "armour")]
extern crate self as armdb;
#[cfg(feature = "armour")]
mod access;
mod batch;
#[cfg(feature = "var-collections")]
mod byte_view;
#[cfg(feature = "var-collections")]
mod cache;
#[cfg(feature = "typed-tree")]
pub mod codec;
pub mod compaction;
mod config;
mod const_map;
mod const_tree;
#[cfg(feature = "typed-tree")]
mod counter;
#[cfg(feature = "typed-tree")]
mod counter_dirty;
#[cfg(all(
test,
feature = "typed-tree",
feature = "var-collections",
feature = "armour",
feature = "rapira-codec"
))]
mod counter_tests;
#[cfg(feature = "encryption")]
mod crypto;
mod ctx;
#[cfg(feature = "ctx-gates")]
#[doc(hidden)]
pub mod ctx_gates_sync;
#[cfg(feature = "var-collections")]
mod decoded_cache;
mod disk_loc;
pub mod durability;
mod engine;
mod entry;
mod error;
pub mod fixed;
mod flusher;
#[cfg(feature = "replication")]
pub(crate) mod frame_reader;
mod held_ops;
#[cfg(feature = "typed-tree")]
mod hex;
mod hint;
mod hint_worker;
mod hook;
mod io;
mod key;
mod lock;
mod map_index;
mod meta;
#[cfg(feature = "typed-tree")]
mod projection;
#[cfg(all(feature = "armour", feature = "typed-tree"))]
mod queue;
#[cfg(all(
debug_assertions,
feature = "armour",
feature = "typed-tree",
feature = "queue-test-support"
))]
#[doc(hidden)]
pub use queue::fixed::test_support as queue_test_support;
#[cfg(all(
debug_assertions,
feature = "armour",
feature = "typed-tree",
feature = "queue-test-support"
))]
#[doc(hidden)]
pub use queue::wait::test_support as queue_wake_test_support;
mod recovery;
#[cfg(feature = "encryption")]
mod salt;
mod scope;
mod shard;
mod shutdown;
#[cfg(any(feature = "loom", miri, feature = "bench-internals"))]
pub mod skiplist;
#[cfg(not(any(feature = "loom", miri, feature = "bench-internals")))]
mod skiplist;
mod sweeper;
mod sync;
#[cfg(all(test, feature = "typed-tree"))]
mod test_faults;
mod tree_meta;
mod ttl;
#[allow(dead_code)]
mod txlog;
mod txn_depth;
#[cfg(feature = "typed-tree")]
mod unique;
#[cfg(all(test, feature = "typed-tree", feature = "armour"))]
mod unique_tests;
pub(crate) use txn_depth::AtomicDepthGuard;
#[cfg(feature = "armour")]
#[cfg(not(feature = "test-faults"))]
#[allow(dead_code)]
mod txn;
#[cfg(all(feature = "armour", feature = "test-faults"))]
#[allow(dead_code)]
pub mod txn;
#[cfg(feature = "armour")]
pub use txn::{Selection, Tx, TxConfig, TxScope};
mod upsert;
#[cfg(feature = "var-collections")]
mod value_cache;
#[cfg(feature = "var-collections")]
mod var_map;
#[cfg(feature = "var-collections")]
mod var_tree;
#[cfg(feature = "typed-tree")]
mod zero_map;
#[cfg(feature = "typed-tree")]
mod zero_tree;
#[cfg(feature = "typed-tree")]
mod typed_map;
#[cfg(feature = "typed-tree")]
mod typed_tree;
#[cfg(feature = "typed-tree")]
mod watch;
#[cfg(all(feature = "typed-tree", feature = "var-collections"))]
mod var_typed_map;
#[cfg(all(feature = "typed-tree", feature = "var-collections"))]
mod var_typed_tree;
#[cfg(feature = "replication")]
pub mod replication;
#[cfg(feature = "replication")]
pub mod fixed_replication;
pub mod docs;
#[cfg(feature = "armour")]
pub mod armour;
#[cfg(feature = "schema")]
pub mod schema;
#[cfg(feature = "fjall")]
pub mod lsm;
#[cfg(feature = "armour")]
pub use armour_core;
pub use batch::Applied;
#[allow(deprecated)]
pub use batch::BatchWrite;
#[cfg(feature = "var-collections")]
pub use byte_view::ByteView;
#[cfg(feature = "bitcode-codec")]
pub use codec::BitcodeCodec;
#[cfg(feature = "typed-tree")]
pub use codec::Codec;
#[cfg(feature = "typed-tree")]
pub use codec::InspectionEncoding;
#[cfg(feature = "postcard-codec")]
pub use codec::PostcardCodec;
#[cfg(feature = "rapira-codec")]
pub use codec::RapiraCodec;
#[cfg(feature = "typed-tree")]
pub use codec::ZerocopyCodec;
#[cfg(feature = "bytemuck-codec")]
pub use codec::{BytemuckCodec, BytemuckSliceCodec, BytemuckVec};
pub use compaction::Compactor;
#[cfg(feature = "var-collections")]
pub use config::CacheConfig;
pub use config::Config;
pub use config::IoBackend;
pub use config::Workload;
pub use const_map::{ConstMap, ConstMapIterView, ConstMapShard};
pub use const_tree::{ConstIter, ConstShard, ConstTree};
#[cfg(feature = "typed-tree")]
pub use counter::{
CounterCollection, CounterSink, CounterTargets, OnMissingTarget, OneOfBuilder,
TypedCounterTarget,
};
#[cfg(feature = "encryption")]
pub use crypto::PageCipher;
pub use error::{DbError, DbResult, FencedShard, SchemaMismatchKind, TxFailStage};
pub use fixed::{FixedConfig, FixedMap, FixedTree, FixedWorkload};
pub use flusher::Flusher;
#[cfg(feature = "typed-tree")]
pub use hook::TypedWriteHook;
#[cfg(all(feature = "typed-tree", feature = "var-collections"))]
pub use hook::VarTypedHookAdapter;
#[cfg(feature = "typed-tree")]
pub use hook::ZeroHookAdapter;
pub use hook::{NoHook, WriteHook};
pub use key::{Key, Location};
pub use map_index::{Dir, KeyPage, Page};
#[cfg(feature = "typed-tree")]
#[allow(deprecated)]
pub use projection::Indexed;
#[doc(hidden)]
pub use projection::{CountingIndex, FailFirstDeleteIndex, FailNPutsIndex};
#[cfg(feature = "typed-tree")]
pub use projection::{
DEFAULT_MAX_PROJECTED_BYTES, DEFAULT_MAX_PROJECTED_ROWS, IndexKeyed, IndexTargets, NoEvents,
PendingProjection, ProjectableIndex, Projected, ProjectionSink,
};
#[cfg(all(feature = "typed-tree", feature = "armour"))]
pub use projection::{EventState, Events};
#[cfg(all(
feature = "armour",
feature = "typed-tree",
feature = "rapira-codec",
feature = "var-collections"
))]
pub use queue::VarQueueMode;
#[cfg(all(feature = "armour", feature = "typed-tree"))]
pub use queue::{
DEAD_CLASS, EmitSink, FixedQueueMode, ID_BLOCK, LIVE_CLASS, LeaseToken, LeasedEntry, Queue,
QueueConfig, QueueDue, QueueKey, QueueMode, QueueSpec, QueueStats, QueueStreamPayload,
QueueTargets,
};
pub use scope::{
BoxedRows, BulkScan, ChunkedPage, CoalescedMerge, ConstMapKeyIter, ConstMapRowIter,
ConstTreeKeyIter, ConstTreeRowIter, MapScan, MappedPage, MergeSorted, OrderedScan, OwnedRows,
PageSpec, Progress, Scope, StopReason, StrictRows, TreeScan, boxed, merge_sorted, page_chunks,
};
#[cfg(feature = "fjall")]
pub use scope::{LsmKeyIter, LsmRowIter};
#[cfg(feature = "typed-tree")]
pub use scope::{
MapKeyIter, MapRowIter, TreeKeyIter, TreeRowIter, ZeroMapKeyIter, ZeroMapRowIter,
ZeroTreeKeyIter, ZeroTreeRowIter,
};
#[cfg(feature = "var-collections")]
pub use scope::{VarMapKeyIter, VarMapRowIter, VarTreeKeyIter, VarTreeRowIter};
#[cfg(all(feature = "typed-tree", feature = "var-collections"))]
pub use scope::{VarTypedMapKeyIter, VarTypedMapRowIter, VarTypedTreeKeyIter, VarTypedTreeRowIter};
pub use shutdown::ShutdownSignal;
pub use sweeper::{SweepPassResult, Sweeper};
pub use tree_meta::{CollectionMeta, TreeMeta};
pub use ttl::{SweepOutcome, TtlHook, TtlPolicy};
#[cfg(feature = "typed-tree")]
pub use typed_map::{TypedMap, TypedMapIterView, TypedMapShard};
#[cfg(feature = "typed-tree")]
pub use typed_tree::{TypedIter, TypedRef, TypedShard, TypedTree};
#[cfg(feature = "typed-tree")]
pub use unique::{
ClaimSink, UNIQUE_OWNER_KEY_CAP, UniqueIndex, UniqueNamespace, UniqueOwner, UniqueRow,
UniqueTargets, collection_tag,
};
pub use upsert::{IntoUpsert, Upsert};
#[cfg(feature = "var-collections")]
pub use var_map::{VarMap, VarMapShard};
#[cfg(feature = "var-collections")]
pub use var_tree::{VarIter, VarShard, VarTree};
#[cfg(all(feature = "typed-tree", feature = "var-collections"))]
pub use var_typed_map::{VarTypedMap, VarTypedMapIterView, VarTypedMapShard};
#[cfg(all(feature = "typed-tree", feature = "var-collections"))]
pub use var_typed_tree::{VarTypedIter, VarTypedShard, VarTypedTree};
#[cfg(feature = "typed-tree")]
pub use watch::{
RecvFuture, WatchDecoder, WatchError, WatchEvent, WatchHook, WatchKind, WatchOptions,
WatchReceiver, WatchSpec,
};
#[cfg(feature = "typed-tree")]
pub use zero_map::{ZeroMap, ZeroMapIterView, ZeroMapShard};
#[cfg(feature = "typed-tree")]
pub use zero_tree::{ZeroIter, ZeroShard, ZeroTree};
#[cfg(all(
feature = "armour",
feature = "typed-tree",
feature = "rapira-codec",
feature = "var-collections"
))]
#[macro_export]
macro_rules! queue {
($name:ident, payload = $payload:ty, name = $lit:literal) => {
pub struct $name;
impl $crate::QueueSpec for $name {
type Payload = $payload;
type Mode = $crate::FixedQueueMode;
const NAME: &'static str = $lit;
const PAYLOAD_NAME: &'static str = concat!($lit, ".payload");
}
};
($name:ident, payload = $payload:ty, name = $lit:literal, var) => {
pub struct $name;
impl $crate::QueueSpec for $name {
type Payload = $payload;
type Mode = $crate::VarQueueMode;
const NAME: &'static str = $lit;
const PAYLOAD_NAME: &'static str = concat!($lit, ".payload");
}
};
}
#[cfg(all(
feature = "armour",
feature = "typed-tree",
not(all(feature = "rapira-codec", feature = "var-collections"))
))]
#[macro_export]
macro_rules! queue {
($name:ident, payload = $payload:ty, name = $lit:literal) => {
pub struct $name;
impl $crate::QueueSpec for $name {
type Payload = $payload;
type Mode = $crate::FixedQueueMode;
const NAME: &'static str = $lit;
const PAYLOAD_NAME: &'static str = concat!($lit, ".payload");
}
};
($name:ident, payload = $payload:ty, name = $lit:literal, var) => {
compile_error!("variable queues require the `rapira-codec` and `var-collections` features");
};
}
#[cfg(feature = "armour")]
pub use zerocopy;
#[doc(hidden)]
pub use disk_loc::DiskLoc;
#[doc(hidden)]
pub use entry::{
EntryHeader, FLAGS_MASK, SEQUENCE_MASK, SOFT_DELETE_BIT, TOMBSTONE_BIT, compute_crc32,
entry_size, serialize_entry,
};
#[doc(hidden)]
pub use hint::{HintEntry, hint_entry_size, parse_hint_entries};
#[cfg(feature = "typed-tree")]
#[doc(hidden)]
pub mod testing {
pub use crate::unique::unique_owner_for;
#[cfg(any(test, feature = "test-faults"))]
pub use crate::unique::{corrupt_unique_row, force_put};
pub fn unique_row_for(owner: crate::UniqueOwner) -> crate::UniqueRow {
crate::UniqueRow::new(owner)
}
pub fn now_ms() -> u64 {
crate::unique::reservation_now_ms()
}
#[cfg(feature = "armour")]
pub fn stream_visible_at(sink: &crate::EmitSink<'_>) -> Vec<std::time::SystemTime> {
sink.emissions()
.iter()
.map(|emission| emission.visible_at)
.collect()
}
pub fn claim_sink(
targets: &crate::UniqueTargets,
max_rows: usize,
max_bytes: usize,
) -> crate::ClaimSink<'_> {
crate::ClaimSink::new(targets, max_rows, max_bytes)
}
#[cfg(feature = "armour")]
pub struct TxClaimOp {
pub namespace: &'static str,
pub key: Vec<u8>,
pub owner: crate::UniqueOwner,
is_claim: bool,
is_release: bool,
}
#[cfg(feature = "armour")]
impl TxClaimOp {
pub fn is_claim(&self) -> bool {
self.is_claim
}
pub fn is_release(&self) -> bool {
self.is_release
}
}
#[cfg(feature = "armour")]
impl From<crate::txn::participant::ClaimOp> for TxClaimOp {
fn from(op: crate::txn::participant::ClaimOp) -> Self {
let is_claim = op.is_claim();
let is_release = op.is_release();
Self {
namespace: op.namespace,
key: op.key,
owner: op.owner,
is_claim,
is_release,
}
}
}
#[cfg(feature = "armour")]
pub fn tx_claims_of<K, T, C, H>(
map: &crate::TypedMap<K, T, C, H>,
key: &K,
old: Option<&[u8]>,
new: Option<&[u8]>,
) -> crate::DbResult<Vec<TxClaimOp>>
where
K: crate::Key + Send + Sync + std::hash::Hash + Eq + 'static,
T: crate::CollectionMeta + Send + Sync + 'static,
C: crate::codec::Codec<T> + Sync + 'static,
H: crate::TypedWriteHook<K, T> + 'static,
{
use crate::txn::participant::TxParticipant;
let key_bytes = key.as_bytes().to_vec();
let ops = map.tx_claims(&key_bytes, old, new)?;
Ok(ops.into_iter().map(TxClaimOp::from).collect())
}
#[cfg(feature = "armour")]
pub fn tx_preplan_names<K, T, C, H>(
map: &crate::TypedMap<K, T, C, H>,
) -> crate::DbResult<Vec<&'static str>>
where
K: crate::Key + Send + Sync + std::hash::Hash + Eq,
T: Send + Sync,
C: crate::codec::Codec<T> + Sync,
H: crate::TypedWriteHook<K, T>,
{
Ok(map
.tx_preplan_projection_targets()?
.into_iter()
.map(|p| p.name())
.collect())
}
}
use std::mem::size_of;
pub(crate) fn shard_for_key<K: Key>(
key: &K,
shard_prefix_bits: usize,
shard_count: usize,
) -> usize {
if shard_prefix_bits == 0 || shard_prefix_bits >= size_of::<K>() * 8 {
let hash = xxhash_rust::xxh3::xxh3_64(key.as_bytes());
return (hash as usize) % shard_count;
}
let full_bytes = shard_prefix_bits / 8;
let extra_bits = shard_prefix_bits % 8;
let hash = if extra_bits == 0 {
xxhash_rust::xxh3::xxh3_64(&key.as_bytes()[..full_bytes])
} else {
let mut buf = K::zeroed();
buf.as_bytes_mut()[..full_bytes + 1].copy_from_slice(&key.as_bytes()[..full_bytes + 1]);
let mask = !((1u8 << (8 - extra_bits)) - 1);
buf.as_bytes_mut()[full_bytes] = key.as_bytes()[full_bytes] & mask;
xxhash_rust::xxh3::xxh3_64(&buf.as_bytes()[..full_bytes + 1])
};
(hash as usize) % shard_count
}
pub enum MigrateAction<V> {
Keep,
Update(V),
Delete,
}
#[cfg(feature = "typed-tree")]
#[macro_export]
macro_rules! zero_tree {
($V:ty) => {
$crate::ZeroTree<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
$V,
$crate::TtlHook<$V, $crate::NoHook>,
>
};
($V:ty, fixed) => {
$crate::ZeroTree<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
$V,
$crate::TtlHook<$V, $crate::NoHook>,
$crate::durability::Fixed,
>
};
($V:ty, $H:ty) => {
$crate::ZeroTree<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
$V,
$crate::TtlHook<$V, $H>,
$crate::durability::Bitcask,
>
};
($V:ty, $H:ty, fixed) => {
$crate::ZeroTree<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
$V,
$crate::TtlHook<$V, $H>,
$crate::durability::Fixed,
>
};
}
#[cfg(feature = "typed-tree")]
#[macro_export]
macro_rules! zero_map {
($V:ty) => {
$crate::ZeroMap<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
$V,
$crate::TtlHook<$V, $crate::NoHook>,
>
};
($V:ty, fixed) => {
$crate::ZeroMap<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
$V,
$crate::TtlHook<$V, $crate::NoHook>,
$crate::durability::Fixed,
>
};
($V:ty, $H:ty) => {
$crate::ZeroMap<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
$V,
$crate::TtlHook<$V, $H>,
$crate::durability::Bitcask,
>
};
($V:ty, $H:ty, fixed) => {
$crate::ZeroMap<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
$V,
$crate::TtlHook<$V, $H>,
$crate::durability::Fixed,
>
};
}
#[macro_export]
macro_rules! const_tree {
($V:ty) => {
$crate::ConstTree<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
>
};
($V:ty, fixed) => {
$crate::ConstTree<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
$crate::NoHook,
$crate::durability::Fixed,
>
};
($V:ty, $H:ty) => {
$crate::ConstTree<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
$H,
$crate::durability::Bitcask,
>
};
($V:ty, $H:ty, fixed) => {
$crate::ConstTree<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
$H,
$crate::durability::Fixed,
>
};
}
#[macro_export]
macro_rules! const_map {
($V:ty) => {
$crate::ConstMap<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
>
};
($V:ty, fixed) => {
$crate::ConstMap<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
$crate::NoHook,
$crate::durability::Fixed,
>
};
($V:ty, $H:ty) => {
$crate::ConstMap<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
$H,
$crate::durability::Bitcask,
>
};
($V:ty, $H:ty, fixed) => {
$crate::ConstMap<
<$V as $crate::CollectionMeta>::SelfId,
{ ::std::mem::size_of::<$V>() },
$H,
$crate::durability::Fixed,
>
};
}
#[cfg(feature = "typed-tree")]
#[macro_export]
macro_rules! typed_tree {
($V:ty, $C:ty) => {
$crate::TypedTree<
<$V as $crate::CollectionMeta>::SelfId,
$V,
$C,
$crate::TtlHook<$V, $crate::NoHook>,
>
};
($V:ty, $C:ty, $H:ty) => {
$crate::TypedTree<
<$V as $crate::CollectionMeta>::SelfId,
$V,
$C,
$crate::TtlHook<$V, $H>,
>
};
}
#[cfg(feature = "typed-tree")]
#[macro_export]
macro_rules! typed_map {
($V:ty, $C:ty) => {
$crate::TypedMap<
<$V as $crate::CollectionMeta>::SelfId,
$V,
$C,
$crate::TtlHook<$V, $crate::NoHook>,
>
};
($V:ty, $C:ty, $H:ty) => {
$crate::TypedMap<
<$V as $crate::CollectionMeta>::SelfId,
$V,
$C,
$crate::TtlHook<$V, $H>,
>
};
}
#[cfg(feature = "var-collections")]
#[macro_export]
macro_rules! var_tree {
($V:ty) => {
$crate::VarTree<<$V as $crate::CollectionMeta>::SelfId>
};
($V:ty, $H:ty) => {
$crate::VarTree<<$V as $crate::CollectionMeta>::SelfId, $H>
};
}
#[cfg(feature = "var-collections")]
#[macro_export]
macro_rules! var_map {
($V:ty) => {
$crate::VarMap<<$V as $crate::CollectionMeta>::SelfId>
};
($V:ty, $H:ty) => {
$crate::VarMap<<$V as $crate::CollectionMeta>::SelfId, $H>
};
}
#[cfg(all(feature = "typed-tree", feature = "var-collections"))]
#[macro_export]
macro_rules! var_typed_tree {
($V:ty, $C:ty) => {
$crate::VarTypedTree<
<$V as $crate::CollectionMeta>::SelfId,
$V,
$C,
$crate::TtlHook<$V, $crate::NoHook>,
>
};
($V:ty, $C:ty, $H:ty) => {
$crate::VarTypedTree<
<$V as $crate::CollectionMeta>::SelfId,
$V,
$C,
$crate::TtlHook<$V, $H>,
>
};
}
#[cfg(all(feature = "typed-tree", feature = "var-collections"))]
#[macro_export]
macro_rules! var_typed_map {
($V:ty, $C:ty) => {
$crate::VarTypedMap<
<$V as $crate::CollectionMeta>::SelfId,
$V,
$C,
$crate::TtlHook<$V, $crate::NoHook>,
>
};
($V:ty, $C:ty, $H:ty) => {
$crate::VarTypedMap<
<$V as $crate::CollectionMeta>::SelfId,
$V,
$C,
$crate::TtlHook<$V, $H>,
>
};
}