@optimystic/db-core 1.0.0-beta.3 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/cluster/structs.d.ts +30 -6
- package/dist/src/cluster/structs.d.ts.map +1 -1
- package/dist/src/cluster/structs.js +5 -3
- package/dist/src/cluster/structs.js.map +1 -1
- package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.d.ts +2 -1
- package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.d.ts.map +1 -1
- package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.js +10 -3
- package/dist/src/cohort-topic/antidos/bootstrap-evidence-envelope.js.map +1 -1
- package/dist/src/cohort-topic/wire/codec.d.ts.map +1 -1
- package/dist/src/cohort-topic/wire/codec.js +8 -2
- package/dist/src/cohort-topic/wire/codec.js.map +1 -1
- package/dist/src/collection/collection.d.ts +439 -34
- package/dist/src/collection/collection.d.ts.map +1 -1
- package/dist/src/collection/collection.js +843 -148
- package/dist/src/collection/collection.js.map +1 -1
- package/dist/src/collection/struct.d.ts +109 -4
- package/dist/src/collection/struct.d.ts.map +1 -1
- package/dist/src/collection/struct.js +88 -1
- package/dist/src/collection/struct.js.map +1 -1
- package/dist/src/collections/diary/diary.d.ts +6 -2
- package/dist/src/collections/diary/diary.d.ts.map +1 -1
- package/dist/src/collections/diary/diary.js +5 -2
- package/dist/src/collections/diary/diary.js.map +1 -1
- package/dist/src/collections/tree/struct.d.ts +124 -16
- package/dist/src/collections/tree/struct.d.ts.map +1 -1
- package/dist/src/collections/tree/struct.js +86 -11
- package/dist/src/collections/tree/struct.js.map +1 -1
- package/dist/src/collections/tree/tree.d.ts +13 -3
- package/dist/src/collections/tree/tree.d.ts.map +1 -1
- package/dist/src/collections/tree/tree.js +106 -40
- package/dist/src/collections/tree/tree.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/matchmaking/wire.d.ts.map +1 -1
- package/dist/src/matchmaking/wire.js +8 -2
- package/dist/src/matchmaking/wire.js.map +1 -1
- package/dist/src/network/durability.d.ts +45 -0
- package/dist/src/network/durability.d.ts.map +1 -0
- package/dist/src/network/durability.js +114 -0
- package/dist/src/network/durability.js.map +1 -0
- package/dist/src/network/i-key-network.d.ts +14 -6
- package/dist/src/network/i-key-network.d.ts.map +1 -1
- package/dist/src/network/index.d.ts +3 -0
- package/dist/src/network/index.d.ts.map +1 -1
- package/dist/src/network/index.js +3 -0
- package/dist/src/network/index.js.map +1 -1
- package/dist/src/network/lineage.d.ts +39 -0
- package/dist/src/network/lineage.d.ts.map +1 -0
- package/dist/src/network/lineage.js +61 -0
- package/dist/src/network/lineage.js.map +1 -0
- package/dist/src/network/routing-key.d.ts +24 -0
- package/dist/src/network/routing-key.d.ts.map +1 -0
- package/dist/src/network/routing-key.js +9 -0
- package/dist/src/network/routing-key.js.map +1 -0
- package/dist/src/network/stale-failure.d.ts +5 -1
- package/dist/src/network/stale-failure.d.ts.map +1 -1
- package/dist/src/network/stale-failure.js +5 -1
- package/dist/src/network/stale-failure.js.map +1 -1
- package/dist/src/network/struct.d.ts +151 -8
- package/dist/src/network/struct.d.ts.map +1 -1
- package/dist/src/network/struct.js.map +1 -1
- package/dist/src/reactivity/wire.d.ts.map +1 -1
- package/dist/src/reactivity/wire.js +8 -2
- package/dist/src/reactivity/wire.js.map +1 -1
- package/dist/src/testing/test-transactor.d.ts +64 -7
- package/dist/src/testing/test-transactor.d.ts.map +1 -1
- package/dist/src/testing/test-transactor.js +150 -23
- package/dist/src/testing/test-transactor.js.map +1 -1
- package/dist/src/transaction/coordinator.d.ts +141 -21
- package/dist/src/transaction/coordinator.d.ts.map +1 -1
- package/dist/src/transaction/coordinator.js +408 -122
- package/dist/src/transaction/coordinator.js.map +1 -1
- package/dist/src/transaction/errors.d.ts +39 -10
- package/dist/src/transaction/errors.d.ts.map +1 -1
- package/dist/src/transaction/errors.js +34 -9
- package/dist/src/transaction/errors.js.map +1 -1
- package/dist/src/transaction/index.d.ts +1 -0
- package/dist/src/transaction/index.d.ts.map +1 -1
- package/dist/src/transaction/index.js.map +1 -1
- package/dist/src/transactor/block-floors.d.ts +78 -0
- package/dist/src/transactor/block-floors.d.ts.map +1 -0
- package/dist/src/transactor/block-floors.js +62 -0
- package/dist/src/transactor/block-floors.js.map +1 -0
- package/dist/src/transactor/change-notifier.d.ts +43 -0
- package/dist/src/transactor/change-notifier.d.ts.map +1 -1
- package/dist/src/transactor/change-notifier.js +3 -0
- package/dist/src/transactor/change-notifier.js.map +1 -1
- package/dist/src/transactor/index.d.ts +1 -0
- package/dist/src/transactor/index.d.ts.map +1 -1
- package/dist/src/transactor/index.js +1 -0
- package/dist/src/transactor/index.js.map +1 -1
- package/dist/src/transactor/network-transactor.d.ts +43 -6
- package/dist/src/transactor/network-transactor.d.ts.map +1 -1
- package/dist/src/transactor/network-transactor.js +279 -86
- package/dist/src/transactor/network-transactor.js.map +1 -1
- package/dist/src/transactor/transactor-source.d.ts +94 -4
- package/dist/src/transactor/transactor-source.d.ts.map +1 -1
- package/dist/src/transactor/transactor-source.js +120 -42
- package/dist/src/transactor/transactor-source.js.map +1 -1
- package/dist/src/transactor/transactor.d.ts +14 -1
- package/dist/src/transactor/transactor.d.ts.map +1 -1
- package/dist/src/transform/atomic.d.ts.map +1 -1
- package/dist/src/transform/atomic.js +12 -9
- package/dist/src/transform/atomic.js.map +1 -1
- package/dist/src/transform/base-pins.d.ts +50 -17
- package/dist/src/transform/base-pins.d.ts.map +1 -1
- package/dist/src/transform/base-pins.js +58 -11
- package/dist/src/transform/base-pins.js.map +1 -1
- package/dist/src/transform/cache-source.d.ts +75 -11
- package/dist/src/transform/cache-source.d.ts.map +1 -1
- package/dist/src/transform/cache-source.js +162 -36
- package/dist/src/transform/cache-source.js.map +1 -1
- package/dist/src/transform/digest.d.ts +8 -1
- package/dist/src/transform/digest.d.ts.map +1 -1
- package/dist/src/transform/digest.js +19 -9
- package/dist/src/transform/digest.js.map +1 -1
- package/dist/src/transform/helpers.d.ts +6 -2
- package/dist/src/transform/helpers.d.ts.map +1 -1
- package/dist/src/transform/helpers.js +8 -3
- package/dist/src/transform/helpers.js.map +1 -1
- package/dist/src/transform/tracker.d.ts +94 -14
- package/dist/src/transform/tracker.d.ts.map +1 -1
- package/dist/src/transform/tracker.js +222 -68
- package/dist/src/transform/tracker.js.map +1 -1
- package/dist/src/utility/structural-equals.d.ts +38 -0
- package/dist/src/utility/structural-equals.d.ts.map +1 -0
- package/dist/src/utility/structural-equals.js +77 -0
- package/dist/src/utility/structural-equals.js.map +1 -0
- package/package.json +2 -2
- package/src/cluster/structs.ts +28 -7
- package/src/cohort-topic/antidos/bootstrap-evidence-envelope.ts +260 -253
- package/src/cohort-topic/wire/codec.ts +222 -216
- package/src/collection/collection.ts +960 -157
- package/src/collection/struct.ts +99 -4
- package/src/collections/diary/diary.ts +71 -68
- package/src/collections/tree/struct.ts +155 -23
- package/src/collections/tree/tree.ts +127 -40
- package/src/index.ts +1 -1
- package/src/matchmaking/wire.ts +8 -2
- package/src/network/durability.ts +123 -0
- package/src/network/i-key-network.ts +60 -52
- package/src/network/index.ts +10 -7
- package/src/network/lineage.ts +80 -0
- package/src/network/routing-key.ts +27 -0
- package/src/network/stale-failure.ts +5 -1
- package/src/network/struct.ts +156 -8
- package/src/reactivity/wire.ts +230 -224
- package/src/testing/test-transactor.ts +152 -24
- package/src/transaction/coordinator.ts +470 -131
- package/src/transaction/errors.ts +34 -9
- package/src/transaction/index.ts +1 -0
- package/src/transactor/block-floors.ts +105 -0
- package/src/transactor/change-notifier.ts +129 -80
- package/src/transactor/index.ts +1 -0
- package/src/transactor/network-transactor.ts +297 -89
- package/src/transactor/transactor-source.ts +131 -42
- package/src/transactor/transactor.ts +13 -1
- package/src/transform/atomic.ts +25 -22
- package/src/transform/base-pins.ts +76 -18
- package/src/transform/cache-source.ts +327 -194
- package/src/transform/digest.ts +21 -10
- package/src/transform/helpers.ts +8 -3
- package/src/transform/tracker.ts +423 -270
- package/src/utility/structural-equals.ts +72 -0
- package/dist/src/utility/block-id-to-bytes.d.ts +0 -3
- package/dist/src/utility/block-id-to-bytes.d.ts.map +0 -1
- package/dist/src/utility/block-id-to-bytes.js +0 -7
- package/dist/src/utility/block-id-to-bytes.js.map +0 -1
- package/src/utility/block-id-to-bytes.ts +0 -8
|
@@ -9,7 +9,8 @@ export declare class Tracker<T extends IBlock> implements IBlockStore<T> {
|
|
|
9
9
|
/** The collected set of transformations to be applied. Treat as immutable */
|
|
10
10
|
transforms: import("./struct.js").Transforms;
|
|
11
11
|
/** Committed bases pinned at the moment each update was staged, so the digest pass can
|
|
12
|
-
* describe every updated block even after the read cache evicts its base
|
|
12
|
+
* describe every updated block even after the read cache evicts its base, and so the pend
|
|
13
|
+
* can name the revision each block's operations were computed against. Shared by
|
|
13
14
|
* reference across the trackers of one transaction (see {@link BasePins}); pass an
|
|
14
15
|
* existing store to join a transaction, omit for a private one. */
|
|
15
16
|
readonly pins: BasePins;
|
|
@@ -25,7 +26,8 @@ export declare class Tracker<T extends IBlock> implements IBlockStore<T> {
|
|
|
25
26
|
/** The collected set of transformations to be applied. Treat as immutable */
|
|
26
27
|
transforms?: import("./struct.js").Transforms,
|
|
27
28
|
/** Committed bases pinned at the moment each update was staged, so the digest pass can
|
|
28
|
-
* describe every updated block even after the read cache evicts its base
|
|
29
|
+
* describe every updated block even after the read cache evicts its base, and so the pend
|
|
30
|
+
* can name the revision each block's operations were computed against. Shared by
|
|
29
31
|
* reference across the trackers of one transaction (see {@link BasePins}); pass an
|
|
30
32
|
* existing store to join a transaction, omit for a private one. */
|
|
31
33
|
pins?: BasePins);
|
|
@@ -35,35 +37,87 @@ export declare class Tracker<T extends IBlock> implements IBlockStore<T> {
|
|
|
35
37
|
private baseSource;
|
|
36
38
|
/** The source's generation for an id, or undefined if the source cannot report drift. */
|
|
37
39
|
private sourceGeneration;
|
|
40
|
+
/** Whether the source will answer the next read of `id` from memory with the base it just served.
|
|
41
|
+
* A source that cannot say is taken to — the behaviour before the probe, and right for every
|
|
42
|
+
* source but a CacheSource handing an answer through unkept.
|
|
43
|
+
*
|
|
44
|
+
* The generation cannot carry this. A memo is stamped with the generation read AFTER the load
|
|
45
|
+
* (see {@link tryGet}), so however the source bumps while handing an unkept answer through, the
|
|
46
|
+
* stamp matches on the next read and the memo is served — freezing, under this tracker's staged
|
|
47
|
+
* ops, exactly the base the source declined to freeze. */
|
|
48
|
+
private sourceRetains;
|
|
38
49
|
/** The drift generation from the same authority {@link probeBase} pins from — the base source,
|
|
39
50
|
* so an Atomic validates its pins against the collection's read cache rather than against the
|
|
40
51
|
* drift-blind tracker in between. */
|
|
41
52
|
protected baseGeneration(id: BlockId): number | undefined;
|
|
42
|
-
/** The
|
|
43
|
-
*
|
|
53
|
+
/** The base for `id` as the base source describes it now: its committed revision, its content
|
|
54
|
+
* when the source still has it, and the source's drift generation. Taken from
|
|
44
55
|
* {@link baseSource}, so an Atomic staged over a Collection's tracker pins from the collection's
|
|
45
|
-
* read cache instead of finding nothing. Returns undefined unless
|
|
46
|
-
*
|
|
47
|
-
*
|
|
56
|
+
* read cache instead of finding nothing. Returns undefined unless the source reports drift and a
|
|
57
|
+
* revision — which keeps drift-blind sources (test doubles) on exactly the pre-pin behaviour,
|
|
58
|
+
* and leaves a blind update (a block never read, or read and since cleared) unpinned. A
|
|
59
|
+
* revision without content is a REV-ONLY pin: the block was read and then evicted, so the base
|
|
60
|
+
* can be named but not materialized (see {@link PinnedBase.block}). Recency-neutral. */
|
|
48
61
|
protected probeBase(id: BlockId): PinnedBase | undefined;
|
|
62
|
+
/** Re-judge `pin` against what the base source describes for `id` NOW, if the source's
|
|
63
|
+
* generation for the id has advanced since the pin was last judged. The source's content for
|
|
64
|
+
* the id changed hands; whether the BASE moved is a question of revision, not generation:
|
|
65
|
+
*
|
|
66
|
+
* - the same revision (a re-load of an evicted id, a refresh that re-read identical content, a
|
|
67
|
+
* below-floor answer served again) is the same committed content, so the pin is refreshed in
|
|
68
|
+
* place — the clone filled or replaced, the generation restamped — and stays declarable;
|
|
69
|
+
* - a different revision, or none (the id cleared, folded away, or handed through at another
|
|
70
|
+
* revision), means the staged operations were computed on content the source no longer
|
|
71
|
+
* describes. The pin is marked {@link PinnedBase.moved} and is never repaired here: re-pinning
|
|
72
|
+
* would put the new revision on operations built for the old one, which is precisely the wrong
|
|
73
|
+
* base the storage guard cannot catch. Only a re-stage (which resets this tracker) recovers.
|
|
74
|
+
*
|
|
75
|
+
* Cheap — one generation compare on the common path, two probes on drift — so every consumer of
|
|
76
|
+
* a pin runs it first. */
|
|
77
|
+
private revalidatePin;
|
|
49
78
|
tryGet(id: BlockId, purpose?: ReadPurpose): Promise<T | undefined>;
|
|
50
79
|
/** The block `id` materializes to under the staged transforms, computed WITHOUT loading from the
|
|
51
80
|
* source, plus the committed revision of the base used. `undefined` when not computable here —
|
|
52
|
-
* nothing staged for the id, the result is a delete, or an update's base
|
|
53
|
-
*
|
|
54
|
-
* describe itself)
|
|
81
|
+
* nothing staged for the id, the result is a delete, or an update's base cannot be materialized:
|
|
82
|
+
* unpinned over a drift-blind source and not locally cached (a commit must not pay a network
|
|
83
|
+
* round trip to describe itself), pinned rev-only (the content was evicted before the update was
|
|
84
|
+
* staged — the base is still named by {@link stagedBaseRevs}, only its digest is undeclared), or
|
|
85
|
+
* pinned but MOVED (the operations no longer describe any content; see {@link revalidatePin}).
|
|
55
86
|
*
|
|
56
87
|
* Materializes with the canonical {@link applyTransform} — the exact function the member side
|
|
57
88
|
* uses at commit — so client and member can never disagree on semantics (insert replaces the
|
|
58
89
|
* block, then updates apply, then delete wins). An insert makes the result base-independent, so
|
|
59
|
-
* `baseRev` is absent; updates-only returns the base's
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
90
|
+
* `baseRev` is absent; updates-only returns the pinned base's revision, which is the revision the
|
|
91
|
+
* staged operations were computed against — never the live cache's, which may have moved on.
|
|
92
|
+
* Memo-neutral and recency-neutral: reads observe no change. The one thing it may record is the
|
|
93
|
+
* discovery that a pinned base has moved. */
|
|
63
94
|
peekMaterialized(id: BlockId): {
|
|
64
95
|
block: IBlock;
|
|
65
96
|
baseRev?: number;
|
|
66
97
|
} | undefined;
|
|
98
|
+
/** Per block in `blockIds`, the committed revision its staged UPDATE operations were computed
|
|
99
|
+
* against — the pinned base, fixed when the first of them was staged and unchanged since, even
|
|
100
|
+
* if the base has moved (a moved base is still the truth about the operations; the pend
|
|
101
|
+
* carrying it is refused, which is the point). Only update-only blocks are named: an inserted
|
|
102
|
+
* block is base-independent, a deleted one materializes to nothing, and a block updated
|
|
103
|
+
* without a pin (a blind update, or a drift-blind source) has no base to name. */
|
|
104
|
+
stagedBaseRevs(blockIds: readonly BlockId[]): Record<BlockId, number>;
|
|
105
|
+
/** The staged update-only blocks whose pinned base has MOVED — the base source no longer
|
|
106
|
+
* describes the id at the revision the operations were computed against — after re-judging
|
|
107
|
+
* every such pin against the source (one generation compare each; see {@link revalidatePin}).
|
|
108
|
+
* Restricted to ids THIS tracker stages as updates: the shared store can also hold pins an
|
|
109
|
+
* abandoned per-attempt tracker took for its log blocks, which describe operations this tracker
|
|
110
|
+
* does not carry. A non-empty answer means the pending actions must be re-staged before they
|
|
111
|
+
* are pended (Collection.restageIfBasesMoved). */
|
|
112
|
+
movedBases(): BlockId[];
|
|
113
|
+
/** The staged update-only blocks whose pinned base the base source describes but does not RETAIN
|
|
114
|
+
* — content handed through unkept (a below-floor answer), which the source re-asks for on every
|
|
115
|
+
* read. The pin names the revision last served; storage may have caught up since without any
|
|
116
|
+
* log movement to say so, and only a read can tell. The candidates for a pre-pend re-read. */
|
|
117
|
+
unretainedBases(): BlockId[];
|
|
118
|
+
/** Whether `id` is staged as updates alone — not inserted (base-independent) and not deleted
|
|
119
|
+
* (materializes to nothing), the two shapes for which no base is ever named. */
|
|
120
|
+
private isUpdateOnly;
|
|
67
121
|
/** Forward a leaf-value upgrade down to the source's read collector (duck-typed: only the
|
|
68
122
|
* CacheSource layer implements it). Lets the B-tree point-lookup descent, which reads through
|
|
69
123
|
* this tracker, pin its terminal leaf as a `value` read after tagging interior nodes
|
|
@@ -73,6 +127,32 @@ export declare class Tracker<T extends IBlock> implements IBlockStore<T> {
|
|
|
73
127
|
createBlockHeader(type: BlockType, newId?: BlockId): BlockHeader;
|
|
74
128
|
insert(block: T): void;
|
|
75
129
|
update(blockId: BlockId, op: BlockOperation): void;
|
|
130
|
+
/** Fold a child tracker's staged transform into this one — the flush behind {@link Atomic.commit}
|
|
131
|
+
* — and empty the child. The child's pins are adopted first ({@link BasePins.adopt}), and an
|
|
132
|
+
* update whose id the child pinned keeps that pin as the base of its first operation here rather
|
|
133
|
+
* than probing the base source: the child's pin IS the base those operations were computed
|
|
134
|
+
* against, while the source may have moved on since (a concurrent unlatched read that reloaded
|
|
135
|
+
* the block at a newer revision), and probing would put the newer revision on operations built
|
|
136
|
+
* for the older one — the wrong base the storage-side guard cannot catch. An adopted pin the
|
|
137
|
+
* source no longer describes at its revision is judged moved on its next use, like any pin. An
|
|
138
|
+
* update the child did NOT pin (a blind one) is pinned here exactly as a direct update would be. */
|
|
139
|
+
absorb(child: Tracker<T>): void;
|
|
140
|
+
/** Stage `op` for `blockId` — folded into a staged insert if there is one, else appended to the
|
|
141
|
+
* id's update list — and keep the materialized memo current. Returns whether this was the FIRST
|
|
142
|
+
* update staged for the id here: the moment its base is fixed (see {@link pinBase}). */
|
|
143
|
+
private stageUpdate;
|
|
144
|
+
/** Fix the base of `id`'s staged operations at the moment the FIRST of them is staged in this
|
|
145
|
+
* tracker: the caller just read the block, so the base source describes what the operation was
|
|
146
|
+
* computed against. Whatever the store held for the id before is replaced (or dropped, when the
|
|
147
|
+
* source can pin nothing): no operations of THIS tracker's list were computed on it — a pin that
|
|
148
|
+
* outlived its tracker, such as an abandoned per-attempt tracker's log-block pin from before a
|
|
149
|
+
* refresh cleared the block, would otherwise speak for operations built on something else.
|
|
150
|
+
* (The one pre-existing pin that IS this list's base, an atomic's, is kept by {@link absorb},
|
|
151
|
+
* which never comes through here for it.) A later operation for the same id never re-pins: it
|
|
152
|
+
* re-judges the pin ({@link recheckPin}), and a base found to have moved stays moved. */
|
|
153
|
+
private pinBase;
|
|
154
|
+
/** Re-judge `id`'s pin, if it has one, against the base source (see {@link revalidatePin}). */
|
|
155
|
+
private recheckPin;
|
|
76
156
|
delete(blockId: BlockId): void;
|
|
77
157
|
reset(newTransform?: import("./struct.js").Transforms): import("./struct.js").Transforms;
|
|
78
158
|
transformedBlockIds(): BlockId[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../../src/transform/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,IAAI,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,IAAI,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEhK,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../../src/transform/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,IAAI,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,IAAI,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEhK,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAuBjD;;GAEG;AACH,qBAAa,OAAO,CAAC,CAAC,SAAS,MAAM,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;IAW9D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,6EAA6E;IACtE,UAAU;IACjB;;;;uEAImE;aACnD,IAAI,EAAE,QAAQ;IAlB/B;;;;;;yDAMqD;IACrD,OAAO,CAAC,YAAY,CAAiD;gBAGnD,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IACxC,6EAA6E;IACtE,UAAU,mCAAoB;IACrC;;;;uEAImE;IACnD,IAAI,GAAE,QAAyB;IAUhD;;kGAE8F;IAC9F,OAAO,CAAC,UAAU;IAMlB,yFAAyF;IACzF,OAAO,CAAC,gBAAgB;IAKxB;;;;;;;8DAO0D;IAC1D,OAAO,CAAC,aAAa;IAKrB;;yCAEqC;IACrC,SAAS,CAAC,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS;IAKzD;;;;;;;4FAOwF;IACxF,SAAS,CAAC,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS;IAUxD;;;;;;;;;;;;;;8BAc0B;IAC1B,OAAO,CAAC,aAAa;IAef,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,GAAE,WAAqB,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IA6CjF;;;;;;;;;;;;;;iDAc6C;IAC7C,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;IAmC9E;;;;;sFAKkF;IAClF,cAAc,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC;IAUrE;;;;;;sDAMkD;IAClD,UAAU,IAAI,OAAO,EAAE;IASvB;;;kGAG8F;IAC9F,eAAe,IAAI,OAAO,EAAE;IAU5B;oFACgF;IAChF,OAAO,CAAC,YAAY;IAMpB;;;+FAG2F;IAC3F,aAAa,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI;IAIhC,UAAU,IAAI,OAAO;IAIrB,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,WAAW;IAIhE,MAAM,CAAC,KAAK,EAAE,CAAC;IAcf,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,cAAc;IAK3C;;;;;;;;wGAQoG;IACpG,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;IAc/B;;4FAEwF;IACxF,OAAO,CAAC,WAAW;IAqBnB;;;;;;;;6FAQyF;IACzF,OAAO,CAAC,OAAO;IAMf,+FAA+F;IAC/F,OAAO,CAAC,UAAU;IAKlB,MAAM,CAAC,OAAO,EAAE,OAAO;IAUvB,KAAK,CAAC,YAAY,mCAAoB;IAWtC,mBAAmB,IAAI,OAAO,EAAE;IAIhC,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CAGhC"}
|
|
@@ -2,13 +2,8 @@ import { applyOperation, applyOperations, applyTransform, emptyTransforms, block
|
|
|
2
2
|
import { BasePins } from "./base-pins.js";
|
|
3
3
|
import { ensured } from "../utility/ensured.js";
|
|
4
4
|
/** The base a source can answer from memory, with the committed revision of that content — the
|
|
5
|
-
* shared probe behind
|
|
6
|
-
*
|
|
7
|
-
* because Tracker layers over test doubles as well as CacheSource.
|
|
8
|
-
*
|
|
9
|
-
* Returns undefined unless BOTH probes answer: an LRU-evicted id can leave a stale cached revision
|
|
10
|
-
* behind (see the NOTE on CacheSource's `revisions` map), and `peek` returning undefined for that id
|
|
11
|
-
* is what keeps the stale revision from pairing with a block. */
|
|
5
|
+
* shared probe behind the unpinned {@link Tracker.peekMaterialized} path, for a source that cannot
|
|
6
|
+
* report drift and so takes no pins. Returns undefined unless BOTH probes answer. */
|
|
12
7
|
function cachedBase(source, id) {
|
|
13
8
|
const src = source;
|
|
14
9
|
if (typeof src.peek !== 'function' || typeof src.getCachedRevision !== 'function')
|
|
@@ -36,7 +31,8 @@ export class Tracker {
|
|
|
36
31
|
/** The collected set of transformations to be applied. Treat as immutable */
|
|
37
32
|
transforms = emptyTransforms(),
|
|
38
33
|
/** Committed bases pinned at the moment each update was staged, so the digest pass can
|
|
39
|
-
* describe every updated block even after the read cache evicts its base
|
|
34
|
+
* describe every updated block even after the read cache evicts its base, and so the pend
|
|
35
|
+
* can name the revision each block's operations were computed against. Shared by
|
|
40
36
|
* reference across the trackers of one transaction (see {@link BasePins}); pass an
|
|
41
37
|
* existing store to join a transaction, omit for a private one. */
|
|
42
38
|
pins = new BasePins()) {
|
|
@@ -64,6 +60,18 @@ export class Tracker {
|
|
|
64
60
|
const src = this.source;
|
|
65
61
|
return typeof src.getGeneration === 'function' ? src.getGeneration(id) : undefined;
|
|
66
62
|
}
|
|
63
|
+
/** Whether the source will answer the next read of `id` from memory with the base it just served.
|
|
64
|
+
* A source that cannot say is taken to — the behaviour before the probe, and right for every
|
|
65
|
+
* source but a CacheSource handing an answer through unkept.
|
|
66
|
+
*
|
|
67
|
+
* The generation cannot carry this. A memo is stamped with the generation read AFTER the load
|
|
68
|
+
* (see {@link tryGet}), so however the source bumps while handing an unkept answer through, the
|
|
69
|
+
* stamp matches on the next read and the memo is served — freezing, under this tracker's staged
|
|
70
|
+
* ops, exactly the base the source declined to freeze. */
|
|
71
|
+
sourceRetains(id) {
|
|
72
|
+
const src = this.source;
|
|
73
|
+
return typeof src.retains !== 'function' || src.retains(id);
|
|
74
|
+
}
|
|
67
75
|
/** The drift generation from the same authority {@link probeBase} pins from — the base source,
|
|
68
76
|
* so an Atomic validates its pins against the collection's read cache rather than against the
|
|
69
77
|
* drift-blind tracker in between. */
|
|
@@ -71,19 +79,54 @@ export class Tracker {
|
|
|
71
79
|
const src = this.baseSource();
|
|
72
80
|
return typeof src.getGeneration === 'function' ? src.getGeneration(id) : undefined;
|
|
73
81
|
}
|
|
74
|
-
/** The
|
|
75
|
-
*
|
|
82
|
+
/** The base for `id` as the base source describes it now: its committed revision, its content
|
|
83
|
+
* when the source still has it, and the source's drift generation. Taken from
|
|
76
84
|
* {@link baseSource}, so an Atomic staged over a Collection's tracker pins from the collection's
|
|
77
|
-
* read cache instead of finding nothing. Returns undefined unless
|
|
78
|
-
*
|
|
79
|
-
*
|
|
85
|
+
* read cache instead of finding nothing. Returns undefined unless the source reports drift and a
|
|
86
|
+
* revision — which keeps drift-blind sources (test doubles) on exactly the pre-pin behaviour,
|
|
87
|
+
* and leaves a blind update (a block never read, or read and since cleared) unpinned. A
|
|
88
|
+
* revision without content is a REV-ONLY pin: the block was read and then evicted, so the base
|
|
89
|
+
* can be named but not materialized (see {@link PinnedBase.block}). Recency-neutral. */
|
|
80
90
|
probeBase(id) {
|
|
81
91
|
const src = this.baseSource();
|
|
82
|
-
// Without a drift signal a pin could never be
|
|
83
|
-
if (typeof src.getGeneration !== 'function')
|
|
92
|
+
// Without a drift signal a pin could never be re-judged, so never take one.
|
|
93
|
+
if (typeof src.getGeneration !== 'function' || typeof src.getCachedRevision !== 'function')
|
|
94
|
+
return undefined;
|
|
95
|
+
const rev = src.getCachedRevision(id);
|
|
96
|
+
if (rev === undefined)
|
|
84
97
|
return undefined;
|
|
85
|
-
const
|
|
86
|
-
return
|
|
98
|
+
const block = typeof src.peek === 'function' ? src.peek(id) : undefined;
|
|
99
|
+
return { rev, gen: src.getGeneration(id), ...(block === undefined ? {} : { block }) };
|
|
100
|
+
}
|
|
101
|
+
/** Re-judge `pin` against what the base source describes for `id` NOW, if the source's
|
|
102
|
+
* generation for the id has advanced since the pin was last judged. The source's content for
|
|
103
|
+
* the id changed hands; whether the BASE moved is a question of revision, not generation:
|
|
104
|
+
*
|
|
105
|
+
* - the same revision (a re-load of an evicted id, a refresh that re-read identical content, a
|
|
106
|
+
* below-floor answer served again) is the same committed content, so the pin is refreshed in
|
|
107
|
+
* place — the clone filled or replaced, the generation restamped — and stays declarable;
|
|
108
|
+
* - a different revision, or none (the id cleared, folded away, or handed through at another
|
|
109
|
+
* revision), means the staged operations were computed on content the source no longer
|
|
110
|
+
* describes. The pin is marked {@link PinnedBase.moved} and is never repaired here: re-pinning
|
|
111
|
+
* would put the new revision on operations built for the old one, which is precisely the wrong
|
|
112
|
+
* base the storage guard cannot catch. Only a re-stage (which resets this tracker) recovers.
|
|
113
|
+
*
|
|
114
|
+
* Cheap — one generation compare on the common path, two probes on drift — so every consumer of
|
|
115
|
+
* a pin runs it first. */
|
|
116
|
+
revalidatePin(id, pin) {
|
|
117
|
+
const gen = this.baseGeneration(id);
|
|
118
|
+
if (pin.moved || gen === undefined || pin.gen === gen)
|
|
119
|
+
return pin;
|
|
120
|
+
const src = this.baseSource();
|
|
121
|
+
const rev = typeof src.getCachedRevision === 'function' ? src.getCachedRevision(id) : undefined;
|
|
122
|
+
if (rev !== pin.rev) {
|
|
123
|
+
this.pins.markMoved(id);
|
|
124
|
+
return pin;
|
|
125
|
+
}
|
|
126
|
+
const block = typeof src.peek === 'function' ? src.peek(id) : undefined;
|
|
127
|
+
const refreshed = { rev, gen, ...(block ?? pin.block ? { block: block ?? pin.block } : {}) };
|
|
128
|
+
this.pins.set(id, refreshed);
|
|
129
|
+
return refreshed;
|
|
87
130
|
}
|
|
88
131
|
async tryGet(id, purpose = 'value') {
|
|
89
132
|
// NOTE: precedence here is insert > delete > source+updates. In a well-formed transform an id is
|
|
@@ -109,14 +152,22 @@ export class Tracker {
|
|
|
109
152
|
if (block) {
|
|
110
153
|
const ops = this.transforms.updates?.[id] ?? [];
|
|
111
154
|
if (ops.length > 0) {
|
|
155
|
+
// A read of a block whose base has MOVED under its staged ops is served as the live
|
|
156
|
+
// content plus those ops all the same — never refused. The pend is what pays for a
|
|
157
|
+
// moved base (Collection.restageIfBasesMoved), with one replay.
|
|
112
158
|
applyOperations(block, ops);
|
|
113
159
|
// Memoize only when the source can report drift, and stamp with the generation read
|
|
114
160
|
// AFTER the load — the source may bump during tryGet (a cache miss-load), and stamping
|
|
115
161
|
// with the pre-load generation would force a needless reload on the very next read.
|
|
162
|
+
// And only over a base the source kept: one it will re-ask for must be re-asked for
|
|
163
|
+
// here too, or this memo outlives the source's own refusal to remember it.
|
|
116
164
|
const freshGen = this.sourceGeneration(id);
|
|
117
|
-
if (freshGen !== undefined) {
|
|
165
|
+
if (freshGen !== undefined && this.sourceRetains(id)) {
|
|
118
166
|
this.materialized.set(id, { block, gen: freshGen });
|
|
119
167
|
}
|
|
168
|
+
else {
|
|
169
|
+
this.materialized.delete(id);
|
|
170
|
+
}
|
|
120
171
|
return structuredClone(block); // clone so callers can't mutate the memo
|
|
121
172
|
}
|
|
122
173
|
}
|
|
@@ -124,17 +175,19 @@ export class Tracker {
|
|
|
124
175
|
}
|
|
125
176
|
/** The block `id` materializes to under the staged transforms, computed WITHOUT loading from the
|
|
126
177
|
* source, plus the committed revision of the base used. `undefined` when not computable here —
|
|
127
|
-
* nothing staged for the id, the result is a delete, or an update's base
|
|
128
|
-
*
|
|
129
|
-
* describe itself)
|
|
178
|
+
* nothing staged for the id, the result is a delete, or an update's base cannot be materialized:
|
|
179
|
+
* unpinned over a drift-blind source and not locally cached (a commit must not pay a network
|
|
180
|
+
* round trip to describe itself), pinned rev-only (the content was evicted before the update was
|
|
181
|
+
* staged — the base is still named by {@link stagedBaseRevs}, only its digest is undeclared), or
|
|
182
|
+
* pinned but MOVED (the operations no longer describe any content; see {@link revalidatePin}).
|
|
130
183
|
*
|
|
131
184
|
* Materializes with the canonical {@link applyTransform} — the exact function the member side
|
|
132
185
|
* uses at commit — so client and member can never disagree on semantics (insert replaces the
|
|
133
186
|
* block, then updates apply, then delete wins). An insert makes the result base-independent, so
|
|
134
|
-
* `baseRev` is absent; updates-only returns the base's
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
187
|
+
* `baseRev` is absent; updates-only returns the pinned base's revision, which is the revision the
|
|
188
|
+
* staged operations were computed against — never the live cache's, which may have moved on.
|
|
189
|
+
* Memo-neutral and recency-neutral: reads observe no change. The one thing it may record is the
|
|
190
|
+
* discovery that a pinned base has moved. */
|
|
138
191
|
peekMaterialized(id) {
|
|
139
192
|
const transform = transformForBlockId(this.transforms, id);
|
|
140
193
|
if (transform.insert === undefined && transform.updates === undefined && transform.delete === undefined) {
|
|
@@ -144,33 +197,89 @@ export class Tracker {
|
|
|
144
197
|
return undefined; // delete-last-wins: materializes to nothing
|
|
145
198
|
}
|
|
146
199
|
if (transform.insert) {
|
|
147
|
-
//
|
|
148
|
-
// clones `updates` but NOT `insert`, so clone here to keep the staged transform pristine.
|
|
149
|
-
transform.insert = structuredClone(transform.insert);
|
|
200
|
+
// No clone needed: transformForBlockId already deep-cloned `insert`, which applyTransform mutates.
|
|
150
201
|
const block = applyTransform(undefined, transform);
|
|
151
202
|
return block ? { block } : undefined;
|
|
152
203
|
}
|
|
153
|
-
// Prefer the base pinned when the update was staged — it survives read-cache eviction, which
|
|
154
|
-
// is what keeps digest coverage a function of the transaction rather than of cache residency.
|
|
155
|
-
// The freshness check is correctness-critical, not an optimisation: a stale pin would declare
|
|
156
|
-
// a digest the member disagrees with, turning a blind-but-passing vote into a REJECT — an
|
|
157
|
-
// inaccurate declaration is strictly worse than no declaration, so a drifted pin falls through
|
|
158
|
-
// to the live peek below (which re-answers from the refreshed cache, or omits). The clone on
|
|
159
|
-
// use is also required, not defensive: applyTransform mutates, and syncAttempts re-runs the
|
|
160
|
-
// digest pass on every retry attempt against the same pin.
|
|
161
204
|
const pin = this.pins.get(id);
|
|
162
|
-
if (pin
|
|
163
|
-
const
|
|
164
|
-
|
|
205
|
+
if (pin) {
|
|
206
|
+
const current = this.revalidatePin(id, pin);
|
|
207
|
+
if (current.moved || current.block === undefined)
|
|
208
|
+
return undefined;
|
|
209
|
+
// The clone on use is required, not defensive: applyTransform mutates, and syncAttempts
|
|
210
|
+
// re-runs the digest pass on every retry attempt against the same pin.
|
|
211
|
+
const block = applyTransform(structuredClone(current.block), transform);
|
|
212
|
+
return block ? { block, baseRev: current.rev } : undefined;
|
|
165
213
|
}
|
|
166
|
-
// Unpinned
|
|
167
|
-
//
|
|
214
|
+
// Unpinned. Over a drift-aware base source that is a blind update (the block was never read,
|
|
215
|
+
// or was cleared before the update was staged): nothing is known about what the operations
|
|
216
|
+
// were computed against, so nothing is declared — the live cache may hold the block by now,
|
|
217
|
+
// but declaring ITS revision would name a base the operations were not built on. Only a
|
|
218
|
+
// drift-blind source, which takes no pins, keeps its pre-pin behaviour: the IMMEDIATE source's
|
|
219
|
+
// live peek, not {@link baseSource}, exactly as before pins existed.
|
|
220
|
+
if (typeof this.baseSource().getGeneration === 'function')
|
|
221
|
+
return undefined;
|
|
168
222
|
const base = cachedBase(this.source, id);
|
|
169
223
|
if (!base)
|
|
170
224
|
return undefined;
|
|
171
225
|
const block = applyTransform(base.block, transform); // base already a clone (peek contract)
|
|
172
226
|
return block ? { block, baseRev: base.rev } : undefined;
|
|
173
227
|
}
|
|
228
|
+
/** Per block in `blockIds`, the committed revision its staged UPDATE operations were computed
|
|
229
|
+
* against — the pinned base, fixed when the first of them was staged and unchanged since, even
|
|
230
|
+
* if the base has moved (a moved base is still the truth about the operations; the pend
|
|
231
|
+
* carrying it is refused, which is the point). Only update-only blocks are named: an inserted
|
|
232
|
+
* block is base-independent, a deleted one materializes to nothing, and a block updated
|
|
233
|
+
* without a pin (a blind update, or a drift-blind source) has no base to name. */
|
|
234
|
+
stagedBaseRevs(blockIds) {
|
|
235
|
+
const revs = {};
|
|
236
|
+
for (const id of blockIds) {
|
|
237
|
+
if (!this.isUpdateOnly(id))
|
|
238
|
+
continue;
|
|
239
|
+
const pin = this.pins.get(id);
|
|
240
|
+
if (pin)
|
|
241
|
+
revs[id] = pin.rev;
|
|
242
|
+
}
|
|
243
|
+
return revs;
|
|
244
|
+
}
|
|
245
|
+
/** The staged update-only blocks whose pinned base has MOVED — the base source no longer
|
|
246
|
+
* describes the id at the revision the operations were computed against — after re-judging
|
|
247
|
+
* every such pin against the source (one generation compare each; see {@link revalidatePin}).
|
|
248
|
+
* Restricted to ids THIS tracker stages as updates: the shared store can also hold pins an
|
|
249
|
+
* abandoned per-attempt tracker took for its log blocks, which describe operations this tracker
|
|
250
|
+
* does not carry. A non-empty answer means the pending actions must be re-staged before they
|
|
251
|
+
* are pended (Collection.restageIfBasesMoved). */
|
|
252
|
+
movedBases() {
|
|
253
|
+
const moved = [];
|
|
254
|
+
for (const id of Object.keys(this.transforms.updates ?? {})) {
|
|
255
|
+
const pin = this.pins.get(id);
|
|
256
|
+
if (pin && this.isUpdateOnly(id) && this.revalidatePin(id, pin).moved)
|
|
257
|
+
moved.push(id);
|
|
258
|
+
}
|
|
259
|
+
return moved;
|
|
260
|
+
}
|
|
261
|
+
/** The staged update-only blocks whose pinned base the base source describes but does not RETAIN
|
|
262
|
+
* — content handed through unkept (a below-floor answer), which the source re-asks for on every
|
|
263
|
+
* read. The pin names the revision last served; storage may have caught up since without any
|
|
264
|
+
* log movement to say so, and only a read can tell. The candidates for a pre-pend re-read. */
|
|
265
|
+
unretainedBases() {
|
|
266
|
+
const src = this.baseSource();
|
|
267
|
+
if (typeof src.retains !== 'function' || typeof src.peek !== 'function')
|
|
268
|
+
return [];
|
|
269
|
+
const ids = [];
|
|
270
|
+
for (const id of Object.keys(this.transforms.updates ?? {})) {
|
|
271
|
+
if (this.isUpdateOnly(id) && this.pins.get(id) && !src.retains(id) && src.peek(id) !== undefined)
|
|
272
|
+
ids.push(id);
|
|
273
|
+
}
|
|
274
|
+
return ids;
|
|
275
|
+
}
|
|
276
|
+
/** Whether `id` is staged as updates alone — not inserted (base-independent) and not deleted
|
|
277
|
+
* (materializes to nothing), the two shapes for which no base is ever named. */
|
|
278
|
+
isUpdateOnly(id) {
|
|
279
|
+
return (this.transforms.updates?.[id]?.length ?? 0) > 0
|
|
280
|
+
&& !(this.transforms.inserts && Object.hasOwn(this.transforms.inserts, id))
|
|
281
|
+
&& !this.transforms.deletes?.includes(id);
|
|
282
|
+
}
|
|
174
283
|
/** Forward a leaf-value upgrade down to the source's read collector (duck-typed: only the
|
|
175
284
|
* CacheSource layer implements it). Lets the B-tree point-lookup descent, which reads through
|
|
176
285
|
* this tracker, pin its terminal leaf as a `value` read after tagging interior nodes
|
|
@@ -198,37 +307,81 @@ export class Tracker {
|
|
|
198
307
|
}
|
|
199
308
|
}
|
|
200
309
|
update(blockId, op) {
|
|
310
|
+
if (this.stageUpdate(blockId, op))
|
|
311
|
+
this.pinBase(blockId);
|
|
312
|
+
else
|
|
313
|
+
this.recheckPin(blockId);
|
|
314
|
+
}
|
|
315
|
+
/** Fold a child tracker's staged transform into this one — the flush behind {@link Atomic.commit}
|
|
316
|
+
* — and empty the child. The child's pins are adopted first ({@link BasePins.adopt}), and an
|
|
317
|
+
* update whose id the child pinned keeps that pin as the base of its first operation here rather
|
|
318
|
+
* than probing the base source: the child's pin IS the base those operations were computed
|
|
319
|
+
* against, while the source may have moved on since (a concurrent unlatched read that reloaded
|
|
320
|
+
* the block at a newer revision), and probing would put the newer revision on operations built
|
|
321
|
+
* for the older one — the wrong base the storage-side guard cannot catch. An adopted pin the
|
|
322
|
+
* source no longer describes at its revision is judged moved on its next use, like any pin. An
|
|
323
|
+
* update the child did NOT pin (a blind one) is pinned here exactly as a direct update would be. */
|
|
324
|
+
absorb(child) {
|
|
325
|
+
this.pins.adopt(child.pins);
|
|
326
|
+
const adopted = new Set(child.pins.ids());
|
|
327
|
+
const transform = child.reset();
|
|
328
|
+
for (const blockId of transform.deletes ?? [])
|
|
329
|
+
this.delete(blockId);
|
|
330
|
+
for (const block of Object.values(transform.inserts ?? {}))
|
|
331
|
+
this.insert(block);
|
|
332
|
+
for (const [blockId, ops] of Object.entries(transform.updates ?? {})) {
|
|
333
|
+
for (const op of ops) {
|
|
334
|
+
if (this.stageUpdate(blockId, op) && !adopted.has(blockId))
|
|
335
|
+
this.pinBase(blockId);
|
|
336
|
+
else
|
|
337
|
+
this.recheckPin(blockId);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/** Stage `op` for `blockId` — folded into a staged insert if there is one, else appended to the
|
|
342
|
+
* id's update list — and keep the materialized memo current. Returns whether this was the FIRST
|
|
343
|
+
* update staged for the id here: the moment its base is fixed (see {@link pinBase}). */
|
|
344
|
+
stageUpdate(blockId, op) {
|
|
201
345
|
const inserted = this.transforms.inserts?.[blockId];
|
|
202
346
|
if (inserted) {
|
|
203
347
|
applyOperation(inserted, op);
|
|
348
|
+
return false;
|
|
204
349
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
// Pin the committed base NOW — the caller just read this block, so it is resident — and
|
|
217
|
-
// only when there is no still-fresh pin, so a block updated 50 times pays one base clone.
|
|
218
|
-
// A generation change (an external commit folded into the cache) re-pins against the new
|
|
219
|
-
// base, which is the base the member will apply the whole op list to.
|
|
220
|
-
// NOTE: read-far-then-update stays unpinned — a block read, then evicted by 128+ other
|
|
221
|
-
// reads, and only then updated, probes an already-evicted cache here and is omitted from
|
|
222
|
-
// the digest (pre-existing behaviour; digest.spec.ts pins it). If a workload ever reads a
|
|
223
|
-
// large batch before writing any of it, the closure is to pin on READ for ids that later
|
|
224
|
-
// get updated, at retention proportional to reads rather than to writes.
|
|
225
|
-
const existing = this.pins.get(blockId);
|
|
226
|
-
if (!existing || existing.gen !== this.baseGeneration(blockId)) {
|
|
227
|
-
const pin = this.probeBase(blockId);
|
|
228
|
-
if (pin)
|
|
229
|
-
this.pins.set(blockId, pin);
|
|
230
|
-
}
|
|
350
|
+
const updates = this.transforms.updates ??= {};
|
|
351
|
+
const ops = ensured(updates, blockId, () => []);
|
|
352
|
+
const first = ops.length === 0;
|
|
353
|
+
ops.push(structuredClone(op));
|
|
354
|
+
// The memo already equals (base source content + prior ops); applying just the new op
|
|
355
|
+
// keeps it equal to the full ops list — O(1), no full replay. Leave `gen` untouched: it
|
|
356
|
+
// still records the base-content generation, so a later external source change still
|
|
357
|
+
// forces a reload. (Refreshing gen here would mask stale base content.)
|
|
358
|
+
const memo = this.materialized.get(blockId);
|
|
359
|
+
if (memo) {
|
|
360
|
+
applyOperation(memo.block, op);
|
|
231
361
|
}
|
|
362
|
+
return first;
|
|
363
|
+
}
|
|
364
|
+
/** Fix the base of `id`'s staged operations at the moment the FIRST of them is staged in this
|
|
365
|
+
* tracker: the caller just read the block, so the base source describes what the operation was
|
|
366
|
+
* computed against. Whatever the store held for the id before is replaced (or dropped, when the
|
|
367
|
+
* source can pin nothing): no operations of THIS tracker's list were computed on it — a pin that
|
|
368
|
+
* outlived its tracker, such as an abandoned per-attempt tracker's log-block pin from before a
|
|
369
|
+
* refresh cleared the block, would otherwise speak for operations built on something else.
|
|
370
|
+
* (The one pre-existing pin that IS this list's base, an atomic's, is kept by {@link absorb},
|
|
371
|
+
* which never comes through here for it.) A later operation for the same id never re-pins: it
|
|
372
|
+
* re-judges the pin ({@link recheckPin}), and a base found to have moved stays moved. */
|
|
373
|
+
pinBase(id) {
|
|
374
|
+
const pin = this.probeBase(id);
|
|
375
|
+
if (pin)
|
|
376
|
+
this.pins.set(id, pin);
|
|
377
|
+
else
|
|
378
|
+
this.pins.delete(id);
|
|
379
|
+
}
|
|
380
|
+
/** Re-judge `id`'s pin, if it has one, against the base source (see {@link revalidatePin}). */
|
|
381
|
+
recheckPin(id) {
|
|
382
|
+
const existing = this.pins.get(id);
|
|
383
|
+
if (existing)
|
|
384
|
+
this.revalidatePin(id, existing);
|
|
232
385
|
}
|
|
233
386
|
delete(blockId) {
|
|
234
387
|
if (this.transforms.inserts)
|
|
@@ -246,7 +399,8 @@ export class Tracker {
|
|
|
246
399
|
this.transforms = newTransform;
|
|
247
400
|
this.materialized.clear();
|
|
248
401
|
// The single reclamation point for pins: a plain reset clears them (empty updates), a
|
|
249
|
-
// rollback-style reset(transforms) keeps exactly the pins
|
|
402
|
+
// rollback-style reset(transforms) keeps exactly the pins — moved marks included — for ids
|
|
403
|
+
// still staged as updates.
|
|
250
404
|
this.pins.retainOnly(Object.keys(newTransform.updates ?? {}));
|
|
251
405
|
return oldTransform;
|
|
252
406
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../../src/transform/tracker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC5I,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD;;;;;;;iEAOiE;AACjE,SAAS,UAAU,CAAC,MAAe,EAAE,EAAW;IAC/C,MAAM,GAAG,GAAG,MAGX,CAAC;IACF,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,GAAG,CAAC,iBAAiB,KAAK,UAAU;QAAE,OAAO,SAAS,CAAC;IACpG,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAwB,kCAAkC;IACrF,MAAM,GAAG,GAAG,GAAG,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACtC,OAAO,KAAK,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AAC9E,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,OAAO;IAWD;IAEV;IAKS;IAjBjB;;;;;;yDAMqD;IAC7C,YAAY,GAAG,IAAI,GAAG,EAAsC,CAAC;IAErE,YACkB,MAAuB;IACxC,6EAA6E;IACtE,aAAa,eAAe,EAAE;IACrC;;;uEAGmE;IACnD,OAAiB,IAAI,QAAQ,EAAE;QAP9B,WAAM,GAAN,MAAM,CAAiB;QAEjC,eAAU,GAAV,UAAU,CAAoB;QAKrB,SAAI,GAAJ,IAAI,CAA2B;QAE/C,0FAA0F;QAC1F,4FAA4F;QAC5F,wFAAwF;QACxF,4FAA4F;QAC5F,6CAA6C;QAC7C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IACvC,CAAC;IAED;;kGAE8F;IACtF,UAAU;QACjB,IAAI,GAAG,GAAY,IAAI,CAAC,MAAM,CAAC;QAC/B,OAAO,GAAG,YAAY,OAAO;YAAE,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;QAChD,OAAO,GAAG,CAAC;IACZ,CAAC;IAED,yFAAyF;IACjF,gBAAgB,CAAC,EAAW;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAqD,CAAC;QACvE,OAAO,OAAO,GAAG,CAAC,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACpF,CAAC;IAED;;yCAEqC;IAC3B,cAAc,CAAC,EAAW;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAiD,CAAC;QAC7E,OAAO,OAAO,GAAG,CAAC,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACpF,CAAC;IAED;;;;;iDAK6C;IACnC,SAAS,CAAC,EAAW;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAiD,CAAC;QAC7E,+EAA+E;QAC/E,IAAI,OAAO,GAAG,CAAC,aAAa,KAAK,UAAU;YAAE,OAAO,SAAS,CAAC;QAC9D,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACjC,OAAO,IAAI,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAW,EAAE,UAAuB,OAAO;QACvD,iGAAiG;QACjG,mGAAmG;QACnG,uGAAuG;QACvG,gGAAgG;QAChG,mGAAmG;QACnG,oGAAoG;QACpG,kGAAkG;QAClG,0EAA0E;QAC1E,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;YAC3E,OAAO,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAM,CAAC;QAC1D,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YAC3C,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvC,IAAI,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC;YACrD,OAAO,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAW,2BAA2B;QAC1E,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QACpD,IAAI,KAAK,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;YAChD,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpB,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBAC5B,oFAAoF;gBACpF,uFAAuF;gBACvF,oFAAoF;gBACpF,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;gBAC3C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;oBAC5B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACrD,CAAC;gBACD,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC,CAAc,yCAAyC;YACtF,CAAC;QACF,CAAC;QACD,OAAO,KAAK,CAAC,CAAoC,gDAAgD;IAClG,CAAC;IAED;;;;;;;;;;;;sEAYkE;IAClE,gBAAgB,CAAC,EAAW;QAC3B,MAAM,SAAS,GAAG,mBAAmB,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3D,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,IAAI,SAAS,CAAC,OAAO,KAAK,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACzG,OAAO,SAAS,CAAC,CAA8B,6BAA6B;QAC7E,CAAC;QACD,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;YACtB,OAAO,SAAS,CAAC,CAA8B,4CAA4C;QAC5F,CAAC;QACD,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;YACtB,0FAA0F;YAC1F,0FAA0F;YAC1F,SAAS,CAAC,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACrD,MAAM,KAAK,GAAG,cAAc,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACnD,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACtC,CAAC;QACD,6FAA6F;QAC7F,8FAA8F;QAC9F,8FAA8F;QAC9F,0FAA0F;QAC1F,+FAA+F;QAC/F,6FAA6F;QAC7F,4FAA4F;QAC5F,2DAA2D;QAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9B,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,cAAc,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;YACpE,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACxD,CAAC;QACD,8FAA8F;QAC9F,2DAA2D;QAC3D,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QAC5B,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,uCAAuC;QAC5F,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACzD,CAAC;IAED;;;+FAG2F;IAC3F,aAAa,CAAC,EAAW;QACvB,IAAI,CAAC,MAAoD,CAAC,aAAa,EAAE,CAAC,EAAE,CAAC,CAAC;IAChF,CAAC;IAED,UAAU;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;IACjC,CAAC;IAED,iBAAiB,CAAC,IAAe,EAAE,KAAe;QACjD,OAAO,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,CAAC,KAAQ;QACd,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,KAAK,EAAE,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAClD,2FAA2F;QAC3F,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1C,wFAAwF;QACxF,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QACxC,MAAM,WAAW,GAAG,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5D,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;YACtB,OAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QACjC,CAAC;IACF,CAAC;IAED,MAAM,CAAC,OAAgB,EAAE,EAAkB;QAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC;QACpD,IAAI,QAAQ,EAAE,CAAC;YACd,cAAc,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACP,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,KAAK,EAAE,CAAC;YAC/C,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9D,sFAAsF;YACtF,wFAAwF;YACxF,qFAAqF;YACrF,wEAAwE;YACxE,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC5C,IAAI,IAAI,EAAE,CAAC;gBACV,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAChC,CAAC;YACD,wFAAwF;YACxF,0FAA0F;YAC1F,yFAAyF;YACzF,sEAAsE;YACtE,uFAAuF;YACvF,yFAAyF;YACzF,0FAA0F;YAC1F,yFAAyF;YACzF,yEAAyE;YACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,GAAG,KAAK,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;gBAChE,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;gBACpC,IAAI,GAAG;oBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACtC,CAAC;QACF,CAAC;IACF,CAAC;IAED,MAAM,CAAC,OAAgB;QACtB,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrE,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAClC,mFAAmF;QACnF,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,KAAK,EAAE,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,YAAY,GAAG,eAAe,EAAE;QACrC,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC;QAC/B,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAC1B,sFAAsF;QACtF,2FAA2F;QAC3F,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;QAC9D,OAAO,YAAY,CAAC;IACrB,CAAC;IAED,mBAAmB;QAClB,OAAO,qBAAqB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED,SAAS,CAAC,QAAsB;QAC/B,OAAO,IAAI,CAAC,mBAAmB,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC;CACD"}
|
|
1
|
+
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../../src/transform/tracker.ts"],"names":[],"mappings":"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"}
|