Skip to content

Commit f959baf

Browse files
committed
improve algo
1 parent 2896739 commit f959baf

File tree

1 file changed

+48
-28
lines changed

1 file changed

+48
-28
lines changed

packages/svelte/src/internal/client/runtime.js

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,15 @@ function execute_signal_fn(signal) {
349349

350350
if (current_dependencies !== null) {
351351
let i;
352+
if (dependencies !== null) {
353+
for (i = current_dependencies_index; i < dependencies.length; i++) {
354+
const dependency = dependencies[i];
355+
if (!current_dependencies.includes(dependency)) {
356+
remove_consumer(signal, dependency, false);
357+
}
358+
}
359+
}
360+
352361
if (dependencies !== null && current_dependencies_index > 0) {
353362
dependencies.length = current_dependencies_index + current_dependencies.length;
354363
for (i = 0; i < current_dependencies.length; i++) {
@@ -373,7 +382,7 @@ function execute_signal_fn(signal) {
373382
}
374383
}
375384
} else if (dependencies !== null && current_dependencies_index < dependencies.length) {
376-
remove_consumer(signal, current_dependencies_index, false);
385+
remove_consumers(signal, current_dependencies_index, false);
377386
dependencies.length = current_dependencies_index;
378387
}
379388
return res;
@@ -389,43 +398,54 @@ function execute_signal_fn(signal) {
389398
}
390399
}
391400

401+
/**
402+
* @template V
403+
* @param {import('./types.js').ComputationSignal<V>} signal
404+
* @param {import('./types.js').Signal<V>} dependency
405+
* @param {boolean} remove_unowned
406+
* @returns {void}
407+
*/
408+
function remove_consumer(signal, dependency, remove_unowned) {
409+
const consumers = dependency.c;
410+
let consumers_length = 0;
411+
if (consumers !== null) {
412+
consumers_length = consumers.length - 1;
413+
const index = consumers.indexOf(signal);
414+
if (index !== -1) {
415+
if (consumers_length === 0) {
416+
dependency.c = null;
417+
} else {
418+
// Swap with last element and then remove.
419+
consumers[index] = consumers[consumers_length];
420+
consumers.pop();
421+
}
422+
}
423+
}
424+
if (remove_unowned && consumers_length === 0 && (dependency.f & UNOWNED) !== 0) {
425+
// If the signal is unowned then we need to make sure to change it to dirty.
426+
set_signal_status(dependency, DIRTY);
427+
remove_consumers(
428+
/** @type {import('./types.js').ComputationSignal<V>} **/ (dependency),
429+
0,
430+
true
431+
);
432+
}
433+
}
434+
392435
/**
393436
* @template V
394437
* @param {import('./types.js').ComputationSignal<V>} signal
395438
* @param {number} start_index
396439
* @param {boolean} remove_unowned
397440
* @returns {void}
398441
*/
399-
function remove_consumer(signal, start_index, remove_unowned) {
442+
function remove_consumers(signal, start_index, remove_unowned) {
400443
const dependencies = signal.d;
401444
if (dependencies !== null) {
402445
let i;
403446
for (i = start_index; i < dependencies.length; i++) {
404447
const dependency = dependencies[i];
405-
const consumers = dependency.c;
406-
let consumers_length = 0;
407-
if (consumers !== null) {
408-
consumers_length = consumers.length - 1;
409-
const index = consumers.indexOf(signal);
410-
if (index !== -1) {
411-
if (consumers_length === 0) {
412-
dependency.c = null;
413-
} else {
414-
// Swap with last element and then remove.
415-
consumers[index] = consumers[consumers_length];
416-
consumers.pop();
417-
}
418-
}
419-
}
420-
if (remove_unowned && consumers_length === 0 && (dependency.f & UNOWNED) !== 0) {
421-
// If the signal is unowned then we need to make sure to change it to dirty.
422-
set_signal_status(dependency, DIRTY);
423-
remove_consumer(
424-
/** @type {import('./types.js').ComputationSignal<V>} **/ (dependency),
425-
0,
426-
true
427-
);
428-
}
448+
remove_consumer(signal, dependency, remove_unowned);
429449
}
430450
}
431451
}
@@ -445,7 +465,7 @@ function destroy_references(signal) {
445465
if ((reference.f & IS_EFFECT) !== 0) {
446466
destroy_signal(reference);
447467
} else {
448-
remove_consumer(reference, 0, true);
468+
remove_consumers(reference, 0, true);
449469
reference.d = null;
450470
}
451471
}
@@ -1103,7 +1123,7 @@ export function destroy_signal(signal) {
11031123
const destroy = signal.y;
11041124
const flags = signal.f;
11051125
destroy_references(signal);
1106-
remove_consumer(signal, 0, true);
1126+
remove_consumers(signal, 0, true);
11071127
signal.i =
11081128
signal.r =
11091129
signal.y =

0 commit comments

Comments
 (0)