@@ -19,9 +19,6 @@ pub enum VerifyResult {
19
19
///
20
20
/// The inner value tracks whether the memo or any of its dependencies have an
21
21
/// accumulated value.
22
- ///
23
- /// Don't mark memos verified until we've iterated the full cycle to ensure no inputs changed
24
- /// when encountering this variant.
25
22
Unchanged ( InputAccumulatedValues ) ,
26
23
}
27
24
@@ -37,10 +34,6 @@ impl VerifyResult {
37
34
pub ( crate ) fn unchanged ( ) -> Self {
38
35
Self :: Unchanged ( InputAccumulatedValues :: Empty )
39
36
}
40
-
41
- pub ( crate ) const fn is_unchanged ( & self ) -> bool {
42
- matches ! ( self , Self :: Unchanged ( _) )
43
- }
44
37
}
45
38
46
39
impl < C > IngredientImpl < C >
@@ -146,11 +139,11 @@ where
146
139
// Check if the inputs are still valid. We can just compare `changed_at`.
147
140
let deep_verify =
148
141
self . deep_verify_memo ( db, zalsa, old_memo, database_key_index, cycle_heads) ;
149
- if deep_verify . is_unchanged ( ) {
142
+ if let VerifyResult :: Unchanged ( accumulated_inputs ) = deep_verify {
150
143
return Some ( if old_memo. revisions . changed_at > revision {
151
144
VerifyResult :: Changed
152
145
} else {
153
- VerifyResult :: Unchanged ( old_memo . revisions . accumulated_inputs . load ( ) )
146
+ VerifyResult :: Unchanged ( accumulated_inputs)
154
147
} ) ;
155
148
}
156
149
@@ -316,18 +309,18 @@ where
316
309
memo = memo. tracing_debug( )
317
310
) ;
318
311
319
- if memo. revisions . cycle_heads . is_empty ( ) {
312
+ let cycle_heads = & memo. revisions . cycle_heads ;
313
+ if cycle_heads. is_empty ( ) {
320
314
return true ;
321
315
}
322
316
323
- let cycle_heads = & memo. revisions . cycle_heads ;
324
-
325
317
zalsa_local. with_query_stack ( |stack| {
326
318
cycle_heads. iter ( ) . all ( |cycle_head| {
327
- stack. iter ( ) . rev ( ) . any ( |query| {
328
- query. database_key_index == cycle_head. database_key_index
329
- && query. iteration_count ( ) == cycle_head. iteration_count
330
- } )
319
+ stack
320
+ . iter ( )
321
+ . rev ( )
322
+ . find ( |query| query. database_key_index == cycle_head. database_key_index )
323
+ . is_some_and ( |query| query. iteration_count ( ) == cycle_head. iteration_count )
331
324
} )
332
325
} )
333
326
}
@@ -402,16 +395,18 @@ where
402
395
return VerifyResult :: Changed ;
403
396
}
404
397
398
+ let dyn_db = db. as_dyn_database ( ) ;
399
+
400
+ let mut last_verified_at = old_memo. verified_at . load ( ) ;
401
+ let mut first_iteration = true ;
405
402
' cycle: loop {
403
+ let mut inputs = InputAccumulatedValues :: Empty ;
406
404
// Fully tracked inputs? Iterate over the inputs and check them, one by one.
407
405
//
408
406
// NB: It's important here that we are iterating the inputs in the order that
409
407
// they executed. It's possible that if the value of some input I0 is no longer
410
408
// valid, then some later input I1 might never have executed at all, so verifying
411
409
// it is still up to date is meaningless.
412
- let last_verified_at = old_memo. verified_at . load ( ) ;
413
- let mut inputs = InputAccumulatedValues :: Empty ;
414
- let dyn_db = db. as_dyn_database ( ) ;
415
410
for & edge in edges. input_outputs . iter ( ) {
416
411
match edge {
417
412
QueryEdge :: Input ( dependency_index) => {
@@ -421,9 +416,7 @@ where
421
416
last_verified_at,
422
417
cycle_heads,
423
418
) {
424
- VerifyResult :: Changed => {
425
- break ' cycle VerifyResult :: Changed ;
426
- }
419
+ VerifyResult :: Changed => break ' cycle VerifyResult :: Changed ,
427
420
VerifyResult :: Unchanged ( input_accumulated) => {
428
421
inputs |= input_accumulated;
429
422
}
@@ -477,9 +470,17 @@ where
477
470
// from cycle heads. We will handle our own memo (and the rest of our cycle) on a
478
471
// future iteration; first the outer cycle head needs to verify itself.
479
472
480
- let in_heads = cycle_heads. remove ( & database_key_index) ;
473
+ let was_in_heads = cycle_heads. remove ( & database_key_index) ;
474
+ let heads_non_empty = !cycle_heads. is_empty ( ) ;
475
+ if heads_non_empty {
476
+ // case 2 / 4
477
+ break ' cycle VerifyResult :: Unchanged ( inputs) ;
478
+ } else if !first_iteration {
479
+ // 3 (second loop turn)
480
+ break ' cycle VerifyResult :: Unchanged ( inputs) ;
481
+ } else {
482
+ last_verified_at = zalsa. current_revision ( ) ;
481
483
482
- if cycle_heads. is_empty ( ) {
483
484
old_memo. mark_as_verified ( zalsa, database_key_index) ;
484
485
old_memo. revisions . accumulated_inputs . store ( inputs) ;
485
486
@@ -490,11 +491,15 @@ where
490
491
. store ( true , Ordering :: Relaxed ) ;
491
492
}
492
493
493
- if in_heads {
494
+ if was_in_heads {
495
+ first_iteration = false ;
496
+ // case 3
494
497
continue ' cycle;
498
+ } else {
499
+ // case 1
500
+ break ' cycle VerifyResult :: Unchanged ( inputs) ;
495
501
}
496
502
}
497
- break ' cycle VerifyResult :: Unchanged ( inputs) ;
498
503
}
499
504
}
500
505
}
0 commit comments