diff options
author | Aleksey Kladov <[email protected]> | 2018-09-12 20:30:48 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-09-15 22:00:05 +0100 |
commit | 60fdfec32759d5e006eae9fe09a87b1a28b19983 (patch) | |
tree | 1d92756db29c8bf4fcca33fdb2bb1b9041c53398 /crates/salsa/src | |
parent | cecc7ad5b20e693cb8d962187bd83b9ac234de97 (diff) |
eager invalidation
Diffstat (limited to 'crates/salsa/src')
-rw-r--r-- | crates/salsa/src/lib.rs | 56 |
1 files changed, 52 insertions, 4 deletions
diff --git a/crates/salsa/src/lib.rs b/crates/salsa/src/lib.rs index a54f2a06f..5de3c7774 100644 --- a/crates/salsa/src/lib.rs +++ b/crates/salsa/src/lib.rs | |||
@@ -3,7 +3,7 @@ extern crate parking_lot; | |||
3 | 3 | ||
4 | use std::{ | 4 | use std::{ |
5 | sync::Arc, | 5 | sync::Arc, |
6 | collections::HashMap, | 6 | collections::{HashSet, HashMap}, |
7 | cell::RefCell, | 7 | cell::RefCell, |
8 | }; | 8 | }; |
9 | use parking_lot::Mutex; | 9 | use parking_lot::Mutex; |
@@ -138,7 +138,16 @@ where | |||
138 | return (record.output.clone(), record.output_fingerprint) | 138 | return (record.output.clone(), record.output_fingerprint) |
139 | } | 139 | } |
140 | if self.query_config.ground_fn.contains_key(&query_id.0) { | 140 | if self.query_config.ground_fn.contains_key(&query_id.0) { |
141 | return self.force(query_id, params); | 141 | let (invalidated, record) = { |
142 | let guard = self.db.graph.lock(); | ||
143 | let (gen, ref record) = guard[&query_id]; | ||
144 | (gen == INVALIDATED, record.clone()) | ||
145 | }; | ||
146 | if invalidated { | ||
147 | return self.force(query_id, params); | ||
148 | } else { | ||
149 | return (record.output.clone(), record.output_fingerprint); | ||
150 | } | ||
142 | } | 151 | } |
143 | for (dep_query_id, prev_fingerprint) in record.deps.iter().cloned() { | 152 | for (dep_query_id, prev_fingerprint) in record.deps.iter().cloned() { |
144 | let dep_params: D = { | 153 | let dep_params: D = { |
@@ -198,6 +207,28 @@ where | |||
198 | } | 207 | } |
199 | } | 208 | } |
200 | 209 | ||
210 | pub struct Invalidations { | ||
211 | types: HashSet<QueryTypeId>, | ||
212 | ids: Vec<QueryId>, | ||
213 | } | ||
214 | |||
215 | impl Invalidations { | ||
216 | pub fn new() -> Invalidations { | ||
217 | Invalidations { | ||
218 | types: HashSet::new(), | ||
219 | ids: Vec::new(), | ||
220 | } | ||
221 | } | ||
222 | pub fn invalidate( | ||
223 | &mut self, | ||
224 | query_type: QueryTypeId, | ||
225 | params: impl Iterator<Item=InputFingerprint>, | ||
226 | ) { | ||
227 | self.types.insert(query_type); | ||
228 | self.ids.extend(params.map(|it| QueryId(query_type, it))) | ||
229 | } | ||
230 | } | ||
231 | |||
201 | impl<T, D> Db<T, D> | 232 | impl<T, D> Db<T, D> |
202 | where | 233 | where |
203 | D: Clone | 234 | D: Clone |
@@ -209,9 +240,25 @@ where | |||
209 | } | 240 | } |
210 | } | 241 | } |
211 | 242 | ||
212 | pub fn with_ground_data(&self, ground_data: T) -> Db<T, D> { | 243 | pub fn with_ground_data( |
244 | &self, | ||
245 | ground_data: T, | ||
246 | invalidations: Invalidations, | ||
247 | ) -> Db<T, D> { | ||
248 | for id in self.query_config.ground_fn.keys() { | ||
249 | assert!( | ||
250 | invalidations.types.contains(id), | ||
251 | "all ground queries must be invalidated" | ||
252 | ); | ||
253 | } | ||
254 | |||
213 | let gen = Gen(self.db.gen.0 + 1); | 255 | let gen = Gen(self.db.gen.0 + 1); |
214 | let graph = self.db.graph.lock().clone(); | 256 | let mut graph = self.db.graph.lock().clone(); |
257 | for id in invalidations.ids { | ||
258 | if let Some((gen, _)) = graph.get_mut(&id) { | ||
259 | *gen = INVALIDATED; | ||
260 | } | ||
261 | } | ||
215 | let graph = Mutex::new(graph); | 262 | let graph = Mutex::new(graph); |
216 | Db { | 263 | Db { |
217 | db: Arc::new(DbState { ground_data, gen, graph }), | 264 | db: Arc::new(DbState { ground_data, gen, graph }), |
@@ -232,6 +279,7 @@ where | |||
232 | 279 | ||
233 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 280 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
234 | struct Gen(u64); | 281 | struct Gen(u64); |
282 | const INVALIDATED: Gen = Gen(!0); | ||
235 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 283 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
236 | pub struct InputFingerprint(pub u64); | 284 | pub struct InputFingerprint(pub u64); |
237 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 285 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |