#![doc = include_str!("../README.md")]
#![feature(sync_unsafe_cell)]
#![cfg_attr(target_arch = "aarch64", feature(integer_atomics))]
#![deny(dead_code)]
#![deny(unused)]
#![deny(unused_mut)]
#![deny(clippy::missing_safety_doc)]
#![deny(clippy::undocumented_unsafe_blocks)]
#![cfg_attr(not(test), deny(clippy::expect_used))]
#![cfg_attr(not(test), deny(clippy::unwrap_used))]
#![deny(clippy::question_mark_used)]
#![deny(clippy::needless_borrow)]
#![allow(bindings_with_variant_name)]
#[cfg(not(unix))]
compile_warn!("cesiumdb is not tested on windows");
#[cfg(not(target_pointer_width = "64"))]
compile_warn!("cesiumdb is not tested on 32-bit systems");
#[allow(unused)]
use std::sync::Arc;
use bytes::Bytes;
use crate::{
Batch::{
Delete,
DeleteNs,
Put,
PutNs,
},
errs::CesiumError,
hlc::HLC,
keypair::{
DEFAULT_NS,
KeyBytes,
},
};
pub mod autoconfig;
macro_rules! bench_pub_mod {
($name:ident) => {
pub mod $name;
};
}
bench_pub_mod!(block);
mod block_alloc;
mod bloom;
bench_pub_mod!(compact);
bench_pub_mod!(compaction);
pub mod errs;
mod hash;
pub mod hlc;
mod index;
pub(crate) mod io;
bench_pub_mod!(keypair);
bench_pub_mod!(levels);
pub(crate) mod manifest;
pub(crate) mod manifest_reader;
pub(crate) mod manifest_writer;
bench_pub_mod!(map);
bench_pub_mod!(memtable);
bench_pub_mod!(merge);
pub(crate) mod peek;
bench_pub_mod!(raw_entry);
bench_pub_mod!(segment);
bench_pub_mod!(segment_builder);
mod segment_iterator;
pub(crate) mod segment_reader;
bench_pub_mod!(segment_writer);
pub(crate) mod simd;
pub(crate) mod state;
mod stats;
bench_pub_mod!(utils);
bench_pub_mod!(version);
#[cfg(feature = "telemetry")]
pub mod telemetry;
mod db_inner;
mod db_options;
mod scan;
pub use compaction::{
CompactionStats,
SchedulerConfig,
};
pub(crate) use db_inner::DbInner;
pub use db_options::{
Batch,
DbOptions,
};
pub(crate) use scan::OwnedSegmentIterator;
pub use scan::{
DbScanIterator,
ReadAmpStats,
};
pub use version::VersionStats;
pub struct Db {
pub(crate) inner: Arc<DbInner>,
clock: Arc<dyn HLC>,
}
impl Drop for Db {
fn drop(&mut self) {
let _ = self.close();
}
}
impl Db {
pub fn open(opts: DbOptions) -> Result<Arc<Self>, CesiumError> {
opts.build()
}
pub fn time(&self) -> u128 {
self.clock.time()
}
pub fn put_ns(&self, ns: u64, key: &[u8], value: &[u8]) -> Result<(), CesiumError> {
self.inner
.batch(&[PutNs(ns, key, value, self.clock.time())])
}
pub fn get_ns(&self, ns: u64, key: &[u8]) -> Result<Option<Bytes>, CesiumError> {
match self
.inner
.get(KeyBytes::new(ns, Bytes::copy_from_slice(key), 0))
{
| Ok(v) => match v {
| None => Ok(None),
| Some(v) => Ok(Some(v.as_bytes())),
},
| Err(e) => Err(e),
}
}
pub fn delete_ns(&self, ns: u64, key: &[u8]) -> Result<(), CesiumError> {
self.inner
.batch::<&[u8], &[u8]>(&[DeleteNs(ns, key, self.clock.time())])
}
pub fn put(&self, key: &[u8], value: &[u8]) -> Result<(), CesiumError> {
self.put_ns(DEFAULT_NS, key, value)
}
pub fn get(&self, key: &[u8]) -> Result<Option<Bytes>, CesiumError> {
self.get_ns(DEFAULT_NS, key)
}
pub fn delete(&self, key: &[u8]) -> Result<(), CesiumError> {
self.delete_ns(DEFAULT_NS, key)
}
pub fn scan_ns(
&self,
ns: u64,
lower: std::ops::Bound<&[u8]>,
upper: std::ops::Bound<&[u8]>,
) -> Result<DbScanIterator, CesiumError> {
self.inner.scan(ns, lower, upper)
}
pub fn scan(
&self,
lower: std::ops::Bound<&[u8]>,
upper: std::ops::Bound<&[u8]>,
) -> Result<DbScanIterator, CesiumError> {
self.scan_ns(DEFAULT_NS, lower, upper)
}
pub fn batch<K: AsRef<[u8]>, V: AsRef<[u8]>>(
&self,
ops: &[Batch<K, V>],
) -> Result<(), CesiumError> {
let _ops = ops
.iter()
.map(|b| match b {
| Put(k, v, ts) => PutNs(DEFAULT_NS, k, v, *ts),
| PutNs(ns, k, v, ts) => PutNs(*ns, k, v, *ts),
| Delete(k, ts) => DeleteNs(DEFAULT_NS, k, *ts),
| DeleteNs(ns, k, ts) => DeleteNs(*ns, k, *ts),
})
.collect::<Vec<_>>();
self.inner.batch(&_ops)
}
pub fn sync(&self) -> Result<(), CesiumError> {
self.inner.sync()
}
pub fn close(&self) -> Result<(), CesiumError> {
self.inner.state.lock().shutdown()
}
pub fn compact(&self) -> Result<(), CesiumError> {
let guard = self.inner.state.lock();
guard.compact();
Ok(())
}
pub fn compaction_stats(&self) -> Result<CompactionStats, CesiumError> {
let guard = self.inner.state.lock();
match guard.compaction_stats() {
| Some(stats) => Ok(stats),
| None => Err(CesiumError::CompactionError(
crate::errs::CompactionError::NotInitialized,
)),
}
}
pub fn version_stats(&self) -> VersionStats {
self.inner.version_stats()
}
pub fn read_amp_stats(&self) -> ReadAmpStats {
self.inner.read_amp_stats()
}
pub fn frozen_memtable_count(&self) -> usize {
self.inner.frozen_memtable_count()
}
}
#[cfg(test)]
mod tests;