aboutsummaryrefslogtreecommitdiff
path: root/crates/salsa/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/salsa/src/lib.rs')
-rw-r--r--crates/salsa/src/lib.rs56
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
4use std::{ 4use std::{
5 sync::Arc, 5 sync::Arc,
6 collections::HashMap, 6 collections::{HashSet, HashMap},
7 cell::RefCell, 7 cell::RefCell,
8}; 8};
9use parking_lot::Mutex; 9use 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
210pub struct Invalidations {
211 types: HashSet<QueryTypeId>,
212 ids: Vec<QueryId>,
213}
214
215impl 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
201impl<T, D> Db<T, D> 232impl<T, D> Db<T, D>
202where 233where
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)]
234struct Gen(u64); 281struct Gen(u64);
282const INVALIDATED: Gen = Gen(!0);
235#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 283#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
236pub struct InputFingerprint(pub u64); 284pub struct InputFingerprint(pub u64);
237#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 285#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]