use std::sync::Arc;
use crate::db::Inner;
use crate::storage::Engine;
use crate::Result;
#[derive(Clone)]
pub struct Namespace {
inner: Arc<Inner>,
ns_id: u32,
name: Box<str>,
}
impl Namespace {
pub(crate) fn new(inner: Arc<Inner>, ns_id: u32, name: Box<str>) -> Self {
Self { inner, ns_id, name }
}
fn engine(&self) -> &Engine {
&self.inner.engine
}
#[must_use]
pub fn name(&self) -> &str {
&self.name
}
pub fn insert(&self, key: impl Into<Vec<u8>>, value: impl Into<Vec<u8>>) -> Result<()> {
let key = key.into();
let value = value.into();
self.engine().insert(self.ns_id, &key, &value, 0)
}
pub fn insert_many<I, K, V>(&self, items: I) -> Result<()>
where
I: IntoIterator<Item = (K, V)>,
K: AsRef<[u8]>,
V: AsRef<[u8]>,
{
let owned: Vec<(Vec<u8>, Vec<u8>, u64)> = items
.into_iter()
.map(|(k, v)| (k.as_ref().to_vec(), v.as_ref().to_vec(), 0))
.collect();
self.engine().insert_many(self.ns_id, owned)
}
pub fn get(&self, key: impl AsRef<[u8]>) -> Result<Option<Vec<u8>>> {
self.engine().get(self.ns_id, key.as_ref())
}
pub fn get_zerocopy(&self, key: impl AsRef<[u8]>) -> Result<Option<crate::ValueRef>> {
Ok(self
.engine()
.get_zerocopy(self.ns_id, key.as_ref())?
.map(|(v, _)| v))
}
pub fn remove(&self, key: impl AsRef<[u8]>) -> Result<Option<Vec<u8>>> {
self.engine().remove(self.ns_id, key.as_ref())
}
pub fn contains_key(&self, key: impl AsRef<[u8]>) -> Result<bool> {
Ok(self.engine().get(self.ns_id, key.as_ref())?.is_some())
}
pub fn len(&self) -> Result<usize> {
let count = self.engine().record_count(self.ns_id)?;
usize::try_from(count).map_err(|_| {
crate::Error::InvalidConfig("namespace record count exceeds usize on this target")
})
}
pub fn is_empty(&self) -> Result<bool> {
Ok(self.len()? == 0)
}
pub fn clear(&self) -> Result<()> {
self.engine().clear_namespace(self.ns_id)
}
pub fn iter(&self) -> Result<NamespaceIter> {
let offsets = self.engine().snapshot_offsets(self.ns_id)?;
Ok(NamespaceIter::new(Arc::clone(&self.inner), offsets))
}
pub fn keys(&self) -> Result<NamespaceKeyIter> {
let offsets = self.engine().snapshot_offsets(self.ns_id)?;
Ok(NamespaceKeyIter::new(Arc::clone(&self.inner), offsets))
}
pub fn range<R>(&self, range: R) -> Result<Vec<(Vec<u8>, Vec<u8>)>>
where
R: std::ops::RangeBounds<Vec<u8>>,
{
self.engine().range_scan(self.ns_id, range)
}
pub fn range_prefix(&self, prefix: impl AsRef<[u8]>) -> Result<Vec<(Vec<u8>, Vec<u8>)>> {
let prefix = prefix.as_ref();
let start = prefix.to_vec();
match crate::db::next_prefix(prefix) {
Some(end) => self.range(start..end),
None => self.range(start..),
}
}
pub fn range_iter<R>(&self, range: R) -> Result<NamespaceRangeIter>
where
R: std::ops::RangeBounds<Vec<u8>>,
{
let pairs = self.engine().snapshot_range_offsets(self.ns_id, range)?;
Ok(NamespaceRangeIter::new(Arc::clone(&self.inner), pairs))
}
pub fn range_prefix_iter(&self, prefix: impl AsRef<[u8]>) -> Result<NamespaceRangeIter> {
let prefix = prefix.as_ref();
let start = prefix.to_vec();
match crate::db::next_prefix(prefix) {
Some(end) => self.range_iter(start..end),
None => self.range_iter(start..),
}
}
pub fn iter_from(&self, start: impl AsRef<[u8]>) -> Result<NamespaceRangeIter> {
self.range_iter(start.as_ref().to_vec()..)
}
pub fn iter_after(&self, start: impl AsRef<[u8]>) -> Result<NamespaceRangeIter> {
let start = start.as_ref().to_vec();
self.range_iter((std::ops::Bound::Excluded(start), std::ops::Bound::Unbounded))
}
}
pub struct NamespaceIter {
inner: Arc<Inner>,
offsets: std::vec::IntoIter<u64>,
}
impl NamespaceIter {
fn new(inner: Arc<Inner>, offsets: Vec<u64>) -> Self {
Self {
inner,
offsets: offsets.into_iter(),
}
}
}
impl Iterator for NamespaceIter {
type Item = (Vec<u8>, Vec<u8>);
fn next(&mut self) -> Option<Self::Item> {
for offset in self.offsets.by_ref() {
match self.inner.engine.decode_owned_at(offset) {
Ok(Some((key, value, _))) => return Some((key, value)),
Ok(None) => continue,
Err(_) => continue,
}
}
None
}
}
pub struct NamespaceKeyIter {
inner: Arc<Inner>,
offsets: std::vec::IntoIter<u64>,
}
impl NamespaceKeyIter {
fn new(inner: Arc<Inner>, offsets: Vec<u64>) -> Self {
Self {
inner,
offsets: offsets.into_iter(),
}
}
}
impl Iterator for NamespaceKeyIter {
type Item = Vec<u8>;
fn next(&mut self) -> Option<Self::Item> {
for offset in self.offsets.by_ref() {
match self.inner.engine.decode_owned_at(offset) {
Ok(Some((key, _value, _))) => return Some(key),
Ok(None) => continue,
Err(_) => continue,
}
}
None
}
}
pub struct NamespaceRangeIter {
inner: Arc<Inner>,
pairs: std::vec::IntoIter<(Vec<u8>, u64)>,
}
impl NamespaceRangeIter {
fn new(inner: Arc<Inner>, pairs: Vec<(Vec<u8>, u64)>) -> Self {
Self {
inner,
pairs: pairs.into_iter(),
}
}
}
impl Iterator for NamespaceRangeIter {
type Item = (Vec<u8>, Vec<u8>);
fn next(&mut self) -> Option<Self::Item> {
for (key, offset) in self.pairs.by_ref() {
match self.inner.engine.read_value_with_meta_at(offset, &key) {
Ok(Some((value, _expires))) => return Some((key, value)),
Ok(None) => continue,
Err(_) => continue,
}
}
None
}
}