@fluidframework/merge-tree 2.93.0 → 2.100.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.
@@ -2,135 +2,140 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { BenchmarkType, benchmark } from "@fluid-tools/benchmark";
5
+ import { benchmarkDuration, benchmarkIt } from "@fluid-tools/benchmark";
6
6
  import { MergeTreeDeltaType } from "../ops.js";
7
7
  import { PriorPerspective } from "../perspective.js";
8
8
  import { appendToMergeTreeDeltaRevertibles, } from "../revertibles.js";
9
9
  import { TestString, loadSnapshot } from "./snapshot.utils.js";
10
10
  describe("MergeTree remove", () => {
11
- let summary;
12
- benchmark({
13
- type: BenchmarkType.Measurement,
11
+ benchmarkIt({
14
12
  // baseline summary benchmark to compare to other remove tests. such a
15
13
  // comparison should give a (rough) sense of overhead caused by summary
16
14
  // loading
17
15
  title: "baseline summary load",
18
16
  category: "remove",
19
- before: () => {
20
- const str = new TestString("id", {});
21
- for (let i = 0; i < 1000; i++) {
22
- str.append("a", false);
23
- }
24
- str.applyPendingOps();
25
- summary = str.getSummary();
26
- },
27
- benchmarkFnAsync: async () => {
28
- await loadSnapshot(summary);
29
- },
17
+ ...benchmarkDuration({
18
+ benchmarkFnCustom: async (state) => {
19
+ const str = new TestString("id", {});
20
+ for (let i = 0; i < 1000; i++) {
21
+ str.append("a", false);
22
+ }
23
+ str.applyPendingOps();
24
+ const summary = str.getSummary();
25
+ await state.timeAllBatchesAsync(async () => {
26
+ await loadSnapshot(summary);
27
+ });
28
+ },
29
+ }),
30
30
  });
31
- benchmark({
32
- type: BenchmarkType.Measurement,
31
+ benchmarkIt({
33
32
  title: "remove large range of large tree",
34
33
  category: "remove",
35
- before: () => {
36
- const str = new TestString("id", {});
37
- for (let i = 0; i < 1000; i++) {
38
- str.append("a", false);
39
- }
40
- str.applyPendingOps();
41
- summary = str.getSummary();
42
- },
43
- benchmarkFnAsync: async () => {
44
- const str = await loadSnapshot(summary);
45
- const refSeq = 1000;
46
- const clientId = 0;
47
- str.mergeTree.markRangeRemoved(0, 1000, new PriorPerspective(refSeq, clientId), { seq: 1001, clientId }, { op: { type: MergeTreeDeltaType.REMOVE } });
48
- },
49
- });
50
- for (const length of [10, 100, 1000]) {
51
- benchmark({
52
- type: BenchmarkType.Measurement,
53
- title: `remove range of length ${length} from large tree with undo-redo`,
54
- category: "remove",
55
- before: () => {
34
+ ...benchmarkDuration({
35
+ benchmarkFnCustom: async (state) => {
56
36
  const str = new TestString("id", {});
57
- for (let i = 0; i < length / 2; i++) {
58
- str.append("a", true);
59
- str.appendMarker(true);
37
+ for (let i = 0; i < 1000; i++) {
38
+ str.append("a", false);
60
39
  }
61
40
  str.applyPendingOps();
62
- summary = str.getSummary();
63
- },
64
- benchmarkFnAsync: async () => {
65
- const str = await loadSnapshot(summary);
66
- const revertibles = [];
67
- str.on("delta", (_op, delta) => {
68
- appendToMergeTreeDeltaRevertibles(delta, revertibles);
41
+ const summary = str.getSummary();
42
+ await state.timeAllBatchesAsync(async () => {
43
+ const loadedStr = await loadSnapshot(summary);
44
+ const refSeq = 1000;
45
+ const clientId = 0;
46
+ loadedStr.mergeTree.markRangeRemoved(0, 1000, new PriorPerspective(refSeq, clientId), { seq: 1001, clientId }, { op: { type: MergeTreeDeltaType.REMOVE } });
69
47
  });
70
- const op = str.removeRangeLocal(0, length - 1);
71
- str.applyMsg(str.makeOpMessage(op,
72
- /* seq */ length + 1,
73
- /* refSeq */ length, str.longClientId,
74
- /* minSeq */ length));
75
48
  },
49
+ }),
50
+ });
51
+ for (const length of [10, 100, 1000]) {
52
+ benchmarkIt({
53
+ title: `remove range of length ${length} from large tree with undo-redo`,
54
+ category: "remove",
55
+ ...benchmarkDuration({
56
+ benchmarkFnCustom: async (state) => {
57
+ const str = new TestString("id", {});
58
+ for (let i = 0; i < length / 2; i++) {
59
+ str.append("a", true);
60
+ str.appendMarker(true);
61
+ }
62
+ str.applyPendingOps();
63
+ const summary = str.getSummary();
64
+ await state.timeAllBatchesAsync(async () => {
65
+ const loadedStr = await loadSnapshot(summary);
66
+ const revertibles = [];
67
+ loadedStr.on("delta", (_op, delta) => {
68
+ appendToMergeTreeDeltaRevertibles(delta, revertibles);
69
+ });
70
+ const op = loadedStr.removeRangeLocal(0, length - 1);
71
+ loadedStr.applyMsg(loadedStr.makeOpMessage(op,
72
+ /* seq */ length + 1,
73
+ /* refSeq */ length, loadedStr.longClientId,
74
+ /* minSeq */ length));
75
+ });
76
+ },
77
+ }),
76
78
  });
77
79
  }
78
- benchmark({
79
- type: BenchmarkType.Measurement,
80
+ benchmarkIt({
80
81
  title: "remove start of large tree",
81
82
  category: "remove",
82
- before: () => {
83
- const str = new TestString("id", {});
84
- for (let i = 0; i < 1000; i++) {
85
- str.append("a", false);
86
- }
87
- str.applyPendingOps();
88
- summary = str.getSummary();
89
- },
90
- benchmarkFnAsync: async () => {
91
- const str = await loadSnapshot(summary);
92
- const refSeq = 1000;
93
- const clientId = 0;
94
- str.mergeTree.markRangeRemoved(0, 1, new PriorPerspective(refSeq, clientId), { seq: 1001, clientId }, { op: { type: MergeTreeDeltaType.REMOVE } });
95
- },
83
+ ...benchmarkDuration({
84
+ benchmarkFnCustom: async (state) => {
85
+ const str = new TestString("id", {});
86
+ for (let i = 0; i < 1000; i++) {
87
+ str.append("a", false);
88
+ }
89
+ str.applyPendingOps();
90
+ const summary = str.getSummary();
91
+ await state.timeAllBatchesAsync(async () => {
92
+ const loadedStr = await loadSnapshot(summary);
93
+ const refSeq = 1000;
94
+ const clientId = 0;
95
+ loadedStr.mergeTree.markRangeRemoved(0, 1, new PriorPerspective(refSeq, clientId), { seq: 1001, clientId }, { op: { type: MergeTreeDeltaType.REMOVE } });
96
+ });
97
+ },
98
+ }),
96
99
  });
97
- benchmark({
98
- type: BenchmarkType.Measurement,
100
+ benchmarkIt({
99
101
  title: "remove middle of large tree",
100
102
  category: "remove",
101
- before: () => {
102
- const str = new TestString("id", {});
103
- for (let i = 0; i < 1000; i++) {
104
- str.append("a", false);
105
- }
106
- str.applyPendingOps();
107
- summary = str.getSummary();
108
- },
109
- benchmarkFnAsync: async () => {
110
- const str = await loadSnapshot(summary);
111
- const refSeq = 1000;
112
- const clientId = 0;
113
- str.mergeTree.markRangeRemoved(499, 501, new PriorPerspective(refSeq, clientId), { seq: 1001, clientId }, { op: { type: MergeTreeDeltaType.REMOVE } });
114
- },
103
+ ...benchmarkDuration({
104
+ benchmarkFnCustom: async (state) => {
105
+ const str = new TestString("id", {});
106
+ for (let i = 0; i < 1000; i++) {
107
+ str.append("a", false);
108
+ }
109
+ str.applyPendingOps();
110
+ const summary = str.getSummary();
111
+ await state.timeAllBatchesAsync(async () => {
112
+ const loadedStr = await loadSnapshot(summary);
113
+ const refSeq = 1000;
114
+ const clientId = 0;
115
+ loadedStr.mergeTree.markRangeRemoved(499, 501, new PriorPerspective(refSeq, clientId), { seq: 1001, clientId }, { op: { type: MergeTreeDeltaType.REMOVE } });
116
+ });
117
+ },
118
+ }),
115
119
  });
116
- benchmark({
117
- type: BenchmarkType.Measurement,
120
+ benchmarkIt({
118
121
  title: "remove end of large tree",
119
122
  category: "remove",
120
- before: () => {
121
- const str = new TestString("id", {});
122
- for (let i = 0; i < 1000; i++) {
123
- str.append("a", false);
124
- }
125
- str.applyPendingOps();
126
- summary = str.getSummary();
127
- },
128
- benchmarkFnAsync: async () => {
129
- const str = await loadSnapshot(summary);
130
- const refSeq = 1000;
131
- const clientId = 0;
132
- str.mergeTree.markRangeRemoved(999, 1000, new PriorPerspective(refSeq, clientId), { seq: 1001, clientId }, { op: { type: MergeTreeDeltaType.REMOVE } });
133
- },
123
+ ...benchmarkDuration({
124
+ benchmarkFnCustom: async (state) => {
125
+ const str = new TestString("id", {});
126
+ for (let i = 0; i < 1000; i++) {
127
+ str.append("a", false);
128
+ }
129
+ str.applyPendingOps();
130
+ const summary = str.getSummary();
131
+ await state.timeAllBatchesAsync(async () => {
132
+ const loadedStr = await loadSnapshot(summary);
133
+ const refSeq = 1000;
134
+ const clientId = 0;
135
+ loadedStr.mergeTree.markRangeRemoved(999, 1000, new PriorPerspective(refSeq, clientId), { seq: 1001, clientId }, { op: { type: MergeTreeDeltaType.REMOVE } });
136
+ });
137
+ },
138
+ }),
134
139
  });
135
140
  });
136
141
  //# sourceMappingURL=Removal.perf.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Removal.perf.spec.js","sourceRoot":"","sources":["../../src/test/Removal.perf.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGlE,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAEN,iCAAiC,GACjC,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE/D,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IACjC,IAAI,OAAqB,CAAC;IAE1B,SAAS,CAAC;QACT,IAAI,EAAE,aAAa,CAAC,WAAW;QAC/B,sEAAsE;QACtE,uEAAuE;QACvE,UAAU;QACV,KAAK,EAAE,uBAAuB;QAC9B,QAAQ,EAAE,QAAQ;QAClB,MAAM,EAAE,GAAG,EAAE;YACZ,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACxB,CAAC;YAED,GAAG,CAAC,eAAe,EAAE,CAAC;YACtB,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;QAC5B,CAAC;QACD,gBAAgB,EAAE,KAAK,IAAI,EAAE;YAC5B,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;KACD,CAAC,CAAC;IAEH,SAAS,CAAC;QACT,IAAI,EAAE,aAAa,CAAC,WAAW;QAC/B,KAAK,EAAE,kCAAkC;QACzC,QAAQ,EAAE,QAAQ;QAClB,MAAM,EAAE,GAAG,EAAE;YACZ,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACxB,CAAC;YAED,GAAG,CAAC,eAAe,EAAE,CAAC;YACtB,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;QAC5B,CAAC;QACD,gBAAgB,EAAE,KAAK,IAAI,EAAE;YAC5B,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;YAExC,MAAM,MAAM,GAAG,IAAI,CAAC;YACpB,MAAM,QAAQ,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,SAAS,CAAC,gBAAgB,CAC7B,CAAC,EACD,IAAI,EACJ,IAAI,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,EACtC,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,EACvB,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAC3C,CAAC;QACH,CAAC;KACD,CAAC,CAAC;IAEH,KAAK,MAAM,MAAM,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;QACtC,SAAS,CAAC;YACT,IAAI,EAAE,aAAa,CAAC,WAAW;YAC/B,KAAK,EAAE,0BAA0B,MAAM,iCAAiC;YACxE,QAAQ,EAAE,QAAQ;YAClB,MAAM,EAAE,GAAG,EAAE;gBACZ,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;oBACrC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;oBACtB,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;gBACxB,CAAC;gBAED,GAAG,CAAC,eAAe,EAAE,CAAC;gBACtB,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;YAC5B,CAAC;YACD,gBAAgB,EAAE,KAAK,IAAI,EAAE;gBAC5B,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;gBAExC,MAAM,WAAW,GAA+B,EAAE,CAAC;gBACnD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;oBAC9B,iCAAiC,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;gBACvD,CAAC,CAAC,CAAC;gBAEH,MAAM,EAAE,GAAG,GAAG,CAAC,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC/C,GAAG,CAAC,QAAQ,CACX,GAAG,CAAC,aAAa,CAChB,EAAE;gBACF,SAAS,CAAC,MAAM,GAAG,CAAC;gBACpB,YAAY,CAAC,MAAM,EACnB,GAAG,CAAC,YAAY;gBAChB,YAAY,CAAC,MAAM,CACnB,CACD,CAAC;YACH,CAAC;SACD,CAAC,CAAC;IACJ,CAAC;IAED,SAAS,CAAC;QACT,IAAI,EAAE,aAAa,CAAC,WAAW;QAC/B,KAAK,EAAE,4BAA4B;QACnC,QAAQ,EAAE,QAAQ;QAClB,MAAM,EAAE,GAAG,EAAE;YACZ,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACxB,CAAC;YAED,GAAG,CAAC,eAAe,EAAE,CAAC;YACtB,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;QAC5B,CAAC;QACD,gBAAgB,EAAE,KAAK,IAAI,EAAE;YAC5B,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;YAExC,MAAM,MAAM,GAAG,IAAI,CAAC;YACpB,MAAM,QAAQ,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,SAAS,CAAC,gBAAgB,CAC7B,CAAC,EACD,CAAC,EACD,IAAI,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,EACtC,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,EACvB,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAC3C,CAAC;QACH,CAAC;KACD,CAAC,CAAC;IAEH,SAAS,CAAC;QACT,IAAI,EAAE,aAAa,CAAC,WAAW;QAC/B,KAAK,EAAE,6BAA6B;QACpC,QAAQ,EAAE,QAAQ;QAClB,MAAM,EAAE,GAAG,EAAE;YACZ,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACxB,CAAC;YAED,GAAG,CAAC,eAAe,EAAE,CAAC;YACtB,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;QAC5B,CAAC;QACD,gBAAgB,EAAE,KAAK,IAAI,EAAE;YAC5B,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;YAExC,MAAM,MAAM,GAAG,IAAI,CAAC;YACpB,MAAM,QAAQ,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,SAAS,CAAC,gBAAgB,CAC7B,GAAG,EACH,GAAG,EACH,IAAI,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,EACtC,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,EACvB,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAC3C,CAAC;QACH,CAAC;KACD,CAAC,CAAC;IAEH,SAAS,CAAC;QACT,IAAI,EAAE,aAAa,CAAC,WAAW;QAC/B,KAAK,EAAE,0BAA0B;QACjC,QAAQ,EAAE,QAAQ;QAClB,MAAM,EAAE,GAAG,EAAE;YACZ,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACxB,CAAC;YAED,GAAG,CAAC,eAAe,EAAE,CAAC;YACtB,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;QAC5B,CAAC;QACD,gBAAgB,EAAE,KAAK,IAAI,EAAE;YAC5B,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;YAExC,MAAM,MAAM,GAAG,IAAI,CAAC;YACpB,MAAM,QAAQ,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,SAAS,CAAC,gBAAgB,CAC7B,GAAG,EACH,IAAI,EACJ,IAAI,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,EACtC,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,EACvB,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAC3C,CAAC;QACH,CAAC;KACD,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { BenchmarkType, benchmark } from \"@fluid-tools/benchmark\";\nimport type { ISummaryTree } from \"@fluidframework/driver-definitions\";\n\nimport { MergeTreeDeltaType } from \"../ops.js\";\nimport { PriorPerspective } from \"../perspective.js\";\nimport {\n\ttype MergeTreeDeltaRevertible,\n\tappendToMergeTreeDeltaRevertibles,\n} from \"../revertibles.js\";\n\nimport { TestString, loadSnapshot } from \"./snapshot.utils.js\";\n\ndescribe(\"MergeTree remove\", () => {\n\tlet summary: ISummaryTree;\n\n\tbenchmark({\n\t\ttype: BenchmarkType.Measurement,\n\t\t// baseline summary benchmark to compare to other remove tests. such a\n\t\t// comparison should give a (rough) sense of overhead caused by summary\n\t\t// loading\n\t\ttitle: \"baseline summary load\",\n\t\tcategory: \"remove\",\n\t\tbefore: () => {\n\t\t\tconst str = new TestString(\"id\", {});\n\t\t\tfor (let i = 0; i < 1000; i++) {\n\t\t\t\tstr.append(\"a\", false);\n\t\t\t}\n\n\t\t\tstr.applyPendingOps();\n\t\t\tsummary = str.getSummary();\n\t\t},\n\t\tbenchmarkFnAsync: async () => {\n\t\t\tawait loadSnapshot(summary);\n\t\t},\n\t});\n\n\tbenchmark({\n\t\ttype: BenchmarkType.Measurement,\n\t\ttitle: \"remove large range of large tree\",\n\t\tcategory: \"remove\",\n\t\tbefore: () => {\n\t\t\tconst str = new TestString(\"id\", {});\n\t\t\tfor (let i = 0; i < 1000; i++) {\n\t\t\t\tstr.append(\"a\", false);\n\t\t\t}\n\n\t\t\tstr.applyPendingOps();\n\t\t\tsummary = str.getSummary();\n\t\t},\n\t\tbenchmarkFnAsync: async () => {\n\t\t\tconst str = await loadSnapshot(summary);\n\n\t\t\tconst refSeq = 1000;\n\t\t\tconst clientId = 0;\n\t\t\tstr.mergeTree.markRangeRemoved(\n\t\t\t\t0,\n\t\t\t\t1000,\n\t\t\t\tnew PriorPerspective(refSeq, clientId),\n\t\t\t\t{ seq: 1001, clientId },\n\t\t\t\t{ op: { type: MergeTreeDeltaType.REMOVE } },\n\t\t\t);\n\t\t},\n\t});\n\n\tfor (const length of [10, 100, 1000]) {\n\t\tbenchmark({\n\t\t\ttype: BenchmarkType.Measurement,\n\t\t\ttitle: `remove range of length ${length} from large tree with undo-redo`,\n\t\t\tcategory: \"remove\",\n\t\t\tbefore: () => {\n\t\t\t\tconst str = new TestString(\"id\", {});\n\t\t\t\tfor (let i = 0; i < length / 2; i++) {\n\t\t\t\t\tstr.append(\"a\", true);\n\t\t\t\t\tstr.appendMarker(true);\n\t\t\t\t}\n\n\t\t\t\tstr.applyPendingOps();\n\t\t\t\tsummary = str.getSummary();\n\t\t\t},\n\t\t\tbenchmarkFnAsync: async () => {\n\t\t\t\tconst str = await loadSnapshot(summary);\n\n\t\t\t\tconst revertibles: MergeTreeDeltaRevertible[] = [];\n\t\t\t\tstr.on(\"delta\", (_op, delta) => {\n\t\t\t\t\tappendToMergeTreeDeltaRevertibles(delta, revertibles);\n\t\t\t\t});\n\n\t\t\t\tconst op = str.removeRangeLocal(0, length - 1);\n\t\t\t\tstr.applyMsg(\n\t\t\t\t\tstr.makeOpMessage(\n\t\t\t\t\t\top,\n\t\t\t\t\t\t/* seq */ length + 1,\n\t\t\t\t\t\t/* refSeq */ length,\n\t\t\t\t\t\tstr.longClientId,\n\t\t\t\t\t\t/* minSeq */ length,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t}\n\n\tbenchmark({\n\t\ttype: BenchmarkType.Measurement,\n\t\ttitle: \"remove start of large tree\",\n\t\tcategory: \"remove\",\n\t\tbefore: () => {\n\t\t\tconst str = new TestString(\"id\", {});\n\t\t\tfor (let i = 0; i < 1000; i++) {\n\t\t\t\tstr.append(\"a\", false);\n\t\t\t}\n\n\t\t\tstr.applyPendingOps();\n\t\t\tsummary = str.getSummary();\n\t\t},\n\t\tbenchmarkFnAsync: async () => {\n\t\t\tconst str = await loadSnapshot(summary);\n\n\t\t\tconst refSeq = 1000;\n\t\t\tconst clientId = 0;\n\t\t\tstr.mergeTree.markRangeRemoved(\n\t\t\t\t0,\n\t\t\t\t1,\n\t\t\t\tnew PriorPerspective(refSeq, clientId),\n\t\t\t\t{ seq: 1001, clientId },\n\t\t\t\t{ op: { type: MergeTreeDeltaType.REMOVE } },\n\t\t\t);\n\t\t},\n\t});\n\n\tbenchmark({\n\t\ttype: BenchmarkType.Measurement,\n\t\ttitle: \"remove middle of large tree\",\n\t\tcategory: \"remove\",\n\t\tbefore: () => {\n\t\t\tconst str = new TestString(\"id\", {});\n\t\t\tfor (let i = 0; i < 1000; i++) {\n\t\t\t\tstr.append(\"a\", false);\n\t\t\t}\n\n\t\t\tstr.applyPendingOps();\n\t\t\tsummary = str.getSummary();\n\t\t},\n\t\tbenchmarkFnAsync: async () => {\n\t\t\tconst str = await loadSnapshot(summary);\n\n\t\t\tconst refSeq = 1000;\n\t\t\tconst clientId = 0;\n\t\t\tstr.mergeTree.markRangeRemoved(\n\t\t\t\t499,\n\t\t\t\t501,\n\t\t\t\tnew PriorPerspective(refSeq, clientId),\n\t\t\t\t{ seq: 1001, clientId },\n\t\t\t\t{ op: { type: MergeTreeDeltaType.REMOVE } },\n\t\t\t);\n\t\t},\n\t});\n\n\tbenchmark({\n\t\ttype: BenchmarkType.Measurement,\n\t\ttitle: \"remove end of large tree\",\n\t\tcategory: \"remove\",\n\t\tbefore: () => {\n\t\t\tconst str = new TestString(\"id\", {});\n\t\t\tfor (let i = 0; i < 1000; i++) {\n\t\t\t\tstr.append(\"a\", false);\n\t\t\t}\n\n\t\t\tstr.applyPendingOps();\n\t\t\tsummary = str.getSummary();\n\t\t},\n\t\tbenchmarkFnAsync: async () => {\n\t\t\tconst str = await loadSnapshot(summary);\n\n\t\t\tconst refSeq = 1000;\n\t\t\tconst clientId = 0;\n\t\t\tstr.mergeTree.markRangeRemoved(\n\t\t\t\t999,\n\t\t\t\t1000,\n\t\t\t\tnew PriorPerspective(refSeq, clientId),\n\t\t\t\t{ seq: 1001, clientId },\n\t\t\t\t{ op: { type: MergeTreeDeltaType.REMOVE } },\n\t\t\t);\n\t\t},\n\t});\n});\n"]}
1
+ {"version":3,"file":"Removal.perf.spec.js","sourceRoot":"","sources":["../../src/test/Removal.perf.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { benchmarkDuration, benchmarkIt } from \"@fluid-tools/benchmark\";\n\nimport { MergeTreeDeltaType } from \"../ops.js\";\nimport { PriorPerspective } from \"../perspective.js\";\nimport {\n\ttype MergeTreeDeltaRevertible,\n\tappendToMergeTreeDeltaRevertibles,\n} from \"../revertibles.js\";\n\nimport { TestString, loadSnapshot } from \"./snapshot.utils.js\";\n\ndescribe(\"MergeTree remove\", () => {\n\tbenchmarkIt({\n\t\t// baseline summary benchmark to compare to other remove tests. such a\n\t\t// comparison should give a (rough) sense of overhead caused by summary\n\t\t// loading\n\t\ttitle: \"baseline summary load\",\n\t\tcategory: \"remove\",\n\t\t...benchmarkDuration({\n\t\t\tbenchmarkFnCustom: async (state) => {\n\t\t\t\tconst str = new TestString(\"id\", {});\n\t\t\t\tfor (let i = 0; i < 1000; i++) {\n\t\t\t\t\tstr.append(\"a\", false);\n\t\t\t\t}\n\t\t\t\tstr.applyPendingOps();\n\t\t\t\tconst summary = str.getSummary();\n\t\t\t\tawait state.timeAllBatchesAsync(async () => {\n\t\t\t\t\tawait loadSnapshot(summary);\n\t\t\t\t});\n\t\t\t},\n\t\t}),\n\t});\n\n\tbenchmarkIt({\n\t\ttitle: \"remove large range of large tree\",\n\t\tcategory: \"remove\",\n\t\t...benchmarkDuration({\n\t\t\tbenchmarkFnCustom: async (state) => {\n\t\t\t\tconst str = new TestString(\"id\", {});\n\t\t\t\tfor (let i = 0; i < 1000; i++) {\n\t\t\t\t\tstr.append(\"a\", false);\n\t\t\t\t}\n\t\t\t\tstr.applyPendingOps();\n\t\t\t\tconst summary = str.getSummary();\n\t\t\t\tawait state.timeAllBatchesAsync(async () => {\n\t\t\t\t\tconst loadedStr = await loadSnapshot(summary);\n\n\t\t\t\t\tconst refSeq = 1000;\n\t\t\t\t\tconst clientId = 0;\n\t\t\t\t\tloadedStr.mergeTree.markRangeRemoved(\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1000,\n\t\t\t\t\t\tnew PriorPerspective(refSeq, clientId),\n\t\t\t\t\t\t{ seq: 1001, clientId },\n\t\t\t\t\t\t{ op: { type: MergeTreeDeltaType.REMOVE } },\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t},\n\t\t}),\n\t});\n\n\tfor (const length of [10, 100, 1000]) {\n\t\tbenchmarkIt({\n\t\t\ttitle: `remove range of length ${length} from large tree with undo-redo`,\n\t\t\tcategory: \"remove\",\n\t\t\t...benchmarkDuration({\n\t\t\t\tbenchmarkFnCustom: async (state) => {\n\t\t\t\t\tconst str = new TestString(\"id\", {});\n\t\t\t\t\tfor (let i = 0; i < length / 2; i++) {\n\t\t\t\t\t\tstr.append(\"a\", true);\n\t\t\t\t\t\tstr.appendMarker(true);\n\t\t\t\t\t}\n\t\t\t\t\tstr.applyPendingOps();\n\t\t\t\t\tconst summary = str.getSummary();\n\t\t\t\t\tawait state.timeAllBatchesAsync(async () => {\n\t\t\t\t\t\tconst loadedStr = await loadSnapshot(summary);\n\n\t\t\t\t\t\tconst revertibles: MergeTreeDeltaRevertible[] = [];\n\t\t\t\t\t\tloadedStr.on(\"delta\", (_op, delta) => {\n\t\t\t\t\t\t\tappendToMergeTreeDeltaRevertibles(delta, revertibles);\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst op = loadedStr.removeRangeLocal(0, length - 1);\n\t\t\t\t\t\tloadedStr.applyMsg(\n\t\t\t\t\t\t\tloadedStr.makeOpMessage(\n\t\t\t\t\t\t\t\top,\n\t\t\t\t\t\t\t\t/* seq */ length + 1,\n\t\t\t\t\t\t\t\t/* refSeq */ length,\n\t\t\t\t\t\t\t\tloadedStr.longClientId,\n\t\t\t\t\t\t\t\t/* minSeq */ length,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t}),\n\t\t});\n\t}\n\n\tbenchmarkIt({\n\t\ttitle: \"remove start of large tree\",\n\t\tcategory: \"remove\",\n\t\t...benchmarkDuration({\n\t\t\tbenchmarkFnCustom: async (state) => {\n\t\t\t\tconst str = new TestString(\"id\", {});\n\t\t\t\tfor (let i = 0; i < 1000; i++) {\n\t\t\t\t\tstr.append(\"a\", false);\n\t\t\t\t}\n\t\t\t\tstr.applyPendingOps();\n\t\t\t\tconst summary = str.getSummary();\n\t\t\t\tawait state.timeAllBatchesAsync(async () => {\n\t\t\t\t\tconst loadedStr = await loadSnapshot(summary);\n\n\t\t\t\t\tconst refSeq = 1000;\n\t\t\t\t\tconst clientId = 0;\n\t\t\t\t\tloadedStr.mergeTree.markRangeRemoved(\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\tnew PriorPerspective(refSeq, clientId),\n\t\t\t\t\t\t{ seq: 1001, clientId },\n\t\t\t\t\t\t{ op: { type: MergeTreeDeltaType.REMOVE } },\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t},\n\t\t}),\n\t});\n\n\tbenchmarkIt({\n\t\ttitle: \"remove middle of large tree\",\n\t\tcategory: \"remove\",\n\t\t...benchmarkDuration({\n\t\t\tbenchmarkFnCustom: async (state) => {\n\t\t\t\tconst str = new TestString(\"id\", {});\n\t\t\t\tfor (let i = 0; i < 1000; i++) {\n\t\t\t\t\tstr.append(\"a\", false);\n\t\t\t\t}\n\t\t\t\tstr.applyPendingOps();\n\t\t\t\tconst summary = str.getSummary();\n\t\t\t\tawait state.timeAllBatchesAsync(async () => {\n\t\t\t\t\tconst loadedStr = await loadSnapshot(summary);\n\n\t\t\t\t\tconst refSeq = 1000;\n\t\t\t\t\tconst clientId = 0;\n\t\t\t\t\tloadedStr.mergeTree.markRangeRemoved(\n\t\t\t\t\t\t499,\n\t\t\t\t\t\t501,\n\t\t\t\t\t\tnew PriorPerspective(refSeq, clientId),\n\t\t\t\t\t\t{ seq: 1001, clientId },\n\t\t\t\t\t\t{ op: { type: MergeTreeDeltaType.REMOVE } },\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t},\n\t\t}),\n\t});\n\n\tbenchmarkIt({\n\t\ttitle: \"remove end of large tree\",\n\t\tcategory: \"remove\",\n\t\t...benchmarkDuration({\n\t\t\tbenchmarkFnCustom: async (state) => {\n\t\t\t\tconst str = new TestString(\"id\", {});\n\t\t\t\tfor (let i = 0; i < 1000; i++) {\n\t\t\t\t\tstr.append(\"a\", false);\n\t\t\t\t}\n\t\t\t\tstr.applyPendingOps();\n\t\t\t\tconst summary = str.getSummary();\n\t\t\t\tawait state.timeAllBatchesAsync(async () => {\n\t\t\t\t\tconst loadedStr = await loadSnapshot(summary);\n\n\t\t\t\t\tconst refSeq = 1000;\n\t\t\t\t\tconst clientId = 0;\n\t\t\t\t\tloadedStr.mergeTree.markRangeRemoved(\n\t\t\t\t\t\t999,\n\t\t\t\t\t\t1000,\n\t\t\t\t\t\tnew PriorPerspective(refSeq, clientId),\n\t\t\t\t\t\t{ seq: 1001, clientId },\n\t\t\t\t\t\t{ op: { type: MergeTreeDeltaType.REMOVE } },\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t},\n\t\t}),\n\t});\n});\n"]}
@@ -2,30 +2,26 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { BenchmarkType, benchmark } from "@fluid-tools/benchmark";
5
+ import { benchmarkDuration, benchmarkIt } from "@fluid-tools/benchmark";
6
6
  import { TestString, loadSnapshot } from "./snapshot.utils.js";
7
7
  describe("MergeTree snapshots", () => {
8
- let summary;
9
8
  for (const summarySize of [10, 50, 100, 500, 1000, 5000, 10_000]) {
10
- const test = benchmark({
11
- type: BenchmarkType.Measurement,
9
+ const test = benchmarkIt({
12
10
  title: `load snapshot with ${summarySize} segments`,
13
11
  category: "snapshot loading",
14
- before: () => {
15
- const str = new TestString("id", {});
16
- for (let i = 0; i < summarySize; i++) {
17
- str.append("a", false);
18
- }
19
- str.applyPendingOps();
20
- summary = str.getSummary();
21
- },
22
- benchmarkFnAsync: async () => {
23
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
24
- await loadSnapshot(summary);
25
- },
26
- after: () => {
27
- summary = undefined;
28
- },
12
+ ...benchmarkDuration({
13
+ benchmarkFnCustom: async (state) => {
14
+ const str = new TestString("id", {});
15
+ for (let i = 0; i < summarySize; i++) {
16
+ str.append("a", false);
17
+ }
18
+ str.applyPendingOps();
19
+ const summary = str.getSummary();
20
+ await state.timeAllBatchesAsync(async () => {
21
+ await loadSnapshot(summary);
22
+ });
23
+ },
24
+ }),
29
25
  });
30
26
  if (summarySize > 5000) {
31
27
  const currentTimeout = test.timeout();
@@ -1 +1 @@
1
- {"version":3,"file":"Snapshot.perf.spec.js","sourceRoot":"","sources":["../../src/test/Snapshot.perf.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGlE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE/D,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACpC,IAAI,OAAiC,CAAC;IAEtC,KAAK,MAAM,WAAW,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,GAAG,SAAS,CAAC;YACtB,IAAI,EAAE,aAAa,CAAC,WAAW;YAC/B,KAAK,EAAE,sBAAsB,WAAW,WAAW;YACnD,QAAQ,EAAE,kBAAkB;YAC5B,MAAM,EAAE,GAAG,EAAE;gBACZ,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;oBACtC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACxB,CAAC;gBAED,GAAG,CAAC,eAAe,EAAE,CAAC;gBACtB,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;YAC5B,CAAC;YACD,gBAAgB,EAAE,KAAK,IAAI,EAAE;gBAC5B,oEAAoE;gBACpE,MAAM,YAAY,CAAC,OAAQ,CAAC,CAAC;YAC9B,CAAC;YACD,KAAK,EAAE,GAAG,EAAE;gBACX,OAAO,GAAG,SAAS,CAAC;YACrB,CAAC;SACD,CAAC,CAAC;QAEH,IAAI,WAAW,GAAG,IAAI,EAAE,CAAC;YACxB,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YACtC,iFAAiF;YACjF,IAAI,CAAC,OAAO,CAAC,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;QACzE,CAAC;IACF,CAAC;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { BenchmarkType, benchmark } from \"@fluid-tools/benchmark\";\nimport type { ISummaryTree } from \"@fluidframework/driver-definitions\";\n\nimport { TestString, loadSnapshot } from \"./snapshot.utils.js\";\n\ndescribe(\"MergeTree snapshots\", () => {\n\tlet summary: ISummaryTree | undefined;\n\n\tfor (const summarySize of [10, 50, 100, 500, 1000, 5000, 10_000]) {\n\t\tconst test = benchmark({\n\t\t\ttype: BenchmarkType.Measurement,\n\t\t\ttitle: `load snapshot with ${summarySize} segments`,\n\t\t\tcategory: \"snapshot loading\",\n\t\t\tbefore: () => {\n\t\t\t\tconst str = new TestString(\"id\", {});\n\t\t\t\tfor (let i = 0; i < summarySize; i++) {\n\t\t\t\t\tstr.append(\"a\", false);\n\t\t\t\t}\n\n\t\t\t\tstr.applyPendingOps();\n\t\t\t\tsummary = str.getSummary();\n\t\t\t},\n\t\t\tbenchmarkFnAsync: async () => {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tawait loadSnapshot(summary!);\n\t\t\t},\n\t\t\tafter: () => {\n\t\t\t\tsummary = undefined;\n\t\t\t},\n\t\t});\n\n\t\tif (summarySize > 5000) {\n\t\t\tconst currentTimeout = test.timeout();\n\t\t\t// Default value of 2 seconds causes failure around P95 for large snapshot sizes.\n\t\t\ttest.timeout(currentTimeout === 0 ? 0 : Math.max(5000, currentTimeout));\n\t\t}\n\t}\n});\n"]}
1
+ {"version":3,"file":"Snapshot.perf.spec.js","sourceRoot":"","sources":["../../src/test/Snapshot.perf.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGxE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE/D,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACpC,KAAK,MAAM,WAAW,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,GAAG,WAAW,CAAC;YACxB,KAAK,EAAE,sBAAsB,WAAW,WAAW;YACnD,QAAQ,EAAE,kBAAkB;YAC5B,GAAG,iBAAiB,CAAC;gBACpB,iBAAiB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;oBAClC,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;wBACtC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;oBACxB,CAAC;oBACD,GAAG,CAAC,eAAe,EAAE,CAAC;oBACtB,MAAM,OAAO,GAAiB,GAAG,CAAC,UAAU,EAAE,CAAC;oBAC/C,MAAM,KAAK,CAAC,mBAAmB,CAAC,KAAK,IAAI,EAAE;wBAC1C,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;oBAC7B,CAAC,CAAC,CAAC;gBACJ,CAAC;aACD,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,WAAW,GAAG,IAAI,EAAE,CAAC;YACxB,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YACtC,iFAAiF;YACjF,IAAI,CAAC,OAAO,CAAC,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;QACzE,CAAC;IACF,CAAC;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { benchmarkDuration, benchmarkIt } from \"@fluid-tools/benchmark\";\nimport type { ISummaryTree } from \"@fluidframework/driver-definitions\";\n\nimport { TestString, loadSnapshot } from \"./snapshot.utils.js\";\n\ndescribe(\"MergeTree snapshots\", () => {\n\tfor (const summarySize of [10, 50, 100, 500, 1000, 5000, 10_000]) {\n\t\tconst test = benchmarkIt({\n\t\t\ttitle: `load snapshot with ${summarySize} segments`,\n\t\t\tcategory: \"snapshot loading\",\n\t\t\t...benchmarkDuration({\n\t\t\t\tbenchmarkFnCustom: async (state) => {\n\t\t\t\t\tconst str = new TestString(\"id\", {});\n\t\t\t\t\tfor (let i = 0; i < summarySize; i++) {\n\t\t\t\t\t\tstr.append(\"a\", false);\n\t\t\t\t\t}\n\t\t\t\t\tstr.applyPendingOps();\n\t\t\t\t\tconst summary: ISummaryTree = str.getSummary();\n\t\t\t\t\tawait state.timeAllBatchesAsync(async () => {\n\t\t\t\t\t\tawait loadSnapshot(summary);\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t}),\n\t\t});\n\n\t\tif (summarySize > 5000) {\n\t\t\tconst currentTimeout = test.timeout();\n\t\t\t// Default value of 2 seconds causes failure around P95 for large snapshot sizes.\n\t\t\ttest.timeout(currentTimeout === 0 ? 0 : Math.max(5000, currentTimeout));\n\t\t}\n\t}\n});\n"]}
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { BenchmarkType, benchmark } from "@fluid-tools/benchmark";
5
+ import { BenchmarkType, benchmarkDuration, benchmarkIt } from "@fluid-tools/benchmark";
6
6
  import { AttributionCollection as NewAttributionCollection, } from "../attributionCollection.js";
7
7
  import { TextSegmentGranularity } from "../textSegment.js";
8
8
  function getCollectionSizes(ctor, baseSuiteType) {
@@ -21,73 +21,81 @@ function getCollectionSizes(ctor, baseSuiteType) {
21
21
  { name: "maximum keys", collection: maxSizeCollection, type: BenchmarkType.Diagnostic },
22
22
  ];
23
23
  }
24
- function runAttributionCollectionSuite(ctor, suiteBaseType) {
24
+ function runAttributionCollectionSuite(ctor, suiteBaseType = BenchmarkType.Measurement) {
25
25
  const collectionTestCases = getCollectionSizes(ctor, suiteBaseType);
26
26
  for (const { name, collection, type } of collectionTestCases) {
27
27
  describe(`using a collection with ${name}`, () => {
28
28
  const { length } = collection;
29
- benchmark({
29
+ benchmarkIt({
30
30
  title: "getAtOffset at the start",
31
- benchmarkFn: () => collection.getAtOffset(0),
31
+ ...benchmarkDuration({ benchmarkFn: () => collection.getAtOffset(0) }),
32
32
  type,
33
33
  });
34
- benchmark({
34
+ benchmarkIt({
35
35
  title: "getAtOffset at the end",
36
- benchmarkFn: () => collection.getAtOffset(length - 1),
36
+ ...benchmarkDuration({ benchmarkFn: () => collection.getAtOffset(length - 1) }),
37
37
  type,
38
38
  });
39
- benchmark({
39
+ benchmarkIt({
40
40
  title: "getAtOffset in the middle",
41
- benchmarkFn: () => collection.getAtOffset(length / 2),
41
+ ...benchmarkDuration({ benchmarkFn: () => collection.getAtOffset(length / 2) }),
42
42
  type: BenchmarkType.Diagnostic,
43
43
  });
44
- benchmark({
44
+ benchmarkIt({
45
45
  title: "getKeysInOffsetRange from start to end",
46
- benchmarkFn: () => collection.getKeysInOffsetRange(0),
46
+ ...benchmarkDuration({ benchmarkFn: () => collection.getKeysInOffsetRange(0) }),
47
47
  type,
48
48
  });
49
- benchmark({
49
+ benchmarkIt({
50
50
  title: "getKeysInOffsetRange from start to mid",
51
- benchmarkFn: () => collection.getKeysInOffsetRange(0, length / 2),
51
+ ...benchmarkDuration({
52
+ benchmarkFn: () => collection.getKeysInOffsetRange(0, length / 2),
53
+ }),
52
54
  type,
53
55
  });
54
- benchmark({
56
+ benchmarkIt({
55
57
  title: "getKeysInOffsetRange from mid to end",
56
- benchmarkFn: () => collection.getKeysInOffsetRange(length / 2, length - 1),
58
+ ...benchmarkDuration({
59
+ benchmarkFn: () => collection.getKeysInOffsetRange(length / 2, length - 1),
60
+ }),
57
61
  type,
58
62
  });
59
- benchmark({
63
+ benchmarkIt({
60
64
  title: "getAll",
61
- benchmarkFn: () => collection.getAll(),
65
+ ...benchmarkDuration({ benchmarkFn: () => collection.getAll() }),
62
66
  type,
63
67
  });
64
- benchmark({
68
+ benchmarkIt({
65
69
  title: "clone",
66
- benchmarkFn: () => collection.clone(),
70
+ ...benchmarkDuration({ benchmarkFn: () => collection.clone() }),
67
71
  type,
68
72
  });
69
- benchmark({
73
+ benchmarkIt({
70
74
  title: "split + append in the middle",
71
- benchmarkFn: () => {
72
- const split = collection.splitAt(length / 2);
73
- collection.append(split);
74
- },
75
+ ...benchmarkDuration({
76
+ benchmarkFn: () => {
77
+ const split = collection.splitAt(length / 2);
78
+ collection.append(split);
79
+ },
80
+ }),
75
81
  type,
76
82
  });
77
83
  });
78
84
  }
79
- benchmark({
85
+ benchmarkIt({
80
86
  title: "construction",
81
- benchmarkFn: () => new ctor(42, { type: "op", seq: 5 }),
87
+ ...benchmarkDuration({ benchmarkFn: () => new ctor(42, { type: "op", seq: 5 }) }),
82
88
  type: suiteBaseType,
83
89
  });
84
90
  const segmentsToSerialize = collectionTestCases.map(({ collection }) => ({
85
91
  attribution: collection,
86
92
  cachedLength: collection.length,
87
93
  }));
88
- benchmark({
94
+ benchmarkIt({
89
95
  title: "serializing",
90
- benchmarkFn: () => ctor.serializeAttributionCollections(segmentsToSerialize),
96
+ ...benchmarkDuration({
97
+ benchmarkFn: () => ctor.serializeAttributionCollections(segmentsToSerialize),
98
+ }),
91
99
  type: suiteBaseType,
92
100
  });
93
101
  const summary = ctor.serializeAttributionCollections(segmentsToSerialize);
@@ -97,11 +105,13 @@ function runAttributionCollectionSuite(ctor, suiteBaseType) {
97
105
  segments.push({
98
106
  cachedLength: summary.length - 9 * Math.floor(summary.length / 10),
99
107
  });
100
- benchmark({
108
+ benchmarkIt({
101
109
  title: "deserialize into 10 segments",
102
- benchmarkFn: () => {
103
- ctor.populateAttributionCollections(segments, summary);
104
- },
110
+ ...benchmarkDuration({
111
+ benchmarkFn: () => {
112
+ ctor.populateAttributionCollections(segments, summary);
113
+ },
114
+ }),
105
115
  type: suiteBaseType,
106
116
  });
107
117
  }
@@ -109,7 +119,7 @@ describe("IAttributionCollection perf", () => {
109
119
  // There was a RedBlack tree based implementation for the collection entries, but the linear array based one won due to constant
110
120
  // factors/memory characteristics, so just kept the array based one.
111
121
  describe("list-based implementation", () => {
112
- runAttributionCollectionSuite(NewAttributionCollection, BenchmarkType.Measurement);
122
+ runAttributionCollectionSuite(NewAttributionCollection);
113
123
  });
114
124
  });
115
125
  //# sourceMappingURL=attributionCollection.perf.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"attributionCollection.perf.spec.js","sourceRoot":"","sources":["../../src/test/attributionCollection.perf.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { BenchmarkType, benchmark } from \"@fluid-tools/benchmark\";\nimport type { AttributionKey } from \"@fluidframework/runtime-definitions/internal\";\n\nimport {\n\ttype IAttributionCollection,\n\tAttributionCollection as NewAttributionCollection,\n\ttype SerializedAttributionCollection,\n} from \"../attributionCollection.js\";\nimport type { ISegment } from \"../mergeTreeNodes.js\";\nimport { TextSegmentGranularity } from \"../textSegment.js\";\n\ninterface IAttributionCollectionCtor {\n\tnew (length: number, key?: AttributionKey): IAttributionCollection<AttributionKey>;\n\n\tserializeAttributionCollections(\n\t\tsegments: Iterable<{\n\t\t\tattribution?: IAttributionCollection<AttributionKey>;\n\t\t\tcachedLength: number;\n\t\t}>,\n\t): SerializedAttributionCollection;\n\n\tpopulateAttributionCollections(\n\t\tsegments: Iterable<Partial<ISegment>>,\n\t\tsummary: SerializedAttributionCollection,\n\t): void;\n}\n\nfunction getCollectionSizes(\n\tctor: IAttributionCollectionCtor,\n\tbaseSuiteType: BenchmarkType,\n): {\n\tname: string;\n\tcollection: IAttributionCollection<AttributionKey>;\n\ttype: BenchmarkType;\n}[] {\n\tconst singleKeyCollection = new ctor(5, { type: \"op\", seq: 42 });\n\tconst tenKeyCollection = new ctor(2, { type: \"op\", seq: 0 });\n\tfor (let i = 1; i < 10; i++) {\n\t\ttenKeyCollection.append(new ctor(3 * i, { type: \"op\", seq: i }));\n\t}\n\tconst maxSizeCollection = new ctor(1, { type: \"op\", seq: 0 });\n\tfor (let i = 1; i < TextSegmentGranularity; i++) {\n\t\tmaxSizeCollection.append(new ctor(1, { type: \"op\", seq: i }));\n\t}\n\treturn [\n\t\t{ name: \"one key\", collection: singleKeyCollection, type: BenchmarkType.Diagnostic },\n\t\t{ name: \"ten keys\", collection: tenKeyCollection, type: baseSuiteType },\n\t\t{ name: \"maximum keys\", collection: maxSizeCollection, type: BenchmarkType.Diagnostic },\n\t];\n}\n\nfunction runAttributionCollectionSuite(\n\tctor: IAttributionCollectionCtor,\n\tsuiteBaseType: BenchmarkType,\n): void {\n\tconst collectionTestCases = getCollectionSizes(ctor, suiteBaseType);\n\tfor (const { name, collection, type } of collectionTestCases) {\n\t\tdescribe(`using a collection with ${name}`, () => {\n\t\t\tconst { length } = collection;\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"getAtOffset at the start\",\n\t\t\t\tbenchmarkFn: () => collection.getAtOffset(0),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"getAtOffset at the end\",\n\t\t\t\tbenchmarkFn: () => collection.getAtOffset(length - 1),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"getAtOffset in the middle\",\n\t\t\t\tbenchmarkFn: () => collection.getAtOffset(length / 2),\n\t\t\t\ttype: BenchmarkType.Diagnostic,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"getKeysInOffsetRange from start to end\",\n\t\t\t\tbenchmarkFn: () => collection.getKeysInOffsetRange(0),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"getKeysInOffsetRange from start to mid\",\n\t\t\t\tbenchmarkFn: () => collection.getKeysInOffsetRange(0, length / 2),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"getKeysInOffsetRange from mid to end\",\n\t\t\t\tbenchmarkFn: () => collection.getKeysInOffsetRange(length / 2, length - 1),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"getAll\",\n\t\t\t\tbenchmarkFn: () => collection.getAll(),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"clone\",\n\t\t\t\tbenchmarkFn: () => collection.clone(),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"split + append in the middle\",\n\t\t\t\tbenchmarkFn: () => {\n\t\t\t\t\tconst split = collection.splitAt(length / 2);\n\t\t\t\t\tcollection.append(split);\n\t\t\t\t},\n\t\t\t\ttype,\n\t\t\t});\n\t\t});\n\t}\n\n\tbenchmark({\n\t\ttitle: \"construction\",\n\t\tbenchmarkFn: () => new ctor(42, { type: \"op\", seq: 5 }),\n\t\ttype: suiteBaseType,\n\t});\n\n\tconst segmentsToSerialize = collectionTestCases.map(({ collection }) => ({\n\t\tattribution: collection,\n\t\tcachedLength: collection.length,\n\t}));\n\n\tbenchmark({\n\t\ttitle: \"serializing\",\n\t\tbenchmarkFn: () => ctor.serializeAttributionCollections(segmentsToSerialize),\n\t\ttype: suiteBaseType,\n\t});\n\n\tconst summary = ctor.serializeAttributionCollections(segmentsToSerialize);\n\tconst segments: Partial<ISegment>[] = Array.from({ length: 9 }, () => ({\n\t\tcachedLength: Math.floor(summary.length / 10),\n\t})) as ISegment[];\n\tsegments.push({\n\t\tcachedLength: summary.length - 9 * Math.floor(summary.length / 10),\n\t} satisfies Partial<ISegment>);\n\tbenchmark({\n\t\ttitle: \"deserialize into 10 segments\",\n\t\tbenchmarkFn: () => {\n\t\t\tctor.populateAttributionCollections(segments, summary);\n\t\t},\n\t\ttype: suiteBaseType,\n\t});\n}\n\ndescribe(\"IAttributionCollection perf\", () => {\n\t// There was a RedBlack tree based implementation for the collection entries, but the linear array based one won due to constant\n\t// factors/memory characteristics, so just kept the array based one.\n\tdescribe(\"list-based implementation\", () => {\n\t\trunAttributionCollectionSuite(NewAttributionCollection, BenchmarkType.Measurement);\n\t});\n});\n"]}
1
+ {"version":3,"file":"attributionCollection.perf.spec.js","sourceRoot":"","sources":["../../src/test/attributionCollection.perf.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { BenchmarkType, benchmarkDuration, benchmarkIt } from \"@fluid-tools/benchmark\";\nimport type { AttributionKey } from \"@fluidframework/runtime-definitions/internal\";\n\nimport {\n\ttype IAttributionCollection,\n\tAttributionCollection as NewAttributionCollection,\n\ttype SerializedAttributionCollection,\n} from \"../attributionCollection.js\";\nimport type { ISegment } from \"../mergeTreeNodes.js\";\nimport { TextSegmentGranularity } from \"../textSegment.js\";\n\ninterface IAttributionCollectionCtor {\n\tnew (length: number, key?: AttributionKey): IAttributionCollection<AttributionKey>;\n\n\tserializeAttributionCollections(\n\t\tsegments: Iterable<{\n\t\t\tattribution?: IAttributionCollection<AttributionKey>;\n\t\t\tcachedLength: number;\n\t\t}>,\n\t): SerializedAttributionCollection;\n\n\tpopulateAttributionCollections(\n\t\tsegments: Iterable<Partial<ISegment>>,\n\t\tsummary: SerializedAttributionCollection,\n\t): void;\n}\n\nfunction getCollectionSizes(\n\tctor: IAttributionCollectionCtor,\n\tbaseSuiteType: BenchmarkType,\n): {\n\tname: string;\n\tcollection: IAttributionCollection<AttributionKey>;\n\ttype: BenchmarkType;\n}[] {\n\tconst singleKeyCollection = new ctor(5, { type: \"op\", seq: 42 });\n\tconst tenKeyCollection = new ctor(2, { type: \"op\", seq: 0 });\n\tfor (let i = 1; i < 10; i++) {\n\t\ttenKeyCollection.append(new ctor(3 * i, { type: \"op\", seq: i }));\n\t}\n\tconst maxSizeCollection = new ctor(1, { type: \"op\", seq: 0 });\n\tfor (let i = 1; i < TextSegmentGranularity; i++) {\n\t\tmaxSizeCollection.append(new ctor(1, { type: \"op\", seq: i }));\n\t}\n\treturn [\n\t\t{ name: \"one key\", collection: singleKeyCollection, type: BenchmarkType.Diagnostic },\n\t\t{ name: \"ten keys\", collection: tenKeyCollection, type: baseSuiteType },\n\t\t{ name: \"maximum keys\", collection: maxSizeCollection, type: BenchmarkType.Diagnostic },\n\t];\n}\n\nfunction runAttributionCollectionSuite(\n\tctor: IAttributionCollectionCtor,\n\tsuiteBaseType: BenchmarkType = BenchmarkType.Measurement,\n): void {\n\tconst collectionTestCases = getCollectionSizes(ctor, suiteBaseType);\n\tfor (const { name, collection, type } of collectionTestCases) {\n\t\tdescribe(`using a collection with ${name}`, () => {\n\t\t\tconst { length } = collection;\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"getAtOffset at the start\",\n\t\t\t\t...benchmarkDuration({ benchmarkFn: () => collection.getAtOffset(0) }),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"getAtOffset at the end\",\n\t\t\t\t...benchmarkDuration({ benchmarkFn: () => collection.getAtOffset(length - 1) }),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"getAtOffset in the middle\",\n\t\t\t\t...benchmarkDuration({ benchmarkFn: () => collection.getAtOffset(length / 2) }),\n\t\t\t\ttype: BenchmarkType.Diagnostic,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"getKeysInOffsetRange from start to end\",\n\t\t\t\t...benchmarkDuration({ benchmarkFn: () => collection.getKeysInOffsetRange(0) }),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"getKeysInOffsetRange from start to mid\",\n\t\t\t\t...benchmarkDuration({\n\t\t\t\t\tbenchmarkFn: () => collection.getKeysInOffsetRange(0, length / 2),\n\t\t\t\t}),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"getKeysInOffsetRange from mid to end\",\n\t\t\t\t...benchmarkDuration({\n\t\t\t\t\tbenchmarkFn: () => collection.getKeysInOffsetRange(length / 2, length - 1),\n\t\t\t\t}),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"getAll\",\n\t\t\t\t...benchmarkDuration({ benchmarkFn: () => collection.getAll() }),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"clone\",\n\t\t\t\t...benchmarkDuration({ benchmarkFn: () => collection.clone() }),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"split + append in the middle\",\n\t\t\t\t...benchmarkDuration({\n\t\t\t\t\tbenchmarkFn: () => {\n\t\t\t\t\t\tconst split = collection.splitAt(length / 2);\n\t\t\t\t\t\tcollection.append(split);\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\ttype,\n\t\t\t});\n\t\t});\n\t}\n\n\tbenchmarkIt({\n\t\ttitle: \"construction\",\n\t\t...benchmarkDuration({ benchmarkFn: () => new ctor(42, { type: \"op\", seq: 5 }) }),\n\t\ttype: suiteBaseType,\n\t});\n\n\tconst segmentsToSerialize = collectionTestCases.map(({ collection }) => ({\n\t\tattribution: collection,\n\t\tcachedLength: collection.length,\n\t}));\n\n\tbenchmarkIt({\n\t\ttitle: \"serializing\",\n\t\t...benchmarkDuration({\n\t\t\tbenchmarkFn: () => ctor.serializeAttributionCollections(segmentsToSerialize),\n\t\t}),\n\t\ttype: suiteBaseType,\n\t});\n\n\tconst summary = ctor.serializeAttributionCollections(segmentsToSerialize);\n\tconst segments: Partial<ISegment>[] = Array.from({ length: 9 }, () => ({\n\t\tcachedLength: Math.floor(summary.length / 10),\n\t})) as ISegment[];\n\tsegments.push({\n\t\tcachedLength: summary.length - 9 * Math.floor(summary.length / 10),\n\t} satisfies Partial<ISegment>);\n\tbenchmarkIt({\n\t\ttitle: \"deserialize into 10 segments\",\n\t\t...benchmarkDuration({\n\t\t\tbenchmarkFn: () => {\n\t\t\t\tctor.populateAttributionCollections(segments, summary);\n\t\t\t},\n\t\t}),\n\t\ttype: suiteBaseType,\n\t});\n}\n\ndescribe(\"IAttributionCollection perf\", () => {\n\t// There was a RedBlack tree based implementation for the collection entries, but the linear array based one won due to constant\n\t// factors/memory characteristics, so just kept the array based one.\n\tdescribe(\"list-based implementation\", () => {\n\t\trunAttributionCollectionSuite(NewAttributionCollection);\n\t});\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/merge-tree",
3
- "version": "2.93.0",
3
+ "version": "2.100.0",
4
4
  "description": "Merge tree",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -81,30 +81,30 @@
81
81
  "temp-directory": "nyc/.nyc_output"
82
82
  },
83
83
  "dependencies": {
84
- "@fluid-internal/client-utils": "~2.93.0",
85
- "@fluidframework/container-definitions": "~2.93.0",
86
- "@fluidframework/core-interfaces": "~2.93.0",
87
- "@fluidframework/core-utils": "~2.93.0",
88
- "@fluidframework/datastore-definitions": "~2.93.0",
89
- "@fluidframework/driver-definitions": "~2.93.0",
90
- "@fluidframework/runtime-definitions": "~2.93.0",
91
- "@fluidframework/runtime-utils": "~2.93.0",
92
- "@fluidframework/shared-object-base": "~2.93.0",
93
- "@fluidframework/telemetry-utils": "~2.93.0"
84
+ "@fluid-internal/client-utils": "~2.100.0",
85
+ "@fluidframework/container-definitions": "~2.100.0",
86
+ "@fluidframework/core-interfaces": "~2.100.0",
87
+ "@fluidframework/core-utils": "~2.100.0",
88
+ "@fluidframework/datastore-definitions": "~2.100.0",
89
+ "@fluidframework/driver-definitions": "~2.100.0",
90
+ "@fluidframework/runtime-definitions": "~2.100.0",
91
+ "@fluidframework/runtime-utils": "~2.100.0",
92
+ "@fluidframework/shared-object-base": "~2.100.0",
93
+ "@fluidframework/telemetry-utils": "~2.100.0"
94
94
  },
95
95
  "devDependencies": {
96
96
  "@arethetypeswrong/cli": "^0.18.2",
97
97
  "@biomejs/biome": "~2.4.5",
98
- "@fluid-internal/mocha-test-setup": "~2.93.0",
99
- "@fluid-private/stochastic-test-utils": "~2.93.0",
100
- "@fluid-private/test-pairwise-generator": "~2.93.0",
101
- "@fluid-tools/benchmark": "^0.55.0",
102
- "@fluid-tools/build-cli": "^0.64.0",
98
+ "@fluid-internal/mocha-test-setup": "~2.100.0",
99
+ "@fluid-private/stochastic-test-utils": "~2.100.0",
100
+ "@fluid-private/test-pairwise-generator": "~2.100.0",
101
+ "@fluid-tools/benchmark": "^0.58.0",
102
+ "@fluid-tools/build-cli": "^0.65.0",
103
103
  "@fluidframework/build-common": "^2.0.3",
104
- "@fluidframework/build-tools": "^0.64.0",
104
+ "@fluidframework/build-tools": "^0.65.0",
105
105
  "@fluidframework/eslint-config-fluid": "^9.0.0",
106
106
  "@fluidframework/merge-tree-previous": "npm:@fluidframework/merge-tree@2.92.0",
107
- "@fluidframework/test-runtime-utils": "~2.93.0",
107
+ "@fluidframework/test-runtime-utils": "~2.100.0",
108
108
  "@microsoft/api-extractor": "7.58.1",
109
109
  "@types/diff": "^3.5.1",
110
110
  "@types/mocha": "^10.0.10",