Skip to content

Commit

Permalink
Merge branch 'miraclx/revamp-store' into miraclx/store/bump-node
Browse files Browse the repository at this point in the history
  • Loading branch information
miraclx committed Jun 26, 2024
2 parents 4e2f160 + a4def77 commit cad88db
Show file tree
Hide file tree
Showing 13 changed files with 324 additions and 34 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/store/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ repository.workspace = true
license.workspace = true

[dependencies]
borsh = { workspace = true, features = ["derive"] }
camino.workspace = true
eyre.workspace = true
generic-array.workspace = true
rocksdb.workspace = true
strum = { workspace = true, features = ["derive"] }
thiserror.workspace = true

calimero-primitives = { path = "../primitives" }
16 changes: 16 additions & 0 deletions crates/store/src/entry.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use crate::key::AsKeyParts;
use crate::slice::Slice;

pub trait DataType: Sized {
type Error;

fn from_slice(slice: Slice) -> Result<Self, Self::Error>;
fn as_slice(&self) -> Result<Slice, Self::Error>;
}

pub trait Entry {
type Key: AsKeyParts;
type DataType: DataType;

fn key(&self) -> &Self::Key;
}
85 changes: 85 additions & 0 deletions crates/store/src/handle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use thiserror::Error;

use crate::entry::{DataType, Entry};
use crate::iter::{Iter, Structured};
use crate::key::FromKeyParts;
use crate::layer::{read_only, temporal, Layer, ReadLayer, WriteLayer};
use crate::Store;

pub struct StoreHandle<L = Store> {
pub(crate) inner: L,
}

impl<L: Layer> StoreHandle<L> {
pub fn new(inner: L) -> Self {
Self { inner }
}

pub fn into_inner(self) -> L {
self.inner
}
}

impl<'k, L: ReadLayer<'k>> StoreHandle<L> {
pub fn read_only(&'k self) -> read_only::ReadOnly<'k, L> {
read_only::ReadOnly::new(&self.inner)
}
}

impl<'base, 'k, 'v, L: WriteLayer<'k, 'v>> StoreHandle<L> {
pub fn temporal(&'base mut self) -> temporal::Temporal<'base, 'k, 'v, L> {
temporal::Temporal::new(&mut self.inner)
}
}

#[derive(Debug, Error)]
pub enum Error<E: DataType> {
LayerError(eyre::Report),
CodecError(E::Error),
}

impl<E: DataType> From<eyre::Report> for Error<E> {
fn from(err: eyre::Report) -> Self {
Self::LayerError(err)
}
}

impl<'k, L: ReadLayer<'k>> StoreHandle<L> {
pub fn has<E: Entry>(&self, entry: &'k E) -> Result<bool, Error<E::DataType>> {
Ok(self.inner.has(entry.key())?)
}

pub fn get<E: Entry>(&self, entry: &'k E) -> Result<Option<E::DataType>, Error<E::DataType>> {
match self.inner.get(entry.key())? {
Some(value) => Ok(Some(
E::DataType::from_slice(value).map_err(Error::CodecError)?,
)),
None => Ok(None),
}
}

pub fn iter<E: Entry<Key: FromKeyParts>>(
&'k self,
start: &'k E,
) -> Result<Iter<Structured<E::Key>, Structured<E::DataType>>, Error<E::DataType>> {
Ok(self.inner.iter(start.key())?.structured_value())
}
}

impl<'k, 'v, L: WriteLayer<'k, 'v>> StoreHandle<L> {
pub fn put<E: Entry>(
&mut self,
entry: &'k E,
value: &'v E::DataType,
) -> Result<(), Error<E::DataType>> {
self.inner
.put(entry.key(), value.as_slice().map_err(Error::CodecError)?)
.map_err(Error::LayerError)
}

pub fn delete<E: Entry>(&mut self, entry: &'k E) -> Result<(), Error<E::DataType>> {
self.inner.delete(entry.key()).map_err(Error::LayerError)
}
}

// todo! experiment with restoring {Read,Write}Layer for StoreHandle
76 changes: 54 additions & 22 deletions crates/store/src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ use std::marker::PhantomData;

use calimero_primitives::reflect::Reflect;

use crate::entry::DataType;
use crate::key::{FromKeyParts, Key as KeyCore}; // rename key here to KeyBuf
use crate::slice::Slice;

#[derive(Debug)]
pub struct Iter<'a, K = Unstructured> {
pub struct Iter<'a, K = Unstructured, V = Unstructured> {
inner: Box<dyn DBIter + 'a>,
_priv: PhantomData<K>,
_priv: PhantomData<(K, V)>,
}

pub trait DBIter {
Expand All @@ -23,33 +24,45 @@ impl<'a> fmt::Debug for dyn DBIter + 'a {
}
}

impl<'a, K> Iter<'a, K> {
impl<'a, K, V> Iter<'a, K, V> {
pub fn new<T: DBIter + 'a>(inner: T) -> Self {
Self {
inner: Box::new(inner),
_priv: PhantomData,
}
}

pub fn keys(&mut self) -> IterKeys<'_, 'a, K> {
pub fn keys(&mut self) -> IterKeys<'_, 'a, K, V> {
IterKeys { iter: self }
}

pub fn entries(&mut self) -> IterEntries<'_, 'a, K> {
pub fn entries(&mut self) -> IterEntries<'_, 'a, K, V> {
IterEntries { iter: self }
}
}

impl<'a> Iter<'a, Unstructured> {
pub fn structured<K: FromKeyParts>(self) -> Iter<'a, Structured<K>> {
impl<'a, V> Iter<'a, Unstructured, V> {
pub fn structured_key<K: FromKeyParts>(self) -> Iter<'a, Structured<K>, V> {
Iter {
inner: self.inner,
_priv: PhantomData,
}
}
}

impl<'a, K> Iter<'a, K, Unstructured> {
pub fn structured_value<V: DataType>(self) -> Iter<'a, K, Structured<V>> {
Iter {
inner: self.inner,
_priv: PhantomData,
}
}
}

impl<'a, K> DBIter for Iter<'a, K> {
type Key<'a> = Slice<'a>;
type Value<'a> = Slice<'a>;

impl<'a, K> DBIter for Iter<'a, K, Unstructured> {
fn next(&mut self) -> eyre::Result<Option<Key>> {
self.inner.next()
}
Expand All @@ -59,13 +72,11 @@ impl<'a, K> DBIter for Iter<'a, K> {
}
}

pub struct IterKeys<'a, 'b, K> {
iter: &'a mut Iter<'b, K>,
pub struct IterKeys<'a, 'b, K, V> {
iter: &'a mut Iter<'b, K, V>,
}

type Key<'a> = Slice<'a>;

impl<'a, 'b, K: TryIntoKey<'a>> Iterator for IterKeys<'a, 'b, K> {
impl<'a, 'b, K: TryIntoKey<'a>, V> Iterator for IterKeys<'a, 'b, K, V> {
type Item = K::Key;

fn next(&mut self) -> Option<Self::Item> {
Expand All @@ -78,16 +89,12 @@ impl<'a, 'b, K: TryIntoKey<'a>> Iterator for IterKeys<'a, 'b, K> {
}
}

pub struct IterEntries<'a, 'b, K> {
iter: &'a mut Iter<'b, K>,
pub struct IterEntries<'a, 'b, K, V> {
iter: &'a mut Iter<'b, K, V>,
}

type Value<'a> = Slice<'a>;

type Entry<'a, K> = (K, Value<'a>);

impl<'a, 'b, K: TryIntoKey<'a>> Iterator for IterEntries<'a, 'b, K> {
type Item = Entry<'a, K::Key>;
impl<'a, 'b, K: TryIntoKey<'a>, V: TryIntoValue<'a>> Iterator for IterEntries<'a, 'b, K, V> {
type Item = (K::Key, V::Value);

fn next(&mut self) -> Option<Self::Item> {
let key = {
Expand All @@ -104,7 +111,7 @@ impl<'a, 'b, K: TryIntoKey<'a>> Iterator for IterEntries<'a, 'b, K> {
unsafe { std::mem::transmute(value) }
};

Some((K::try_into_key(key).ok()?, value))
Some((K::try_into_key(key).ok()?, V::try_into_value(value).ok()?))
}
}

Expand All @@ -127,6 +134,13 @@ pub trait TryIntoKey<'a>: private::Sealed {
fn try_into_key(key: Key<'a>) -> Result<Self::Key, Self::Error>;
}

pub trait TryIntoValue<'a>: private::Sealed {
type Value;
type Error;

fn try_into_value(key: Value<'a>) -> Result<Self::Value, Self::Error>;
}

pub enum Error<E> {
SizeMismatch,
Structured(E),
Expand All @@ -144,6 +158,15 @@ impl<'a, K: FromKeyParts> TryIntoKey<'a> for Structured<K> {
}
}

impl<'a, V: DataType> TryIntoValue<'a> for Structured<V> {
type Value = V;
type Error = Error<V::Error>;

fn try_into_value(value: Value<'a>) -> Result<Self::Value, Self::Error> {
V::from_slice(value).map_err(Error::Structured)
}
}

impl private::Sealed for Unstructured {}
impl<'a> TryIntoKey<'a> for Unstructured {
type Key = Key<'a>;
Expand All @@ -154,6 +177,15 @@ impl<'a> TryIntoKey<'a> for Unstructured {
}
}

impl<'a> TryIntoValue<'a> for Unstructured {
type Value = Value<'a>;
type Error = ();

fn try_into_value(value: Value<'a>) -> Result<Self::Value, Self::Error> {
Ok(value)
}
}

pub struct IterPair<A, B>(pub A, pub B);

impl<A, B> DBIter for IterPair<A, B>
Expand Down
9 changes: 5 additions & 4 deletions crates/store/src/key/context.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::convert::Infallible;
use std::fmt;

use generic_array::sequence::Concat;
Expand Down Expand Up @@ -36,7 +37,7 @@ impl AsKeyParts for ContextMeta {
}

impl FromKeyParts for ContextMeta {
type Error = ();
type Error = Infallible;

fn try_from_parts(parts: Key<Self::Components>) -> Result<Self, Self::Error> {
Ok(Self(*<&_>::from(&parts)))
Expand Down Expand Up @@ -93,7 +94,7 @@ impl AsKeyParts for ContextIdentity {
}

impl FromKeyParts for ContextIdentity {
type Error = ();
type Error = Infallible;

fn try_from_parts(parts: Key<Self::Components>) -> Result<Self, Self::Error> {
Ok(Self(parts))
Expand Down Expand Up @@ -149,7 +150,7 @@ impl AsKeyParts for ContextState {
}

impl FromKeyParts for ContextState {
type Error = ();
type Error = Infallible;

fn try_from_parts(parts: Key<Self::Components>) -> Result<Self, Self::Error> {
Ok(Self(parts))
Expand Down Expand Up @@ -210,7 +211,7 @@ impl AsKeyParts for ContextTransaction {
}

impl FromKeyParts for ContextTransaction {
type Error = ();
type Error = Infallible;

fn try_from_parts(parts: Key<Self::Components>) -> Result<Self, Self::Error> {
Ok(Self(parts))
Expand Down
19 changes: 15 additions & 4 deletions crates/store/src/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::iter::{Iter, Structured};
use crate::key::{AsKeyParts, FromKeyParts};
use crate::slice::Slice;
use crate::tx::Transaction;
use crate::{Store, StoreHandle};

// todo!
// mod cache;
Expand All @@ -28,11 +29,21 @@ pub trait WriteLayer<'k, 'v>: ReadLayer<'k> {
fn commit(self) -> eyre::Result<()>;
}

impl Layer for crate::Store {
pub trait LayerExt: Sized {
fn handle(self) -> StoreHandle<Self>;
}

impl<L: Layer> LayerExt for L {
fn handle(self) -> StoreHandle<Self> {
StoreHandle::new(self)
}
}

impl Layer for Store {
type Base = Self;
}

impl<'k> ReadLayer<'k> for crate::Store {
impl<'k> ReadLayer<'k> for Store {
fn has(&self, key: &impl AsKeyParts) -> eyre::Result<bool> {
let (col, key) = key.parts();

Expand All @@ -48,11 +59,11 @@ impl<'k> ReadLayer<'k> for crate::Store {
fn iter<K: AsKeyParts + FromKeyParts>(&self, start: &K) -> eyre::Result<Iter<Structured<K>>> {
let (col, key) = start.parts();

Ok(self.db.iter(col, key.as_slice())?.structured())
Ok(self.db.iter(col, key.as_slice())?.structured_key())
}
}

impl<'k, 'v> WriteLayer<'k, 'v> for crate::Store {
impl<'k, 'v> WriteLayer<'k, 'v> for Store {
fn put(&mut self, key: &'k impl AsKeyParts, value: Slice<'v>) -> eyre::Result<()> {
let (col, key) = key.parts();

Expand Down
6 changes: 4 additions & 2 deletions crates/store/src/layer/experiments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ mod layer {
impl private::Sealed for Interior {}
impl Discriminant for Interior {
type Ref<'a, T> = &'a T
where T: ?Sized + 'a;
where
T: ?Sized + 'a;
}

impl private::Sealed for Identity {}
impl Discriminant for Identity {
type Ref<'a, T> = &'a mut T
where T: ?Sized + 'a;
where
T: ?Sized + 'a;
}

pub trait WriteLayer<D: Discriminant> {
Expand Down
Loading

0 comments on commit cad88db

Please sign in to comment.