use std::ops::ControlFlow;
use std::sync::Arc;
use std::time::Duration;
use serde::de::DeserializeOwned;
use serde::Serialize;
use crate::codec::encode;
use crate::error::{Error, Result};
use crate::format::{Entry, Store};
use crate::secret::Secret;
use crate::store::{fetch, remove_from, seal_into, Inner};
#[derive(Clone)]
pub struct Tree {
inner: Arc<Inner>,
name: String,
}
impl Tree {
pub(crate) fn new(inner: Arc<Inner>, name: String) -> Self {
Self { inner, name }
}
pub fn name(&self) -> &str {
&self.name
}
pub fn get<V: DeserializeOwned>(&self, key: &str) -> Result<Option<V>> {
let entry = {
let g = self.inner.read_store()?;
fetch(&g, &self.name, key)
};
match entry {
Some(e) => self.inner.read_value(&self.name, key, &e),
None => Ok(None),
}
}
pub fn require<V: DeserializeOwned>(&self, key: &str) -> Result<V> {
self.get(key)?.ok_or(Error::KeyNotFound)
}
pub fn get_secret<V: DeserializeOwned>(&self, key: &str) -> Result<Option<Secret<V>>> {
Ok(self.get::<V>(key)?.map(Secret::new))
}
pub fn put<V: Serialize>(&self, key: &str, value: &V) -> Result<()> {
self.put_inner(key, value, None)
}
pub fn put_with_ttl<V: Serialize>(&self, key: &str, value: &V, ttl: Duration) -> Result<()> {
self.put_inner(key, value, Some(ttl))
}
fn put_inner<V: Serialize>(&self, key: &str, value: &V, ttl: Option<Duration>) -> Result<()> {
self.inner.ensure_writable()?;
{
let mut g = self.inner.write_store()?;
seal_into(&self.inner, &mut g, &self.name, key, value, ttl)?;
}
self.inner.after_write()
}
pub fn remove(&self, key: &str) -> Result<bool> {
self.inner.ensure_writable()?;
let existed = {
let mut g = self.inner.write_store()?;
remove_from(&mut g, &self.name, key)
};
self.inner.after_write()?;
Ok(existed)
}
pub fn contains(&self, key: &str) -> Result<bool> {
let entry = {
let g = self.inner.read_store()?;
fetch(&g, &self.name, key)
};
match entry {
Some(e) => self.inner.is_live(&self.name, key, &e),
None => Ok(false),
}
}
pub fn len(&self) -> Result<usize> {
let mut n = 0;
for (k, e) in self.snapshot_entries(|_| true)? {
if self.inner.is_live(&self.name, &k, &e)? {
n += 1;
}
}
Ok(n)
}
pub fn is_empty(&self) -> Result<bool> {
Ok(self.len()? == 0)
}
pub fn update<V, F>(&self, key: &str, f: F) -> Result<()>
where
V: Serialize + DeserializeOwned,
F: FnOnce(Option<V>) -> Option<V>,
{
self.inner.ensure_writable()?;
{
let mut g = self.inner.write_store()?;
let current = self.load::<V>(&g, key)?;
match f(current) {
Some(v) => seal_into(&self.inner, &mut g, &self.name, key, &v, None)?,
None => {
remove_from(&mut g, &self.name, key);
}
}
}
self.inner.after_write()
}
pub fn get_or_insert_with<V, F>(&self, key: &str, f: F) -> Result<V>
where
V: Serialize + DeserializeOwned,
F: FnOnce() -> V,
{
self.inner.ensure_writable()?;
let (value, wrote) = {
let mut g = self.inner.write_store()?;
match self.load::<V>(&g, key)? {
Some(v) => (v, false),
None => {
let v = f();
seal_into(&self.inner, &mut g, &self.name, key, &v, None)?;
(v, true)
}
}
};
if wrote {
self.inner.after_write()?;
}
Ok(value)
}
pub fn compare_and_swap<V: Serialize + DeserializeOwned>(
&self,
key: &str,
expected: Option<&V>,
new: Option<&V>,
) -> Result<bool> {
self.inner.ensure_writable()?;
let swapped = {
let mut g = self.inner.write_store()?;
let current_bytes = match fetch(&g, &self.name, key) {
Some(e) => self.inner.open_entry(&self.name, key, &e)?,
None => None,
};
let expected_bytes = match expected {
Some(v) => Some(encode(v)?),
None => None,
};
if current_bytes == expected_bytes {
match new {
Some(v) => seal_into(&self.inner, &mut g, &self.name, key, v, None)?,
None => {
remove_from(&mut g, &self.name, key);
}
}
true
} else {
false
}
};
if swapped {
self.inner.after_write()?;
}
Ok(swapped)
}
pub fn keys(&self) -> Result<Vec<String>> {
let mut out = Vec::new();
for (k, e) in self.snapshot_entries(|_| true)? {
if self.inner.is_live(&self.name, &k, &e)? {
out.push(k);
}
}
Ok(out)
}
pub fn keys_sorted(&self) -> Result<Vec<String>> {
let mut keys = self.keys()?;
keys.sort();
Ok(keys)
}
pub fn prefix<V: DeserializeOwned>(&self, prefix: &str) -> Result<Vec<(String, V)>> {
let mut out = Vec::new();
for (k, e) in self.snapshot_entries(|key| key.starts_with(prefix))? {
if let Some(v) = self.inner.read_value::<V>(&self.name, &k, &e)? {
out.push((k, v));
}
}
Ok(out)
}
pub fn for_each<V, F>(&self, mut f: F) -> Result<()>
where
V: DeserializeOwned,
F: FnMut(&str, V) -> ControlFlow<()>,
{
for (k, e) in self.snapshot_entries(|_| true)? {
if let Some(v) = self.inner.read_value::<V>(&self.name, &k, &e)? {
if let ControlFlow::Break(()) = f(&k, v) {
break;
}
}
}
Ok(())
}
pub fn clear(&self) -> Result<()> {
self.inner.ensure_writable()?;
{
let mut g = self.inner.write_store()?;
if let Some(bucket) = g.get_mut(&self.name) {
bucket.clear();
}
}
self.inner.after_write()
}
fn load<V: DeserializeOwned>(&self, store: &Store, key: &str) -> Result<Option<V>> {
match fetch(store, &self.name, key) {
Some(e) => self.inner.read_value(&self.name, key, &e),
None => Ok(None),
}
}
fn snapshot_entries<P: Fn(&str) -> bool>(&self, pred: P) -> Result<Vec<(String, Entry)>> {
let g = self.inner.read_store()?;
Ok(g.get(&self.name)
.map(|b| {
b.iter()
.filter(|(k, _)| pred(k))
.map(|(k, e)| (k.clone(), e.clone()))
.collect()
})
.unwrap_or_default())
}
}