Skip to content

Commit 5b411a2

Browse files
authored
refactor: Use CycleHeadSet in maybe_update_after (#953)
1 parent 679d82c commit 5b411a2

File tree

12 files changed

+59
-42
lines changed

12 files changed

+59
-42
lines changed

src/accumulator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::panic::UnwindSafe;
77

88
use accumulated::{Accumulated, AnyAccumulated};
99

10-
use crate::cycle::CycleHeads;
10+
use crate::cycle::CycleHeadKeys;
1111
use crate::function::VerifyResult;
1212
use crate::ingredient::{Ingredient, Jar};
1313
use crate::plumbing::ZalsaLocal;
@@ -106,7 +106,7 @@ impl<A: Accumulator> Ingredient for IngredientImpl<A> {
106106
_db: crate::database::RawDatabase<'_>,
107107
_input: Id,
108108
_revision: Revision,
109-
_cycle_heads: &mut CycleHeads,
109+
_cycle_heads: &mut CycleHeadKeys,
110110
) -> VerifyResult {
111111
panic!("nothing should ever depend on an accumulator directly")
112112
}

src/cycle.rs

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -178,22 +178,6 @@ impl CycleHeads {
178178
}
179179
}
180180

181-
#[inline]
182-
pub(crate) fn push_initial(&mut self, database_key_index: DatabaseKeyIndex) {
183-
if let Some(existing) = self
184-
.0
185-
.iter()
186-
.find(|candidate| candidate.database_key_index == database_key_index)
187-
{
188-
assert_eq!(existing.iteration_count, IterationCount::initial());
189-
} else {
190-
self.0.push(CycleHead {
191-
database_key_index,
192-
iteration_count: IterationCount::initial(),
193-
});
194-
}
195-
}
196-
197181
#[inline]
198182
pub(crate) fn extend(&mut self, other: &Self) {
199183
self.0.reserve(other.0.len());
@@ -247,6 +231,37 @@ pub(crate) fn empty_cycle_heads() -> &'static CycleHeads {
247231
EMPTY_CYCLE_HEADS.get_or_init(|| CycleHeads(ThinVec::new()))
248232
}
249233

234+
/// Set of cycle head database keys.
235+
///
236+
/// Unlike [`CycleHeads`], this type doesn't track the iteration count
237+
/// of each cycle head.
238+
#[derive(Debug, Clone, Eq, PartialEq)]
239+
pub struct CycleHeadKeys(Vec<DatabaseKeyIndex>);
240+
241+
impl CycleHeadKeys {
242+
pub(crate) fn new() -> Self {
243+
Self(Vec::new())
244+
}
245+
246+
pub(crate) fn insert(&mut self, database_key_index: DatabaseKeyIndex) {
247+
if !self.0.contains(&database_key_index) {
248+
self.0.push(database_key_index);
249+
}
250+
}
251+
252+
pub(crate) fn remove(&mut self, value: &DatabaseKeyIndex) -> bool {
253+
let found = self.0.iter().position(|&head| head == *value);
254+
let Some(found) = found else { return false };
255+
256+
self.0.swap_remove(found);
257+
true
258+
}
259+
260+
pub(crate) fn is_empty(&self) -> bool {
261+
self.0.is_empty()
262+
}
263+
}
264+
250265
#[derive(Debug, PartialEq, Eq)]
251266
pub enum ProvisionalStatus {
252267
Provisional { iteration: IterationCount },

src/function.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ use std::sync::OnceLock;
77
pub(crate) use sync::SyncGuard;
88

99
use crate::cycle::{
10-
empty_cycle_heads, CycleHeads, CycleRecoveryAction, CycleRecoveryStrategy, ProvisionalStatus,
10+
empty_cycle_heads, CycleHeadKeys, CycleHeads, CycleRecoveryAction, CycleRecoveryStrategy,
11+
ProvisionalStatus,
1112
};
1213
use crate::database::RawDatabase;
1314
use crate::function::delete::DeletedEntries;
@@ -265,7 +266,7 @@ where
265266
db: RawDatabase<'_>,
266267
input: Id,
267268
revision: Revision,
268-
cycle_heads: &mut CycleHeads,
269+
cycle_heads: &mut CycleHeadKeys,
269270
) -> VerifyResult {
270271
// SAFETY: The `db` belongs to the ingredient as per caller invariant
271272
let db = unsafe { self.view_caster().downcast_unchecked(db) };

src/function/fetch.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::cycle::{CycleHeads, CycleRecoveryStrategy, IterationCount};
1+
use crate::cycle::{CycleHeadKeys, CycleHeads, CycleRecoveryStrategy, IterationCount};
22
use crate::function::memo::Memo;
33
use crate::function::sync::ClaimResult;
44
use crate::function::{Configuration, IngredientImpl, VerifyResult};
@@ -222,7 +222,7 @@ where
222222

223223
if let Some(old_memo) = opt_old_memo {
224224
if old_memo.value.is_some() {
225-
let mut cycle_heads = CycleHeads::default();
225+
let mut cycle_heads = CycleHeadKeys::new();
226226
if let VerifyResult::Unchanged { .. } =
227227
self.deep_verify_memo(db, zalsa, old_memo, database_key_index, &mut cycle_heads)
228228
{

src/function/maybe_changed_after.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#[cfg(feature = "accumulator")]
22
use crate::accumulator::accumulated_map::InputAccumulatedValues;
3-
use crate::cycle::{CycleHeads, CycleRecoveryStrategy, IterationCount, ProvisionalStatus};
3+
use crate::cycle::{CycleHeadKeys, CycleRecoveryStrategy, IterationCount, ProvisionalStatus};
44
use crate::function::memo::Memo;
55
use crate::function::sync::ClaimResult;
66
use crate::function::{Configuration, IngredientImpl};
@@ -51,7 +51,7 @@ where
5151
db: &'db C::DbView,
5252
id: Id,
5353
revision: Revision,
54-
cycle_heads: &mut CycleHeads,
54+
cycle_heads: &mut CycleHeadKeys,
5555
) -> VerifyResult {
5656
let (zalsa, zalsa_local) = db.zalsas();
5757
let memo_ingredient_index = self.memo_ingredient_index(zalsa, id);
@@ -108,7 +108,7 @@ where
108108
key_index: Id,
109109
revision: Revision,
110110
memo_ingredient_index: MemoIngredientIndex,
111-
cycle_heads: &mut CycleHeads,
111+
cycle_heads: &mut CycleHeadKeys,
112112
) -> Option<VerifyResult> {
113113
let database_key_index = self.database_key_index(key_index);
114114

@@ -135,7 +135,7 @@ where
135135
crate::tracing::debug!(
136136
"hit cycle at {database_key_index:?} in `maybe_changed_after`, returning fixpoint initial value",
137137
);
138-
cycle_heads.push_initial(database_key_index);
138+
cycle_heads.insert(database_key_index);
139139
return Some(VerifyResult::unchanged());
140140
}
141141
},
@@ -406,7 +406,7 @@ where
406406
zalsa: &Zalsa,
407407
old_memo: &Memo<'_, C>,
408408
database_key_index: DatabaseKeyIndex,
409-
cycle_heads: &mut CycleHeads,
409+
cycle_heads: &mut CycleHeadKeys,
410410
) -> VerifyResult {
411411
crate::tracing::debug!(
412412
"{database_key_index:?}: deep_verify_memo(old_memo = {old_memo:#?})",
@@ -447,7 +447,7 @@ where
447447
// are tracked by the outer query. Nothing should have changed assuming that the
448448
// fixpoint initial function is deterministic.
449449
QueryOriginRef::FixpointInitial => {
450-
cycle_heads.push_initial(database_key_index);
450+
cycle_heads.insert(database_key_index);
451451
VerifyResult::unchanged()
452452
}
453453
QueryOriginRef::DerivedUntracked(_) => {

src/ingredient.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use std::any::{Any, TypeId};
22
use std::fmt;
33

44
use crate::cycle::{
5-
empty_cycle_heads, CycleHeads, CycleRecoveryStrategy, IterationCount, ProvisionalStatus,
5+
empty_cycle_heads, CycleHeadKeys, CycleHeads, CycleRecoveryStrategy, IterationCount,
6+
ProvisionalStatus,
67
};
78
use crate::database::RawDatabase;
89
use crate::function::VerifyResult;
@@ -51,7 +52,7 @@ pub trait Ingredient: Any + std::fmt::Debug + Send + Sync {
5152
db: crate::database::RawDatabase<'_>,
5253
input: Id,
5354
revision: Revision,
54-
cycle_heads: &mut CycleHeads,
55+
cycle_heads: &mut CycleHeadKeys,
5556
) -> VerifyResult;
5657

5758
/// Returns information about the current provisional status of `input`.

src/input.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub mod singleton;
88

99
use input_field::FieldIngredientImpl;
1010

11-
use crate::cycle::CycleHeads;
11+
use crate::cycle::CycleHeadKeys;
1212
use crate::function::VerifyResult;
1313
use crate::id::{AsId, FromId, FromIdWithDb};
1414
use crate::ingredient::Ingredient;
@@ -226,7 +226,7 @@ impl<C: Configuration> Ingredient for IngredientImpl<C> {
226226
_db: crate::database::RawDatabase<'_>,
227227
_input: Id,
228228
_revision: Revision,
229-
_cycle_heads: &mut CycleHeads,
229+
_cycle_heads: &mut CycleHeadKeys,
230230
) -> VerifyResult {
231231
// Input ingredients are just a counter, they store no data, they are immortal.
232232
// Their *fields* are stored in function ingredients elsewhere.

src/input/input_field.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::fmt;
22
use std::marker::PhantomData;
33

4-
use crate::cycle::CycleHeads;
4+
use crate::cycle::CycleHeadKeys;
55
use crate::function::VerifyResult;
66
use crate::ingredient::Ingredient;
77
use crate::input::{Configuration, IngredientImpl, Value};
@@ -56,7 +56,7 @@ where
5656
_db: crate::database::RawDatabase<'_>,
5757
input: Id,
5858
revision: Revision,
59-
_cycle_heads: &mut CycleHeads,
59+
_cycle_heads: &mut CycleHeadKeys,
6060
) -> VerifyResult {
6161
let value = <IngredientImpl<C>>::data(zalsa, input);
6262
VerifyResult::changed_if(value.revisions[self.field_index] > revision)

src/interned.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crossbeam_utils::CachePadded;
1010
use intrusive_collections::{intrusive_adapter, LinkedList, LinkedListLink, UnsafeRef};
1111
use rustc_hash::FxBuildHasher;
1212

13-
use crate::cycle::CycleHeads;
13+
use crate::cycle::CycleHeadKeys;
1414
use crate::durability::Durability;
1515
use crate::function::VerifyResult;
1616
use crate::id::{AsId, FromId};
@@ -797,7 +797,7 @@ where
797797
_db: crate::database::RawDatabase<'_>,
798798
input: Id,
799799
_revision: Revision,
800-
_cycle_heads: &mut CycleHeads,
800+
_cycle_heads: &mut CycleHeadKeys,
801801
) -> VerifyResult {
802802
// Record the current revision as active.
803803
let current_revision = zalsa.current_revision();

src/key.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use core::fmt;
22

3-
use crate::cycle::CycleHeads;
3+
use crate::cycle::CycleHeadKeys;
44
use crate::function::VerifyResult;
55
use crate::zalsa::{IngredientIndex, Zalsa};
66
use crate::Id;
@@ -39,7 +39,7 @@ impl DatabaseKeyIndex {
3939
db: crate::database::RawDatabase<'_>,
4040
zalsa: &Zalsa,
4141
last_verified_at: crate::Revision,
42-
cycle_heads: &mut CycleHeads,
42+
cycle_heads: &mut CycleHeadKeys,
4343
) -> VerifyResult {
4444
// SAFETY: The `db` belongs to the ingredient
4545
unsafe {

0 commit comments

Comments
 (0)