@fluidframework/map 2.0.0-rc.2.0.1 → 2.0.0-rc.3.0.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/CHANGELOG.md +44 -0
- package/api-report/map.api.md +17 -158
- package/dist/directory.d.ts +7 -51
- package/dist/directory.d.ts.map +1 -1
- package/dist/directory.js +39 -107
- package/dist/directory.js.map +1 -1
- package/dist/directoryFactory.d.ts +54 -0
- package/dist/directoryFactory.d.ts.map +1 -0
- package/dist/directoryFactory.js +91 -0
- package/dist/directoryFactory.js.map +1 -0
- package/dist/index.d.ts +3 -45
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -55
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +7 -57
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/internalInterfaces.d.ts +50 -1
- package/dist/internalInterfaces.d.ts.map +1 -1
- package/dist/internalInterfaces.js.map +1 -1
- package/dist/legacy.d.ts +25 -0
- package/dist/localValues.d.ts +1 -1
- package/dist/localValues.d.ts.map +1 -1
- package/dist/localValues.js +6 -6
- package/dist/localValues.js.map +1 -1
- package/dist/map.d.ts +4 -36
- package/dist/map.d.ts.map +1 -1
- package/dist/map.js +9 -60
- package/dist/map.js.map +1 -1
- package/dist/mapFactory.d.ts +52 -0
- package/dist/mapFactory.d.ts.map +1 -0
- package/dist/mapFactory.js +71 -0
- package/dist/mapFactory.js.map +1 -0
- package/dist/mapKernel.d.ts +3 -3
- package/dist/mapKernel.d.ts.map +1 -1
- package/dist/mapKernel.js +14 -14
- package/dist/mapKernel.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/public.d.ts +12 -0
- package/internal.d.ts +11 -0
- package/legacy.d.ts +11 -0
- package/lib/directory.d.ts +7 -51
- package/lib/directory.d.ts.map +1 -1
- package/lib/directory.js +6 -73
- package/lib/directory.js.map +1 -1
- package/lib/directoryFactory.d.ts +54 -0
- package/lib/directoryFactory.d.ts.map +1 -0
- package/lib/directoryFactory.js +87 -0
- package/lib/directoryFactory.js.map +1 -0
- package/lib/index.d.ts +3 -45
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -50
- package/lib/index.js.map +1 -1
- package/lib/interfaces.d.ts +7 -57
- package/lib/interfaces.d.ts.map +1 -1
- package/lib/interfaces.js.map +1 -1
- package/lib/internalInterfaces.d.ts +50 -1
- package/lib/internalInterfaces.d.ts.map +1 -1
- package/lib/internalInterfaces.js.map +1 -1
- package/lib/legacy.d.ts +25 -0
- package/lib/localValues.d.ts +1 -1
- package/lib/localValues.d.ts.map +1 -1
- package/lib/localValues.js +1 -1
- package/lib/localValues.js.map +1 -1
- package/lib/map.d.ts +4 -36
- package/lib/map.d.ts.map +1 -1
- package/lib/map.js +4 -54
- package/lib/map.js.map +1 -1
- package/lib/mapFactory.d.ts +52 -0
- package/lib/mapFactory.d.ts.map +1 -0
- package/lib/mapFactory.js +67 -0
- package/lib/mapFactory.js.map +1 -0
- package/lib/mapKernel.d.ts +3 -3
- package/lib/mapKernel.d.ts.map +1 -1
- package/lib/mapKernel.js +2 -2
- package/lib/mapKernel.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/public.d.ts +12 -0
- package/package.json +105 -59
- package/src/directory.ts +16 -100
- package/src/directoryFactory.ts +120 -0
- package/src/index.ts +2 -73
- package/src/interfaces.ts +7 -62
- package/src/internalInterfaces.ts +55 -2
- package/src/localValues.ts +6 -5
- package/src/map.ts +8 -71
- package/src/mapFactory.ts +101 -0
- package/src/mapKernel.ts +13 -9
- package/src/packageVersion.ts +1 -1
- package/api-extractor-cjs.json +0 -8
- package/dist/map-alpha.d.ts +0 -898
- package/dist/map-beta.d.ts +0 -195
- package/dist/map-public.d.ts +0 -195
- package/dist/map-untrimmed.d.ts +0 -912
- package/lib/map-alpha.d.ts +0 -898
- package/lib/map-beta.d.ts +0 -195
- package/lib/map-public.d.ts +0 -195
- package/lib/map-untrimmed.d.ts +0 -912
- package/lib/test/memory/directory.spec.js +0 -71
- package/lib/test/memory/directory.spec.js.map +0 -1
- package/lib/test/memory/map.spec.js +0 -71
- package/lib/test/memory/map.spec.js.map +0 -1
- package/lib/test/mocha/directory.order.spec.js +0 -422
- package/lib/test/mocha/directory.order.spec.js.map +0 -1
- package/lib/test/mocha/directory.snapshot.spec.js +0 -111
- package/lib/test/mocha/directory.snapshot.spec.js.map +0 -1
- package/lib/test/mocha/directory.spec.js +0 -1406
- package/lib/test/mocha/directory.spec.js.map +0 -1
- package/lib/test/mocha/directoryEquivalenceUtils.js +0 -36
- package/lib/test/mocha/directoryEquivalenceUtils.js.map +0 -1
- package/lib/test/mocha/directoryFuzzTests.spec.js +0 -337
- package/lib/test/mocha/directoryFuzzTests.spec.js.map +0 -1
- package/lib/test/mocha/dirname.cjs +0 -16
- package/lib/test/mocha/dirname.cjs.map +0 -1
- package/lib/test/mocha/map.fuzz.spec.js +0 -114
- package/lib/test/mocha/map.fuzz.spec.js.map +0 -1
- package/lib/test/mocha/map.spec.js +0 -685
- package/lib/test/mocha/map.spec.js.map +0 -1
- package/lib/test/mocha/rebasing.spec.js +0 -158
- package/lib/test/mocha/rebasing.spec.js.map +0 -1
- package/lib/test/mocha/reconnection.spec.js +0 -327
- package/lib/test/mocha/reconnection.spec.js.map +0 -1
- package/lib/test/types/validateMapPrevious.generated.js +0 -66
- package/lib/test/types/validateMapPrevious.generated.js.map +0 -1
- /package/{dist → lib}/tsdoc-metadata.json +0 -0
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { MockFluidDataStoreRuntime } from "@fluidframework/test-runtime-utils";
|
|
6
|
-
import { benchmarkMemory } from "@fluid-tools/benchmark";
|
|
7
|
-
import { DirectoryFactory, SharedDirectory } from "../../directory.js";
|
|
8
|
-
function createLocalDirectory(id) {
|
|
9
|
-
const directory = new SharedDirectory(id, new MockFluidDataStoreRuntime(), DirectoryFactory.Attributes);
|
|
10
|
-
return directory;
|
|
11
|
-
}
|
|
12
|
-
describe("SharedDirectory memory usage", () => {
|
|
13
|
-
// IMPORTANT: variables scoped to the test suite are a big problem for memory-profiling tests
|
|
14
|
-
// because they won't be out of scope when we garbage-collect between runs of the same test,
|
|
15
|
-
// and that will skew measurements. Tests should allocate all the memory they need using local
|
|
16
|
-
// variables scoped to the test function itself, so several iterations of a given test can
|
|
17
|
-
// measure from the same baseline (as much as possible).
|
|
18
|
-
beforeEach(async () => {
|
|
19
|
-
// CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables
|
|
20
|
-
// whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.
|
|
21
|
-
// See the comment at the top of the test suite for more details.
|
|
22
|
-
});
|
|
23
|
-
afterEach(() => {
|
|
24
|
-
// CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables
|
|
25
|
-
// whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.
|
|
26
|
-
// See the comment at the top of the test suite for more details.
|
|
27
|
-
});
|
|
28
|
-
benchmarkMemory(new (class {
|
|
29
|
-
constructor() {
|
|
30
|
-
this.title = "Create empty directory";
|
|
31
|
-
this.minSampleCount = 500;
|
|
32
|
-
this.dir = createLocalDirectory("testDirectory");
|
|
33
|
-
}
|
|
34
|
-
async run() {
|
|
35
|
-
this.dir = createLocalDirectory("testDirectory");
|
|
36
|
-
}
|
|
37
|
-
})());
|
|
38
|
-
const numbersOfEntriesForTests = [1000, 10000, 100000];
|
|
39
|
-
for (const x of numbersOfEntriesForTests) {
|
|
40
|
-
benchmarkMemory(new (class {
|
|
41
|
-
constructor() {
|
|
42
|
-
this.title = `Add ${x} integers to a local directory`;
|
|
43
|
-
this.dir = createLocalDirectory("testDirectory");
|
|
44
|
-
}
|
|
45
|
-
async run() {
|
|
46
|
-
for (let i = 0; i < x; i++) {
|
|
47
|
-
this.dir.set(i.toString().padStart(6, "0"), i);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
beforeIteration() {
|
|
51
|
-
this.dir = createLocalDirectory("testDirectory");
|
|
52
|
-
}
|
|
53
|
-
})());
|
|
54
|
-
benchmarkMemory(new (class {
|
|
55
|
-
constructor() {
|
|
56
|
-
this.title = `Add ${x} integers to a local directory, clear it`;
|
|
57
|
-
this.dir = createLocalDirectory("testDirectory");
|
|
58
|
-
}
|
|
59
|
-
async run() {
|
|
60
|
-
for (let i = 0; i < x; i++) {
|
|
61
|
-
this.dir.set(i.toString().padStart(6, "0"), i);
|
|
62
|
-
}
|
|
63
|
-
this.dir.clear();
|
|
64
|
-
}
|
|
65
|
-
beforeIteration() {
|
|
66
|
-
this.dir = createLocalDirectory("testDirectory");
|
|
67
|
-
}
|
|
68
|
-
})());
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
//# sourceMappingURL=directory.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"directory.spec.js","sourceRoot":"","sources":["../../../src/test/memory/directory.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAqB,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAEvE,SAAS,oBAAoB,CAAC,EAAU;IACvC,MAAM,SAAS,GAAG,IAAI,eAAe,CACpC,EAAE,EACF,IAAI,yBAAyB,EAAE,EAC/B,gBAAgB,CAAC,UAAU,CAC3B,CAAC;IACF,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC7C,6FAA6F;IAC7F,4FAA4F;IAC5F,8FAA8F;IAC9F,0FAA0F;IAC1F,wDAAwD;IAExD,UAAU,CAAC,KAAK,IAAI,EAAE;QACrB,gGAAgG;QAChG,8FAA8F;QAC9F,iEAAiE;IAClE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACd,gGAAgG;QAChG,8FAA8F;QAC9F,iEAAiE;IAClE,CAAC,CAAC,CAAC;IAEH,eAAe,CACd,IAAI,CAAC;QAAA;YACY,UAAK,GAAG,wBAAwB,CAAC;YACjC,mBAAc,GAAG,GAAG,CAAC;YAE7B,QAAG,GAAoB,oBAAoB,CAAC,eAAe,CAAC,CAAC;QAKtE,CAAC;QAHO,KAAK,CAAC,GAAG;YACf,IAAI,CAAC,GAAG,GAAG,oBAAoB,CAAC,eAAe,CAAC,CAAC;QAClD,CAAC;KACD,CAAC,EAAE,CACJ,CAAC;IAEF,MAAM,wBAAwB,GAAG,CAAC,IAAI,EAAE,KAAM,EAAE,MAAO,CAAC,CAAC;IAEzD,KAAK,MAAM,CAAC,IAAI,wBAAwB,EAAE;QACzC,eAAe,CACd,IAAI,CAAC;YAAA;gBACY,UAAK,GAAG,OAAO,CAAC,gCAAgC,CAAC;gBACzD,QAAG,GAAoB,oBAAoB,CAAC,eAAe,CAAC,CAAC;YAWtE,CAAC;YATO,KAAK,CAAC,GAAG;gBACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;oBAC3B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;iBAC/C;YACF,CAAC;YAEM,eAAe;gBACrB,IAAI,CAAC,GAAG,GAAG,oBAAoB,CAAC,eAAe,CAAC,CAAC;YAClD,CAAC;SACD,CAAC,EAAE,CACJ,CAAC;QAEF,eAAe,CACd,IAAI,CAAC;YAAA;gBACY,UAAK,GAAG,OAAO,CAAC,0CAA0C,CAAC;gBACnE,QAAG,GAAoB,oBAAoB,CAAC,eAAe,CAAC,CAAC;YAYtE,CAAC;YAVO,KAAK,CAAC,GAAG;gBACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;oBAC3B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;iBAC/C;gBACD,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YAClB,CAAC;YAEM,eAAe;gBACrB,IAAI,CAAC,GAAG,GAAG,oBAAoB,CAAC,eAAe,CAAC,CAAC;YAClD,CAAC;SACD,CAAC,EAAE,CACJ,CAAC;KACF;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { MockFluidDataStoreRuntime } from \"@fluidframework/test-runtime-utils\";\nimport { benchmarkMemory, IMemoryTestObject } from \"@fluid-tools/benchmark\";\nimport { DirectoryFactory, SharedDirectory } from \"../../directory.js\";\n\nfunction createLocalDirectory(id: string): SharedDirectory {\n\tconst directory = new SharedDirectory(\n\t\tid,\n\t\tnew MockFluidDataStoreRuntime(),\n\t\tDirectoryFactory.Attributes,\n\t);\n\treturn directory;\n}\n\ndescribe(\"SharedDirectory memory usage\", () => {\n\t// IMPORTANT: variables scoped to the test suite are a big problem for memory-profiling tests\n\t// because they won't be out of scope when we garbage-collect between runs of the same test,\n\t// and that will skew measurements. Tests should allocate all the memory they need using local\n\t// variables scoped to the test function itself, so several iterations of a given test can\n\t// measure from the same baseline (as much as possible).\n\n\tbeforeEach(async () => {\n\t\t// CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables\n\t\t// whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.\n\t\t// See the comment at the top of the test suite for more details.\n\t});\n\n\tafterEach(() => {\n\t\t// CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables\n\t\t// whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.\n\t\t// See the comment at the top of the test suite for more details.\n\t});\n\n\tbenchmarkMemory(\n\t\tnew (class implements IMemoryTestObject {\n\t\t\tpublic readonly title = \"Create empty directory\";\n\t\t\tpublic readonly minSampleCount = 500;\n\n\t\t\tprivate dir: SharedDirectory = createLocalDirectory(\"testDirectory\");\n\n\t\t\tpublic async run(): Promise<void> {\n\t\t\t\tthis.dir = createLocalDirectory(\"testDirectory\");\n\t\t\t}\n\t\t})(),\n\t);\n\n\tconst numbersOfEntriesForTests = [1000, 10_000, 100_000];\n\n\tfor (const x of numbersOfEntriesForTests) {\n\t\tbenchmarkMemory(\n\t\t\tnew (class implements IMemoryTestObject {\n\t\t\t\tpublic readonly title = `Add ${x} integers to a local directory`;\n\t\t\t\tprivate dir: SharedDirectory = createLocalDirectory(\"testDirectory\");\n\n\t\t\t\tpublic async run(): Promise<void> {\n\t\t\t\t\tfor (let i = 0; i < x; i++) {\n\t\t\t\t\t\tthis.dir.set(i.toString().padStart(6, \"0\"), i);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tpublic beforeIteration(): void {\n\t\t\t\t\tthis.dir = createLocalDirectory(\"testDirectory\");\n\t\t\t\t}\n\t\t\t})(),\n\t\t);\n\n\t\tbenchmarkMemory(\n\t\t\tnew (class implements IMemoryTestObject {\n\t\t\t\tpublic readonly title = `Add ${x} integers to a local directory, clear it`;\n\t\t\t\tprivate dir: SharedDirectory = createLocalDirectory(\"testDirectory\");\n\n\t\t\t\tpublic async run(): Promise<void> {\n\t\t\t\t\tfor (let i = 0; i < x; i++) {\n\t\t\t\t\t\tthis.dir.set(i.toString().padStart(6, \"0\"), i);\n\t\t\t\t\t}\n\t\t\t\t\tthis.dir.clear();\n\t\t\t\t}\n\n\t\t\t\tpublic beforeIteration(): void {\n\t\t\t\t\tthis.dir = createLocalDirectory(\"testDirectory\");\n\t\t\t\t}\n\t\t\t})(),\n\t\t);\n\t}\n});\n"]}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { MockFluidDataStoreRuntime } from "@fluidframework/test-runtime-utils";
|
|
6
|
-
import { benchmarkMemory } from "@fluid-tools/benchmark";
|
|
7
|
-
import { MapFactory, SharedMap } from "../../map.js";
|
|
8
|
-
function createLocalMap(id) {
|
|
9
|
-
const map = new SharedMap(id, new MockFluidDataStoreRuntime(), MapFactory.Attributes);
|
|
10
|
-
return map;
|
|
11
|
-
}
|
|
12
|
-
describe("SharedMap memory usage", () => {
|
|
13
|
-
// IMPORTANT: variables scoped to the test suite are a big problem for memory-profiling tests
|
|
14
|
-
// because they won't be out of scope when we garbage-collect between runs of the same test,
|
|
15
|
-
// and that will skew measurements. Tests should allocate all the memory they need using local
|
|
16
|
-
// variables scoped to the test function itself, so several iterations of a given test can
|
|
17
|
-
// measure from the same baseline (as much as possible).
|
|
18
|
-
beforeEach(async () => {
|
|
19
|
-
// CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables
|
|
20
|
-
// whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.
|
|
21
|
-
// See the comment at the top of the test suite for more details.
|
|
22
|
-
});
|
|
23
|
-
afterEach(() => {
|
|
24
|
-
// CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables
|
|
25
|
-
// whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.
|
|
26
|
-
// See the comment at the top of the test suite for more details.
|
|
27
|
-
});
|
|
28
|
-
benchmarkMemory(new (class {
|
|
29
|
-
constructor() {
|
|
30
|
-
this.title = "Create empty map";
|
|
31
|
-
this.minSampleCount = 500;
|
|
32
|
-
this.map = createLocalMap("testMap");
|
|
33
|
-
}
|
|
34
|
-
async run() {
|
|
35
|
-
this.map = createLocalMap("testMap");
|
|
36
|
-
}
|
|
37
|
-
})());
|
|
38
|
-
const numbersOfEntriesForTests = [1000, 10000, 100000];
|
|
39
|
-
for (const x of numbersOfEntriesForTests) {
|
|
40
|
-
benchmarkMemory(new (class {
|
|
41
|
-
constructor() {
|
|
42
|
-
this.title = `Add ${x} integers to a local map`;
|
|
43
|
-
this.map = createLocalMap("testMap");
|
|
44
|
-
}
|
|
45
|
-
async run() {
|
|
46
|
-
for (let i = 0; i < x; i++) {
|
|
47
|
-
this.map.set(i.toString().padStart(6, "0"), i);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
beforeIteration() {
|
|
51
|
-
this.map = createLocalMap("testMap");
|
|
52
|
-
}
|
|
53
|
-
})());
|
|
54
|
-
benchmarkMemory(new (class {
|
|
55
|
-
constructor() {
|
|
56
|
-
this.title = `Add ${x} integers to a local map, clear it`;
|
|
57
|
-
this.map = createLocalMap("testMap");
|
|
58
|
-
}
|
|
59
|
-
async run() {
|
|
60
|
-
for (let i = 0; i < x; i++) {
|
|
61
|
-
this.map.set(i.toString().padStart(6, "0"), i);
|
|
62
|
-
}
|
|
63
|
-
this.map.clear();
|
|
64
|
-
}
|
|
65
|
-
beforeIteration() {
|
|
66
|
-
this.map = createLocalMap("testMap");
|
|
67
|
-
}
|
|
68
|
-
})());
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
//# sourceMappingURL=map.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"map.spec.js","sourceRoot":"","sources":["../../../src/test/memory/map.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAqB,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAErD,SAAS,cAAc,CAAC,EAAU;IACjC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,EAAE,EAAE,IAAI,yBAAyB,EAAE,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IACtF,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACvC,6FAA6F;IAC7F,4FAA4F;IAC5F,8FAA8F;IAC9F,0FAA0F;IAC1F,wDAAwD;IAExD,UAAU,CAAC,KAAK,IAAI,EAAE;QACrB,gGAAgG;QAChG,8FAA8F;QAC9F,iEAAiE;IAClE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACd,gGAAgG;QAChG,8FAA8F;QAC9F,iEAAiE;IAClE,CAAC,CAAC,CAAC;IAEH,eAAe,CACd,IAAI,CAAC;QAAA;YACY,UAAK,GAAG,kBAAkB,CAAC;YAC3B,mBAAc,GAAG,GAAG,CAAC;YAE7B,QAAG,GAAc,cAAc,CAAC,SAAS,CAAC,CAAC;QAKpD,CAAC;QAHO,KAAK,CAAC,GAAG;YACf,IAAI,CAAC,GAAG,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC;KACD,CAAC,EAAE,CACJ,CAAC;IAEF,MAAM,wBAAwB,GAAG,CAAC,IAAI,EAAE,KAAM,EAAE,MAAO,CAAC,CAAC;IAEzD,KAAK,MAAM,CAAC,IAAI,wBAAwB,EAAE;QACzC,eAAe,CACd,IAAI,CAAC;YAAA;gBACY,UAAK,GAAG,OAAO,CAAC,0BAA0B,CAAC;gBACnD,QAAG,GAAc,cAAc,CAAC,SAAS,CAAC,CAAC;YAWpD,CAAC;YATO,KAAK,CAAC,GAAG;gBACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;oBAC3B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;iBAC/C;YACF,CAAC;YAEM,eAAe;gBACrB,IAAI,CAAC,GAAG,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;YACtC,CAAC;SACD,CAAC,EAAE,CACJ,CAAC;QAEF,eAAe,CACd,IAAI,CAAC;YAAA;gBACY,UAAK,GAAG,OAAO,CAAC,oCAAoC,CAAC;gBAC7D,QAAG,GAAc,cAAc,CAAC,SAAS,CAAC,CAAC;YAYpD,CAAC;YAVO,KAAK,CAAC,GAAG;gBACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;oBAC3B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;iBAC/C;gBACD,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YAClB,CAAC;YAEM,eAAe;gBACrB,IAAI,CAAC,GAAG,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;YACtC,CAAC;SACD,CAAC,EAAE,CACJ,CAAC;KACF;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { MockFluidDataStoreRuntime } from \"@fluidframework/test-runtime-utils\";\nimport { benchmarkMemory, IMemoryTestObject } from \"@fluid-tools/benchmark\";\nimport { MapFactory, SharedMap } from \"../../map.js\";\n\nfunction createLocalMap(id: string): SharedMap {\n\tconst map = new SharedMap(id, new MockFluidDataStoreRuntime(), MapFactory.Attributes);\n\treturn map;\n}\n\ndescribe(\"SharedMap memory usage\", () => {\n\t// IMPORTANT: variables scoped to the test suite are a big problem for memory-profiling tests\n\t// because they won't be out of scope when we garbage-collect between runs of the same test,\n\t// and that will skew measurements. Tests should allocate all the memory they need using local\n\t// variables scoped to the test function itself, so several iterations of a given test can\n\t// measure from the same baseline (as much as possible).\n\n\tbeforeEach(async () => {\n\t\t// CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables\n\t\t// whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.\n\t\t// See the comment at the top of the test suite for more details.\n\t});\n\n\tafterEach(() => {\n\t\t// CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables\n\t\t// whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.\n\t\t// See the comment at the top of the test suite for more details.\n\t});\n\n\tbenchmarkMemory(\n\t\tnew (class implements IMemoryTestObject {\n\t\t\tpublic readonly title = \"Create empty map\";\n\t\t\tpublic readonly minSampleCount = 500;\n\n\t\t\tprivate map: SharedMap = createLocalMap(\"testMap\");\n\n\t\t\tpublic async run(): Promise<void> {\n\t\t\t\tthis.map = createLocalMap(\"testMap\");\n\t\t\t}\n\t\t})(),\n\t);\n\n\tconst numbersOfEntriesForTests = [1000, 10_000, 100_000];\n\n\tfor (const x of numbersOfEntriesForTests) {\n\t\tbenchmarkMemory(\n\t\t\tnew (class implements IMemoryTestObject {\n\t\t\t\tpublic readonly title = `Add ${x} integers to a local map`;\n\t\t\t\tprivate map: SharedMap = createLocalMap(\"testMap\");\n\n\t\t\t\tpublic async run(): Promise<void> {\n\t\t\t\t\tfor (let i = 0; i < x; i++) {\n\t\t\t\t\t\tthis.map.set(i.toString().padStart(6, \"0\"), i);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tpublic beforeIteration(): void {\n\t\t\t\t\tthis.map = createLocalMap(\"testMap\");\n\t\t\t\t}\n\t\t\t})(),\n\t\t);\n\n\t\tbenchmarkMemory(\n\t\t\tnew (class implements IMemoryTestObject {\n\t\t\t\tpublic readonly title = `Add ${x} integers to a local map, clear it`;\n\t\t\t\tprivate map: SharedMap = createLocalMap(\"testMap\");\n\n\t\t\t\tpublic async run(): Promise<void> {\n\t\t\t\t\tfor (let i = 0; i < x; i++) {\n\t\t\t\t\t\tthis.map.set(i.toString().padStart(6, \"0\"), i);\n\t\t\t\t\t}\n\t\t\t\t\tthis.map.clear();\n\t\t\t\t}\n\n\t\t\t\tpublic beforeIteration(): void {\n\t\t\t\t\tthis.map = createLocalMap(\"testMap\");\n\t\t\t\t}\n\t\t\t})(),\n\t\t);\n\t}\n});\n"]}
|
|
@@ -1,422 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { strict as assert } from "node:assert";
|
|
6
|
-
import { MockContainerRuntimeFactory, MockContainerRuntimeFactoryForReconnection, MockFluidDataStoreRuntime, MockSharedObjectServices, MockStorage, } from "@fluidframework/test-runtime-utils";
|
|
7
|
-
import { AttachState } from "@fluidframework/container-definitions";
|
|
8
|
-
import { DirectoryFactory, SharedDirectory, } from "../../directory.js";
|
|
9
|
-
function createConnectedDirectory(id, runtimeFactory) {
|
|
10
|
-
const dataStoreRuntime = new MockFluidDataStoreRuntime();
|
|
11
|
-
const containerRuntime = runtimeFactory.createContainerRuntime(dataStoreRuntime);
|
|
12
|
-
const services = {
|
|
13
|
-
deltaConnection: dataStoreRuntime.createDeltaConnection(),
|
|
14
|
-
objectStorage: new MockStorage(),
|
|
15
|
-
};
|
|
16
|
-
const directory = new SharedDirectory(id, dataStoreRuntime, DirectoryFactory.Attributes);
|
|
17
|
-
directory.connect(services);
|
|
18
|
-
return directory;
|
|
19
|
-
}
|
|
20
|
-
class TestSharedDirectory extends SharedDirectory {
|
|
21
|
-
testApplyStashedOp(content) {
|
|
22
|
-
this.lastMetadata = undefined;
|
|
23
|
-
this.applyStashedOp(content);
|
|
24
|
-
return this.lastMetadata;
|
|
25
|
-
}
|
|
26
|
-
submitLocalMessage(op, localOpMetadata) {
|
|
27
|
-
this.lastMetadata = localOpMetadata;
|
|
28
|
-
super.submitLocalMessage(op, localOpMetadata);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
async function populate(directory, content) {
|
|
32
|
-
const storage = new MockSharedObjectServices({
|
|
33
|
-
header: JSON.stringify(content),
|
|
34
|
-
});
|
|
35
|
-
return directory.load(storage);
|
|
36
|
-
}
|
|
37
|
-
function assertDirectoryIterationOrder(directory, expectedDirNames) {
|
|
38
|
-
const actualDirNames = [];
|
|
39
|
-
for (const [subdirName, subdirObject] of directory.subdirectories()) {
|
|
40
|
-
actualDirNames.push(subdirName);
|
|
41
|
-
}
|
|
42
|
-
assert.deepEqual(actualDirNames, expectedDirNames);
|
|
43
|
-
}
|
|
44
|
-
describe("Directory Iteration Order", () => {
|
|
45
|
-
describe("Local state", () => {
|
|
46
|
-
let directory;
|
|
47
|
-
let dataStoreRuntime;
|
|
48
|
-
beforeEach("createDirectory", async () => {
|
|
49
|
-
dataStoreRuntime = new MockFluidDataStoreRuntime({ attachState: AttachState.Detached });
|
|
50
|
-
directory = new SharedDirectory("directory", dataStoreRuntime, DirectoryFactory.Attributes);
|
|
51
|
-
});
|
|
52
|
-
it("create subdirectories", () => {
|
|
53
|
-
directory.createSubDirectory("b");
|
|
54
|
-
directory.createSubDirectory("a");
|
|
55
|
-
directory.createSubDirectory("c");
|
|
56
|
-
assertDirectoryIterationOrder(directory, ["b", "a", "c"]);
|
|
57
|
-
});
|
|
58
|
-
it("create nested subdirectories", () => {
|
|
59
|
-
directory.createSubDirectory("c").createSubDirectory("c-a");
|
|
60
|
-
directory.createSubDirectory("a").createSubDirectory("a-b");
|
|
61
|
-
directory.createSubDirectory("a").createSubDirectory("a-a");
|
|
62
|
-
directory.createSubDirectory("b");
|
|
63
|
-
directory.createSubDirectory("c").createSubDirectory("c-c");
|
|
64
|
-
directory.createSubDirectory("a").createSubDirectory("a-c");
|
|
65
|
-
directory.createSubDirectory("c").createSubDirectory("c-b");
|
|
66
|
-
assertDirectoryIterationOrder(directory, ["c", "a", "b"]);
|
|
67
|
-
assert.notEqual(directory.getWorkingDirectory("/a"), undefined);
|
|
68
|
-
assertDirectoryIterationOrder(directory.getWorkingDirectory("/a"), [
|
|
69
|
-
"a-b",
|
|
70
|
-
"a-a",
|
|
71
|
-
"a-c",
|
|
72
|
-
]);
|
|
73
|
-
assert.notEqual(directory.getWorkingDirectory("/b"), undefined);
|
|
74
|
-
assertDirectoryIterationOrder(directory.getWorkingDirectory("/b"), []);
|
|
75
|
-
assert.notEqual(directory.getWorkingDirectory("/c"), undefined);
|
|
76
|
-
assertDirectoryIterationOrder(directory.getWorkingDirectory("/c"), [
|
|
77
|
-
"c-a",
|
|
78
|
-
"c-c",
|
|
79
|
-
"c-b",
|
|
80
|
-
]);
|
|
81
|
-
});
|
|
82
|
-
it("delete subdirectories", () => {
|
|
83
|
-
directory.createSubDirectory("c").createSubDirectory("c-a");
|
|
84
|
-
directory.createSubDirectory("a").createSubDirectory("a-b");
|
|
85
|
-
directory.createSubDirectory("a").createSubDirectory("a-a");
|
|
86
|
-
directory.createSubDirectory("b");
|
|
87
|
-
directory.createSubDirectory("c").createSubDirectory("c-c");
|
|
88
|
-
directory.createSubDirectory("a").createSubDirectory("a-c");
|
|
89
|
-
directory.createSubDirectory("c").createSubDirectory("c-b");
|
|
90
|
-
directory.deleteSubDirectory("a");
|
|
91
|
-
assertDirectoryIterationOrder(directory, ["c", "b"]);
|
|
92
|
-
directory.createSubDirectory("a");
|
|
93
|
-
assertDirectoryIterationOrder(directory, ["c", "b", "a"]);
|
|
94
|
-
directory.getWorkingDirectory("/c")?.createSubDirectory("c-d");
|
|
95
|
-
directory.getWorkingDirectory("/c")?.deleteSubDirectory("c-c");
|
|
96
|
-
assertDirectoryIterationOrder(directory.getWorkingDirectory("/c"), [
|
|
97
|
-
"c-a",
|
|
98
|
-
"c-b",
|
|
99
|
-
"c-d",
|
|
100
|
-
]);
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
describe("Connected state", () => {
|
|
104
|
-
let containerRuntimeFactory;
|
|
105
|
-
let directory1;
|
|
106
|
-
let directory2;
|
|
107
|
-
beforeEach("createDirectories", async () => {
|
|
108
|
-
containerRuntimeFactory = new MockContainerRuntimeFactory();
|
|
109
|
-
// Create the first directory.
|
|
110
|
-
directory1 = createConnectedDirectory("directory1", containerRuntimeFactory);
|
|
111
|
-
// Create the second directory.
|
|
112
|
-
directory2 = createConnectedDirectory("directory2", containerRuntimeFactory);
|
|
113
|
-
});
|
|
114
|
-
it("Remote messages have no conflict with the local pending ops", () => {
|
|
115
|
-
directory1.createSubDirectory("a");
|
|
116
|
-
directory1.createSubDirectory("b").createSubDirectory("b-b");
|
|
117
|
-
directory2.createSubDirectory("c");
|
|
118
|
-
directory2.createSubDirectory("d");
|
|
119
|
-
directory1.deleteSubDirectory("a");
|
|
120
|
-
directory2.createSubDirectory("b").createSubDirectory("b-a");
|
|
121
|
-
containerRuntimeFactory.processSomeMessages(3);
|
|
122
|
-
assertDirectoryIterationOrder(directory1, ["b"]);
|
|
123
|
-
assertDirectoryIterationOrder(directory2, ["a", "b", "c", "d"]);
|
|
124
|
-
containerRuntimeFactory.processSomeMessages(2);
|
|
125
|
-
assertDirectoryIterationOrder(directory1, ["b", "c", "d"]);
|
|
126
|
-
assertDirectoryIterationOrder(directory2, ["a", "b", "c", "d"]);
|
|
127
|
-
containerRuntimeFactory.processAllMessages();
|
|
128
|
-
assertDirectoryIterationOrder(directory1, ["b", "c", "d"]);
|
|
129
|
-
assertDirectoryIterationOrder(directory2, ["b", "c", "d"]);
|
|
130
|
-
assert(directory1.getWorkingDirectory("b"));
|
|
131
|
-
assert(directory2.getWorkingDirectory("b"));
|
|
132
|
-
assertDirectoryIterationOrder(directory1.getWorkingDirectory("b"), [
|
|
133
|
-
"b-b",
|
|
134
|
-
"b-a",
|
|
135
|
-
]);
|
|
136
|
-
assertDirectoryIterationOrder(directory2.getWorkingDirectory("b"), [
|
|
137
|
-
"b-b",
|
|
138
|
-
"b-a",
|
|
139
|
-
]);
|
|
140
|
-
});
|
|
141
|
-
it("Remote messages have conflicts with the local pending ops", () => {
|
|
142
|
-
directory1.createSubDirectory("b");
|
|
143
|
-
directory2.createSubDirectory("a");
|
|
144
|
-
directory2.createSubDirectory("b");
|
|
145
|
-
containerRuntimeFactory.processSomeMessages(3);
|
|
146
|
-
assertDirectoryIterationOrder(directory1, ["b", "a"]);
|
|
147
|
-
assertDirectoryIterationOrder(directory2, ["b", "a"]);
|
|
148
|
-
directory1.createSubDirectory("d").createSubDirectory("d-b");
|
|
149
|
-
directory2.createSubDirectory("d").createSubDirectory("d-a");
|
|
150
|
-
containerRuntimeFactory.processSomeMessages(4);
|
|
151
|
-
assertDirectoryIterationOrder(directory1, ["b", "a", "d"]);
|
|
152
|
-
assertDirectoryIterationOrder(directory2, ["b", "a", "d"]);
|
|
153
|
-
assert.notEqual(directory1.getWorkingDirectory("/d"), undefined);
|
|
154
|
-
assertDirectoryIterationOrder(directory1.getWorkingDirectory("/d"), ["d-b", "d-a"]);
|
|
155
|
-
assert.notEqual(directory2.getWorkingDirectory("/d"), undefined);
|
|
156
|
-
assertDirectoryIterationOrder(directory2.getWorkingDirectory("/d"), ["d-b", "d-a"]);
|
|
157
|
-
directory1.deleteSubDirectory("d");
|
|
158
|
-
directory2.getWorkingDirectory("/d")?.createSubDirectory("d-c");
|
|
159
|
-
assertDirectoryIterationOrder(directory1, ["b", "a"]);
|
|
160
|
-
assertDirectoryIterationOrder(directory2, ["b", "a", "d"]);
|
|
161
|
-
assertDirectoryIterationOrder(directory2.getWorkingDirectory("/d"), ["d-b", "d-a", "d-c"]);
|
|
162
|
-
containerRuntimeFactory.processAllMessages();
|
|
163
|
-
assertDirectoryIterationOrder(directory1, ["b", "a"]);
|
|
164
|
-
assertDirectoryIterationOrder(directory2, ["b", "a"]);
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
describe("Serialization/Load", () => {
|
|
168
|
-
let directory1;
|
|
169
|
-
it("can be compatible with the old format summary", async () => {
|
|
170
|
-
const dataStoreRuntime = new MockFluidDataStoreRuntime({
|
|
171
|
-
attachState: AttachState.Detached,
|
|
172
|
-
});
|
|
173
|
-
directory1 = new SharedDirectory("directory", dataStoreRuntime, DirectoryFactory.Attributes);
|
|
174
|
-
await populate(directory1, {
|
|
175
|
-
storage: {
|
|
176
|
-
key1: {
|
|
177
|
-
type: "Plain",
|
|
178
|
-
value: "val1",
|
|
179
|
-
},
|
|
180
|
-
key2: {
|
|
181
|
-
type: "Plain",
|
|
182
|
-
value: "val2",
|
|
183
|
-
},
|
|
184
|
-
},
|
|
185
|
-
subdirectories: {
|
|
186
|
-
b: {
|
|
187
|
-
storage: {
|
|
188
|
-
testKey: {
|
|
189
|
-
type: "Plain",
|
|
190
|
-
value: "testValue",
|
|
191
|
-
},
|
|
192
|
-
testKey2: {
|
|
193
|
-
type: "Plain",
|
|
194
|
-
value: "testValue2",
|
|
195
|
-
},
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
c: {
|
|
199
|
-
storage: {
|
|
200
|
-
testKey3: {
|
|
201
|
-
type: "Plain",
|
|
202
|
-
value: "testValue3",
|
|
203
|
-
},
|
|
204
|
-
},
|
|
205
|
-
},
|
|
206
|
-
a: {
|
|
207
|
-
storage: {},
|
|
208
|
-
},
|
|
209
|
-
},
|
|
210
|
-
});
|
|
211
|
-
assertDirectoryIterationOrder(directory1, ["b", "c", "a"]);
|
|
212
|
-
});
|
|
213
|
-
it("can be compatible with the new format summary", async () => {
|
|
214
|
-
const dataStoreRuntime = new MockFluidDataStoreRuntime({
|
|
215
|
-
attachState: AttachState.Detached,
|
|
216
|
-
});
|
|
217
|
-
directory1 = new SharedDirectory("directory", dataStoreRuntime, DirectoryFactory.Attributes);
|
|
218
|
-
await populate(directory1, {
|
|
219
|
-
storage: {
|
|
220
|
-
key1: {
|
|
221
|
-
type: "Plain",
|
|
222
|
-
value: "val1",
|
|
223
|
-
},
|
|
224
|
-
key2: {
|
|
225
|
-
type: "Plain",
|
|
226
|
-
value: "val2",
|
|
227
|
-
},
|
|
228
|
-
},
|
|
229
|
-
subdirectories: {
|
|
230
|
-
b: {
|
|
231
|
-
storage: {
|
|
232
|
-
testKey: {
|
|
233
|
-
type: "Plain",
|
|
234
|
-
value: "testValue",
|
|
235
|
-
},
|
|
236
|
-
testKey2: {
|
|
237
|
-
type: "Plain",
|
|
238
|
-
value: "testValue2",
|
|
239
|
-
},
|
|
240
|
-
},
|
|
241
|
-
ci: {
|
|
242
|
-
csn: 4,
|
|
243
|
-
ccIds: ["client1"],
|
|
244
|
-
},
|
|
245
|
-
},
|
|
246
|
-
c: {
|
|
247
|
-
storage: {
|
|
248
|
-
testKey3: {
|
|
249
|
-
type: "Plain",
|
|
250
|
-
value: "testValue3",
|
|
251
|
-
},
|
|
252
|
-
},
|
|
253
|
-
subdirectories: {
|
|
254
|
-
c_b: {
|
|
255
|
-
storage: {},
|
|
256
|
-
ci: {
|
|
257
|
-
csn: 5,
|
|
258
|
-
ccIds: ["client1"],
|
|
259
|
-
},
|
|
260
|
-
},
|
|
261
|
-
c_a: {
|
|
262
|
-
storage: {},
|
|
263
|
-
ci: {
|
|
264
|
-
csn: 6,
|
|
265
|
-
ccIds: ["client1"],
|
|
266
|
-
},
|
|
267
|
-
},
|
|
268
|
-
},
|
|
269
|
-
ci: {
|
|
270
|
-
csn: 2,
|
|
271
|
-
ccIds: ["client2"],
|
|
272
|
-
ccsn: 1,
|
|
273
|
-
},
|
|
274
|
-
},
|
|
275
|
-
a: {
|
|
276
|
-
storage: {},
|
|
277
|
-
ci: {
|
|
278
|
-
csn: 4,
|
|
279
|
-
ccIds: ["client2"],
|
|
280
|
-
},
|
|
281
|
-
},
|
|
282
|
-
},
|
|
283
|
-
ci: {
|
|
284
|
-
csn: 1,
|
|
285
|
-
ccIds: ["client1", "client2"],
|
|
286
|
-
},
|
|
287
|
-
});
|
|
288
|
-
assertDirectoryIterationOrder(directory1, ["c", "b", "a"]);
|
|
289
|
-
assert(directory1.getWorkingDirectory("/c"));
|
|
290
|
-
assertDirectoryIterationOrder(directory1.getWorkingDirectory("/c"), ["c_b", "c_a"]);
|
|
291
|
-
});
|
|
292
|
-
it("serialize the contents, load it into another directory and maintain the order", async () => {
|
|
293
|
-
directory1 = new SharedDirectory("dir1", new MockFluidDataStoreRuntime(), DirectoryFactory.Attributes);
|
|
294
|
-
directory1.createSubDirectory("c");
|
|
295
|
-
directory1.createSubDirectory("b");
|
|
296
|
-
directory1.createSubDirectory("a");
|
|
297
|
-
const containerRuntimeFactory = new MockContainerRuntimeFactory();
|
|
298
|
-
const dataStoreRuntime = new MockFluidDataStoreRuntime();
|
|
299
|
-
const containerRuntime = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime);
|
|
300
|
-
const services = MockSharedObjectServices.createFromSummary(directory1.getAttachSummary().summary);
|
|
301
|
-
services.deltaConnection = dataStoreRuntime.createDeltaConnection();
|
|
302
|
-
const directory2 = new SharedDirectory("map2", dataStoreRuntime, DirectoryFactory.Attributes);
|
|
303
|
-
await directory2.load(services);
|
|
304
|
-
assertDirectoryIterationOrder(directory2, ["c", "b", "a"]);
|
|
305
|
-
});
|
|
306
|
-
it("can be compatible with the detached scenario", async () => {
|
|
307
|
-
// It is to reproduce the regression bug causing the corruption of the summarization, indicated by 0x85c
|
|
308
|
-
// https://dev.azure.com/fluidframework/internal/_workitems/edit/7013
|
|
309
|
-
const runtimeFactory = new MockContainerRuntimeFactory();
|
|
310
|
-
const dataStoreRuntime = new MockFluidDataStoreRuntime();
|
|
311
|
-
runtimeFactory.createContainerRuntime(dataStoreRuntime);
|
|
312
|
-
const factory = SharedDirectory.getFactory();
|
|
313
|
-
const summaryContent = '{"blobs":[],"content":{"ci":{"csn":0,"ccIds":[]},"subdirectories":{"detached1":{"ci":{"csn":0,"ccIds":["97cd0b77-34b1-46a8-bbe2-5fbefb3e014b"]}},"detached2":{"ci":{"csn":0,"ccIds":["97cd0b77-34b1-46a8-bbe2-5fbefb3e014b"]}},"detached3":{"ci":{"csn":-1,"ccIds":["97cd0b77-34b1-46a8-bbe2-5fbefb3e014b"]}}}}}';
|
|
314
|
-
const summary = {
|
|
315
|
-
type: 1,
|
|
316
|
-
tree: {
|
|
317
|
-
header: {
|
|
318
|
-
type: 2,
|
|
319
|
-
content: summaryContent,
|
|
320
|
-
},
|
|
321
|
-
},
|
|
322
|
-
};
|
|
323
|
-
const directory = await factory.load(dataStoreRuntime, "A", {
|
|
324
|
-
deltaConnection: dataStoreRuntime.createDeltaConnection(),
|
|
325
|
-
objectStorage: MockStorage.createFromSummary(summary),
|
|
326
|
-
}, factory.attributes);
|
|
327
|
-
await directory.summarize();
|
|
328
|
-
});
|
|
329
|
-
});
|
|
330
|
-
describe("Reconnection", () => {
|
|
331
|
-
let containerRuntimeFactory;
|
|
332
|
-
let containerRuntime1;
|
|
333
|
-
let containerRuntime2;
|
|
334
|
-
let directory1;
|
|
335
|
-
let directory2;
|
|
336
|
-
beforeEach("createDirectories", async () => {
|
|
337
|
-
containerRuntimeFactory = new MockContainerRuntimeFactoryForReconnection();
|
|
338
|
-
// Create the first SharedDirectory
|
|
339
|
-
const dataStoreRuntime1 = new MockFluidDataStoreRuntime();
|
|
340
|
-
containerRuntime1 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime1);
|
|
341
|
-
const services1 = {
|
|
342
|
-
deltaConnection: dataStoreRuntime1.createDeltaConnection(),
|
|
343
|
-
objectStorage: new MockStorage(),
|
|
344
|
-
};
|
|
345
|
-
directory1 = new SharedDirectory("dir1", dataStoreRuntime1, DirectoryFactory.Attributes);
|
|
346
|
-
directory1.connect(services1);
|
|
347
|
-
// Create the second SharedDirectory
|
|
348
|
-
const dataStoreRuntime2 = new MockFluidDataStoreRuntime();
|
|
349
|
-
containerRuntime2 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime2);
|
|
350
|
-
const services2 = {
|
|
351
|
-
deltaConnection: dataStoreRuntime2.createDeltaConnection(),
|
|
352
|
-
objectStorage: new MockStorage(),
|
|
353
|
-
};
|
|
354
|
-
directory2 = new SharedDirectory("dir1", dataStoreRuntime2, DirectoryFactory.Attributes);
|
|
355
|
-
directory2.connect(services2);
|
|
356
|
-
});
|
|
357
|
-
it("Can resend unacked ops on reconnection and impact the order", async () => {
|
|
358
|
-
directory1.createSubDirectory("a");
|
|
359
|
-
directory1.createSubDirectory("b");
|
|
360
|
-
directory2.createSubDirectory("c");
|
|
361
|
-
directory2.createSubDirectory("b");
|
|
362
|
-
// Disconnect and reconnect the first client
|
|
363
|
-
containerRuntime1.connected = false;
|
|
364
|
-
containerRuntime1.connected = true;
|
|
365
|
-
containerRuntimeFactory.processAllMessages();
|
|
366
|
-
assertDirectoryIterationOrder(directory1, ["c", "b", "a"]);
|
|
367
|
-
assertDirectoryIterationOrder(directory2, ["c", "b", "a"]);
|
|
368
|
-
});
|
|
369
|
-
it("can maintain order when a client disconnects in the meanwhile", async () => {
|
|
370
|
-
directory1.createSubDirectory("c");
|
|
371
|
-
containerRuntimeFactory.processAllMessages();
|
|
372
|
-
// Disconnect the first client
|
|
373
|
-
containerRuntime1.connected = false;
|
|
374
|
-
directory1.createSubDirectory("a");
|
|
375
|
-
directory2.createSubDirectory("d");
|
|
376
|
-
directory2.createSubDirectory("b");
|
|
377
|
-
// Reconnect the first client.
|
|
378
|
-
containerRuntime1.connected = true;
|
|
379
|
-
assertDirectoryIterationOrder(directory1, ["c", "a"]);
|
|
380
|
-
assertDirectoryIterationOrder(directory2, ["c", "d", "b"]);
|
|
381
|
-
containerRuntimeFactory.processAllMessages();
|
|
382
|
-
assertDirectoryIterationOrder(directory1, ["c", "d", "b", "a"]);
|
|
383
|
-
assertDirectoryIterationOrder(directory2, ["c", "d", "b", "a"]);
|
|
384
|
-
});
|
|
385
|
-
});
|
|
386
|
-
describe("Op Processing", () => {
|
|
387
|
-
let directory;
|
|
388
|
-
beforeEach("createDirectory", async () => {
|
|
389
|
-
const dataStoreRuntime = new MockFluidDataStoreRuntime();
|
|
390
|
-
directory = new TestSharedDirectory("dir1", dataStoreRuntime, DirectoryFactory.Attributes);
|
|
391
|
-
});
|
|
392
|
-
it("applyStashedOp", async () => {
|
|
393
|
-
const op1 = {
|
|
394
|
-
type: "createSubDirectory",
|
|
395
|
-
path: "./",
|
|
396
|
-
subdirName: "c",
|
|
397
|
-
};
|
|
398
|
-
const op2 = {
|
|
399
|
-
type: "createSubDirectory",
|
|
400
|
-
path: "./",
|
|
401
|
-
subdirName: "b",
|
|
402
|
-
};
|
|
403
|
-
const op3 = {
|
|
404
|
-
type: "createSubDirectory",
|
|
405
|
-
path: "./",
|
|
406
|
-
subdirName: "a",
|
|
407
|
-
};
|
|
408
|
-
const op4 = {
|
|
409
|
-
type: "deleteSubDirectory",
|
|
410
|
-
path: "./",
|
|
411
|
-
subdirName: "b",
|
|
412
|
-
};
|
|
413
|
-
directory.testApplyStashedOp(op1);
|
|
414
|
-
directory.testApplyStashedOp(op2);
|
|
415
|
-
directory.testApplyStashedOp(op3);
|
|
416
|
-
assertDirectoryIterationOrder(directory, ["c", "b", "a"]);
|
|
417
|
-
directory.testApplyStashedOp(op4);
|
|
418
|
-
assertDirectoryIterationOrder(directory, ["c", "a"]);
|
|
419
|
-
});
|
|
420
|
-
});
|
|
421
|
-
});
|
|
422
|
-
//# sourceMappingURL=directory.order.spec.js.map
|