Skip to content

Commit 2418d70

Browse files
committed
Tidy up
1 parent 82aa013 commit 2418d70

File tree

6 files changed

+120
-105
lines changed

6 files changed

+120
-105
lines changed

macros/src/track.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,7 @@ pub fn expand(block: &syn::ItemImpl) -> Result<proc_macro2::TokenStream> {
5555
true #(&& #tracked_valids)*
5656
}
5757

58-
fn surface<'a, 'r>(tracked: &'r Tracked<'a, #ty>) -> &'r Surface<'a>
59-
where
60-
Self: Track,
61-
{
58+
fn surface<'a, 'r>(tracked: &'r Tracked<'a, #ty>) -> &'r Surface<'a> {
6259
// Safety: Surface is repr(transparent).
6360
unsafe { &*(tracked as *const _ as *const _) }
6461
}

src/cache.rs

Lines changed: 5 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use std::any::Any;
22
use std::cell::RefCell;
33
use std::fmt::Debug;
4-
use std::hash::{Hash, Hasher};
5-
use std::marker::PhantomData;
64

75
use siphasher::sip128::{Hasher128, SipHasher};
86

9-
use crate::track::{from_parts, to_parts, Track, Trackable, Tracked};
7+
use crate::input::Input;
8+
use crate::internal::Family;
109

1110
thread_local! {
1211
/// The global, dynamic cache shared by all memoized functions.
@@ -37,19 +36,19 @@ impl Cache {
3736
where
3837
In: Input,
3938
Out: Debug + Clone + 'static,
40-
F: for<'f> Fn(<In::Focus as Family<'f>>::Out) -> Out,
39+
F: for<'f> Fn(<In::Hooked as Family<'f>>::Out) -> Out,
4140
{
4241
// Compute the hash of the input's key part.
4342
let hash = {
4443
let mut state = SipHasher::new();
45-
input.hash(&mut state);
44+
input.key(&mut state);
4645
state.finish128().as_u128()
4746
};
4847

4948
let mut hit = true;
5049
let output = self.lookup::<In, Out>(hash, &input).unwrap_or_else(|| {
5150
let constraint = In::Constraint::default();
52-
let input = input.focus(&constraint);
51+
let input = input.hook_up(&constraint);
5352
let value = func(input);
5453
let constrained = Constrained { value: value.clone(), constraint };
5554
self.insert::<In, Out>(hash, constrained);
@@ -93,70 +92,3 @@ impl Cache {
9392
self.map.borrow_mut().push(entry);
9493
}
9594
}
96-
97-
pub trait Input {
98-
type Constraint: Default + 'static;
99-
type Focus: for<'f> Family<'f>;
100-
101-
fn hash<H: Hasher>(&self, state: &mut H);
102-
fn valid(&self, constraint: &Self::Constraint) -> bool;
103-
fn focus<'f>(
104-
self,
105-
constraint: &'f Self::Constraint,
106-
) -> <Self::Focus as Family<'f>>::Out
107-
where
108-
Self: 'f;
109-
}
110-
111-
impl<T: Hash> Input for T {
112-
type Constraint = ();
113-
type Focus = HashFamily<T>;
114-
115-
fn hash<H: Hasher>(&self, state: &mut H) {
116-
Hash::hash(self, state);
117-
}
118-
119-
fn valid(&self, _: &()) -> bool {
120-
true
121-
}
122-
123-
fn focus<'f>(self, _: &'f ()) -> Self
124-
where
125-
Self: 'f,
126-
{
127-
self
128-
}
129-
}
130-
131-
pub struct HashFamily<T>(PhantomData<T>);
132-
impl<T> Family<'_> for HashFamily<T> {
133-
type Out = T;
134-
}
135-
136-
impl<'a, T: Track> Input for Tracked<'a, T> {
137-
type Constraint = <T as Trackable>::Constraint;
138-
type Focus = TrackedFamily<T>;
139-
140-
fn hash<H: Hasher>(&self, _: &mut H) {}
141-
142-
fn valid(&self, constraint: &Self::Constraint) -> bool {
143-
Trackable::valid(to_parts(*self).0, constraint)
144-
}
145-
146-
fn focus<'f>(self, constraint: &'f Self::Constraint) -> Tracked<'f, T>
147-
where
148-
Self: 'f,
149-
{
150-
from_parts(to_parts(self).0, Some(constraint))
151-
}
152-
}
153-
154-
pub struct TrackedFamily<T>(PhantomData<T>);
155-
impl<'f, T: Track + 'f> Family<'f> for TrackedFamily<T> {
156-
type Out = Tracked<'f, T>;
157-
}
158-
159-
pub trait Family<'a> {
160-
/// The surface with lifetime.
161-
type Out;
162-
}

src/input.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use std::hash::{Hash, Hasher};
2+
use std::marker::PhantomData;
3+
4+
use crate::internal::Family;
5+
use crate::track::{from_parts, to_parts, Track, Trackable, Tracked};
6+
7+
/// An argument to a cached function.
8+
pub trait Input {
9+
/// Describes an instance of the argument.
10+
type Constraint: Default + 'static;
11+
12+
/// The argument with constraints hooked in.
13+
type Hooked: for<'f> Family<'f>;
14+
15+
/// Hash the argument if it is a _key_ argument
16+
fn key<H: Hasher>(&self, state: &mut H);
17+
18+
/// Validate the argument if it is a _tracked_ argument.
19+
fn valid(&self, constraint: &Self::Constraint) -> bool;
20+
21+
/// Hook up the given constraints if this is a _tracked_ argument.
22+
fn hook_up<'f>(
23+
self,
24+
constraint: &'f Self::Constraint,
25+
) -> <Self::Hooked as Family<'f>>::Out
26+
where
27+
Self: 'f;
28+
}
29+
30+
impl<T: Hash> Input for T {
31+
/// No constraint for hashed arguments.
32+
type Constraint = ();
33+
34+
/// The hooked-up type is just `Self`.
35+
type Hooked = IdFamily<Self>;
36+
37+
fn key<H: Hasher>(&self, state: &mut H) {
38+
Hash::hash(self, state);
39+
}
40+
41+
fn valid(&self, _: &()) -> bool {
42+
true
43+
}
44+
45+
fn hook_up<'f>(self, _: &'f ()) -> Self
46+
where
47+
Self: 'f,
48+
{
49+
self
50+
}
51+
}
52+
53+
impl<'a, T: Track> Input for Tracked<'a, T> {
54+
/// Forwarded constraint from Trackable implementation.
55+
type Constraint = <T as Trackable>::Constraint;
56+
57+
/// The hooked-up type is `Tracked<'f, T>`.
58+
type Hooked = TrackedFamily<T>;
59+
60+
fn key<H: Hasher>(&self, _: &mut H) {}
61+
62+
fn valid(&self, constraint: &Self::Constraint) -> bool {
63+
Trackable::valid(to_parts(*self).0, constraint)
64+
}
65+
66+
fn hook_up<'f>(self, constraint: &'f Self::Constraint) -> Tracked<'f, T>
67+
where
68+
Self: 'f,
69+
{
70+
from_parts(to_parts(self).0, Some(constraint))
71+
}
72+
}
73+
74+
/// Identity type constructor.
75+
pub struct IdFamily<T>(PhantomData<T>);
76+
77+
impl<T> Family<'_> for IdFamily<T> {
78+
type Out = T;
79+
}
80+
81+
/// 'f -> Tracked<'f, T> type constructor.
82+
pub struct TrackedFamily<T>(PhantomData<T>);
83+
84+
impl<'f, T: Track + 'f> Family<'f> for TrackedFamily<T> {
85+
type Out = Tracked<'f, T>;
86+
}

src/lib.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
mod cache;
44
mod hash;
5+
mod input;
56
mod track;
67

78
pub use crate::track::{Track, Tracked};
@@ -12,5 +13,11 @@ pub use comemo_macros::{memoize, track};
1213
pub mod internal {
1314
pub use crate::cache::CACHE;
1415
pub use crate::hash::HashConstraint;
15-
pub use crate::track::{from_parts, to_parts, Family, Trackable};
16+
pub use crate::track::{from_parts, to_parts, Trackable};
17+
18+
/// Helper trait for lifetime type families.
19+
pub trait Family<'a> {
20+
/// The concrete type with lifetime 'a.
21+
type Out;
22+
}
1623
}

src/main.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,7 @@ const _: () = {
5555
&& constraint.height.valid(&self.height())
5656
}
5757

58-
fn surface<'a, 'r>(tracked: &'r Tracked<'a, Image>) -> &'r Surface<'a>
59-
where
60-
Self: Track,
61-
{
58+
fn surface<'a, 'r>(tracked: &'r Tracked<'a, Image>) -> &'r Surface<'a> {
6259
// Safety: Surface is repr(transparent).
6360
unsafe { &*(tracked as *const _ as *const _) }
6461
}

src/track.rs

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::ops::Deref;
22

3+
use crate::internal::Family;
4+
35
/// Tracks accesses to a value.
46
///
57
/// Encapsulates a reference to a value and tracks all accesses to it. The only
@@ -44,25 +46,6 @@ where
4446
}
4547
}
4648

47-
/// Destructure a `Tracked<_>` into its parts.
48-
pub fn to_parts<T>(tracked: Tracked<T>) -> (&T, Option<&T::Constraint>)
49-
where
50-
T: Track,
51-
{
52-
(tracked.inner, tracked.constraint)
53-
}
54-
55-
/// Create a `Tracked<_>` from its parts.
56-
pub fn from_parts<'a, T>(
57-
inner: &'a T,
58-
constraint: Option<&'a T::Constraint>,
59-
) -> Tracked<'a, T>
60-
where
61-
T: Track,
62-
{
63-
Tracked { inner, constraint }
64-
}
65-
6649
/// A trackable type.
6750
///
6851
/// This is implemented by types that have an implementation block annoted with
@@ -93,8 +76,21 @@ pub trait Trackable: 'static {
9376
Self: Track;
9477
}
9578

96-
/// Workaround for Surface<'a> until GATs are stable.
97-
pub trait Family<'a> {
98-
/// The surface with lifetime.
99-
type Out;
79+
/// Destructure a `Tracked<_>` into its parts.
80+
pub fn to_parts<T>(tracked: Tracked<T>) -> (&T, Option<&T::Constraint>)
81+
where
82+
T: Track,
83+
{
84+
(tracked.inner, tracked.constraint)
85+
}
86+
87+
/// Create a `Tracked<_>` from its parts.
88+
pub fn from_parts<'a, T>(
89+
inner: &'a T,
90+
constraint: Option<&'a T::Constraint>,
91+
) -> Tracked<'a, T>
92+
where
93+
T: Track,
94+
{
95+
Tracked { inner, constraint }
10096
}

0 commit comments

Comments
 (0)