@@ -60,10 +60,16 @@ where
6060
6161 // Check if we have a verified version: this is the hot path.
6262 let memo_guard = self . get_memo_from_table_for ( zalsa, id, memo_ingredient_index) ;
63- if let Some ( memo) = memo_guard {
64- if self . validate_may_be_provisional ( db, zalsa, database_key_index, memo)
65- && self . shallow_verify_memo ( db, zalsa, database_key_index, memo)
66- {
63+ let Some ( memo) = memo_guard else {
64+ // No memo? Assume has changed.
65+ return VerifyResult :: Changed ;
66+ } ;
67+
68+ if let Some ( shallow_update) = self . shallow_verify_memo ( zalsa, database_key_index, memo)
69+ {
70+ if self . validate_provisional ( db, zalsa, database_key_index, memo) {
71+ self . update_shallow ( db, zalsa, database_key_index, memo, shallow_update) ;
72+
6773 return if memo. revisions . changed_at > revision {
6874 VerifyResult :: Changed
6975 } else {
@@ -73,16 +79,14 @@ where
7379 )
7480 } ;
7581 }
76- if let Some ( mcs) =
77- self . maybe_changed_after_cold ( zalsa, db, id, revision, memo_ingredient_index)
78- {
79- return mcs;
80- } else {
81- // We failed to claim, have to retry.
82- }
82+ }
83+
84+ if let Some ( mcs) =
85+ self . maybe_changed_after_cold ( zalsa, db, id, revision, memo_ingredient_index)
86+ {
87+ return mcs;
8388 } else {
84- // No memo? Assume has changed.
85- return VerifyResult :: Changed ;
89+ // We failed to claim, have to retry.
8690 }
8791 }
8892 }
@@ -167,7 +171,7 @@ where
167171 Some ( VerifyResult :: Changed )
168172 }
169173
170- /// True if the memo's value and `changed_at` time is still valid in this revision.
174+ /// `Some` if the memo's value and `changed_at` time is still valid in this revision.
171175 /// Does only a shallow O(1) check, doesn't walk the dependencies.
172176 ///
173177 /// In general, a provisional memo (from cycle iteration) does not verify. Since we don't
@@ -177,11 +181,10 @@ where
177181 #[ inline]
178182 pub ( super ) fn shallow_verify_memo (
179183 & self ,
180- db : & C :: DbView ,
181184 zalsa : & Zalsa ,
182185 database_key_index : DatabaseKeyIndex ,
183186 memo : & Memo < C :: Output < ' _ > > ,
184- ) -> bool {
187+ ) -> Option < ShallowUpdate > {
185188 tracing:: debug!(
186189 "{database_key_index:?}: shallow_verify_memo(memo = {memo:#?})" ,
187190 memo = memo. tracing_debug( )
@@ -191,7 +194,7 @@ where
191194
192195 if verified_at == revision_now {
193196 // Already verified.
194- return true ;
197+ return Some ( ShallowUpdate :: Verified ) ;
195198 }
196199
197200 let last_changed = zalsa. last_changed_revision ( memo. revisions . durability ) ;
@@ -204,17 +207,31 @@ where
204207 ) ;
205208 if last_changed <= verified_at {
206209 // No input of the suitable durability has changed since last verified.
210+ Some ( ShallowUpdate :: HigherDurability ( revision_now) )
211+ } else {
212+ None
213+ }
214+ }
215+
216+ #[ inline]
217+ pub ( super ) fn update_shallow (
218+ & self ,
219+ db : & C :: DbView ,
220+ zalsa : & Zalsa ,
221+ database_key_index : DatabaseKeyIndex ,
222+ memo : & Memo < C :: Output < ' _ > > ,
223+ update : ShallowUpdate ,
224+ ) {
225+ if let ShallowUpdate :: HigherDurability ( revision_now) = update {
207226 memo. mark_as_verified (
208227 db,
209228 revision_now,
210229 database_key_index,
211230 memo. revisions . accumulated_inputs . load ( ) ,
212231 ) ;
232+
213233 memo. mark_outputs_as_verified ( zalsa, db. as_dyn_database ( ) , database_key_index) ;
214- return true ;
215234 }
216-
217- false
218235 }
219236
220237 /// Validates this memo if it is a provisional memo. Returns true for non provisional memos or
@@ -311,10 +328,15 @@ where
311328 old_memo = old_memo. tracing_debug( )
312329 ) ;
313330
314- if self . validate_may_be_provisional ( db, zalsa, database_key_index, old_memo)
315- && self . shallow_verify_memo ( db, zalsa, database_key_index, old_memo)
316- {
317- return VerifyResult :: unchanged ( ) ;
331+ let shallow_update = self . shallow_verify_memo ( zalsa, database_key_index, old_memo) ;
332+ let shallow_update_possible = shallow_update. is_some ( ) ;
333+
334+ if let Some ( shallow_update) = shallow_update {
335+ if self . validate_provisional ( db, zalsa, database_key_index, old_memo) {
336+ self . update_shallow ( db, zalsa, database_key_index, old_memo, shallow_update) ;
337+
338+ return VerifyResult :: unchanged ( ) ;
339+ }
318340 }
319341
320342 match & old_memo. revisions . origin {
@@ -339,7 +361,9 @@ where
339361 VerifyResult :: Changed
340362 }
341363 QueryOrigin :: Derived ( edges) => {
342- if old_memo. may_be_provisional ( ) {
364+ let is_provisional = old_memo. may_be_provisional ( ) ;
365+ // If the value is from the same revision but is still provisional, consider it changed
366+ if shallow_update_possible && is_provisional {
343367 return VerifyResult :: Changed ;
344368 }
345369
@@ -428,15 +452,18 @@ where
428452 inputs,
429453 ) ;
430454
455+ if is_provisional {
456+ old_memo
457+ . revisions
458+ . verified_final
459+ . store ( true , Ordering :: Relaxed ) ;
460+ }
461+
431462 if in_heads {
432- // Iterate our dependency graph again, starting from the top. We clear the
433- // cycle heads here because we are starting a fresh traversal. (It might be
434- // logically clearer to create a new HashSet each time, but clearing the
435- // existing one is more efficient.)
436- cycle_heads. clear ( ) ;
437463 continue ' cycle;
438464 }
439465 }
466+
440467 break ' cycle VerifyResult :: Unchanged (
441468 InputAccumulatedValues :: Empty ,
442469 cycle_heads,
@@ -446,3 +473,13 @@ where
446473 }
447474 }
448475}
476+
477+ #[ derive( Copy , Clone , Eq , PartialEq ) ]
478+ pub ( super ) enum ShallowUpdate {
479+ /// The memo is from this revision and has already been verified
480+ Verified ,
481+
482+ /// The revision for the memo's durability hasn't changed. It can be marked as verified
483+ /// in this revision.
484+ HigherDurability ( Revision ) ,
485+ }
0 commit comments