@fluidframework/merge-tree 2.22.0 → 2.22.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +38 -9
- package/dist/mergeTree.js.map +1 -1
- package/dist/test/obliterate.concurrent.spec.js +52 -0
- package/dist/test/obliterate.concurrent.spec.js.map +1 -1
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +38 -9
- package/lib/mergeTree.js.map +1 -1
- package/lib/test/obliterate.concurrent.spec.js +52 -0
- package/lib/test/obliterate.concurrent.spec.js.map +1 -1
- package/package.json +16 -16
- package/src/mergeTree.ts +46 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/merge-tree",
|
|
3
|
-
"version": "2.22.
|
|
3
|
+
"version": "2.22.1",
|
|
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.22.
|
|
85
|
-
"@fluidframework/container-definitions": "~2.22.
|
|
86
|
-
"@fluidframework/core-interfaces": "~2.22.
|
|
87
|
-
"@fluidframework/core-utils": "~2.22.
|
|
88
|
-
"@fluidframework/datastore-definitions": "~2.22.
|
|
89
|
-
"@fluidframework/driver-definitions": "~2.22.
|
|
90
|
-
"@fluidframework/runtime-definitions": "~2.22.
|
|
91
|
-
"@fluidframework/runtime-utils": "~2.22.
|
|
92
|
-
"@fluidframework/shared-object-base": "~2.22.
|
|
93
|
-
"@fluidframework/telemetry-utils": "~2.22.
|
|
84
|
+
"@fluid-internal/client-utils": "~2.22.1",
|
|
85
|
+
"@fluidframework/container-definitions": "~2.22.1",
|
|
86
|
+
"@fluidframework/core-interfaces": "~2.22.1",
|
|
87
|
+
"@fluidframework/core-utils": "~2.22.1",
|
|
88
|
+
"@fluidframework/datastore-definitions": "~2.22.1",
|
|
89
|
+
"@fluidframework/driver-definitions": "~2.22.1",
|
|
90
|
+
"@fluidframework/runtime-definitions": "~2.22.1",
|
|
91
|
+
"@fluidframework/runtime-utils": "~2.22.1",
|
|
92
|
+
"@fluidframework/shared-object-base": "~2.22.1",
|
|
93
|
+
"@fluidframework/telemetry-utils": "~2.22.1"
|
|
94
94
|
},
|
|
95
95
|
"devDependencies": {
|
|
96
96
|
"@arethetypeswrong/cli": "^0.17.1",
|
|
97
97
|
"@biomejs/biome": "~1.9.3",
|
|
98
|
-
"@fluid-internal/mocha-test-setup": "~2.22.
|
|
99
|
-
"@fluid-private/stochastic-test-utils": "~2.22.
|
|
100
|
-
"@fluid-private/test-pairwise-generator": "~2.22.
|
|
98
|
+
"@fluid-internal/mocha-test-setup": "~2.22.1",
|
|
99
|
+
"@fluid-private/stochastic-test-utils": "~2.22.1",
|
|
100
|
+
"@fluid-private/test-pairwise-generator": "~2.22.1",
|
|
101
101
|
"@fluid-tools/benchmark": "^0.50.0",
|
|
102
102
|
"@fluid-tools/build-cli": "^0.51.0",
|
|
103
103
|
"@fluidframework/build-common": "^2.0.3",
|
|
104
104
|
"@fluidframework/build-tools": "^0.51.0",
|
|
105
105
|
"@fluidframework/eslint-config-fluid": "^5.7.3",
|
|
106
|
-
"@fluidframework/merge-tree-previous": "npm:@fluidframework/merge-tree@2.
|
|
107
|
-
"@fluidframework/test-runtime-utils": "~2.22.
|
|
106
|
+
"@fluidframework/merge-tree-previous": "npm:@fluidframework/merge-tree@2.22.0",
|
|
107
|
+
"@fluidframework/test-runtime-utils": "~2.22.1",
|
|
108
108
|
"@microsoft/api-extractor": "7.47.8",
|
|
109
109
|
"@types/diff": "^3.5.1",
|
|
110
110
|
"@types/mocha": "^10.0.10",
|
package/src/mergeTree.ts
CHANGED
|
@@ -1611,6 +1611,8 @@ export class MergeTree {
|
|
|
1611
1611
|
let normalizedNewestSeq: number = 0;
|
|
1612
1612
|
const movedClientIds: number[] = [];
|
|
1613
1613
|
const movedSeqs: number[] = [];
|
|
1614
|
+
let newestAcked: ObliterateInfo | undefined;
|
|
1615
|
+
let oldestUnacked: ObliterateInfo | undefined;
|
|
1614
1616
|
for (const ob of this.obliterates.findOverlapping(newSegment)) {
|
|
1615
1617
|
// compute a normalized seq that takes into account local seqs
|
|
1616
1618
|
// but is still comparable to remote seqs to keep the checks below easy
|
|
@@ -1641,6 +1643,23 @@ export class MergeTree {
|
|
|
1641
1643
|
normalizedNewestSeq = normalizedObSeq;
|
|
1642
1644
|
newest = ob;
|
|
1643
1645
|
}
|
|
1646
|
+
|
|
1647
|
+
if (
|
|
1648
|
+
ob.seq !== UnassignedSequenceNumber &&
|
|
1649
|
+
(newestAcked === undefined || newestAcked.seq < ob.seq)
|
|
1650
|
+
) {
|
|
1651
|
+
newestAcked = ob;
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
if (
|
|
1655
|
+
ob.seq === UnassignedSequenceNumber &&
|
|
1656
|
+
(oldestUnacked === undefined || oldestUnacked.localSeq! > ob.localSeq!)
|
|
1657
|
+
) {
|
|
1658
|
+
// There can be one local obliterate surrounding a segment if a client repeatedly obliterates
|
|
1659
|
+
// a region (ex: in the text ABCDEFG, obliterate D, then obliterate CE, then BF). In this case,
|
|
1660
|
+
// the first one that's applied will be the one that actually removes the segment.
|
|
1661
|
+
oldestUnacked = ob;
|
|
1662
|
+
}
|
|
1644
1663
|
}
|
|
1645
1664
|
}
|
|
1646
1665
|
|
|
@@ -1649,23 +1668,41 @@ export class MergeTree {
|
|
|
1649
1668
|
// by the same client that's inserting this segment, we let them insert into this range and therefore don't
|
|
1650
1669
|
// mark it obliterated.
|
|
1651
1670
|
if (oldest && newest?.clientId !== clientId) {
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1671
|
+
let moveInfo: IMoveInfo;
|
|
1672
|
+
if (newestAcked === newest || newestAcked?.clientId !== clientId) {
|
|
1673
|
+
moveInfo = {
|
|
1674
|
+
movedClientIds,
|
|
1675
|
+
movedSeq: oldest.seq,
|
|
1676
|
+
movedSeqs,
|
|
1677
|
+
localMovedSeq: oldestUnacked?.localSeq,
|
|
1678
|
+
wasMovedOnInsert: oldest.seq !== UnassignedSequenceNumber,
|
|
1679
|
+
};
|
|
1680
|
+
} else {
|
|
1681
|
+
assert(
|
|
1682
|
+
oldestUnacked !== undefined,
|
|
1683
|
+
"Expected local obliterate to be defined if newestAcked is not equal to newest",
|
|
1684
|
+
);
|
|
1685
|
+
// There's a pending local obliterate for this range, so it will be marked as obliterated by us. However,
|
|
1686
|
+
// all other clients are under the impression that the most recent acked obliterate won the right to insert
|
|
1687
|
+
// in this range.
|
|
1688
|
+
moveInfo = {
|
|
1689
|
+
movedClientIds: [oldestUnacked.clientId],
|
|
1690
|
+
movedSeq: oldestUnacked.seq,
|
|
1691
|
+
movedSeqs: [oldestUnacked.seq],
|
|
1692
|
+
localMovedSeq: oldestUnacked.localSeq,
|
|
1693
|
+
wasMovedOnInsert: false,
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1659
1696
|
|
|
1660
1697
|
overwriteInfo(newSegment, moveInfo);
|
|
1661
1698
|
|
|
1662
1699
|
if (moveInfo.localMovedSeq !== undefined) {
|
|
1663
1700
|
assert(
|
|
1664
|
-
|
|
1701
|
+
oldestUnacked?.segmentGroup !== undefined,
|
|
1665
1702
|
0x86c /* expected segment group to exist */,
|
|
1666
1703
|
);
|
|
1667
1704
|
|
|
1668
|
-
this.addToPendingList(newSegment,
|
|
1705
|
+
this.addToPendingList(newSegment, oldestUnacked?.segmentGroup);
|
|
1669
1706
|
}
|
|
1670
1707
|
|
|
1671
1708
|
if (newSegment.parent) {
|