aboutsummaryrefslogtreecommitdiff
path: root/crates/salsa/src/lib.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-09-12 20:11:26 +0100
committerAleksey Kladov <[email protected]>2018-09-15 22:00:05 +0100
commitcecc7ad5b20e693cb8d962187bd83b9ac234de97 (patch)
tree4bb388adae050ba0457cb0ca3b2bfcc9af353871 /crates/salsa/src/lib.rs
parent8cf9c2719652d298006d51bc82a32908ab4e5335 (diff)
be generic over data
Diffstat (limited to 'crates/salsa/src/lib.rs')
-rw-r--r--crates/salsa/src/lib.rs91
1 files changed, 48 insertions, 43 deletions
diff --git a/crates/salsa/src/lib.rs b/crates/salsa/src/lib.rs
index 69c7b35fa..a54f2a06f 100644
--- a/crates/salsa/src/lib.rs
+++ b/crates/salsa/src/lib.rs
@@ -3,53 +3,52 @@ extern crate parking_lot;
3 3
4use std::{ 4use std::{
5 sync::Arc, 5 sync::Arc,
6 any::Any,
7 collections::HashMap, 6 collections::HashMap,
8 cell::RefCell, 7 cell::RefCell,
9}; 8};
10use parking_lot::Mutex; 9use parking_lot::Mutex;
11 10
12type GroundQueryFn<T> = fn(&T, &(Any + Send + Sync + 'static)) -> (Box<Any + Send + Sync + 'static>, OutputFingerprint); 11type GroundQueryFn<T, D> = fn(&T, &D) -> (D, OutputFingerprint);
13type QueryFn<T> = fn(&QueryCtx<T>, &(Any + Send + Sync + 'static)) -> (Box<Any + Send + Sync + 'static>, OutputFingerprint); 12type QueryFn<T, D> = fn(&QueryCtx<T, D>, &D) -> (D, OutputFingerprint);
14 13
15#[derive(Debug)] 14#[derive(Debug)]
16pub struct Db<T> { 15pub struct Db<T, D> {
17 db: Arc<DbState<T>>, 16 db: Arc<DbState<T, D>>,
18 query_config: Arc<QueryConfig<T>>, 17 query_config: Arc<QueryConfig<T, D>>,
19} 18}
20 19
21pub struct QueryConfig<T> { 20pub struct QueryConfig<T, D> {
22 ground_fn: HashMap<QueryTypeId, GroundQueryFn<T>>, 21 ground_fn: HashMap<QueryTypeId, GroundQueryFn<T, D>>,
23 query_fn: HashMap<QueryTypeId, QueryFn<T>>, 22 query_fn: HashMap<QueryTypeId, QueryFn<T, D>>,
24} 23}
25 24
26impl<T> ::std::fmt::Debug for QueryConfig<T> { 25impl<T, D> ::std::fmt::Debug for QueryConfig<T, D> {
27 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { 26 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
28 ::std::fmt::Display::fmt("QueryConfig { ... }", f) 27 ::std::fmt::Display::fmt("QueryConfig { ... }", f)
29 } 28 }
30} 29}
31 30
32#[derive(Debug)] 31#[derive(Debug)]
33struct DbState<T> { 32struct DbState<T, D> {
34 ground_data: T, 33 ground_data: T,
35 gen: Gen, 34 gen: Gen,
36 graph: Mutex<im::HashMap<QueryId, (Gen, Arc<QueryRecord>)>>, 35 graph: Mutex<im::HashMap<QueryId, (Gen, Arc<QueryRecord<D>>)>>,
37} 36}
38 37
39#[derive(Debug)] 38#[derive(Debug)]
40struct QueryRecord { 39struct QueryRecord<D> {
41 params: Arc<Any + Send + Sync + 'static>, 40 params: D,
42 output: Arc<Any + Send + Sync + 'static>, 41 output: D,
43 output_fingerprint: OutputFingerprint, 42 output_fingerprint: OutputFingerprint,
44 deps: Vec<(QueryId, OutputFingerprint)>, 43 deps: Vec<(QueryId, OutputFingerprint)>,
45} 44}
46 45
47impl<T> DbState<T> { 46impl<T, D> DbState<T, D> {
48 fn record( 47 fn record(
49 &self, 48 &self,
50 query_id: QueryId, 49 query_id: QueryId,
51 params: Arc<Any + Send + Sync + 'static>, 50 params: D,
52 output: Arc<Any + Send + Sync + 'static>, 51 output: D,
53 output_fingerprint: OutputFingerprint, 52 output_fingerprint: OutputFingerprint,
54 deps: Vec<(QueryId, OutputFingerprint)>, 53 deps: Vec<(QueryId, OutputFingerprint)>,
55 ) { 54 ) {
@@ -64,7 +63,7 @@ impl<T> DbState<T> {
64 } 63 }
65} 64}
66 65
67impl<T> QueryConfig<T> { 66impl<T, D> QueryConfig<T, D> {
68 pub fn new() -> Self { 67 pub fn new() -> Self {
69 QueryConfig { 68 QueryConfig {
70 ground_fn: HashMap::new(), 69 ground_fn: HashMap::new(),
@@ -74,7 +73,7 @@ impl<T> QueryConfig<T> {
74 pub fn with_ground_query( 73 pub fn with_ground_query(
75 mut self, 74 mut self,
76 query_type: QueryTypeId, 75 query_type: QueryTypeId,
77 query_fn: GroundQueryFn<T> 76 query_fn: GroundQueryFn<T, D>
78 ) -> Self { 77 ) -> Self {
79 let prev = self.ground_fn.insert(query_type, query_fn); 78 let prev = self.ground_fn.insert(query_type, query_fn);
80 assert!(prev.is_none()); 79 assert!(prev.is_none());
@@ -83,7 +82,7 @@ impl<T> QueryConfig<T> {
83 pub fn with_query( 82 pub fn with_query(
84 mut self, 83 mut self,
85 query_type: QueryTypeId, 84 query_type: QueryTypeId,
86 query_fn: QueryFn<T>, 85 query_fn: QueryFn<T, D>,
87 ) -> Self { 86 ) -> Self {
88 let prev = self.query_fn.insert(query_type, query_fn); 87 let prev = self.query_fn.insert(query_type, query_fn);
89 assert!(prev.is_none()); 88 assert!(prev.is_none());
@@ -91,15 +90,18 @@ impl<T> QueryConfig<T> {
91 } 90 }
92} 91}
93 92
94pub struct QueryCtx<T> { 93pub struct QueryCtx<T, D> {
95 db: Arc<DbState<T>>, 94 db: Arc<DbState<T, D>>,
96 query_config: Arc<QueryConfig<T>>, 95 query_config: Arc<QueryConfig<T, D>>,
97 stack: RefCell<Vec<Vec<(QueryId, OutputFingerprint)>>>, 96 stack: RefCell<Vec<Vec<(QueryId, OutputFingerprint)>>>,
98 executed: RefCell<Vec<QueryTypeId>>, 97 executed: RefCell<Vec<QueryTypeId>>,
99} 98}
100 99
101impl<T> QueryCtx<T> { 100impl<T, D> QueryCtx<T, D>
102 fn new(db: &Db<T>) -> QueryCtx<T> { 101where
102 D: Clone
103{
104 fn new(db: &Db<T, D>) -> QueryCtx<T, D> {
103 QueryCtx { 105 QueryCtx {
104 db: Arc::clone(&db.db), 106 db: Arc::clone(&db.db),
105 query_config: Arc::clone(&db.query_config), 107 query_config: Arc::clone(&db.query_config),
@@ -110,8 +112,8 @@ impl<T> QueryCtx<T> {
110 pub fn get( 112 pub fn get(
111 &self, 113 &self,
112 query_id: QueryId, 114 query_id: QueryId,
113 params: Arc<Any + Send + Sync + 'static>, 115 params: D,
114 ) -> Arc<Any + Send + Sync + 'static> { 116 ) -> D {
115 let (res, output_fingerprint) = self.get_inner(query_id, params); 117 let (res, output_fingerprint) = self.get_inner(query_id, params);
116 self.record_dep(query_id, output_fingerprint); 118 self.record_dep(query_id, output_fingerprint);
117 res 119 res
@@ -120,8 +122,8 @@ impl<T> QueryCtx<T> {
120 pub fn get_inner( 122 pub fn get_inner(
121 &self, 123 &self,
122 query_id: QueryId, 124 query_id: QueryId,
123 params: Arc<Any + Send + Sync + 'static>, 125 params: D,
124 ) -> (Arc<Any + Send + Sync + 'static>, OutputFingerprint) { 126 ) -> (D, OutputFingerprint) {
125 let (gen, record) = { 127 let (gen, record) = {
126 let guard = self.db.graph.lock(); 128 let guard = self.db.graph.lock();
127 match guard.get(&query_id).map(|it| it.clone()){ 129 match guard.get(&query_id).map(|it| it.clone()){
@@ -139,7 +141,7 @@ impl<T> QueryCtx<T> {
139 return self.force(query_id, params); 141 return self.force(query_id, params);
140 } 142 }
141 for (dep_query_id, prev_fingerprint) in record.deps.iter().cloned() { 143 for (dep_query_id, prev_fingerprint) in record.deps.iter().cloned() {
142 let dep_params: Arc<Any + Send + Sync + 'static> = { 144 let dep_params: D = {
143 let guard = self.db.graph.lock(); 145 let guard = self.db.graph.lock();
144 guard[&dep_query_id] 146 guard[&dep_query_id]
145 .1 147 .1
@@ -160,29 +162,29 @@ impl<T> QueryCtx<T> {
160 fn force( 162 fn force(
161 &self, 163 &self,
162 query_id: QueryId, 164 query_id: QueryId,
163 params: Arc<Any + Send + Sync + 'static>, 165 params: D,
164 ) -> (Arc<Any + Send + Sync + 'static>, OutputFingerprint) { 166 ) -> (D, OutputFingerprint) {
165 self.executed.borrow_mut().push(query_id.0); 167 self.executed.borrow_mut().push(query_id.0);
166 self.stack.borrow_mut().push(Vec::new()); 168 self.stack.borrow_mut().push(Vec::new());
167 169
168 let (res, output_fingerprint) = if let Some(f) = self.ground_query_fn_by_type(query_id.0) { 170 let (res, output_fingerprint) = if let Some(f) = self.ground_query_fn_by_type(query_id.0) {
169 f(&self.db.ground_data, &*params) 171 f(&self.db.ground_data, &params)
170 } else if let Some(f) = self.query_fn_by_type(query_id.0) { 172 } else if let Some(f) = self.query_fn_by_type(query_id.0) {
171 f(self, &*params) 173 f(self, &params)
172 } else { 174 } else {
173 panic!("unknown query type: {:?}", query_id.0); 175 panic!("unknown query type: {:?}", query_id.0);
174 }; 176 };
175 177
176 let res: Arc<Any + Send + Sync + 'static> = res.into(); 178 let res: D = res.into();
177 179
178 let deps = self.stack.borrow_mut().pop().unwrap(); 180 let deps = self.stack.borrow_mut().pop().unwrap();
179 self.db.record(query_id, params, res.clone(), output_fingerprint, deps); 181 self.db.record(query_id, params, res.clone(), output_fingerprint, deps);
180 (res, output_fingerprint) 182 (res, output_fingerprint)
181 } 183 }
182 fn ground_query_fn_by_type(&self, query_type: QueryTypeId) -> Option<GroundQueryFn<T>> { 184 fn ground_query_fn_by_type(&self, query_type: QueryTypeId) -> Option<GroundQueryFn<T, D>> {
183 self.query_config.ground_fn.get(&query_type).map(|&it| it) 185 self.query_config.ground_fn.get(&query_type).map(|&it| it)
184 } 186 }
185 fn query_fn_by_type(&self, query_type: QueryTypeId) -> Option<QueryFn<T>> { 187 fn query_fn_by_type(&self, query_type: QueryTypeId) -> Option<QueryFn<T, D>> {
186 self.query_config.query_fn.get(&query_type).map(|&it| it) 188 self.query_config.query_fn.get(&query_type).map(|&it| it)
187 } 189 }
188 fn record_dep( 190 fn record_dep(
@@ -196,15 +198,18 @@ impl<T> QueryCtx<T> {
196 } 198 }
197} 199}
198 200
199impl<T> Db<T> { 201impl<T, D> Db<T, D>
200 pub fn new(query_config: QueryConfig<T>, ground_data: T) -> Db<T> { 202where
203 D: Clone
204{
205 pub fn new(query_config: QueryConfig<T, D>, ground_data: T) -> Db<T, D> {
201 Db { 206 Db {
202 db: Arc::new(DbState { ground_data, gen: Gen(0), graph: Default::default() }), 207 db: Arc::new(DbState { ground_data, gen: Gen(0), graph: Default::default() }),
203 query_config: Arc::new(query_config), 208 query_config: Arc::new(query_config),
204 } 209 }
205 } 210 }
206 211
207 pub fn with_ground_data(&self, ground_data: T) -> Db<T> { 212 pub fn with_ground_data(&self, ground_data: T) -> Db<T, D> {
208 let gen = Gen(self.db.gen.0 + 1); 213 let gen = Gen(self.db.gen.0 + 1);
209 let graph = self.db.graph.lock().clone(); 214 let graph = self.db.graph.lock().clone();
210 let graph = Mutex::new(graph); 215 let graph = Mutex::new(graph);
@@ -216,8 +221,8 @@ impl<T> Db<T> {
216 pub fn get( 221 pub fn get(
217 &self, 222 &self,
218 query_id: QueryId, 223 query_id: QueryId,
219 params: Box<Any + Send + Sync + 'static>, 224 params: D,
220 ) -> (Arc<Any + Send + Sync + 'static>, Vec<QueryTypeId>) { 225 ) -> (D, Vec<QueryTypeId>) {
221 let ctx = QueryCtx::new(self); 226 let ctx = QueryCtx::new(self);
222 let res = ctx.get(query_id, params.into()); 227 let res = ctx.get(query_id, params.into());
223 let executed = ::std::mem::replace(&mut *ctx.executed.borrow_mut(), Vec::new()); 228 let executed = ::std::mem::replace(&mut *ctx.executed.borrow_mut(), Vec::new());