@minnowdb/core 0.2.1 → 0.3.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/README.md +21 -32
- package/dist/engine/artifact-cache.d.ts +2 -0
- package/dist/engine/artifact-cache.d.ts.map +1 -1
- package/dist/engine/artifact-cache.js +5 -0
- package/dist/engine/artifact-cache.js.map +1 -1
- package/dist/engine/batch.d.ts +6 -1
- package/dist/engine/batch.d.ts.map +1 -1
- package/dist/engine/batch.js +17 -6
- package/dist/engine/batch.js.map +1 -1
- package/dist/engine/catalog.d.ts +22 -2
- package/dist/engine/catalog.d.ts.map +1 -1
- package/dist/engine/catalog.js +30 -3
- package/dist/engine/catalog.js.map +1 -1
- package/dist/engine/client.d.ts +2 -0
- package/dist/engine/client.d.ts.map +1 -1
- package/dist/engine/client.js +20 -10
- package/dist/engine/client.js.map +1 -1
- package/dist/engine/database.d.ts +67 -5
- package/dist/engine/database.d.ts.map +1 -1
- package/dist/engine/database.js +3508 -369
- package/dist/engine/database.js.map +1 -1
- package/dist/engine/defaults.d.ts +4 -7
- package/dist/engine/defaults.d.ts.map +1 -1
- package/dist/engine/defaults.js +47 -21
- package/dist/engine/defaults.js.map +1 -1
- package/dist/engine/fts.d.ts.map +1 -1
- package/dist/engine/fts.js +2 -0
- package/dist/engine/fts.js.map +1 -1
- package/dist/engine/index.d.ts +1 -0
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +1 -0
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/live.d.ts.map +1 -1
- package/dist/engine/live.js +10 -2
- package/dist/engine/live.js.map +1 -1
- package/dist/engine/optimizer.d.ts.map +1 -1
- package/dist/engine/optimizer.js +258 -23
- package/dist/engine/optimizer.js.map +1 -1
- package/dist/engine/query-cache.d.ts +1 -1
- package/dist/engine/query-cache.d.ts.map +1 -1
- package/dist/engine/query-cache.js +3 -1
- package/dist/engine/query-cache.js.map +1 -1
- package/dist/engine/query.d.ts +130 -22
- package/dist/engine/query.d.ts.map +1 -1
- package/dist/engine/query.js +1344 -241
- package/dist/engine/query.js.map +1 -1
- package/dist/engine/schema-wire.d.ts +6 -2
- package/dist/engine/schema-wire.d.ts.map +1 -1
- package/dist/engine/schema-wire.js +40 -33
- package/dist/engine/schema-wire.js.map +1 -1
- package/dist/engine/schema.d.ts +157 -76
- package/dist/engine/schema.d.ts.map +1 -1
- package/dist/engine/schema.js +548 -103
- package/dist/engine/schema.js.map +1 -1
- package/dist/engine/sort-keys.d.ts +4 -3
- package/dist/engine/sort-keys.d.ts.map +1 -1
- package/dist/engine/sort-keys.js +42 -27
- package/dist/engine/sort-keys.js.map +1 -1
- package/dist/engine/sql-domains.d.ts +26 -0
- package/dist/engine/sql-domains.d.ts.map +1 -0
- package/dist/engine/sql-domains.js +421 -0
- package/dist/engine/sql-domains.js.map +1 -0
- package/dist/engine/sql-driver.d.ts +19 -0
- package/dist/engine/sql-driver.d.ts.map +1 -0
- package/dist/engine/sql-driver.js +2 -0
- package/dist/engine/sql-driver.js.map +1 -0
- package/dist/engine/sql-json.d.ts +7 -8
- package/dist/engine/sql-json.d.ts.map +1 -1
- package/dist/engine/sql-json.js +28 -14
- package/dist/engine/sql-json.js.map +1 -1
- package/dist/engine/sql-semantics.d.ts +2 -0
- package/dist/engine/sql-semantics.d.ts.map +1 -1
- package/dist/engine/sql-semantics.js +69 -3
- package/dist/engine/sql-semantics.js.map +1 -1
- package/dist/engine/vector.d.ts +5 -1
- package/dist/engine/vector.d.ts.map +1 -1
- package/dist/engine/vector.js +433 -61
- package/dist/engine/vector.js.map +1 -1
- package/dist/engine/worker-host.d.ts +1 -0
- package/dist/engine/worker-host.d.ts.map +1 -1
- package/dist/engine/worker-host.js +4 -0
- package/dist/engine/worker-host.js.map +1 -1
- package/dist/plan/index.d.ts +3 -3
- package/dist/plan/index.js +3 -3
- package/dist/storage/indexeddb.d.ts +44 -5
- package/dist/storage/indexeddb.d.ts.map +1 -1
- package/dist/storage/indexeddb.js +738 -175
- package/dist/storage/indexeddb.js.map +1 -1
- package/dist/storage/memory.d.ts +27 -10
- package/dist/storage/memory.d.ts.map +1 -1
- package/dist/storage/memory.js +67 -18
- package/dist/storage/memory.js.map +1 -1
- package/dist/storage/opfs/leader.d.ts +28 -6
- package/dist/storage/opfs/leader.d.ts.map +1 -1
- package/dist/storage/opfs/leader.js +301 -34
- package/dist/storage/opfs/leader.js.map +1 -1
- package/dist/storage/opfs/rpc.d.ts.map +1 -1
- package/dist/storage/opfs/rpc.js +2 -1
- package/dist/storage/opfs/rpc.js.map +1 -1
- package/dist/storage/opfs/store.d.ts +34 -5
- package/dist/storage/opfs/store.d.ts.map +1 -1
- package/dist/storage/opfs/store.js +41 -0
- package/dist/storage/opfs/store.js.map +1 -1
- package/dist/storage/snapshot.d.ts +14 -0
- package/dist/storage/snapshot.d.ts.map +1 -1
- package/dist/storage/snapshot.js +44 -0
- package/dist/storage/snapshot.js.map +1 -1
- package/dist/storage/toolkit/index.d.ts +1 -1
- package/dist/storage/toolkit/index.d.ts.map +1 -1
- package/dist/storage/toolkit/index.js +1 -1
- package/dist/storage/toolkit/index.js.map +1 -1
- package/dist/storage/toolkit/record-core.d.ts +19 -5
- package/dist/storage/toolkit/record-core.d.ts.map +1 -1
- package/dist/storage/toolkit/record-core.js +353 -78
- package/dist/storage/toolkit/record-core.js.map +1 -1
- package/dist/storage/toolkit/wire.d.ts +15 -0
- package/dist/storage/toolkit/wire.d.ts.map +1 -1
- package/dist/storage/toolkit/wire.js +134 -0
- package/dist/storage/toolkit/wire.js.map +1 -1
- package/dist/storage/types.d.ts +213 -31
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/types.js +291 -20
- package/dist/storage/types.js.map +1 -1
- package/dist/testing/block-store-conformance.d.ts.map +1 -1
- package/dist/testing/block-store-conformance.js +153 -2
- package/dist/testing/block-store-conformance.js.map +1 -1
- package/dist/testing/index.d.ts +9 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +23 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/simulator.d.ts +98 -0
- package/dist/testing/simulator.d.ts.map +1 -0
- package/dist/testing/simulator.js +560 -0
- package/dist/testing/simulator.js.map +1 -0
- package/dist/testing/sqllogictest.d.ts +90 -0
- package/dist/testing/sqllogictest.d.ts.map +1 -0
- package/dist/testing/sqllogictest.js +435 -0
- package/dist/testing/sqllogictest.js.map +1 -0
- package/dist/transactions/index.d.ts +18 -3
- package/dist/transactions/index.d.ts.map +1 -1
- package/dist/transactions/index.js +64 -8
- package/dist/transactions/index.js.map +1 -1
- package/package.json +5 -3
- package/postgres-feature-profile.json +223 -0
- package/sql-feature-matrix.json +172 -252
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
import { MinnowDatabase } from "../engine/database.js";
|
|
2
|
+
import { MemoryBlockStore } from "../storage/index.js";
|
|
3
|
+
import { FaultInjectingBlockStore } from "./index.js";
|
|
4
|
+
import { md5Hex } from "./sqllogictest.js";
|
|
5
|
+
/** Chooses every storage completion from a seeded queue and keeps only a bounded trace tail. */
|
|
6
|
+
export class DeterministicScheduler {
|
|
7
|
+
#random;
|
|
8
|
+
#traceLimit;
|
|
9
|
+
#pending = [];
|
|
10
|
+
#trace = [];
|
|
11
|
+
#sequence = 0;
|
|
12
|
+
#highWater = 0;
|
|
13
|
+
constructor(seed, traceLimit = 256) {
|
|
14
|
+
if (!Number.isSafeInteger(traceLimit) || traceLimit < 0) {
|
|
15
|
+
throw new RangeError("Simulator trace limit must be a non-negative whole number");
|
|
16
|
+
}
|
|
17
|
+
this.#random = mulberry32(seed);
|
|
18
|
+
this.#traceLimit = traceLimit;
|
|
19
|
+
}
|
|
20
|
+
get highWater() {
|
|
21
|
+
return this.#highWater;
|
|
22
|
+
}
|
|
23
|
+
get trace() {
|
|
24
|
+
return this.#trace;
|
|
25
|
+
}
|
|
26
|
+
schedule(label, run) {
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
28
|
+
this.#pending.push({ label, run, resolve, reject });
|
|
29
|
+
this.#highWater = Math.max(this.#highWater, this.#pending.length);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
async settle(promises) {
|
|
33
|
+
const state = { complete: false };
|
|
34
|
+
const settled = Promise.allSettled(promises).then((results) => {
|
|
35
|
+
state.complete = true;
|
|
36
|
+
return results;
|
|
37
|
+
});
|
|
38
|
+
let emptyTurns = 0;
|
|
39
|
+
while (!state.complete) {
|
|
40
|
+
await Promise.resolve();
|
|
41
|
+
const pending = this.#pending.length;
|
|
42
|
+
if (pending === 0) {
|
|
43
|
+
emptyTurns++;
|
|
44
|
+
if (emptyTurns > 100) {
|
|
45
|
+
throw new Error("Deterministic simulator deadlocked with no scheduled storage operation");
|
|
46
|
+
}
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
emptyTurns = 0;
|
|
50
|
+
const index = Math.floor(this.#random() * pending);
|
|
51
|
+
const operation = this.#pending.splice(index, 1)[0];
|
|
52
|
+
if (operation === undefined)
|
|
53
|
+
continue;
|
|
54
|
+
try {
|
|
55
|
+
const value = await operation.run();
|
|
56
|
+
operation.resolve(value);
|
|
57
|
+
this.#record(operation.label, "resolved");
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
operation.reject(error);
|
|
61
|
+
this.#record(operation.label, "rejected");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return settled;
|
|
65
|
+
}
|
|
66
|
+
#record(operation, outcome) {
|
|
67
|
+
this.#sequence++;
|
|
68
|
+
if (this.#traceLimit === 0)
|
|
69
|
+
return;
|
|
70
|
+
this.#trace.push({ sequence: this.#sequence, operation, outcome });
|
|
71
|
+
if (this.#trace.length > this.#traceLimit)
|
|
72
|
+
this.#trace.shift();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** Wraps every asynchronous BlockStore entry point in the deterministic completion scheduler. */
|
|
76
|
+
export function scheduledBlockStore(store, scheduler) {
|
|
77
|
+
return new Proxy(store, {
|
|
78
|
+
get(target, property) {
|
|
79
|
+
const value = Reflect.get(target, property, target);
|
|
80
|
+
if (typeof value !== "function")
|
|
81
|
+
return value;
|
|
82
|
+
const method = value;
|
|
83
|
+
if (property === "close")
|
|
84
|
+
return (...arguments_) => method.apply(target, arguments_);
|
|
85
|
+
return (...arguments_) => scheduler.schedule(String(property), async () => method.apply(target, arguments_));
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
export function generateSimulationPlan(seed, options = {}) {
|
|
90
|
+
if (!Number.isSafeInteger(seed)) {
|
|
91
|
+
throw new RangeError("Simulator seed must be a whole number");
|
|
92
|
+
}
|
|
93
|
+
const rounds = options.rounds ?? 48;
|
|
94
|
+
const clients = options.clients ?? 4;
|
|
95
|
+
const keySpace = options.keySpace ?? 32;
|
|
96
|
+
if (!Number.isSafeInteger(rounds) || rounds < 1 || rounds > 100_000) {
|
|
97
|
+
throw new RangeError("Simulator rounds must be between 1 and 100,000");
|
|
98
|
+
}
|
|
99
|
+
if (!Number.isSafeInteger(clients) || clients < 1 || clients > 32) {
|
|
100
|
+
throw new RangeError("Simulator clients must be between 1 and 32");
|
|
101
|
+
}
|
|
102
|
+
if (!Number.isSafeInteger(keySpace) || keySpace < 1 || keySpace > 10_000) {
|
|
103
|
+
throw new RangeError("Simulator key space must be between 1 and 10,000");
|
|
104
|
+
}
|
|
105
|
+
if (keySpace < clients) {
|
|
106
|
+
throw new RangeError("Simulator key space must be at least the client count");
|
|
107
|
+
}
|
|
108
|
+
const random = mulberry32(seed);
|
|
109
|
+
const steps = [];
|
|
110
|
+
const faultPoints = [
|
|
111
|
+
"beforeBlockWrite",
|
|
112
|
+
"afterBlockWrite",
|
|
113
|
+
"beforeTransactionCommit",
|
|
114
|
+
"afterTransactionCommit",
|
|
115
|
+
];
|
|
116
|
+
for (let round = 0; round < rounds; round++) {
|
|
117
|
+
const operations = [];
|
|
118
|
+
const start = Math.floor(random() * keySpace);
|
|
119
|
+
let stride = Math.floor(random() * keySpace) + 1;
|
|
120
|
+
while (greatestCommonDivisor(stride, keySpace) !== 1)
|
|
121
|
+
stride++;
|
|
122
|
+
for (let client = 0; client < clients; client++) {
|
|
123
|
+
// A round is a genuinely concurrent commit race, but its row mutations commute. That gives
|
|
124
|
+
// the reference model one exact answer instead of guessing which same-key promise linearized
|
|
125
|
+
// last. Contention still happens at the shared manifest/transaction boundary.
|
|
126
|
+
const key = ((start + client * stride) % keySpace) + 1;
|
|
127
|
+
if (random() < 0.18)
|
|
128
|
+
operations.push({ kind: "delete", client, key });
|
|
129
|
+
else
|
|
130
|
+
operations.push({ kind: "put", client, key, amount: Math.floor(random() * 1_000_000) });
|
|
131
|
+
}
|
|
132
|
+
steps.push({ kind: "concurrent", operations });
|
|
133
|
+
if (round % 4 === 3)
|
|
134
|
+
steps.push({ kind: "checkpoint" });
|
|
135
|
+
if (round % 12 === 11)
|
|
136
|
+
steps.push({ kind: "maintenance" });
|
|
137
|
+
if (round % 20 === 19) {
|
|
138
|
+
const point = faultPoints[Math.floor(random() * faultPoints.length)] ?? "beforeBlockWrite";
|
|
139
|
+
steps.push({
|
|
140
|
+
kind: "fault",
|
|
141
|
+
point,
|
|
142
|
+
occurrence: 1,
|
|
143
|
+
operation: {
|
|
144
|
+
kind: "put",
|
|
145
|
+
client: Math.floor(random() * clients),
|
|
146
|
+
key: Math.floor(random() * keySpace) + 1,
|
|
147
|
+
amount: Math.floor(random() * 1_000_000),
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
steps.push({ kind: "checkpoint" }, { kind: "maintenance" }, { kind: "checkpoint" });
|
|
153
|
+
return { version: 1, seed, clients, keySpace, steps };
|
|
154
|
+
}
|
|
155
|
+
export function parseSimulationPlan(source) {
|
|
156
|
+
const value = JSON.parse(source);
|
|
157
|
+
if (typeof value !== "object" || value === null)
|
|
158
|
+
throw new TypeError("Simulation plan must be an object");
|
|
159
|
+
const plan = value;
|
|
160
|
+
if (plan.version !== 1)
|
|
161
|
+
throw new TypeError("Simulation plan version must be 1");
|
|
162
|
+
if (!Number.isSafeInteger(plan.seed))
|
|
163
|
+
throw new TypeError("Simulation seed must be a whole number");
|
|
164
|
+
if (!Number.isSafeInteger(plan.clients) || (plan.clients ?? 0) < 1 || (plan.clients ?? 0) > 32) {
|
|
165
|
+
throw new TypeError("Simulation client count is invalid");
|
|
166
|
+
}
|
|
167
|
+
if (!Number.isSafeInteger(plan.keySpace) ||
|
|
168
|
+
(plan.keySpace ?? 0) < 1 ||
|
|
169
|
+
(plan.keySpace ?? 0) > 10_000) {
|
|
170
|
+
throw new TypeError("Simulation key space is invalid");
|
|
171
|
+
}
|
|
172
|
+
if ((plan.keySpace ?? 0) < (plan.clients ?? 0)) {
|
|
173
|
+
throw new TypeError("Simulation key space must be at least the client count");
|
|
174
|
+
}
|
|
175
|
+
if (!Array.isArray(plan.steps) || plan.steps.length > 200_000) {
|
|
176
|
+
throw new TypeError("Simulation steps must be a bounded array");
|
|
177
|
+
}
|
|
178
|
+
validateSteps(plan.steps, plan.clients ?? 0, plan.keySpace ?? 0);
|
|
179
|
+
return plan;
|
|
180
|
+
}
|
|
181
|
+
/** Runs a replayable state-machine plan through production SQL, transactions, and block storage. */
|
|
182
|
+
export async function runSimulation(plan, options = {}) {
|
|
183
|
+
parseSimulationPlan(JSON.stringify(plan));
|
|
184
|
+
const base = new MemoryBlockStore();
|
|
185
|
+
const faults = new FaultController();
|
|
186
|
+
const scheduler = new DeterministicScheduler(plan.seed ^ 0x5f3759df, options.traceEvents ?? 256);
|
|
187
|
+
const store = scheduledBlockStore(new FaultInjectingBlockStore(base, (point) => faults.inject(point)), scheduler);
|
|
188
|
+
let clock = Date.parse("2026-01-01T00:00:00.000Z");
|
|
189
|
+
let id = 0;
|
|
190
|
+
const createDatabase = () => new MinnowDatabase(store, {
|
|
191
|
+
compression: "raw",
|
|
192
|
+
rowsPerBlock: 8,
|
|
193
|
+
maxCommitRetries: 16,
|
|
194
|
+
now: () => new Date(clock),
|
|
195
|
+
createId: () => `sim-${String(id++)}`,
|
|
196
|
+
bufferPoolBytes: 0,
|
|
197
|
+
autoCompact: false,
|
|
198
|
+
autoCollect: false,
|
|
199
|
+
});
|
|
200
|
+
const setup = createDatabase();
|
|
201
|
+
await drive(scheduler, setup.execute("CREATE TABLE items (id INTEGER PRIMARY KEY, client INTEGER NOT NULL, amount INTEGER NOT NULL)"));
|
|
202
|
+
await drive(scheduler, setup.close());
|
|
203
|
+
const clients = Array.from({ length: plan.clients }, createDatabase);
|
|
204
|
+
const model = new Map();
|
|
205
|
+
let acceptedMutations = 0;
|
|
206
|
+
let rejectedConflicts = 0;
|
|
207
|
+
let injectedFaults = 0;
|
|
208
|
+
let checkpoints = 0;
|
|
209
|
+
for (const step of plan.steps) {
|
|
210
|
+
clock += 1_000;
|
|
211
|
+
if (step.kind === "concurrent") {
|
|
212
|
+
const operations = step.operations.map((operation) => executeMutation(requireClient(clients, operation.client), operation)
|
|
213
|
+
.then(() => {
|
|
214
|
+
applyMutation(model, operation);
|
|
215
|
+
acceptedMutations++;
|
|
216
|
+
})
|
|
217
|
+
.catch((error) => {
|
|
218
|
+
if (/manifest changed|conflict/iu.test(errorMessage(error))) {
|
|
219
|
+
rejectedConflicts++;
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
throw error;
|
|
223
|
+
}));
|
|
224
|
+
assertSettled(await scheduler.settle(operations));
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
if (step.kind === "checkpoint") {
|
|
228
|
+
await assertModel(scheduler, clients[0] ?? setup, model);
|
|
229
|
+
checkpoints++;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
if (step.kind === "maintenance") {
|
|
233
|
+
const database = clients[0] ?? setup;
|
|
234
|
+
await drive(scheduler, database.compactTable("items"));
|
|
235
|
+
// One pass can remove obsolete manifests/segments while their transaction journals are
|
|
236
|
+
// still provenance roots. The next pass can reclaim those now-unreferenced journals.
|
|
237
|
+
await drive(scheduler, database.collectGarbage());
|
|
238
|
+
await drive(scheduler, database.collectGarbage());
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
const before = new Map(model);
|
|
242
|
+
const after = new Map(model);
|
|
243
|
+
applyMutation(after, step.operation);
|
|
244
|
+
faults.arm(step.point, step.occurrence);
|
|
245
|
+
const result = await scheduler.settle([
|
|
246
|
+
executeMutation(requireClient(clients, step.operation.client), step.operation),
|
|
247
|
+
]);
|
|
248
|
+
if (!faults.fired)
|
|
249
|
+
throw new Error(`Simulation fault was not reached: ${step.point}`);
|
|
250
|
+
injectedFaults++;
|
|
251
|
+
faults.disarm();
|
|
252
|
+
const failedClient = requireClient(clients, step.operation.client);
|
|
253
|
+
await drive(scheduler, failedClient.close());
|
|
254
|
+
const replacement = createDatabase();
|
|
255
|
+
clients[step.operation.client] = replacement;
|
|
256
|
+
const actual = await readRows(scheduler, replacement);
|
|
257
|
+
if (sameRows(actual, before)) {
|
|
258
|
+
if (result[0]?.status === "fulfilled") {
|
|
259
|
+
throw new Error(`Fault ${step.point} returned success but did not persist its mutation`);
|
|
260
|
+
}
|
|
261
|
+
replaceModel(model, before);
|
|
262
|
+
}
|
|
263
|
+
else if (sameRows(actual, after))
|
|
264
|
+
replaceModel(model, after);
|
|
265
|
+
else
|
|
266
|
+
throw new Error(`Fault ${step.point} left a state that was neither before nor after the mutation`);
|
|
267
|
+
}
|
|
268
|
+
await assertModel(scheduler, clients[0] ?? setup, model);
|
|
269
|
+
const closeResults = await scheduler.settle(clients.map((client) => client.close()));
|
|
270
|
+
assertSettled(closeResults);
|
|
271
|
+
// Measure eventual storage after the simulated tabs release their deliberately cached reader
|
|
272
|
+
// leases. A fresh maintenance client can then collapse history without an artificial pin from
|
|
273
|
+
// the workload whose final state has already been checked.
|
|
274
|
+
const maintenance = createDatabase();
|
|
275
|
+
const compacted = await compactToFixedPoint(scheduler, maintenance, plan.steps.length);
|
|
276
|
+
const maintenanceCompactions = compacted.passes;
|
|
277
|
+
const compactionStop = compacted.stop;
|
|
278
|
+
const collected = await collectToFixedPoint(scheduler, maintenance, plan.steps.length);
|
|
279
|
+
let collectionPasses = collected.passes;
|
|
280
|
+
const collectionTail = [...collected.tail];
|
|
281
|
+
await assertModel(scheduler, maintenance, model);
|
|
282
|
+
await drive(scheduler, maintenance.close());
|
|
283
|
+
const sweeper = createDatabase();
|
|
284
|
+
const swept = await collectToFixedPoint(scheduler, sweeper, plan.steps.length);
|
|
285
|
+
collectionPasses += swept.passes;
|
|
286
|
+
collectionTail.push(...swept.tail);
|
|
287
|
+
if (collectionTail.length > 8)
|
|
288
|
+
collectionTail.splice(0, collectionTail.length - 8);
|
|
289
|
+
await drive(scheduler, sweeper.close());
|
|
290
|
+
const rows = sortedRows(model);
|
|
291
|
+
const [blockIds, segments, transactions, manifests, currentManifest, leases, compactions, storageBytes,] = await Promise.all([
|
|
292
|
+
base.listBlockIds(),
|
|
293
|
+
base.listSegments(),
|
|
294
|
+
base.listTransactions(),
|
|
295
|
+
base.listManifests(),
|
|
296
|
+
base.getCurrentManifest(),
|
|
297
|
+
base.listLeases(),
|
|
298
|
+
base.listCompactionJobs(),
|
|
299
|
+
base.getLogicalStorageBytes(),
|
|
300
|
+
]);
|
|
301
|
+
const blockLimit = plan.keySpace * 16 + 64;
|
|
302
|
+
const segmentLimit = plan.keySpace + 16;
|
|
303
|
+
const transactionLimit = segmentLimit + 16;
|
|
304
|
+
if (blockIds.length > blockLimit ||
|
|
305
|
+
segments.length > segmentLimit ||
|
|
306
|
+
transactions.length > transactionLimit) {
|
|
307
|
+
const transactionStates = transactions.reduce((counts, transaction) => {
|
|
308
|
+
counts[transaction.status] = (counts[transaction.status] ?? 0) + 1;
|
|
309
|
+
return counts;
|
|
310
|
+
}, {});
|
|
311
|
+
const compactionStates = compactions.reduce((counts, compaction) => {
|
|
312
|
+
counts[compaction.state] = (counts[compaction.state] ?? 0) + 1;
|
|
313
|
+
return counts;
|
|
314
|
+
}, {});
|
|
315
|
+
throw new Error(`Storage did not compact to a bound: ${String(blockIds.length)}/${String(blockLimit)} blocks, ` +
|
|
316
|
+
`${String(segments.length)}/${String(segmentLimit)} segments, ` +
|
|
317
|
+
`${String(transactions.length)}/${String(transactionLimit)} transactions; ` +
|
|
318
|
+
`${JSON.stringify(transactionStates)} transaction states, ` +
|
|
319
|
+
`${JSON.stringify(compactionStates)} compaction states, ` +
|
|
320
|
+
`${String(currentManifest?.blockIds.length ?? 0)} current blocks, compaction stopped at ${compactionStop}, ` +
|
|
321
|
+
`${String(manifests.length)} manifests (${String(manifests.filter((manifest) => manifest.prunedAt !== undefined).length)} pruned) remain after ${String(maintenanceCompactions)} compactions ` +
|
|
322
|
+
`and ${String(collectionPasses)} collection passes; collection tail ${JSON.stringify(collectionTail)}`);
|
|
323
|
+
}
|
|
324
|
+
if (manifests.length > 2) {
|
|
325
|
+
throw new Error(`Garbage collection left ${String(manifests.length)} manifests and ${String(leases.length)} leases`);
|
|
326
|
+
}
|
|
327
|
+
if (leases.length !== 0) {
|
|
328
|
+
throw new Error(`Simulation clients leaked ${String(leases.length)} leases`);
|
|
329
|
+
}
|
|
330
|
+
const trace = [...scheduler.trace];
|
|
331
|
+
return {
|
|
332
|
+
seed: plan.seed,
|
|
333
|
+
acceptedMutations,
|
|
334
|
+
rejectedConflicts,
|
|
335
|
+
injectedFaults,
|
|
336
|
+
checkpoints,
|
|
337
|
+
maintenanceCompactions,
|
|
338
|
+
compactionStop,
|
|
339
|
+
collectionPasses,
|
|
340
|
+
collectionTail,
|
|
341
|
+
rows,
|
|
342
|
+
blockCount: blockIds.length,
|
|
343
|
+
segmentCount: segments.length,
|
|
344
|
+
transactionCount: transactions.length,
|
|
345
|
+
manifestCount: manifests.length,
|
|
346
|
+
leaseCount: leases.length,
|
|
347
|
+
storageBytes,
|
|
348
|
+
schedulerHighWater: scheduler.highWater,
|
|
349
|
+
trace,
|
|
350
|
+
traceDigest: md5Hex(JSON.stringify(trace)),
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
class FaultController {
|
|
354
|
+
#point;
|
|
355
|
+
#occurrence = 0;
|
|
356
|
+
#seen = 0;
|
|
357
|
+
fired = false;
|
|
358
|
+
arm(point, occurrence) {
|
|
359
|
+
this.#point = point;
|
|
360
|
+
this.#occurrence = occurrence;
|
|
361
|
+
this.#seen = 0;
|
|
362
|
+
this.fired = false;
|
|
363
|
+
}
|
|
364
|
+
disarm() {
|
|
365
|
+
this.#point = undefined;
|
|
366
|
+
}
|
|
367
|
+
inject(point) {
|
|
368
|
+
if (point !== this.#point || this.fired)
|
|
369
|
+
return;
|
|
370
|
+
this.#seen++;
|
|
371
|
+
if (this.#seen !== this.#occurrence)
|
|
372
|
+
return;
|
|
373
|
+
this.fired = true;
|
|
374
|
+
throw new Error(`injected ${point} #${String(this.#occurrence)}`);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
async function drive(scheduler, promise) {
|
|
378
|
+
const result = (await scheduler.settle([promise]))[0];
|
|
379
|
+
if (result?.status === "fulfilled")
|
|
380
|
+
return result.value;
|
|
381
|
+
throw result?.reason ?? new Error("Scheduled operation did not settle");
|
|
382
|
+
}
|
|
383
|
+
function assertSettled(results) {
|
|
384
|
+
const failed = results.find((result) => result.status === "rejected");
|
|
385
|
+
if (failed?.status === "rejected")
|
|
386
|
+
throw failed.reason;
|
|
387
|
+
}
|
|
388
|
+
function executeMutation(database, operation) {
|
|
389
|
+
if (operation.kind === "delete") {
|
|
390
|
+
return database.execute("DELETE FROM items WHERE id = ?", [operation.key]);
|
|
391
|
+
}
|
|
392
|
+
return database.execute("INSERT INTO items (id, client, amount) VALUES (?, ?, ?) " +
|
|
393
|
+
"ON CONFLICT (id) DO UPDATE SET client = excluded.client, amount = excluded.amount", [operation.key, operation.client, operation.amount]);
|
|
394
|
+
}
|
|
395
|
+
function applyMutation(model, operation) {
|
|
396
|
+
if (operation.kind === "delete")
|
|
397
|
+
model.delete(operation.key);
|
|
398
|
+
else
|
|
399
|
+
model.set(operation.key, {
|
|
400
|
+
id: operation.key,
|
|
401
|
+
client: operation.client,
|
|
402
|
+
amount: operation.amount,
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
async function assertModel(scheduler, database, model) {
|
|
406
|
+
const actual = await readRows(scheduler, database);
|
|
407
|
+
if (!sameRows(actual, model)) {
|
|
408
|
+
throw new Error(`Model mismatch:\nexpected ${JSON.stringify(sortedRows(model))}\nreceived ${JSON.stringify(actual)}`);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
async function readRows(scheduler, database) {
|
|
412
|
+
const result = await drive(scheduler, database.query("SELECT id, client, amount FROM items ORDER BY id", { memoize: false }));
|
|
413
|
+
return result.rows;
|
|
414
|
+
}
|
|
415
|
+
function sameRows(rows, model) {
|
|
416
|
+
return JSON.stringify(rows) === JSON.stringify(sortedRows(model));
|
|
417
|
+
}
|
|
418
|
+
function sortedRows(model) {
|
|
419
|
+
return [...model.values()].sort((left, right) => left.id - right.id);
|
|
420
|
+
}
|
|
421
|
+
function replaceModel(target, source) {
|
|
422
|
+
target.clear();
|
|
423
|
+
for (const [key, value] of source)
|
|
424
|
+
target.set(key, value);
|
|
425
|
+
}
|
|
426
|
+
function requireClient(clients, index) {
|
|
427
|
+
const client = clients[index];
|
|
428
|
+
if (client === undefined)
|
|
429
|
+
throw new RangeError(`Simulation client is out of range: ${String(index)}`);
|
|
430
|
+
return client;
|
|
431
|
+
}
|
|
432
|
+
function validateSteps(steps, clients, keySpace) {
|
|
433
|
+
const validPoint = new Set([
|
|
434
|
+
"beforeBlockWrite",
|
|
435
|
+
"afterBlockWrite",
|
|
436
|
+
"beforeBlockRead",
|
|
437
|
+
"afterBlockRead",
|
|
438
|
+
"beforeManifestCommit",
|
|
439
|
+
"afterManifestCommit",
|
|
440
|
+
"beforeTransactionCommit",
|
|
441
|
+
"afterTransactionCommit",
|
|
442
|
+
]);
|
|
443
|
+
const validateMutation = (value) => {
|
|
444
|
+
if (typeof value !== "object" || value === null) {
|
|
445
|
+
throw new TypeError("Simulation mutation must be an object");
|
|
446
|
+
}
|
|
447
|
+
const operation = value;
|
|
448
|
+
if (operation.kind !== "put" && operation.kind !== "delete") {
|
|
449
|
+
throw new TypeError("Simulation mutation kind is invalid");
|
|
450
|
+
}
|
|
451
|
+
const client = operation.client;
|
|
452
|
+
if (typeof client !== "number" ||
|
|
453
|
+
!Number.isSafeInteger(client) ||
|
|
454
|
+
client < 0 ||
|
|
455
|
+
client >= clients) {
|
|
456
|
+
throw new TypeError("Simulation mutation has an invalid client");
|
|
457
|
+
}
|
|
458
|
+
const key = operation.key;
|
|
459
|
+
if (typeof key !== "number" || !Number.isSafeInteger(key) || key < 1 || key > keySpace) {
|
|
460
|
+
throw new TypeError("Simulation mutation has an invalid key");
|
|
461
|
+
}
|
|
462
|
+
if (operation.kind === "put" &&
|
|
463
|
+
(typeof operation.amount !== "number" || !Number.isSafeInteger(operation.amount))) {
|
|
464
|
+
throw new TypeError("Simulation put has an invalid amount");
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
for (const value of steps) {
|
|
468
|
+
if (typeof value !== "object" || value === null) {
|
|
469
|
+
throw new TypeError("Simulation step must be an object");
|
|
470
|
+
}
|
|
471
|
+
const step = value;
|
|
472
|
+
if (step.kind === "concurrent") {
|
|
473
|
+
if (!Array.isArray(step.operations) || step.operations.length > clients * 4) {
|
|
474
|
+
throw new TypeError("Simulation concurrent step is unbounded");
|
|
475
|
+
}
|
|
476
|
+
step.operations.forEach(validateMutation);
|
|
477
|
+
}
|
|
478
|
+
else if (step.kind === "fault") {
|
|
479
|
+
if (typeof step.point !== "string" || !validPoint.has(step.point)) {
|
|
480
|
+
throw new TypeError("Simulation fault point is invalid");
|
|
481
|
+
}
|
|
482
|
+
const occurrence = step.occurrence;
|
|
483
|
+
if (typeof occurrence !== "number" || !Number.isSafeInteger(occurrence) || occurrence < 1) {
|
|
484
|
+
throw new TypeError("Simulation fault occurrence is invalid");
|
|
485
|
+
}
|
|
486
|
+
validateMutation(step.operation);
|
|
487
|
+
}
|
|
488
|
+
else if (step.kind !== "checkpoint" && step.kind !== "maintenance") {
|
|
489
|
+
throw new TypeError("Simulation step kind is invalid");
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
function errorMessage(error) {
|
|
494
|
+
return error instanceof Error ? error.message : String(error);
|
|
495
|
+
}
|
|
496
|
+
async function compactToFixedPoint(scheduler, database, workloadSteps) {
|
|
497
|
+
const maximumPasses = Math.min(10_000, workloadSteps + 128);
|
|
498
|
+
for (let pass = 0; pass < maximumPasses; pass++) {
|
|
499
|
+
const result = await drive(scheduler, database.compactTable("items"));
|
|
500
|
+
if (!result.compacted)
|
|
501
|
+
return { passes: pass, stop: result.skipReason ?? "unknown" };
|
|
502
|
+
}
|
|
503
|
+
throw new Error(`Compaction did not converge within ${String(maximumPasses)} passes`);
|
|
504
|
+
}
|
|
505
|
+
async function collectToFixedPoint(scheduler, database, workloadSteps) {
|
|
506
|
+
const maximumPasses = Math.min(10_000, workloadSteps + 128);
|
|
507
|
+
let emptyPasses = 0;
|
|
508
|
+
const tail = [];
|
|
509
|
+
for (let pass = 1; pass <= maximumPasses; pass++) {
|
|
510
|
+
const result = await drive(scheduler, database.collectGarbage());
|
|
511
|
+
tail.push(summarizeCollection(result));
|
|
512
|
+
if (tail.length > 8)
|
|
513
|
+
tail.shift();
|
|
514
|
+
const changed = result.prunedManifestCount +
|
|
515
|
+
result.reclaimedSegmentCount +
|
|
516
|
+
result.reclaimedBlockCount +
|
|
517
|
+
result.reclaimedTransactionCount;
|
|
518
|
+
// collectGarbage also prunes finished maintenance records after returning its counters. A
|
|
519
|
+
// zero-artifact pass can therefore remove the final provenance root that lets the next pass
|
|
520
|
+
// reclaim bytes. Two consecutive empty passes prove both layers have settled.
|
|
521
|
+
if (changed === 0) {
|
|
522
|
+
emptyPasses++;
|
|
523
|
+
if (emptyPasses === 2)
|
|
524
|
+
return { passes: pass, tail };
|
|
525
|
+
}
|
|
526
|
+
else
|
|
527
|
+
emptyPasses = 0;
|
|
528
|
+
}
|
|
529
|
+
throw new Error(`Garbage collection did not converge within ${String(maximumPasses)} passes`);
|
|
530
|
+
}
|
|
531
|
+
function summarizeCollection(result) {
|
|
532
|
+
return {
|
|
533
|
+
prunedManifests: result.prunedManifestCount,
|
|
534
|
+
retainedManifests: result.retainedManifestCount,
|
|
535
|
+
reclaimedSegments: result.reclaimedSegmentCount,
|
|
536
|
+
retainedSegments: result.retainedSegmentCount,
|
|
537
|
+
reclaimedBlocks: result.reclaimedBlockCount,
|
|
538
|
+
retainedBlocks: result.retainedBlockCount,
|
|
539
|
+
reclaimedTransactions: result.reclaimedTransactionCount,
|
|
540
|
+
retainedTransactions: result.retainedTransactionCount,
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
function mulberry32(seed) {
|
|
544
|
+
let state = seed >>> 0;
|
|
545
|
+
return () => {
|
|
546
|
+
state = (state + 0x6d2b79f5) >>> 0;
|
|
547
|
+
let mixed = state;
|
|
548
|
+
mixed = Math.imul(mixed ^ (mixed >>> 15), mixed | 1);
|
|
549
|
+
mixed ^= mixed + Math.imul(mixed ^ (mixed >>> 7), mixed | 61);
|
|
550
|
+
return ((mixed ^ (mixed >>> 14)) >>> 0) / 4_294_967_296;
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
function greatestCommonDivisor(left, right) {
|
|
554
|
+
let a = left;
|
|
555
|
+
let b = right;
|
|
556
|
+
while (b !== 0)
|
|
557
|
+
[a, b] = [b, a % b];
|
|
558
|
+
return a;
|
|
559
|
+
}
|
|
560
|
+
//# sourceMappingURL=simulator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulator.js","sourceRoot":"","sources":["../../src/testing/simulator.ts"],"names":[],"mappings":"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"}
|