Skip to content

Commit adc00e8

Browse files
committed
Split AggregatedDirtyContainerCount
1 parent 23f63c9 commit adc00e8

File tree

5 files changed

+389
-559
lines changed

5 files changed

+389
-559
lines changed

turbopack/crates/turbo-tasks-backend/src/backend/mod.rs

Lines changed: 84 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ use crate::backend::operation::TaskDirtyCause;
4848
use crate::{
4949
backend::{
5050
operation::{
51-
AggregatedDataUpdate, AggregationUpdateJob, AggregationUpdateQueue,
52-
CleanupOldEdgesOperation, ConnectChildOperation, ExecuteContext, ExecuteContextImpl,
51+
AggregationUpdateJob, AggregationUpdateQueue, CleanupOldEdgesOperation,
52+
ComputeDirtyAndCleanUpdate, ConnectChildOperation, ExecuteContext, ExecuteContextImpl,
5353
Operation, OutdatedEdge, TaskGuard, connect_children, get_aggregation_number,
5454
get_uppers, is_root_node, make_task_dirty_internal, prepare_new_children,
5555
},
@@ -560,10 +560,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
560560
let is_dirty = task.is_dirty(self.session_id);
561561

562562
// Check the dirty count of the root node
563-
let dirty_tasks = get!(task, AggregatedDirtyContainerCount)
564-
.cloned()
565-
.unwrap_or_default()
566-
.get(self.session_id);
563+
let dirty_tasks = task.dirty_container_count(self.session_id);
567564
if dirty_tasks > 0 || is_dirty {
568565
let activeness = get_mut!(task, Activeness);
569566
let mut task_ids_to_schedule: Vec<_> = Vec::new();
@@ -627,10 +624,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
627624
};
628625

629626
// Check the dirty count of the root node
630-
let dirty_tasks = get!(task, AggregatedDirtyContainerCount)
631-
.cloned()
632-
.unwrap_or_default()
633-
.get(ctx.session_id());
627+
let dirty_tasks = task.dirty_container_count(ctx.session_id());
634628

635629
let task_description = ctx.get_task_description(task_id);
636630
let is_dirty = if is_dirty { ", dirty" } else { "" };
@@ -2292,72 +2286,96 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
22922286
},
22932287
));
22942288

2295-
// Update the dirty state
2296-
let old_dirtyness = task.dirtyness_and_session();
2297-
2298-
let new_dirtyness = if session_dependent {
2299-
Some((Dirtyness::SessionDependent, Some(self.session_id)))
2300-
} else {
2301-
None
2289+
// Grab the old dirty state
2290+
let old_dirtyness = get!(task, Dirty).cloned();
2291+
let (was_dirty, was_current_session_clean, old_clean_in_session) = match old_dirtyness {
2292+
None => (false, false, None),
2293+
Some(Dirtyness::Dirty) => (true, false, None),
2294+
Some(Dirtyness::SessionDependent) => {
2295+
let clean_in_session = get!(task, CleanInSession).copied();
2296+
(
2297+
true,
2298+
clean_in_session == Some(self.session_id),
2299+
clean_in_session,
2300+
)
2301+
}
23022302
};
2303+
let old_dirty_value = if was_dirty { 1 } else { 0 };
2304+
let old_current_session_clean_value = if was_current_session_clean { 1 } else { 0 };
23032305

2304-
let dirty_changed = old_dirtyness != new_dirtyness;
2305-
let data_update = if dirty_changed {
2306-
if let Some((value, _)) = new_dirtyness {
2306+
// Compute the new dirty state
2307+
let (new_dirtyness, new_clean_in_session, new_dirty_value, new_current_session_clean_value) =
2308+
if session_dependent {
2309+
(
2310+
Some(Dirtyness::SessionDependent),
2311+
Some(self.session_id),
2312+
1,
2313+
1,
2314+
)
2315+
} else {
2316+
(None, None, 0, 0)
2317+
};
2318+
2319+
// Update the dirty state
2320+
if old_dirtyness != new_dirtyness {
2321+
if let Some(value) = new_dirtyness {
23072322
task.insert(CachedDataItem::Dirty { value });
23082323
} else if old_dirtyness.is_some() {
23092324
task.remove(&CachedDataItemKey::Dirty {});
23102325
}
2311-
if let Some(session_id) = new_dirtyness.and_then(|t| t.1) {
2326+
}
2327+
if old_clean_in_session != new_clean_in_session {
2328+
if let Some(session_id) = new_clean_in_session {
23122329
task.insert(CachedDataItem::CleanInSession { value: session_id });
2313-
} else if old_dirtyness.is_some_and(|t| t.1.is_some()) {
2330+
} else if old_clean_in_session.is_some() {
23142331
task.remove(&CachedDataItemKey::CleanInSession {});
23152332
}
2333+
}
23162334

2317-
let mut dirty_containers = get!(task, AggregatedDirtyContainerCount)
2335+
// Propagate dirtyness changes
2336+
let data_update = if old_dirty_value != new_dirty_value
2337+
|| old_current_session_clean_value != new_current_session_clean_value
2338+
{
2339+
let dirty_container_count = get!(task, AggregatedDirtyContainerCount)
23182340
.cloned()
23192341
.unwrap_or_default();
2320-
if let Some((old_dirtyness, old_clean_in_session)) = old_dirtyness {
2321-
dirty_containers
2322-
.update_with_dirtyness_and_session(old_dirtyness, old_clean_in_session);
2323-
}
2324-
let aggregated_update = match (old_dirtyness, new_dirtyness) {
2325-
(None, None) => unreachable!(),
2326-
(Some(old), None) => {
2327-
dirty_containers.undo_update_with_dirtyness_and_session(old.0, old.1)
2328-
}
2329-
(None, Some(new)) => {
2330-
dirty_containers.update_with_dirtyness_and_session(new.0, new.1)
2331-
}
2332-
(Some(old), Some(new)) => {
2333-
dirty_containers.replace_dirtyness_and_session(old.0, old.1, new.0, new.1)
2334-
}
2335-
};
2336-
if !aggregated_update.is_zero() {
2337-
if aggregated_update.get(self.session_id) < 0
2338-
&& let Some(activeness_state) = get_mut!(task, Activeness)
2339-
{
2340-
activeness_state.all_clean_event.notify(usize::MAX);
2341-
activeness_state.unset_active_until_clean();
2342-
if activeness_state.is_empty() {
2343-
task.remove(&CachedDataItemKey::Activeness {});
2344-
}
2342+
let current_session_clean_container_count = get!(
2343+
task,
2344+
AggregatedSessionDependentCleanContainerCount {
2345+
session_id: self.session_id
23452346
}
2346-
AggregationUpdateJob::data_update(
2347-
&mut task,
2348-
AggregatedDataUpdate::new().dirty_container_update(
2349-
task_id,
2350-
aggregated_update.count,
2351-
aggregated_update.current_session_clean(ctx.session_id()),
2352-
),
2353-
)
2354-
} else {
2355-
None
2356-
}
2347+
)
2348+
.copied()
2349+
.unwrap_or_default();
2350+
let result = ComputeDirtyAndCleanUpdate {
2351+
old_dirty_container_count: dirty_container_count,
2352+
new_dirty_container_count: dirty_container_count,
2353+
old_current_session_clean_container_count: current_session_clean_container_count,
2354+
new_current_session_clean_container_count: current_session_clean_container_count,
2355+
old_dirty_value,
2356+
new_dirty_value,
2357+
old_current_session_clean_value,
2358+
new_current_session_clean_value,
2359+
}
2360+
.compute();
2361+
result
2362+
.aggregated_update(task_id)
2363+
.and_then(|aggregated_update| {
2364+
AggregationUpdateJob::data_update(&mut task, aggregated_update)
2365+
})
23572366
} else {
23582367
None
23592368
};
23602369

2370+
if let Some(activeness_state) = get_mut!(task, Activeness) {
2371+
// The task is clean now
2372+
activeness_state.all_clean_event.notify(usize::MAX);
2373+
activeness_state.unset_active_until_clean();
2374+
if activeness_state.is_empty() {
2375+
task.remove(&CachedDataItemKey::Activeness {});
2376+
}
2377+
}
2378+
23612379
#[cfg(feature = "verify_determinism")]
23622380
let reschedule = (dirty_changed || no_output_set) && !task_id.is_transient();
23632381
#[cfg(not(feature = "verify_determinism"))]
@@ -2820,10 +2838,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
28202838
let mut ctx = self.execute_context(turbo_tasks);
28212839
let mut task = ctx.task(task_id, TaskDataCategory::All);
28222840
let is_dirty = task.is_dirty(self.session_id);
2823-
let has_dirty_containers = get!(task, AggregatedDirtyContainerCount)
2824-
.map_or(false, |dirty_containers| {
2825-
dirty_containers.get(self.session_id) > 0
2826-
});
2841+
let has_dirty_containers = task.dirty_container_count(self.session_id) > 0;
28272842
if is_dirty || has_dirty_containers {
28282843
if let Some(activeness_state) = get_mut!(task, Activeness) {
28292844
// We will finish the task, but it would be removed after the task is done
@@ -2913,8 +2928,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
29132928
}
29142929

29152930
let is_dirty = get!(task, Dirty).is_some();
2916-
let has_dirty_container =
2917-
get!(task, AggregatedDirtyContainerCount).is_some_and(|count| count.count > 0);
2931+
let has_dirty_container = task.dirty_container_count(self.session_id) > 0;
29182932
let should_be_in_upper = is_dirty || has_dirty_container;
29192933

29202934
let aggregation_number = get_aggregation_number(&task);
@@ -2937,17 +2951,19 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
29372951

29382952
if should_be_in_upper {
29392953
for upper_id in uppers {
2940-
let task = ctx.task(task_id, TaskDataCategory::All);
2954+
let task = ctx.task(upper_id, TaskDataCategory::All);
29412955
let in_upper = get!(task, AggregatedDirtyContainer { task: task_id })
29422956
.is_some_and(|&dirty| dirty > 0);
29432957
if !in_upper {
2958+
let containers: Vec<_> = get_many!(task, AggregatedDirtyContainer { task: task_id } value => (task_id, *value));
29442959
panic!(
29452960
"Task {} ({}) is dirty, but is not listed in the upper task {} \
2946-
({})",
2961+
({})\nThese dirty containers are present:\n{:#?}",
29472962
task_id,
29482963
ctx.get_task_description(task_id),
29492964
upper_id,
2950-
ctx.get_task_description(upper_id)
2965+
ctx.get_task_description(upper_id),
2966+
containers,
29512967
);
29522968
}
29532969
}

0 commit comments

Comments
 (0)