@@ -13,53 +13,33 @@ use crate::{AsDynDatabase as _, Id, Revision};
13
13
/// Result of memo validation.
14
14
pub enum VerifyResult {
15
15
/// Memo has changed and needs to be recomputed.
16
- ///
17
- /// The cycle heads encountered when validating the memo.
18
- Changed ( CycleHeads ) ,
16
+ Changed ,
19
17
20
18
/// Memo remains valid.
21
19
///
22
- /// The first inner value tracks whether the memo or any of its dependencies have an
20
+ /// The inner value tracks whether the memo or any of its dependencies have an
23
21
/// accumulated value.
24
22
///
25
- /// The second is the cycle heads encountered in validation; don't mark
26
- /// memos verified until we've iterated the full cycle to ensure no inputs changed .
27
- Unchanged ( InputAccumulatedValues , CycleHeads ) ,
23
+ /// Don't mark memos verified until we've iterated the full cycle to ensure no inputs changed
24
+ /// when encountering this variant .
25
+ Unchanged ( InputAccumulatedValues ) ,
28
26
}
29
27
30
28
impl VerifyResult {
31
29
pub ( crate ) fn changed_if ( changed : bool ) -> Self {
32
30
if changed {
33
- Self :: changed ( )
31
+ Self :: Changed
34
32
} else {
35
33
Self :: unchanged ( )
36
34
}
37
35
}
38
36
39
- pub ( crate ) fn changed ( ) -> Self {
40
- Self :: Changed ( CycleHeads :: default ( ) )
41
- }
42
-
43
37
pub ( crate ) fn unchanged ( ) -> Self {
44
- Self :: Unchanged ( InputAccumulatedValues :: Empty , CycleHeads :: default ( ) )
45
- }
46
-
47
- pub ( crate ) fn cycle_heads ( & self ) -> & CycleHeads {
48
- match self {
49
- Self :: Changed ( cycle_heads) => cycle_heads,
50
- Self :: Unchanged ( _, cycle_heads) => cycle_heads,
51
- }
52
- }
53
-
54
- pub ( crate ) fn into_cycle_heads ( self ) -> CycleHeads {
55
- match self {
56
- Self :: Changed ( cycle_heads) => cycle_heads,
57
- Self :: Unchanged ( _, cycle_heads) => cycle_heads,
58
- }
38
+ Self :: Unchanged ( InputAccumulatedValues :: Empty )
59
39
}
60
40
61
41
pub ( crate ) const fn is_unchanged ( & self ) -> bool {
62
- matches ! ( self , Self :: Unchanged ( _, _ ) )
42
+ matches ! ( self , Self :: Unchanged ( _) )
63
43
}
64
44
}
65
45
72
52
db : & ' db C :: DbView ,
73
53
id : Id ,
74
54
revision : Revision ,
75
- in_cycle : bool ,
55
+ cycle_heads : & mut CycleHeads ,
76
56
) -> VerifyResult {
77
57
let ( zalsa, zalsa_local) = db. zalsas ( ) ;
78
58
let memo_ingredient_index = self . memo_ingredient_index ( zalsa, id) ;
@@ -87,20 +67,17 @@ where
87
67
let memo_guard = self . get_memo_from_table_for ( zalsa, id, memo_ingredient_index) ;
88
68
let Some ( memo) = memo_guard else {
89
69
// No memo? Assume has changed.
90
- return VerifyResult :: changed ( ) ;
70
+ return VerifyResult :: Changed ;
91
71
} ;
92
72
93
73
let can_shallow_update = self . shallow_verify_memo ( zalsa, database_key_index, memo) ;
94
74
if can_shallow_update. yes ( ) && !memo. may_be_provisional ( ) {
95
75
self . update_shallow ( zalsa, database_key_index, memo, can_shallow_update) ;
96
76
97
77
return if memo. revisions . changed_at > revision {
98
- VerifyResult :: changed ( )
78
+ VerifyResult :: Changed
99
79
} else {
100
- VerifyResult :: Unchanged (
101
- memo. revisions . accumulated_inputs . load ( ) ,
102
- CycleHeads :: default ( ) ,
103
- )
80
+ VerifyResult :: Unchanged ( memo. revisions . accumulated_inputs . load ( ) )
104
81
} ;
105
82
}
106
83
110
87
id,
111
88
revision,
112
89
memo_ingredient_index,
113
- in_cycle ,
90
+ cycle_heads ,
114
91
) {
115
92
return mcs;
116
93
} else {
@@ -127,7 +104,7 @@ where
127
104
key_index : Id ,
128
105
revision : Revision ,
129
106
memo_ingredient_index : MemoIngredientIndex ,
130
- in_cycle : bool ,
107
+ cycle_heads : & mut CycleHeads ,
131
108
) -> Option < VerifyResult > {
132
109
let database_key_index = self . database_key_index ( key_index) ;
133
110
@@ -148,18 +125,16 @@ where
148
125
tracing:: debug!(
149
126
"hit cycle at {database_key_index:?} in `maybe_changed_after`, returning fixpoint initial value" ,
150
127
) ;
151
- return Some ( VerifyResult :: Unchanged (
152
- InputAccumulatedValues :: Empty ,
153
- CycleHeads :: initial ( database_key_index) ,
154
- ) ) ;
128
+ cycle_heads. push_initial ( database_key_index) ;
129
+ return Some ( VerifyResult :: unchanged ( ) ) ;
155
130
}
156
131
} ,
157
132
ClaimResult :: Claimed ( guard) => guard,
158
133
} ;
159
134
// Load the current memo, if any.
160
135
let Some ( old_memo) = self . get_memo_from_table_for ( zalsa, key_index, memo_ingredient_index)
161
136
else {
162
- return Some ( VerifyResult :: changed ( ) ) ;
137
+ return Some ( VerifyResult :: Changed ) ;
163
138
} ;
164
139
165
140
tracing:: debug!(
@@ -169,15 +144,13 @@ where
169
144
) ;
170
145
171
146
// Check if the inputs are still valid. We can just compare `changed_at`.
172
- let deep_verify = self . deep_verify_memo ( db, zalsa, old_memo, database_key_index) ;
147
+ let deep_verify =
148
+ self . deep_verify_memo ( db, zalsa, old_memo, database_key_index, cycle_heads) ;
173
149
if deep_verify. is_unchanged ( ) {
174
150
return Some ( if old_memo. revisions . changed_at > revision {
175
- VerifyResult :: Changed ( deep_verify . into_cycle_heads ( ) )
151
+ VerifyResult :: Changed
176
152
} else {
177
- VerifyResult :: Unchanged (
178
- old_memo. revisions . accumulated_inputs . load ( ) ,
179
- deep_verify. into_cycle_heads ( ) ,
180
- )
153
+ VerifyResult :: Unchanged ( old_memo. revisions . accumulated_inputs . load ( ) )
181
154
} ) ;
182
155
}
183
156
@@ -191,26 +164,23 @@ where
191
164
// the cycle head returned *fixpoint initial* without validating its dependencies.
192
165
// `in_cycle` tracks if the enclosing query is in a cycle. `deep_verify.cycle_heads` tracks
193
166
// if **this query** encountered a cycle (which means there's some provisional value somewhere floating around).
194
- if old_memo. value . is_some ( ) && !in_cycle && deep_verify . cycle_heads ( ) . is_empty ( ) {
167
+ if old_memo. value . is_some ( ) && cycle_heads. is_empty ( ) {
195
168
let active_query = db. zalsa_local ( ) . push_query ( database_key_index, 0 ) ;
196
169
let memo = self . execute ( db, active_query, Some ( old_memo) ) ;
197
170
let changed_at = memo. revisions . changed_at ;
198
171
199
172
return Some ( if changed_at > revision {
200
- VerifyResult :: changed ( )
173
+ VerifyResult :: Changed
201
174
} else {
202
- VerifyResult :: Unchanged (
203
- match & memo. revisions . accumulated {
204
- Some ( _) => InputAccumulatedValues :: Any ,
205
- None => memo. revisions . accumulated_inputs . load ( ) ,
206
- } ,
207
- CycleHeads :: default ( ) ,
208
- )
175
+ VerifyResult :: Unchanged ( match & memo. revisions . accumulated {
176
+ Some ( _) => InputAccumulatedValues :: Any ,
177
+ None => memo. revisions . accumulated_inputs . load ( ) ,
178
+ } )
209
179
} ) ;
210
180
}
211
181
212
182
// Otherwise, nothing for it: have to consider the value to have changed.
213
- Some ( VerifyResult :: Changed ( deep_verify . into_cycle_heads ( ) ) )
183
+ Some ( VerifyResult :: Changed )
214
184
}
215
185
216
186
/// `Some` if the memo's value and `changed_at` time is still valid in this revision.
@@ -249,7 +219,7 @@ where
249
219
) ;
250
220
if last_changed <= verified_at {
251
221
// No input of the suitable durability has changed since last verified.
252
- ShallowUpdate :: HigherDurability ( revision_now )
222
+ ShallowUpdate :: HigherDurability
253
223
} else {
254
224
ShallowUpdate :: No
255
225
}
@@ -263,8 +233,8 @@ where
263
233
memo : & Memo < C :: Output < ' _ > > ,
264
234
update : ShallowUpdate ,
265
235
) {
266
- if let ShallowUpdate :: HigherDurability ( revision_now ) = update {
267
- memo. mark_as_verified ( zalsa, revision_now , database_key_index) ;
236
+ if let ShallowUpdate :: HigherDurability = update {
237
+ memo. mark_as_verified ( zalsa, database_key_index) ;
268
238
memo. mark_outputs_as_verified ( zalsa, database_key_index) ;
269
239
}
270
240
}
@@ -375,6 +345,7 @@ where
375
345
zalsa : & Zalsa ,
376
346
old_memo : & Memo < C :: Output < ' _ > > ,
377
347
database_key_index : DatabaseKeyIndex ,
348
+ cycle_heads : & mut CycleHeads ,
378
349
) -> VerifyResult {
379
350
tracing:: debug!(
380
351
"{database_key_index:?}: deep_verify_memo(old_memo = {old_memo:#?})" ,
@@ -408,30 +379,29 @@ where
408
379
// Conditionally specified queries
409
380
// where the value is specified
410
381
// in rev 1 but not in rev 2.
411
- VerifyResult :: changed ( )
382
+ VerifyResult :: Changed
412
383
}
413
384
// Return `Unchanged` similar to the initial value that we insert
414
385
// when we hit the cycle. Any dependencies accessed when creating the fixpoint initial
415
386
// are tracked by the outer query. Nothing should have changed assuming that the
416
387
// fixpoint initial function is deterministic.
417
- QueryOrigin :: FixpointInitial => VerifyResult :: Unchanged (
418
- InputAccumulatedValues :: Empty ,
419
- CycleHeads :: initial ( database_key_index ) ,
420
- ) ,
388
+ QueryOrigin :: FixpointInitial => {
389
+ cycle_heads . push_initial ( database_key_index ) ;
390
+ VerifyResult :: unchanged ( )
391
+ }
421
392
QueryOrigin :: DerivedUntracked ( _) => {
422
393
// Untracked inputs? Have to assume that it changed.
423
- VerifyResult :: changed ( )
394
+ VerifyResult :: Changed
424
395
}
425
396
QueryOrigin :: Derived ( edges) => {
426
397
let is_provisional = old_memo. may_be_provisional ( ) ;
427
398
428
399
// If the value is from the same revision but is still provisional, consider it changed
429
400
// because we're now in a new iteration.
430
- if can_shallow_update. yes ( ) && is_provisional {
431
- return VerifyResult :: changed ( ) ;
401
+ if can_shallow_update == ShallowUpdate :: Verified && is_provisional {
402
+ return VerifyResult :: Changed ;
432
403
}
433
404
434
- let mut cycle_heads = CycleHeads :: default ( ) ;
435
405
' cycle: loop {
436
406
// Fully tracked inputs? Iterate over the inputs and check them, one by one.
437
407
//
@@ -449,16 +419,12 @@ where
449
419
dyn_db,
450
420
zalsa,
451
421
last_verified_at,
452
- ! cycle_heads. is_empty ( ) ,
422
+ cycle_heads,
453
423
) {
454
- VerifyResult :: Changed ( heads) => {
455
- // Carry over the heads from the inner query to avoid
456
- // backdating the outer query.
457
- cycle_heads. extend ( & heads) ;
458
- break ' cycle VerifyResult :: Changed ( cycle_heads) ;
424
+ VerifyResult :: Changed => {
425
+ break ' cycle VerifyResult :: Changed ;
459
426
}
460
- VerifyResult :: Unchanged ( input_accumulated, cycles) => {
461
- cycle_heads. extend ( & cycles) ;
427
+ VerifyResult :: Unchanged ( input_accumulated) => {
462
428
inputs |= input_accumulated;
463
429
}
464
430
}
@@ -514,11 +480,7 @@ where
514
480
let in_heads = cycle_heads. remove ( & database_key_index) ;
515
481
516
482
if cycle_heads. is_empty ( ) {
517
- old_memo. mark_as_verified (
518
- zalsa,
519
- zalsa. current_revision ( ) ,
520
- database_key_index,
521
- ) ;
483
+ old_memo. mark_as_verified ( zalsa, database_key_index) ;
522
484
old_memo. revisions . accumulated_inputs . store ( inputs) ;
523
485
524
486
if is_provisional {
@@ -532,7 +494,7 @@ where
532
494
continue ' cycle;
533
495
}
534
496
}
535
- break ' cycle VerifyResult :: Unchanged ( inputs, cycle_heads ) ;
497
+ break ' cycle VerifyResult :: Unchanged ( inputs) ;
536
498
}
537
499
}
538
500
}
@@ -546,7 +508,7 @@ pub(super) enum ShallowUpdate {
546
508
547
509
/// The revision for the memo's durability hasn't changed. It can be marked as verified
548
510
/// in this revision.
549
- HigherDurability ( Revision ) ,
511
+ HigherDurability ,
550
512
551
513
/// The memo requires a deep verification.
552
514
No ,
@@ -556,7 +518,7 @@ impl ShallowUpdate {
556
518
pub ( super ) fn yes ( & self ) -> bool {
557
519
matches ! (
558
520
self ,
559
- ShallowUpdate :: Verified | ShallowUpdate :: HigherDurability ( _ )
521
+ ShallowUpdate :: Verified | ShallowUpdate :: HigherDurability
560
522
)
561
523
}
562
524
}
0 commit comments