use std::{fmt::Debug, future::Future};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
#[cfg(with_testing)]
use crate::random::generate_test_namespace;
use crate::{batch::Batch, common::from_bytes_option, views::ViewError};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommonStoreInternalConfig {
pub max_concurrent_queries: Option<usize>,
pub max_stream_queries: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommonStoreConfig {
pub max_concurrent_queries: Option<usize>,
pub max_stream_queries: usize,
pub cache_size: usize,
}
impl CommonStoreConfig {
pub fn reduced(&self) -> CommonStoreInternalConfig {
CommonStoreInternalConfig {
max_concurrent_queries: self.max_concurrent_queries,
max_stream_queries: self.max_stream_queries,
}
}
}
impl Default for CommonStoreConfig {
fn default() -> Self {
CommonStoreConfig {
max_concurrent_queries: None,
max_stream_queries: 10,
cache_size: 1000,
}
}
}
pub trait KeyValueStoreError: std::error::Error + Debug + From<bcs::Error> {
const BACKEND: &'static str;
}
impl<E: KeyValueStoreError> From<E> for ViewError {
fn from(error: E) -> Self {
Self::StoreError {
backend: E::BACKEND.to_string(),
error: error.to_string(),
}
}
}
pub trait WithError {
type Error: KeyValueStoreError;
}
#[trait_variant::make(ReadableKeyValueStore: Send)]
pub trait LocalReadableKeyValueStore: WithError {
const MAX_KEY_SIZE: usize;
type Keys: KeyIterable<Self::Error>;
type KeyValues: KeyValueIterable<Self::Error>;
fn max_stream_queries(&self) -> usize;
async fn read_value_bytes(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error>;
async fn contains_key(&self, key: &[u8]) -> Result<bool, Self::Error>;
async fn contains_keys(&self, keys: Vec<Vec<u8>>) -> Result<Vec<bool>, Self::Error>;
async fn read_multi_values_bytes(
&self,
keys: Vec<Vec<u8>>,
) -> Result<Vec<Option<Vec<u8>>>, Self::Error>;
async fn find_keys_by_prefix(&self, key_prefix: &[u8]) -> Result<Self::Keys, Self::Error>;
async fn find_key_values_by_prefix(
&self,
key_prefix: &[u8],
) -> Result<Self::KeyValues, Self::Error>;
fn read_value<V: DeserializeOwned>(
&self,
key: &[u8],
) -> impl Future<Output = Result<Option<V>, Self::Error>>
where
Self: Sync,
{
async { from_bytes_option(&self.read_value_bytes(key).await?) }
}
fn read_multi_values<V: DeserializeOwned + Send>(
&self,
keys: Vec<Vec<u8>>,
) -> impl Future<Output = Result<Vec<Option<V>>, Self::Error>>
where
Self: Sync,
{
async {
let mut values = Vec::with_capacity(keys.len());
for entry in self.read_multi_values_bytes(keys).await? {
values.push(from_bytes_option::<_, bcs::Error>(&entry)?);
}
Ok(values)
}
}
}
#[trait_variant::make(WritableKeyValueStore: Send)]
pub trait LocalWritableKeyValueStore: WithError {
const MAX_VALUE_SIZE: usize;
async fn write_batch(&self, batch: Batch) -> Result<(), Self::Error>;
async fn clear_journal(&self) -> Result<(), Self::Error>;
}
#[trait_variant::make(AdminKeyValueStore: Send)]
pub trait LocalAdminKeyValueStore: WithError + Sized {
type Config: Send + Sync;
fn get_name() -> String;
async fn connect(
config: &Self::Config,
namespace: &str,
root_key: &[u8],
) -> Result<Self, Self::Error>;
fn clone_with_root_key(&self, root_key: &[u8]) -> Result<Self, Self::Error>;
async fn list_all(config: &Self::Config) -> Result<Vec<String>, Self::Error>;
async fn list_root_keys(
config: &Self::Config,
namespace: &str,
) -> Result<Vec<Vec<u8>>, Self::Error>;
fn delete_all(config: &Self::Config) -> impl Future<Output = Result<(), Self::Error>> {
async {
let namespaces = Self::list_all(config).await?;
for namespace in namespaces {
Self::delete(config, &namespace).await?;
}
Ok(())
}
}
async fn exists(config: &Self::Config, namespace: &str) -> Result<bool, Self::Error>;
async fn create(config: &Self::Config, namespace: &str) -> Result<(), Self::Error>;
async fn delete(config: &Self::Config, namespace: &str) -> Result<(), Self::Error>;
fn maybe_create_and_connect(
config: &Self::Config,
namespace: &str,
root_key: &[u8],
) -> impl Future<Output = Result<Self, Self::Error>> {
async {
if !Self::exists(config, namespace).await? {
Self::create(config, namespace).await?;
}
Self::connect(config, namespace, root_key).await
}
}
fn recreate_and_connect(
config: &Self::Config,
namespace: &str,
root_key: &[u8],
) -> impl Future<Output = Result<Self, Self::Error>> {
async {
if Self::exists(config, namespace).await? {
Self::delete(config, namespace).await?;
}
Self::create(config, namespace).await?;
Self::connect(config, namespace, root_key).await
}
}
}
pub trait RestrictedKeyValueStore: ReadableKeyValueStore + WritableKeyValueStore {}
impl<T> RestrictedKeyValueStore for T where T: ReadableKeyValueStore + WritableKeyValueStore {}
pub trait LocalRestrictedKeyValueStore:
LocalReadableKeyValueStore + LocalWritableKeyValueStore
{
}
impl<T> LocalRestrictedKeyValueStore for T where
T: LocalReadableKeyValueStore + LocalWritableKeyValueStore
{
}
pub trait KeyValueStore:
ReadableKeyValueStore + WritableKeyValueStore + AdminKeyValueStore
{
}
impl<T> KeyValueStore for T where
T: ReadableKeyValueStore + WritableKeyValueStore + AdminKeyValueStore
{
}
pub trait LocalKeyValueStore:
LocalReadableKeyValueStore + LocalWritableKeyValueStore + LocalAdminKeyValueStore
{
}
impl<T> LocalKeyValueStore for T where
T: LocalReadableKeyValueStore + LocalWritableKeyValueStore + LocalAdminKeyValueStore
{
}
#[cfg(with_testing)]
pub trait TestKeyValueStore: KeyValueStore {
fn new_test_config(
) -> impl std::future::Future<Output = Result<Self::Config, Self::Error>> + Send;
fn new_test_store() -> impl std::future::Future<Output = Result<Self, Self::Error>> + Send {
async {
let config = Self::new_test_config().await?;
let namespace = generate_test_namespace();
let root_key = &[];
Self::recreate_and_connect(&config, &namespace, root_key).await
}
}
}
#[doc(hidden)]
pub struct SimpleKeyIterator<'a, E> {
iter: std::slice::Iter<'a, Vec<u8>>,
_error_type: std::marker::PhantomData<E>,
}
impl<'a, E> Iterator for SimpleKeyIterator<'a, E> {
type Item = Result<&'a [u8], E>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|key| Result::Ok(key.as_ref()))
}
}
impl<E> KeyIterable<E> for Vec<Vec<u8>> {
type Iterator<'a> = SimpleKeyIterator<'a, E>;
fn iterator(&self) -> Self::Iterator<'_> {
SimpleKeyIterator {
iter: self.iter(),
_error_type: std::marker::PhantomData,
}
}
}
#[doc(hidden)]
pub struct SimpleKeyValueIterator<'a, E> {
iter: std::slice::Iter<'a, (Vec<u8>, Vec<u8>)>,
_error_type: std::marker::PhantomData<E>,
}
impl<'a, E> Iterator for SimpleKeyValueIterator<'a, E> {
type Item = Result<(&'a [u8], &'a [u8]), E>;
fn next(&mut self) -> Option<Self::Item> {
self.iter
.next()
.map(|entry| Ok((&entry.0[..], &entry.1[..])))
}
}
#[doc(hidden)]
pub struct SimpleKeyValueIteratorOwned<E> {
iter: std::vec::IntoIter<(Vec<u8>, Vec<u8>)>,
_error_type: std::marker::PhantomData<E>,
}
impl<E> Iterator for SimpleKeyValueIteratorOwned<E> {
type Item = Result<(Vec<u8>, Vec<u8>), E>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(Result::Ok)
}
}
impl<E> KeyValueIterable<E> for Vec<(Vec<u8>, Vec<u8>)> {
type Iterator<'a> = SimpleKeyValueIterator<'a, E>;
type IteratorOwned = SimpleKeyValueIteratorOwned<E>;
fn iterator(&self) -> Self::Iterator<'_> {
SimpleKeyValueIterator {
iter: self.iter(),
_error_type: std::marker::PhantomData,
}
}
fn into_iterator_owned(self) -> Self::IteratorOwned {
SimpleKeyValueIteratorOwned {
iter: self.into_iter(),
_error_type: std::marker::PhantomData,
}
}
}
pub trait KeyIterable<Error> {
type Iterator<'a>: Iterator<Item = Result<&'a [u8], Error>>
where
Self: 'a;
fn iterator(&self) -> Self::Iterator<'_>;
}
pub trait KeyValueIterable<Error> {
type Iterator<'a>: Iterator<Item = Result<(&'a [u8], &'a [u8]), Error>>
where
Self: 'a;
type IteratorOwned: Iterator<Item = Result<(Vec<u8>, Vec<u8>), Error>>;
fn iterator(&self) -> Self::Iterator<'_>;
fn into_iterator_owned(self) -> Self::IteratorOwned;
}