@agoric/swingset-liveslots 0.10.3-other-dev-8f8782b.0 → 0.10.3-other-dev-fbe72e7.0.fbe72e7
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 +2 -0
- package/package.json +34 -26
- package/src/boyd-gc.d.ts +12 -0
- package/src/boyd-gc.d.ts.map +1 -0
- package/src/boyd-gc.js +598 -0
- package/src/cache.d.ts +71 -0
- package/src/cache.d.ts.map +1 -0
- package/src/cache.js +3 -2
- package/src/capdata.d.ts +16 -0
- package/src/capdata.d.ts.map +1 -0
- package/src/capdata.js +17 -10
- package/src/collectionManager.d.ts +47 -0
- package/src/collectionManager.d.ts.map +1 -0
- package/src/collectionManager.js +220 -103
- package/src/facetiousness.d.ts +25 -0
- package/src/facetiousness.d.ts.map +1 -0
- package/src/facetiousness.js +1 -1
- package/src/index.d.ts +4 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +4 -2
- package/src/kdebug.d.ts +7 -0
- package/src/kdebug.d.ts.map +1 -0
- package/src/liveslots.d.ts +42 -0
- package/src/liveslots.d.ts.map +1 -0
- package/src/liveslots.js +137 -305
- package/src/message.d.ts +49 -0
- package/src/message.d.ts.map +1 -0
- package/src/message.js +9 -5
- package/src/parseVatSlots.d.ts +125 -0
- package/src/parseVatSlots.d.ts.map +1 -0
- package/src/parseVatSlots.js +1 -1
- package/src/types-index.d.ts +4 -0
- package/src/types-index.js +2 -0
- package/src/types.d.ts +81 -0
- package/src/types.d.ts.map +1 -0
- package/src/types.js +14 -7
- package/src/vatDataTypes.d.ts +170 -0
- package/src/vatDataTypes.d.ts.map +1 -0
- package/src/vatDataTypes.ts +272 -0
- package/src/vatstore-iterators.d.ts +4 -0
- package/src/vatstore-iterators.d.ts.map +1 -0
- package/src/vatstore-iterators.js +2 -0
- package/src/vatstore-usage.md +198 -0
- package/src/virtualObjectManager.d.ts +44 -0
- package/src/virtualObjectManager.d.ts.map +1 -0
- package/src/virtualObjectManager.js +254 -84
- package/src/virtualReferences.d.ts +61 -0
- package/src/virtualReferences.d.ts.map +1 -0
- package/src/virtualReferences.js +135 -26
- package/src/vpid-tracking.md +92 -0
- package/src/watchedPromises.d.ts +31 -0
- package/src/watchedPromises.d.ts.map +1 -0
- package/src/watchedPromises.js +81 -24
- package/test/{test-baggage.js → baggage.test.js} +1 -2
- package/test/{test-cache.js → cache.test.js} +0 -1
- package/test/clear-collection.test.js +586 -0
- package/test/{test-collection-schema-refcount.js → collection-schema-refcount.test.js} +1 -2
- package/test/{test-collection-upgrade.js → collection-upgrade.test.js} +1 -3
- package/test/{test-collections.js → collections.test.js} +183 -18
- package/test/{test-dropped-collection-weakrefs.js → dropped-collection-weakrefs.test.js} +1 -2
- package/test/dropped-weakset-9939.test.js +80 -0
- package/test/dummyMeterControl.d.ts +2 -0
- package/test/dummyMeterControl.d.ts.map +1 -0
- package/test/dummyMeterControl.js +1 -1
- package/test/{test-durabilityChecks.js → durabilityChecks.test.js} +4 -4
- package/test/engine-gc.d.ts +3 -0
- package/test/engine-gc.d.ts.map +1 -0
- package/test/exo-utils.js +70 -0
- package/test/{test-facetiousness.js → facetiousness.test.js} +1 -2
- package/test/gc-and-finalize.d.ts +5 -0
- package/test/gc-and-finalize.d.ts.map +1 -0
- package/test/gc-and-finalize.js +30 -1
- package/test/gc-before-finalizer.test.js +230 -0
- package/test/gc-helpers.js +4 -5
- package/test/{test-gc-sensitivity.js → gc-sensitivity.test.js} +2 -2
- package/test/handled-promises.test.js +872 -0
- package/test/{test-initial-vrefs.js → initial-vrefs.test.js} +13 -20
- package/test/liveslots-helpers.d.ts +64 -0
- package/test/liveslots-helpers.d.ts.map +1 -0
- package/test/liveslots-helpers.js +13 -7
- package/test/{test-liveslots-mock-gc.js → liveslots-mock-gc.test.js} +101 -2
- package/test/{test-liveslots-real-gc.js → liveslots-real-gc.test.js} +73 -46
- package/test/{test-liveslots.js → liveslots.test.js} +17 -18
- package/test/mock-gc.js +1 -0
- package/test/storeGC/{test-lifecycle.js → lifecycle.test.js} +15 -14
- package/test/storeGC/{test-refcount-management.js → refcount-management.test.js} +1 -2
- package/test/storeGC/{test-scalar-store-kind.js → scalar-store-kind.test.js} +0 -1
- package/test/storeGC/{test-weak-key.js → weak-key.test.js} +1 -2
- package/test/strict-test-env-upgrade.test.js +94 -0
- package/test/util.d.ts +25 -0
- package/test/util.d.ts.map +1 -0
- package/test/util.js +4 -4
- package/test/vat-environment.test.js +65 -0
- package/test/vat-util.d.ts +9 -0
- package/test/vat-util.d.ts.map +1 -0
- package/test/vat-util.js +2 -2
- package/test/virtual-objects/{test-cease-recognition.js → cease-recognition.test.js} +2 -2
- package/test/virtual-objects/{test-cross-facet.js → cross-facet.test.js} +5 -4
- package/test/virtual-objects/{test-empty-data.js → empty-data.test.js} +1 -2
- package/test/virtual-objects/{test-facets.js → facets.test.js} +1 -2
- package/test/virtual-objects/{test-kind-changes.js → kind-changes.test.js} +2 -2
- package/test/virtual-objects/{test-reachable-vrefs.js → reachable-vrefs.test.js} +2 -2
- package/test/virtual-objects/{test-rep-tostring.js → rep-tostring.test.js} +3 -5
- package/test/virtual-objects/{test-retain-remotable.js → retain-remotable.test.js} +25 -24
- package/test/virtual-objects/set-debug-label-instances.js +1 -1
- package/test/virtual-objects/state-shape.test.js +389 -0
- package/test/virtual-objects/{test-virtualObjectGC.js → virtualObjectGC.test.js} +39 -38
- package/test/virtual-objects/{test-virtualObjectManager.js → virtualObjectManager.test.js} +104 -8
- package/test/virtual-objects/{test-vo-real-gc.js → vo-real-gc.test.js} +8 -8
- package/test/virtual-objects/{test-weakcollections-vref-handling.js → weakcollections-vref-handling.test.js} +1 -2
- package/test/{test-vo-test-harness.js → vo-test-harness.test.js} +13 -10
- package/test/{test-vpid-liveslots.js → vpid-liveslots.test.js} +105 -5
- package/test/waitUntilQuiescent.d.ts +3 -0
- package/test/waitUntilQuiescent.d.ts.map +1 -0
- package/test/waitUntilQuiescent.js +2 -1
- package/test/weakset-dropped-remotable.test.js +50 -0
- package/tools/fakeCollectionManager.d.ts +14 -0
- package/tools/fakeCollectionManager.d.ts.map +1 -0
- package/tools/fakeCollectionManager.js +44 -0
- package/tools/fakeVirtualObjectManager.d.ts +32 -0
- package/tools/fakeVirtualObjectManager.d.ts.map +1 -0
- package/tools/fakeVirtualObjectManager.js +62 -0
- package/tools/fakeVirtualSupport.d.ts +278 -0
- package/tools/fakeVirtualSupport.d.ts.map +1 -0
- package/tools/fakeVirtualSupport.js +389 -0
- package/tools/prepare-strict-test-env.d.ts +37 -0
- package/tools/prepare-strict-test-env.d.ts.map +1 -0
- package/tools/prepare-strict-test-env.js +124 -0
- package/tools/prepare-test-env.d.ts +2 -0
- package/tools/prepare-test-env.d.ts.map +1 -0
- package/tools/prepare-test-env.js +13 -0
- package/tools/setup-vat-data.d.ts +9 -0
- package/tools/setup-vat-data.d.ts.map +1 -0
- package/tools/setup-vat-data.js +95 -0
- package/tools/vo-test-harness.d.ts +33 -0
- package/tools/vo-test-harness.d.ts.map +1 -0
- package/tools/vo-test-harness.js +164 -0
- package/CHANGELOG.md +0 -61
- package/test/kmarshal.js +0 -79
- package/test/test-handled-promises.js +0 -360
- package/test/virtual-objects/test-state-shape.js +0 -298
package/src/collectionManager.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { assert, q, Fail } from '@
|
|
1
|
+
import { assert, q, Fail } from '@endo/errors';
|
|
2
2
|
import { Far, passStyleOf } from '@endo/far';
|
|
3
3
|
import {
|
|
4
4
|
zeroPad,
|
|
5
5
|
makeEncodePassable,
|
|
6
6
|
makeDecodePassable,
|
|
7
|
-
isEncodedRemotable,
|
|
8
7
|
compareRank,
|
|
9
8
|
} from '@endo/marshal';
|
|
10
9
|
import {
|
|
@@ -15,7 +14,10 @@ import {
|
|
|
15
14
|
makeCopySet,
|
|
16
15
|
makeCopyMap,
|
|
17
16
|
getRankCover,
|
|
17
|
+
getCopyMapEntries,
|
|
18
|
+
getCopySetKeys,
|
|
18
19
|
} from '@endo/patterns';
|
|
20
|
+
import { isCopyMap, isCopySet } from '@agoric/store';
|
|
19
21
|
import { makeBaseRef, parseVatSlot } from './parseVatSlots.js';
|
|
20
22
|
import {
|
|
21
23
|
enumerateKeysStartEnd,
|
|
@@ -23,6 +25,11 @@ import {
|
|
|
23
25
|
} from './vatstore-iterators.js';
|
|
24
26
|
import { makeCache } from './cache.js';
|
|
25
27
|
|
|
28
|
+
/**
|
|
29
|
+
* @import {ToCapData, FromCapData} from '@endo/marshal';
|
|
30
|
+
* @import {Pattern} from '@endo/patterns';
|
|
31
|
+
*/
|
|
32
|
+
|
|
26
33
|
// XXX TODO: The following key length limit was put in place due to limitations
|
|
27
34
|
// in LMDB. With the move away from LMDB, it is no longer relevant, but I'm
|
|
28
35
|
// leaving it in place for the time being as a general defensive measure against
|
|
@@ -47,10 +54,24 @@ function throwNotDurable(value, slotIndex, serializedValue) {
|
|
|
47
54
|
Fail`value is not durable: ${value} at slot ${q(slotIndex)} of ${serializedValue.body}`;
|
|
48
55
|
}
|
|
49
56
|
|
|
57
|
+
function failNotFound(key, label) {
|
|
58
|
+
Fail`key ${key} not found in collection ${q(label)}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function failNotIterable(value) {
|
|
62
|
+
Fail`provided data source is not iterable: ${value}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
50
65
|
function prefixc(collectionID, dbEntryKey) {
|
|
51
66
|
return `vc.${collectionID}.${dbEntryKey}`;
|
|
52
67
|
}
|
|
53
68
|
|
|
69
|
+
export const collectionMetaKeys = new Set([
|
|
70
|
+
'|entryCount',
|
|
71
|
+
'|nextOrdinal',
|
|
72
|
+
'|schemata',
|
|
73
|
+
]);
|
|
74
|
+
|
|
54
75
|
/**
|
|
55
76
|
* @typedef {object} SchemaCacheValue
|
|
56
77
|
* @property {Pattern} keyShape
|
|
@@ -101,8 +122,8 @@ function makeSchemaCache(syscall, unserialize) {
|
|
|
101
122
|
* @param {(val: any) => string | undefined} convertValToSlot
|
|
102
123
|
* @param {*} convertSlotToVal
|
|
103
124
|
* @param {*} registerValue
|
|
104
|
-
* @param {
|
|
105
|
-
* @param {
|
|
125
|
+
* @param {ToCapData<string>} serialize
|
|
126
|
+
* @param {FromCapData<string>} unserialize
|
|
106
127
|
* @param {(capDatas: any) => void} assertAcceptableSyscallCapdataSize
|
|
107
128
|
*/
|
|
108
129
|
export function makeCollectionManager(
|
|
@@ -126,56 +147,48 @@ export function makeCollectionManager(
|
|
|
126
147
|
scalarMapStore: {
|
|
127
148
|
hasWeakKeys: false,
|
|
128
149
|
kindID: 0,
|
|
129
|
-
// eslint-disable-next-line no-use-before-define
|
|
130
150
|
reanimator: reanimateMapStore,
|
|
131
151
|
durable: false,
|
|
132
152
|
},
|
|
133
153
|
scalarWeakMapStore: {
|
|
134
154
|
hasWeakKeys: true,
|
|
135
155
|
kindID: 0,
|
|
136
|
-
// eslint-disable-next-line no-use-before-define
|
|
137
156
|
reanimator: reanimateWeakMapStore,
|
|
138
157
|
durable: false,
|
|
139
158
|
},
|
|
140
159
|
scalarSetStore: {
|
|
141
160
|
hasWeakKeys: false,
|
|
142
161
|
kindID: 0,
|
|
143
|
-
// eslint-disable-next-line no-use-before-define
|
|
144
162
|
reanimator: reanimateSetStore,
|
|
145
163
|
durable: false,
|
|
146
164
|
},
|
|
147
165
|
scalarWeakSetStore: {
|
|
148
166
|
hasWeakKeys: true,
|
|
149
167
|
kindID: 0,
|
|
150
|
-
// eslint-disable-next-line no-use-before-define
|
|
151
168
|
reanimator: reanimateWeakSetStore,
|
|
152
169
|
durable: false,
|
|
153
170
|
},
|
|
154
171
|
scalarDurableMapStore: {
|
|
155
172
|
hasWeakKeys: false,
|
|
156
173
|
kindID: 0,
|
|
157
|
-
// eslint-disable-next-line no-use-before-define
|
|
158
174
|
reanimator: reanimateMapStore,
|
|
159
175
|
durable: true,
|
|
160
176
|
},
|
|
161
177
|
scalarDurableWeakMapStore: {
|
|
162
178
|
hasWeakKeys: true,
|
|
163
179
|
kindID: 0,
|
|
164
|
-
// eslint-disable-next-line no-use-before-define
|
|
165
180
|
reanimator: reanimateWeakMapStore,
|
|
166
181
|
durable: true,
|
|
167
182
|
},
|
|
168
183
|
scalarDurableSetStore: {
|
|
169
184
|
hasWeakKeys: false,
|
|
170
185
|
kindID: 0,
|
|
171
|
-
// eslint-disable-next-line no-use-before-define
|
|
172
186
|
reanimator: reanimateSetStore,
|
|
173
187
|
durable: true,
|
|
174
188
|
},
|
|
175
189
|
scalarDurableWeakSetStore: {
|
|
176
190
|
hasWeakKeys: true,
|
|
177
191
|
kindID: 0,
|
|
178
|
-
// eslint-disable-next-line no-use-before-define
|
|
179
192
|
reanimator: reanimateWeakSetStore,
|
|
180
193
|
durable: true,
|
|
181
194
|
},
|
|
@@ -198,7 +211,6 @@ export function makeCollectionManager(
|
|
|
198
211
|
vrm.registerKind(
|
|
199
212
|
kindID,
|
|
200
213
|
storeKindInfo[kind].reanimator,
|
|
201
|
-
// eslint-disable-next-line no-use-before-define
|
|
202
214
|
deleteCollection,
|
|
203
215
|
storeKindInfo[kind].durable,
|
|
204
216
|
);
|
|
@@ -244,7 +256,11 @@ export function makeCollectionManager(
|
|
|
244
256
|
const kindInfo = storeKindInfo[kindName];
|
|
245
257
|
kindInfo || Fail`unknown collection kind ${kindName}`;
|
|
246
258
|
const { hasWeakKeys, durable } = kindInfo;
|
|
247
|
-
const getSchema = () =>
|
|
259
|
+
const getSchema = () => {
|
|
260
|
+
const result = schemaCache.get(collectionID);
|
|
261
|
+
assert(result !== undefined);
|
|
262
|
+
return result;
|
|
263
|
+
};
|
|
248
264
|
const dbKeyPrefix = `vc.${collectionID}.`;
|
|
249
265
|
let currentGenerationNumber = 0;
|
|
250
266
|
|
|
@@ -274,8 +290,21 @@ export function makeCollectionManager(
|
|
|
274
290
|
return `${dbKeyPrefix}${dbEntryKey}`;
|
|
275
291
|
}
|
|
276
292
|
|
|
293
|
+
// A "vref" is a string like "o-4" or "o+d44/2:0"
|
|
294
|
+
// An "EncodedKey" is the output of encode-passable:
|
|
295
|
+
// * strings become `s${string}`, like "foo" -> "sfoo"
|
|
296
|
+
// * small positive BigInts become `p${len}:${digits}`, like 47n -> "p2:47"
|
|
297
|
+
// * refs are assigned an "ordinal" and use `r${fixedLengthOrdinal}:${vref}`
|
|
298
|
+
// * e.g. vref(o-4) becomes "r0000000001:o-4"
|
|
299
|
+
// A "DBKey" is used to index the vatstore. DBKeys for collection
|
|
300
|
+
// entries join a collection prefix and an EncodedKey. Some
|
|
301
|
+
// possible DBKeys for entries of collection "5", using collection
|
|
302
|
+
// prefix "vc.5.", are:
|
|
303
|
+
// * "foo" -> "vc.5.sfoo"
|
|
304
|
+
// * 47n -> "vc.5.p2:47"
|
|
305
|
+
// * vref(o-4) -> "vc.5.r0000000001:o-4"
|
|
306
|
+
|
|
277
307
|
const encodeRemotable = remotable => {
|
|
278
|
-
// eslint-disable-next-line no-use-before-define
|
|
279
308
|
const ordinal = getOrdinal(remotable);
|
|
280
309
|
ordinal !== undefined || Fail`no ordinal for ${remotable}`;
|
|
281
310
|
const ordinalTag = zeroPad(ordinal, BIGINT_TAG_LEN);
|
|
@@ -289,10 +318,11 @@ export function makeCollectionManager(
|
|
|
289
318
|
// the resulting function will encode only `Key` arguments.
|
|
290
319
|
const encodeKey = makeEncodePassable({ encodeRemotable });
|
|
291
320
|
|
|
292
|
-
const
|
|
321
|
+
const vrefFromEncodedKey = encodedKey =>
|
|
322
|
+
encodedKey.substring(1 + BIGINT_TAG_LEN + 1);
|
|
293
323
|
|
|
294
324
|
const decodeRemotable = encodedKey =>
|
|
295
|
-
convertSlotToVal(
|
|
325
|
+
convertSlotToVal(vrefFromEncodedKey(encodedKey));
|
|
296
326
|
|
|
297
327
|
// `makeDecodePassable` has three named options:
|
|
298
328
|
// `decodeRemotable`, `decodeError`, and `decodePromise`.
|
|
@@ -328,32 +358,40 @@ export function makeCollectionManager(
|
|
|
328
358
|
}
|
|
329
359
|
|
|
330
360
|
function dbKeyToKey(dbKey) {
|
|
361
|
+
// convert e.g. vc.5.r0000000001:o+v10/1 to r0000000001:o+v10/1
|
|
331
362
|
const dbEntryKey = dbKey.substring(dbKeyPrefix.length);
|
|
332
363
|
return decodeKey(dbEntryKey);
|
|
333
364
|
}
|
|
334
365
|
|
|
366
|
+
function dbKeyToEncodedKey(dbKey) {
|
|
367
|
+
assert(dbKey.startsWith(dbKeyPrefix), dbKey);
|
|
368
|
+
return dbKey.substring(dbKeyPrefix.length);
|
|
369
|
+
}
|
|
370
|
+
|
|
335
371
|
function has(key) {
|
|
336
372
|
const { keyShape } = getSchema();
|
|
337
373
|
if (!matches(key, keyShape)) {
|
|
338
374
|
return false;
|
|
339
|
-
}
|
|
340
|
-
if (passStyleOf(key) === 'remotable') {
|
|
375
|
+
} else if (passStyleOf(key) === 'remotable') {
|
|
341
376
|
return getOrdinal(key) !== undefined;
|
|
342
377
|
} else {
|
|
343
378
|
return syscall.vatstoreGet(keyToDBKey(key)) !== undefined;
|
|
344
379
|
}
|
|
345
380
|
}
|
|
346
381
|
|
|
382
|
+
function mustGet(key, label) {
|
|
383
|
+
if (passStyleOf(key) === 'remotable' && getOrdinal(key) === undefined) {
|
|
384
|
+
failNotFound(key, label);
|
|
385
|
+
}
|
|
386
|
+
const dbKey = keyToDBKey(key);
|
|
387
|
+
const result = syscall.vatstoreGet(dbKey) || failNotFound(key, label);
|
|
388
|
+
return { dbKey, result };
|
|
389
|
+
}
|
|
390
|
+
|
|
347
391
|
function get(key) {
|
|
348
392
|
const { keyShape, label } = getSchema();
|
|
349
393
|
mustMatch(key, keyShape, makeInvalidKeyTypeMsg(label));
|
|
350
|
-
|
|
351
|
-
throw Fail`key ${key} not found in collection ${q(label)}`;
|
|
352
|
-
}
|
|
353
|
-
const result = syscall.vatstoreGet(keyToDBKey(key));
|
|
354
|
-
if (!result) {
|
|
355
|
-
throw Fail`key ${key} not found in collection ${q(label)}`;
|
|
356
|
-
}
|
|
394
|
+
const { result } = mustGet(key, label);
|
|
357
395
|
return unserializeValue(JSON.parse(result));
|
|
358
396
|
}
|
|
359
397
|
|
|
@@ -377,11 +415,11 @@ export function makeCollectionManager(
|
|
|
377
415
|
currentGenerationNumber += 1;
|
|
378
416
|
assertAcceptableSyscallCapdataSize([serializedValue]);
|
|
379
417
|
if (durable) {
|
|
380
|
-
serializedValue.slots.
|
|
418
|
+
for (const [slotIndex, vref] of serializedValue.slots.entries()) {
|
|
381
419
|
if (!vrm.isDurable(vref)) {
|
|
382
420
|
throwNotDurable(value, slotIndex, serializedValue);
|
|
383
421
|
}
|
|
384
|
-
}
|
|
422
|
+
}
|
|
385
423
|
}
|
|
386
424
|
if (passStyleOf(key) === 'remotable') {
|
|
387
425
|
/** @type {string} */
|
|
@@ -397,7 +435,9 @@ export function makeCollectionManager(
|
|
|
397
435
|
vrm.addReachableVref(vref);
|
|
398
436
|
}
|
|
399
437
|
}
|
|
400
|
-
serializedValue.slots
|
|
438
|
+
for (const vref of serializedValue.slots) {
|
|
439
|
+
vrm.addReachableVref(vref);
|
|
440
|
+
}
|
|
401
441
|
syscall.vatstoreSet(keyToDBKey(key), JSON.stringify(serializedValue));
|
|
402
442
|
updateEntryCount(1);
|
|
403
443
|
};
|
|
@@ -416,15 +456,13 @@ export function makeCollectionManager(
|
|
|
416
456
|
const after = serializeValue(harden(value));
|
|
417
457
|
assertAcceptableSyscallCapdataSize([after]);
|
|
418
458
|
if (durable) {
|
|
419
|
-
after.slots.
|
|
459
|
+
for (const [i, vref] of after.slots.entries()) {
|
|
420
460
|
if (!vrm.isDurable(vref)) {
|
|
421
461
|
throwNotDurable(value, i, after);
|
|
422
462
|
}
|
|
423
|
-
}
|
|
463
|
+
}
|
|
424
464
|
}
|
|
425
|
-
const dbKey =
|
|
426
|
-
const rawBefore = syscall.vatstoreGet(dbKey);
|
|
427
|
-
rawBefore || Fail`key ${key} not found in collection ${q(label)}`;
|
|
465
|
+
const { dbKey, result: rawBefore } = mustGet(key, label);
|
|
428
466
|
const before = JSON.parse(rawBefore);
|
|
429
467
|
vrm.updateReferenceCounts(before.slots, after.slots);
|
|
430
468
|
syscall.vatstoreSet(dbKey, JSON.stringify(after));
|
|
@@ -433,12 +471,7 @@ export function makeCollectionManager(
|
|
|
433
471
|
function deleteInternal(key) {
|
|
434
472
|
const { keyShape, label } = getSchema();
|
|
435
473
|
mustMatch(key, keyShape, makeInvalidKeyTypeMsg(label));
|
|
436
|
-
|
|
437
|
-
throw Fail`key ${key} not found in collection ${q(label)}`;
|
|
438
|
-
}
|
|
439
|
-
const dbKey = keyToDBKey(key);
|
|
440
|
-
const rawValue = syscall.vatstoreGet(dbKey);
|
|
441
|
-
rawValue || Fail`key ${key} not found in collection ${q(label)}`;
|
|
474
|
+
const { dbKey, result: rawValue } = mustGet(key, label);
|
|
442
475
|
const value = JSON.parse(rawValue);
|
|
443
476
|
const doMoreGC1 = value.slots.map(vrm.removeReachableVref).some(b => b);
|
|
444
477
|
syscall.vatstoreDelete(dbKey);
|
|
@@ -474,18 +507,15 @@ export function makeCollectionManager(
|
|
|
474
507
|
const end = prefix(coverEnd); // exclusive
|
|
475
508
|
|
|
476
509
|
const generationAtStart = currentGenerationNumber;
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
}
|
|
481
|
-
}
|
|
510
|
+
const checkGen = () =>
|
|
511
|
+
currentGenerationNumber === generationAtStart ||
|
|
512
|
+
Fail`keys in store cannot be added to during iteration`;
|
|
482
513
|
|
|
483
514
|
const needToMatchKey = !matchAny(keyPatt);
|
|
484
515
|
const needToMatchValue = !matchAny(valuePatt);
|
|
485
516
|
|
|
486
|
-
// we
|
|
517
|
+
// we might not need to unserialize the dbKey or get the dbValue
|
|
487
518
|
const needKeys = yieldKeys || needToMatchKey;
|
|
488
|
-
// we don't always need the dbValue
|
|
489
519
|
const needValues = yieldValues || needToMatchValue;
|
|
490
520
|
|
|
491
521
|
/**
|
|
@@ -513,7 +543,7 @@ export function makeCollectionManager(
|
|
|
513
543
|
yield [yieldKeys ? key : undefined, yieldValues ? value : undefined];
|
|
514
544
|
}
|
|
515
545
|
}
|
|
516
|
-
|
|
546
|
+
harden(iter);
|
|
517
547
|
return iter();
|
|
518
548
|
}
|
|
519
549
|
|
|
@@ -523,6 +553,7 @@ export function makeCollectionManager(
|
|
|
523
553
|
yield entry[0];
|
|
524
554
|
}
|
|
525
555
|
}
|
|
556
|
+
harden(iter);
|
|
526
557
|
return iter();
|
|
527
558
|
}
|
|
528
559
|
|
|
@@ -539,40 +570,58 @@ export function makeCollectionManager(
|
|
|
539
570
|
*/
|
|
540
571
|
function clearInternalFull() {
|
|
541
572
|
let doMoreGC = false;
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
//
|
|
547
|
-
for (const dbKey of
|
|
548
|
-
const
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
if (
|
|
553
|
-
|
|
573
|
+
|
|
574
|
+
// visit every DB entry associated with the collection, which
|
|
575
|
+
// (due to sorting) will be collection entries first, and then a
|
|
576
|
+
// mixture of ordinal-assignment mappings and size-independent
|
|
577
|
+
// metadata (both of which start with "|").
|
|
578
|
+
for (const dbKey of enumerateKeysWithPrefix(syscall, dbKeyPrefix)) {
|
|
579
|
+
const encodedKey = dbKeyToEncodedKey(dbKey);
|
|
580
|
+
|
|
581
|
+
// preserve general metadata ("|entryCount" and friends are
|
|
582
|
+
// cleared by our caller)
|
|
583
|
+
if (collectionMetaKeys.has(encodedKey)) continue;
|
|
584
|
+
|
|
585
|
+
if (encodedKey.startsWith('|')) {
|
|
586
|
+
// ordinal assignment; decref or de-recognize its vref
|
|
587
|
+
const keyVref = encodedKey.substring(1);
|
|
588
|
+
parseVatSlot(keyVref);
|
|
554
589
|
if (hasWeakKeys) {
|
|
555
590
|
vrm.removeRecognizableVref(keyVref, `${collectionID}`, true);
|
|
556
591
|
} else {
|
|
557
592
|
doMoreGC = vrm.removeReachableVref(keyVref) || doMoreGC;
|
|
558
593
|
}
|
|
559
|
-
|
|
594
|
+
} else {
|
|
595
|
+
// a collection entry; decref slots from its value
|
|
596
|
+
const value = JSON.parse(syscall.vatstoreGet(dbKey));
|
|
597
|
+
doMoreGC =
|
|
598
|
+
value.slots.map(vrm.removeReachableVref).some(b => b) || doMoreGC;
|
|
560
599
|
}
|
|
600
|
+
|
|
601
|
+
// in either case, delete the DB entry
|
|
602
|
+
syscall.vatstoreDelete(dbKey);
|
|
561
603
|
}
|
|
604
|
+
|
|
562
605
|
return doMoreGC;
|
|
563
606
|
}
|
|
564
607
|
|
|
565
608
|
function clearInternal(isDeleting, keyPatt, valuePatt) {
|
|
566
609
|
let doMoreGC = false;
|
|
567
|
-
if (isDeleting
|
|
610
|
+
if (isDeleting) {
|
|
568
611
|
doMoreGC = clearInternalFull();
|
|
612
|
+
// |entryCount will be deleted along with metadata keys
|
|
613
|
+
} else if (matchAny(keyPatt) && matchAny(valuePatt)) {
|
|
614
|
+
doMoreGC = clearInternalFull();
|
|
615
|
+
if (!hasWeakKeys) {
|
|
616
|
+
syscall.vatstoreSet(prefix('|entryCount'), '0');
|
|
617
|
+
}
|
|
569
618
|
} else {
|
|
619
|
+
let numDeleted = 0;
|
|
570
620
|
for (const k of keys(keyPatt, valuePatt)) {
|
|
621
|
+
numDeleted += 1;
|
|
571
622
|
doMoreGC = deleteInternal(k) || doMoreGC;
|
|
572
623
|
}
|
|
573
|
-
|
|
574
|
-
if (!hasWeakKeys && !isDeleting) {
|
|
575
|
-
syscall.vatstoreSet(prefix('|entryCount'), '0');
|
|
624
|
+
updateEntryCount(-numDeleted);
|
|
576
625
|
}
|
|
577
626
|
return doMoreGC;
|
|
578
627
|
}
|
|
@@ -587,6 +636,7 @@ export function makeCollectionManager(
|
|
|
587
636
|
yield entry[1];
|
|
588
637
|
}
|
|
589
638
|
}
|
|
639
|
+
harden(iter);
|
|
590
640
|
return iter();
|
|
591
641
|
}
|
|
592
642
|
|
|
@@ -596,12 +646,13 @@ export function makeCollectionManager(
|
|
|
596
646
|
yield entry;
|
|
597
647
|
}
|
|
598
648
|
}
|
|
649
|
+
harden(iter);
|
|
599
650
|
return iter();
|
|
600
651
|
}
|
|
601
652
|
|
|
602
653
|
function countEntries(keyPatt, valuePatt) {
|
|
603
654
|
let count = 0;
|
|
604
|
-
// eslint-disable-next-line no-
|
|
655
|
+
// eslint-disable-next-line no-unused-vars
|
|
605
656
|
for (const k of keys(keyPatt, valuePatt)) {
|
|
606
657
|
count += 1;
|
|
607
658
|
}
|
|
@@ -624,6 +675,34 @@ export function makeCollectionManager(
|
|
|
624
675
|
const snapshotMap = (keyPatt, valuePatt) =>
|
|
625
676
|
makeCopyMap(entries(keyPatt, valuePatt));
|
|
626
677
|
|
|
678
|
+
const addAllToSet = elems => {
|
|
679
|
+
if (typeof elems[Symbol.iterator] !== 'function') {
|
|
680
|
+
elems =
|
|
681
|
+
Object.isFrozen(elems) && isCopySet(elems)
|
|
682
|
+
? getCopySetKeys(elems)
|
|
683
|
+
: failNotIterable(elems);
|
|
684
|
+
}
|
|
685
|
+
for (const elem of elems) {
|
|
686
|
+
addToSet(elem);
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
const addAllToMap = mapEntries => {
|
|
691
|
+
if (typeof mapEntries[Symbol.iterator] !== 'function') {
|
|
692
|
+
mapEntries =
|
|
693
|
+
Object.isFrozen(mapEntries) && isCopyMap(mapEntries)
|
|
694
|
+
? getCopyMapEntries(mapEntries)
|
|
695
|
+
: failNotIterable(mapEntries);
|
|
696
|
+
}
|
|
697
|
+
for (const [key, value] of mapEntries) {
|
|
698
|
+
if (has(key)) {
|
|
699
|
+
set(key, value);
|
|
700
|
+
} else {
|
|
701
|
+
doInit(key, value, true);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
};
|
|
705
|
+
|
|
627
706
|
return {
|
|
628
707
|
has,
|
|
629
708
|
get,
|
|
@@ -635,6 +714,8 @@ export function makeCollectionManager(
|
|
|
635
714
|
keys,
|
|
636
715
|
values,
|
|
637
716
|
entries,
|
|
717
|
+
addAllToSet,
|
|
718
|
+
addAllToMap,
|
|
638
719
|
snapshotSet,
|
|
639
720
|
snapshotMap,
|
|
640
721
|
sizeInternal,
|
|
@@ -647,12 +728,23 @@ export function makeCollectionManager(
|
|
|
647
728
|
const hasWeakKeys = storeKindInfo[kindName].hasWeakKeys;
|
|
648
729
|
const raw = summonCollectionInternal(initial, collectionID, kindName);
|
|
649
730
|
|
|
650
|
-
const {
|
|
731
|
+
const {
|
|
732
|
+
has,
|
|
733
|
+
get,
|
|
734
|
+
init,
|
|
735
|
+
addToSet,
|
|
736
|
+
addAllToMap,
|
|
737
|
+
addAllToSet,
|
|
738
|
+
set,
|
|
739
|
+
delete: del,
|
|
740
|
+
} = raw;
|
|
651
741
|
const weakMethods = {
|
|
652
742
|
has,
|
|
653
743
|
get,
|
|
654
744
|
init,
|
|
655
745
|
addToSet,
|
|
746
|
+
addAllToSet,
|
|
747
|
+
addAllToMap,
|
|
656
748
|
set,
|
|
657
749
|
delete: del,
|
|
658
750
|
};
|
|
@@ -700,7 +792,9 @@ export function makeCollectionManager(
|
|
|
700
792
|
const collection = summonCollectionInternal(false, collectionID, kindName);
|
|
701
793
|
|
|
702
794
|
let doMoreGC = collection.clearInternal(true);
|
|
703
|
-
const
|
|
795
|
+
const record = schemaCache.get(collectionID);
|
|
796
|
+
assert(record !== undefined);
|
|
797
|
+
const { schemataCapData } = record;
|
|
704
798
|
doMoreGC =
|
|
705
799
|
schemataCapData.slots.map(vrm.removeReachableVref).some(b => b) ||
|
|
706
800
|
doMoreGC;
|
|
@@ -747,13 +841,15 @@ export function makeCollectionManager(
|
|
|
747
841
|
}
|
|
748
842
|
const schemataCapData = serialize(harden(schemata));
|
|
749
843
|
if (isDurable) {
|
|
750
|
-
schemataCapData.slots.
|
|
844
|
+
for (const [slotIndex, vref] of schemataCapData.slots.entries()) {
|
|
751
845
|
if (!vrm.isDurable(vref)) {
|
|
752
846
|
throwNotDurable(vref, slotIndex, schemataCapData);
|
|
753
847
|
}
|
|
754
|
-
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
for (const vref of schemataCapData.slots) {
|
|
851
|
+
vrm.addReachableVref(vref);
|
|
755
852
|
}
|
|
756
|
-
schemataCapData.slots.forEach(vrm.addReachableVref);
|
|
757
853
|
|
|
758
854
|
schemaCache.set(
|
|
759
855
|
collectionID,
|
|
@@ -764,12 +860,48 @@ export function makeCollectionManager(
|
|
|
764
860
|
}
|
|
765
861
|
|
|
766
862
|
function collectionToMapStore(collection) {
|
|
767
|
-
const {
|
|
768
|
-
|
|
863
|
+
const {
|
|
864
|
+
has,
|
|
865
|
+
get,
|
|
866
|
+
init,
|
|
867
|
+
set,
|
|
868
|
+
delete: del,
|
|
869
|
+
addAllToMap,
|
|
870
|
+
keys,
|
|
871
|
+
values,
|
|
872
|
+
entries,
|
|
873
|
+
snapshotMap,
|
|
874
|
+
getSize,
|
|
875
|
+
clear,
|
|
876
|
+
} = collection;
|
|
877
|
+
const mapStore = {
|
|
878
|
+
has,
|
|
879
|
+
get,
|
|
880
|
+
init,
|
|
881
|
+
set,
|
|
882
|
+
delete: del,
|
|
883
|
+
addAll: addAllToMap,
|
|
884
|
+
keys,
|
|
885
|
+
values,
|
|
886
|
+
entries,
|
|
887
|
+
snapshot: snapshotMap,
|
|
888
|
+
getSize,
|
|
889
|
+
clear,
|
|
890
|
+
};
|
|
891
|
+
return Far('mapStore', mapStore);
|
|
769
892
|
}
|
|
770
893
|
|
|
771
894
|
function collectionToWeakMapStore(collection) {
|
|
772
|
-
|
|
895
|
+
const { has, get, init, set, delete: del, addAllToMap } = collection;
|
|
896
|
+
const weakMapStore = {
|
|
897
|
+
has,
|
|
898
|
+
get,
|
|
899
|
+
init,
|
|
900
|
+
set,
|
|
901
|
+
delete: del,
|
|
902
|
+
addAll: addAllToMap,
|
|
903
|
+
};
|
|
904
|
+
return Far('weakMapStore', weakMapStore);
|
|
773
905
|
}
|
|
774
906
|
|
|
775
907
|
function collectionToSetStore(collection) {
|
|
@@ -777,50 +909,35 @@ export function makeCollectionManager(
|
|
|
777
909
|
has,
|
|
778
910
|
addToSet,
|
|
779
911
|
delete: del,
|
|
912
|
+
addAllToSet,
|
|
780
913
|
keys,
|
|
781
|
-
getSize,
|
|
782
914
|
snapshotSet,
|
|
915
|
+
getSize,
|
|
783
916
|
clear,
|
|
784
917
|
} = collection;
|
|
785
|
-
function* entries(patt) {
|
|
786
|
-
for (const k of keys(patt)) {
|
|
787
|
-
yield [k, k];
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
function addAll(elems) {
|
|
791
|
-
for (const elem of elems) {
|
|
792
|
-
addToSet(elem, null);
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
918
|
|
|
796
919
|
const setStore = {
|
|
797
920
|
has,
|
|
798
921
|
add: addToSet,
|
|
799
|
-
addAll,
|
|
800
922
|
delete: del,
|
|
923
|
+
addAll: addAllToSet,
|
|
801
924
|
keys: patt => keys(patt),
|
|
802
925
|
values: patt => keys(patt),
|
|
803
|
-
entries,
|
|
804
|
-
getSize: patt => getSize(patt),
|
|
805
926
|
snapshot: snapshotSet,
|
|
927
|
+
getSize: patt => getSize(patt),
|
|
806
928
|
clear,
|
|
807
929
|
};
|
|
808
930
|
return Far('setStore', setStore);
|
|
809
931
|
}
|
|
810
932
|
|
|
811
933
|
function collectionToWeakSetStore(collection) {
|
|
812
|
-
const { has, addToSet, delete: del } = collection;
|
|
813
|
-
function addAll(elems) {
|
|
814
|
-
for (const elem of elems) {
|
|
815
|
-
addToSet(elem);
|
|
816
|
-
}
|
|
817
|
-
}
|
|
934
|
+
const { has, addToSet, delete: del, addAllToSet } = collection;
|
|
818
935
|
|
|
819
936
|
const weakSetStore = {
|
|
820
937
|
has,
|
|
821
938
|
add: addToSet,
|
|
822
|
-
addAll,
|
|
823
939
|
delete: del,
|
|
940
|
+
addAll: addAllToSet,
|
|
824
941
|
};
|
|
825
942
|
return Far('weakSetStore', weakSetStore);
|
|
826
943
|
}
|
|
@@ -829,7 +946,7 @@ export function makeCollectionManager(
|
|
|
829
946
|
* Produce a big map.
|
|
830
947
|
*
|
|
831
948
|
* @template K,V
|
|
832
|
-
* @param {string} [label
|
|
949
|
+
* @param {string} [label] - diagnostic label for the store
|
|
833
950
|
* @param {StoreOptions} [options]
|
|
834
951
|
* @returns {MapStore<K,V>}
|
|
835
952
|
*/
|
|
@@ -873,7 +990,7 @@ export function makeCollectionManager(
|
|
|
873
990
|
* Produce a weak big map.
|
|
874
991
|
*
|
|
875
992
|
* @template K,V
|
|
876
|
-
* @param {string} [label
|
|
993
|
+
* @param {string} [label] - diagnostic label for the store
|
|
877
994
|
* @param {StoreOptions} [options]
|
|
878
995
|
* @returns {WeakMapStore<K,V>}
|
|
879
996
|
*/
|
|
@@ -902,7 +1019,7 @@ export function makeCollectionManager(
|
|
|
902
1019
|
* Produce a big set.
|
|
903
1020
|
*
|
|
904
1021
|
* @template K
|
|
905
|
-
* @param {string} [label
|
|
1022
|
+
* @param {string} [label] - diagnostic label for the store
|
|
906
1023
|
* @param {StoreOptions} [options]
|
|
907
1024
|
* @returns {SetStore<K>}
|
|
908
1025
|
*/
|
|
@@ -929,7 +1046,7 @@ export function makeCollectionManager(
|
|
|
929
1046
|
* Produce a weak big set.
|
|
930
1047
|
*
|
|
931
1048
|
* @template K
|
|
932
|
-
* @param {string} [label
|
|
1049
|
+
* @param {string} [label] - diagnostic label for the store
|
|
933
1050
|
* @param {StoreOptions} [options]
|
|
934
1051
|
* @returns {WeakSetStore<K>}
|
|
935
1052
|
*/
|
|
@@ -1006,7 +1123,7 @@ export function makeCollectionManager(
|
|
|
1006
1123
|
* remotables.
|
|
1007
1124
|
*
|
|
1008
1125
|
* @template K,V
|
|
1009
|
-
* @param {string} [label
|
|
1126
|
+
* @param {string} [label] - diagnostic label for the store
|
|
1010
1127
|
* @param {StoreOptions} [options]
|
|
1011
1128
|
* @returns {MapStore<K,V>}
|
|
1012
1129
|
*/
|
|
@@ -1018,7 +1135,7 @@ export function makeCollectionManager(
|
|
|
1018
1135
|
* primitives, or remotables.
|
|
1019
1136
|
*
|
|
1020
1137
|
* @template K,V
|
|
1021
|
-
* @param {string} [label
|
|
1138
|
+
* @param {string} [label] - diagnostic label for the store
|
|
1022
1139
|
* @param {StoreOptions} [options]
|
|
1023
1140
|
* @returns {WeakMapStore<K,V>}
|
|
1024
1141
|
*/
|
|
@@ -1030,7 +1147,7 @@ export function makeCollectionManager(
|
|
|
1030
1147
|
* remotables.
|
|
1031
1148
|
*
|
|
1032
1149
|
* @template K
|
|
1033
|
-
* @param {string} [label
|
|
1150
|
+
* @param {string} [label] - diagnostic label for the store
|
|
1034
1151
|
* @param {StoreOptions} [options]
|
|
1035
1152
|
* @returns {SetStore<K>}
|
|
1036
1153
|
*/
|
|
@@ -1042,7 +1159,7 @@ export function makeCollectionManager(
|
|
|
1042
1159
|
* primitives, or remotables.
|
|
1043
1160
|
*
|
|
1044
1161
|
* @template K
|
|
1045
|
-
* @param {string} [label
|
|
1162
|
+
* @param {string} [label] - diagnostic label for the store
|
|
1046
1163
|
* @param {StoreOptions} [options]
|
|
1047
1164
|
* @returns {WeakSetStore<K>}
|
|
1048
1165
|
*/
|