Skip to content

Commit

Permalink
Experiment with "owning memo"
Browse files Browse the repository at this point in the history
U cannot get this to work. It's close but I think it requires lifetime bounds on the HRTB lifetimes e.g. `F: for<'a, 'store: 'a> ...`, which currently isn't possible (seems to have been possible at one point? rust-lang/rust#50555 Could also be just that the syntax didn't result in an error, but had no semantic meaning attached to it.)
  • Loading branch information
RSSchermer committed Apr 6, 2022
1 parent 72fd009 commit 7e6e585
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 23 deletions.
16 changes: 8 additions & 8 deletions src/memo/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,21 @@ impl<C, S, T> CellMemo<C, S>
}
}

impl<C, S, T> Memo for CellMemo<C, S>
impl<C, S, T: 'static> Memo for CellMemo<C, S>
where
C: TypeConstructor,
S: for<'a, 'store> Fn(&'a C::Type<'store>, ReadContext<'store>) -> &'a VersionedCell<'store, T>
+ Clone,
{
type RootTC = C;
type Target<'store> = VersionedCell<'store, T>;
type Target<'a, 'store: 'a> = &'a VersionedCell<'store, T>;
type Selector = CellSelector<C, S>;

fn refresh<'a, 'store>(
fn refresh<'a, 'store: 'a>(
&mut self,
root: &'a C::Type<'store>,
cx: ReadContext<'store>,
) -> Refresh<&'a Self::Target<'store>> {
) -> Refresh<Self::Target<'a, 'store>> {
if cx.store_id() != self.store_id {
panic!("cannot resolve selector against different store")
}
Expand Down Expand Up @@ -75,19 +75,19 @@ pub struct CellSelector<C, S> {
_marker: marker::PhantomData<*const C>,
}

impl<C, S, T> Selector for CellSelector<C, S>
impl<C, S, T: 'static> Selector for CellSelector<C, S>
where
C: TypeConstructor,
S: for<'a, 'store> Fn(&'a C::Type<'store>, ReadContext<'store>) -> &'a VersionedCell<'store, T>,
{
type RootTC = C;
type Target<'store> = VersionedCell<'store, T>;
type Target<'a, 'store: 'a> = &'a VersionedCell<'store, T>;

fn select<'a, 'store>(
fn select<'a, 'store: 'a>(
&self,
root: &'a C::Type<'store>,
cx: ReadContext<'store>,
) -> &'a Self::Target<'store> {
) -> Self::Target<'a, 'store> {
(self.lens)(root, cx)
}
}
8 changes: 4 additions & 4 deletions src/memo/memo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ impl<T> Deref for Refresh<T> {
pub trait Memo {
type RootTC: TypeConstructor;

type Target<'store>;
type Target<'a, 'store: 'a>;

type Selector: for<'store> Selector<RootTC = Self::RootTC, Target<'store> = Self::Target<'store>>;
type Selector: Selector;

fn refresh<'a, 'store>(
fn refresh<'a, 'store: 'a>(
&mut self,
root: &'a <Self::RootTC as TypeConstructor>::Type<'store>,
cx: ReadContext<'store>,
) -> Refresh<&'a Self::Target<'store>>;
) -> Refresh<Self::Target<'a, 'store>>;

fn selector(&self) -> Self::Selector;
}
1 change: 1 addition & 0 deletions src/memo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub use self::selector::*;

pub mod cell;
pub mod node;
pub mod owned;

fn test() {
use futures::StreamExt;
Expand Down
12 changes: 6 additions & 6 deletions src/memo/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ impl<N, C, S> Memo for NodeMemo<N, C, S>
+ Clone,
{
type RootTC = C;
type Target<'store> = VersionedCell<'store, N::Type<'store>>;
type Target<'a, 'store: 'a> = &'a VersionedCell<'store, N::Type<'store>>;
type Selector = NodeSelector<N, C, S>;

fn refresh<'a, 'store>(
fn refresh<'a, 'store: 'a>(
&mut self,
root: &'a C::Type<'store>,
cx: ReadContext<'store>,
) -> Refresh<&'a Self::Target<'store>> {
) -> Refresh<Self::Target<'a, 'store>> {
if cx.store_id() != self.store_id {
panic!("cannot resolve selector against different store")
}
Expand Down Expand Up @@ -89,13 +89,13 @@ impl<N, C, S> Selector for NodeSelector<N, C, S>
S: for<'a, 'store> Fn(&'a C::Type<'store>, ReadContext<'store>) -> &'a VersionedCell<'store, N::Type<'store>>,
{
type RootTC = C;
type Target<'store> = VersionedCell<'store, N::Type<'store>>;
type Target<'a, 'store: 'a> = &'a VersionedCell<'store, N::Type<'store>>;

fn select<'a, 'store>(
fn select<'a, 'store: 'a>(
&self,
root: &'a C::Type<'store>,
cx: ReadContext<'store>,
) -> &'a Self::Target<'store> {
) -> Self::Target<'a, 'store> {
(self.lens)(root, cx)
}
}
89 changes: 89 additions & 0 deletions src/memo/owned.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use std::sync::atomic::AtomicU64;
use std::marker;
use crate::TypeConstructor;
use crate::store::{ReadContext, Store};
use crate::versioned_cell::VersionedCell;
use crate::memo::{Memo, Refresh, Selector};
use std::sync::atomic;

pub struct OwnedMemo<C, S, T> {
select: S,
store_id: u64,
last: T,
_marker: marker::PhantomData<*const C>,
}

impl<C, S, T> OwnedMemo<C, S, T>
where
C: TypeConstructor,
S: for<'a, 'store> Fn(&'a C::Type<'store>, ReadContext<'store>) -> T,
{
pub fn new(store: &Store<C>, select: S) -> Self {
let last = store.with(|root, cx| select(root, cx));

OwnedMemo {
select,
store_id: store.id(),
last,
_marker: marker::PhantomData,
}
}
}

// impl<C, S, T> Memo for OwnedMemo<C, S>
// where
// C: TypeConstructor,
// S: for<'a, 'store> Fn(&'a C::Type<'store>, ReadContext<'store>) -> &'a VersionedCell<'store, T>
// + Clone,
// {
// type RootTC = C;
// type Target<'store> = VersionedCell<'store, T>;
// type Selector = CellSelector<C, S>;
//
// fn refresh<'a, 'store>(
// &mut self,
// root: &'a C::Type<'store>,
// cx: ReadContext<'store>,
// ) -> Refresh<&'a Self::Target<'store>> {
// if cx.store_id() != self.store_id {
// panic!("cannot resolve selector against different store")
// }
//
// let cell = (self.select)(root, cx);
// let version = cell.version();
// let last_version = self.last_version;
//
// self.last_version = version;
//
// if version == last_version {
// Refresh::Unchanged(cell)
// } else {
// Refresh::Changed(cell)
// }
// }
//
// fn selector(&self) -> Self::Selector {
// CellSelector {
// lens: self.select.clone(),
// _marker: marker::PhantomData,
// }
// }
// }

pub struct OwnedSelector<C, T> {
value: T,
_marker: marker::PhantomData<*const C>
}

impl<C, T> Selector for OwnedSelector<C, T> where C: TypeConstructor, T: Clone {
type RootTC = C;
type Target<'a, 'store: 'a> = T;

fn select<'a, 'store: 'a>(
&self,
root: &'a C::Type<'store>,
cx: ReadContext<'store>,
) -> T {
self.value.clone()
}
}
6 changes: 3 additions & 3 deletions src/memo/selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ use crate::store::ReadContext;
pub trait Selector {
type RootTC: TypeConstructor;

type Target<'store>;
type Target<'a, 'store: 'a>;

fn select<'a, 'store>(
fn select<'a, 'store: 'a>(
&self,
root: &'a <Self::RootTC as TypeConstructor>::Type<'store>,
cx: ReadContext<'store>,
) -> &'a Self::Target<'store>;
) -> Self::Target<'a, 'store>;
}
4 changes: 2 additions & 2 deletions src/watcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl<C, S> View<C, S>
{
pub fn with<F, R>(&self, f: F) -> R
where
F: for<'store> FnOnce(&S::Target<'store>, ReadContext<'store>) -> R,
F: for<'a, 'store> FnOnce(S::Target<'a, 'store>, ReadContext<'store>) -> R,
{
self.store.with(|root, cx| f(self.selector.select(root, cx), cx))
}
Expand Down Expand Up @@ -157,7 +157,7 @@ impl<C, M0, M1> View2<C, M0, M1>
{
pub fn with<F, R>(&self, f: F) -> R
where
F: for<'store> FnOnce((&M0::Target<'store>, &M1::Target<'store>), ReadContext<'store>) -> R,
F: for<'a, 'store> FnOnce((M0::Target<'a, 'store>, M1::Target<'a, 'store>), ReadContext<'store>) -> R,
{
self.store.with(|root, cx| {
let selector_0 = self.selector_0.select(root, cx);
Expand Down

0 comments on commit 7e6e585

Please sign in to comment.