Skip to content

Commit 9a3a9b8

Browse files
committed
Using a linked list instead of an array for the flush unused queue
1 parent 99d99da commit 9a3a9b8

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

src/internal/storeTrackingUsage.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import { createQueue, type QueueItem } from './linkedQueue';
12
import { RawStoreFlags } from './store';
23
import { checkNotInNotificationPhase, RawStoreWritable } from './storeWritable';
34
import { activeConsumer, untrack } from './untrack';
45

5-
let flushUnusedQueue: RawStoreTrackingUsage<any>[] | null = null;
6+
const { shift, add, remove } = createQueue<RawStoreTrackingUsage<any>>();
67
let inFlushUnused = false;
8+
let plannedFlushUnused = false;
79

810
export const flushUnused = (): void => {
911
// Ignoring coverage for the following lines because, unless there is a bug in tansu (which would have to be fixed!)
@@ -12,24 +14,27 @@ export const flushUnused = (): void => {
1214
if (inFlushUnused) {
1315
throw new Error('assert failed: recursive flushUnused call');
1416
}
17+
plannedFlushUnused = false;
1518
inFlushUnused = true;
1619
try {
17-
const queue = flushUnusedQueue;
18-
if (queue) {
19-
flushUnusedQueue = null;
20-
for (let i = 0, l = queue.length; i < l; i++) {
21-
const producer = queue[i];
22-
producer.flags &= ~RawStoreFlags.FLUSH_PLANNED;
23-
producer.checkUnused();
24-
}
20+
let producer = shift();
21+
while (producer) {
22+
producer.flags &= ~RawStoreFlags.FLUSH_PLANNED;
23+
producer.checkUnused();
24+
producer = shift();
2525
}
2626
} finally {
2727
inFlushUnused = false;
2828
}
2929
};
3030

31-
export abstract class RawStoreTrackingUsage<T> extends RawStoreWritable<T> {
31+
export abstract class RawStoreTrackingUsage<T>
32+
extends RawStoreWritable<T>
33+
implements QueueItem<RawStoreTrackingUsage<any>>
34+
{
3235
private extraUsages = 0;
36+
next: RawStoreTrackingUsage<any> | null = null;
37+
prev: RawStoreTrackingUsage<any> | null = null;
3338
abstract startUse(): void;
3439
abstract endUse(): void;
3540

@@ -42,6 +47,10 @@ export abstract class RawStoreTrackingUsage<T> extends RawStoreWritable<T> {
4247
if (!this.extraUsages && !this.consumerFirst) {
4348
throw new Error('assert failed: untracked producer usage');
4449
}
50+
if (flags & RawStoreFlags.FLUSH_PLANNED) {
51+
remove(this);
52+
this.flags &= ~RawStoreFlags.FLUSH_PLANNED;
53+
}
4554
this.flags |= RawStoreFlags.START_USE_CALLED;
4655
untrack(() => this.startUse());
4756
}
@@ -55,11 +64,11 @@ export abstract class RawStoreTrackingUsage<T> extends RawStoreWritable<T> {
5564
untrack(() => this.endUse());
5665
} else if (!(flags & RawStoreFlags.FLUSH_PLANNED)) {
5766
this.flags |= RawStoreFlags.FLUSH_PLANNED;
58-
if (!flushUnusedQueue) {
59-
flushUnusedQueue = [];
67+
if (!plannedFlushUnused) {
68+
plannedFlushUnused = true;
6069
queueMicrotask(flushUnused);
6170
}
62-
flushUnusedQueue.push(this);
71+
add(this);
6372
}
6473
}
6574
}

0 commit comments

Comments
 (0)