mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-01-29 15:49:13 +00:00
distinguish no-value from not computed at all
In the case of no-value, we track the revision where the value was last changed, which will be useful for maybe-changed-since.
This commit is contained in:
parent
e7a8abc648
commit
91ed93a4d4
1 changed files with 28 additions and 6 deletions
|
@ -94,10 +94,27 @@ pub(super) enum MemoInputs {
|
|||
|
||||
/// Return value of `probe` helper.
|
||||
enum ProbeState<V, G> {
|
||||
UpToDate(Result<V, CycleError>),
|
||||
/// Another thread was active but has completed.
|
||||
/// Try again!
|
||||
Retry,
|
||||
|
||||
/// No entry for this key at all.
|
||||
NotComputed(G),
|
||||
|
||||
/// There is an entry, but its contents have not been
|
||||
/// verified in this revision.
|
||||
Stale(G),
|
||||
Absent(G),
|
||||
|
||||
/// There is an entry, and it has been verified
|
||||
/// in this revision, but it has no cached
|
||||
/// value. The `Revision` is the revision where the
|
||||
/// value last changed (if we were to recompute it).
|
||||
NoValue(G, Revision),
|
||||
|
||||
/// There is an entry which has been verified,
|
||||
/// and it has the following value-- or, we blocked
|
||||
/// on another thread, and that resulted in a cycle.
|
||||
UpToDate(Result<V, CycleError>),
|
||||
}
|
||||
|
||||
impl<Q, MP> Slot<Q, MP>
|
||||
|
@ -138,7 +155,9 @@ where
|
|||
loop {
|
||||
match self.probe(db, self.state.read(), runtime, revision_now) {
|
||||
ProbeState::UpToDate(v) => return v,
|
||||
ProbeState::Stale(_) | ProbeState::Absent(_) => break,
|
||||
ProbeState::Stale(..) | ProbeState::NoValue(..) | ProbeState::NotComputed(..) => {
|
||||
break
|
||||
}
|
||||
ProbeState::Retry => continue,
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +184,9 @@ where
|
|||
let old_memo = loop {
|
||||
match self.probe(db, self.state.upgradable_read(), runtime, revision_now) {
|
||||
ProbeState::UpToDate(v) => return v,
|
||||
ProbeState::Stale(state) | ProbeState::Absent(state) => {
|
||||
ProbeState::Stale(state)
|
||||
| ProbeState::NotComputed(state)
|
||||
| ProbeState::NoValue(state, _) => {
|
||||
type RwLockUpgradableReadGuard<'a, T> =
|
||||
lock_api::RwLockUpgradableReadGuard<'a, RawRwLock, T>;
|
||||
|
||||
|
@ -318,7 +339,7 @@ where
|
|||
StateGuard: Deref<Target = QueryState<Q>>,
|
||||
{
|
||||
match &*state {
|
||||
QueryState::NotComputed => ProbeState::Absent(state),
|
||||
QueryState::NotComputed => ProbeState::NotComputed(state),
|
||||
|
||||
QueryState::InProgress { id, anyone_waiting } => {
|
||||
let other_id = *id;
|
||||
|
@ -376,7 +397,8 @@ where
|
|||
|
||||
ProbeState::UpToDate(Ok(value))
|
||||
} else {
|
||||
ProbeState::Absent(state)
|
||||
let changed_at = memo.revisions.changed_at;
|
||||
ProbeState::NoValue(state, changed_at)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue