mirror of
https://github.com/salsa-rs/salsa.git
synced 2024-10-23 12:49:57 +00:00
track the "changed at" revision for every query read as well
This commit is contained in:
parent
436d4d5084
commit
5849af83ac
4 changed files with 43 additions and 30 deletions
|
@ -82,12 +82,11 @@ where
|
|||
key: &Q::Key,
|
||||
descriptor: &QC::QueryDescriptor,
|
||||
) -> Result<Q::Value, CycleDetected> {
|
||||
let StampedValue {
|
||||
value,
|
||||
changed_at: _,
|
||||
} = self.read(query, key, &descriptor)?;
|
||||
let StampedValue { value, changed_at } = self.read(query, key, &descriptor)?;
|
||||
|
||||
query.salsa_runtime().report_query_read(descriptor);
|
||||
query
|
||||
.salsa_runtime()
|
||||
.report_query_read(descriptor, changed_at);
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ where
|
|||
|
||||
// Query was not previously executed or value is potentially
|
||||
// stale. Let's execute!
|
||||
let (value, inputs) = query
|
||||
let (mut stamped_value, inputs) = query
|
||||
.salsa_runtime()
|
||||
.execute_query_implementation::<Q>(query, descriptor, key);
|
||||
|
||||
|
@ -173,10 +173,10 @@ where
|
|||
// really change, even if some of its inputs have. So we can
|
||||
// "backdate" its `changed_at` revision to be the same as the
|
||||
// old value.
|
||||
let mut changed_at = revision_now;
|
||||
if let Some(QueryState::Memoized(old_memo)) = &old_value {
|
||||
if old_memo.stamped_value.value == value {
|
||||
changed_at = old_memo.stamped_value.changed_at;
|
||||
if old_memo.stamped_value.value == stamped_value.value {
|
||||
assert!(old_memo.stamped_value.changed_at <= stamped_value.changed_at);
|
||||
stamped_value.changed_at = old_memo.stamped_value.changed_at;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,10 +186,7 @@ where
|
|||
let old_value = map_write.insert(
|
||||
key.clone(),
|
||||
QueryState::Memoized(Memo {
|
||||
stamped_value: StampedValue {
|
||||
value: value.clone(),
|
||||
changed_at,
|
||||
},
|
||||
stamped_value: stamped_value.clone(),
|
||||
inputs,
|
||||
verified_at: revision_now,
|
||||
}),
|
||||
|
@ -203,7 +200,7 @@ where
|
|||
);
|
||||
}
|
||||
|
||||
Ok(StampedValue { value, changed_at })
|
||||
Ok(stamped_value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,12 +215,11 @@ where
|
|||
key: &Q::Key,
|
||||
descriptor: &QC::QueryDescriptor,
|
||||
) -> Result<Q::Value, CycleDetected> {
|
||||
let StampedValue {
|
||||
value,
|
||||
changed_at: _,
|
||||
} = self.read(query, key, &descriptor)?;
|
||||
let StampedValue { value, changed_at } = self.read(query, key, &descriptor)?;
|
||||
|
||||
query.salsa_runtime().report_query_read(descriptor);
|
||||
query
|
||||
.salsa_runtime()
|
||||
.report_query_read(descriptor, changed_at);
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ where
|
|||
query: &QC,
|
||||
descriptor: &QC::QueryDescriptor,
|
||||
key: &Q::Key,
|
||||
) -> (Q::Value, QueryDescriptorSet<QC>)
|
||||
) -> (StampedValue<Q::Value>, QueryDescriptorSet<QC>)
|
||||
where
|
||||
Q: Query<QC>,
|
||||
{
|
||||
|
@ -111,7 +111,11 @@ where
|
|||
let value = Q::execute(query, key.clone());
|
||||
|
||||
// Extract accumulated inputs.
|
||||
let ActiveQuery { subqueries, .. } = {
|
||||
let ActiveQuery {
|
||||
subqueries,
|
||||
changed_at,
|
||||
..
|
||||
} = {
|
||||
let mut local_state = self.local_state.borrow_mut();
|
||||
|
||||
// Sanity check: pushes and pops should be balanced.
|
||||
|
@ -120,7 +124,7 @@ where
|
|||
local_state.query_stack.pop().unwrap()
|
||||
};
|
||||
|
||||
(value, subqueries)
|
||||
(StampedValue { value, changed_at }, subqueries)
|
||||
}
|
||||
|
||||
/// Reports that the currently active query read the result from
|
||||
|
@ -131,9 +135,9 @@ where
|
|||
/// - `descriptor`: the query whose result was read
|
||||
/// - `changed_revision`: the last revision in which the result of that
|
||||
/// query had changed
|
||||
crate fn report_query_read(&self, descriptor: &QC::QueryDescriptor) {
|
||||
crate fn report_query_read(&self, descriptor: &QC::QueryDescriptor, changed_at: Revision) {
|
||||
if let Some(top_query) = self.local_state.borrow_mut().query_stack.last_mut() {
|
||||
top_query.add_read(descriptor);
|
||||
top_query.add_read(descriptor, changed_at);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,6 +176,9 @@ struct ActiveQuery<QC: QueryContext> {
|
|||
/// What query is executing
|
||||
descriptor: QC::QueryDescriptor,
|
||||
|
||||
/// Records the maximum revision where any subquery changed
|
||||
changed_at: Revision,
|
||||
|
||||
/// Each subquery
|
||||
subqueries: QueryDescriptorSet<QC>,
|
||||
}
|
||||
|
@ -180,12 +187,14 @@ impl<QC: QueryContext> ActiveQuery<QC> {
|
|||
fn new(descriptor: QC::QueryDescriptor) -> Self {
|
||||
ActiveQuery {
|
||||
descriptor,
|
||||
changed_at: Revision::ZERO,
|
||||
subqueries: QueryDescriptorSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_read(&mut self, subquery: &QC::QueryDescriptor) {
|
||||
fn add_read(&mut self, subquery: &QC::QueryDescriptor, changed_at: Revision) {
|
||||
self.subqueries.insert(subquery.clone());
|
||||
self.changed_at = self.changed_at.max(changed_at);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::runtime::Revision;
|
||||
use crate::runtime::StampedValue;
|
||||
use crate::CycleDetected;
|
||||
use crate::Query;
|
||||
use crate::QueryContext;
|
||||
|
@ -54,16 +55,24 @@ where
|
|||
return Err(CycleDetected);
|
||||
}
|
||||
|
||||
// FIXME: Should we even call `execute_query_implementation`
|
||||
// here? Or should we just call `Q::execute`, and maybe
|
||||
// separate out the `push`/`pop` operations.
|
||||
let (value, _inputs) = query
|
||||
let (
|
||||
StampedValue {
|
||||
value,
|
||||
changed_at: _,
|
||||
},
|
||||
_inputs,
|
||||
) = query
|
||||
.salsa_runtime()
|
||||
.execute_query_implementation::<Q>(query, descriptor, key);
|
||||
|
||||
let was_in_progress = self.in_progress.lock().remove(key);
|
||||
assert!(was_in_progress);
|
||||
|
||||
query.salsa_runtime().report_query_read(descriptor);
|
||||
let revision_now = query.salsa_runtime().current_revision();
|
||||
|
||||
query
|
||||
.salsa_runtime()
|
||||
.report_query_read(descriptor, revision_now);
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue