@fluid-experimental/tree 1.0.0 → 1.1.0-76254
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/EditLog.d.ts.map +1 -1
- package/dist/EditLog.js +4 -7
- package/dist/EditLog.js.map +1 -1
- package/dist/LogViewer.d.ts.map +1 -1
- package/dist/LogViewer.js +1 -7
- package/dist/LogViewer.js.map +1 -1
- package/dist/SharedTree.d.ts.map +1 -1
- package/dist/SharedTree.js +12 -12
- package/dist/SharedTree.js.map +1 -1
- package/dist/SharedTreeEncoder.d.ts.map +1 -1
- package/dist/SharedTreeEncoder.js +6 -12
- package/dist/SharedTreeEncoder.js.map +1 -1
- package/dist/TransactionInternal.d.ts.map +1 -1
- package/dist/TransactionInternal.js +4 -7
- package/dist/TransactionInternal.js.map +1 -1
- package/dist/id-compressor/IdCompressor.d.ts +3 -1
- package/dist/id-compressor/IdCompressor.d.ts.map +1 -1
- package/dist/id-compressor/IdCompressor.js +45 -17
- package/dist/id-compressor/IdCompressor.js.map +1 -1
- package/lib/EditLog.d.ts.map +1 -1
- package/lib/EditLog.js +4 -7
- package/lib/EditLog.js.map +1 -1
- package/lib/LogViewer.d.ts.map +1 -1
- package/lib/LogViewer.js +1 -7
- package/lib/LogViewer.js.map +1 -1
- package/lib/SharedTree.d.ts.map +1 -1
- package/lib/SharedTree.js +12 -12
- package/lib/SharedTree.js.map +1 -1
- package/lib/SharedTreeEncoder.d.ts.map +1 -1
- package/lib/SharedTreeEncoder.js +6 -12
- package/lib/SharedTreeEncoder.js.map +1 -1
- package/lib/TransactionInternal.d.ts.map +1 -1
- package/lib/TransactionInternal.js +4 -7
- package/lib/TransactionInternal.js.map +1 -1
- package/lib/id-compressor/IdCompressor.d.ts +3 -1
- package/lib/id-compressor/IdCompressor.d.ts.map +1 -1
- package/lib/id-compressor/IdCompressor.js +45 -17
- package/lib/id-compressor/IdCompressor.js.map +1 -1
- package/lib/test/MergeHealthTelemetryHeartbeat.tests.js +1 -1
- package/lib/test/MergeHealthTelemetryHeartbeat.tests.js.map +1 -1
- package/lib/test/SessionIdNormalizer.tests.js +4 -6
- package/lib/test/SessionIdNormalizer.tests.js.map +1 -1
- package/lib/test/Summary.tests.js +3 -6
- package/lib/test/Summary.tests.js.map +1 -1
- package/lib/test/utilities/SharedTreeTests.d.ts.map +1 -1
- package/lib/test/utilities/SharedTreeTests.js +33 -11
- package/lib/test/utilities/SharedTreeTests.js.map +1 -1
- package/lib/test/utilities/TestNode.d.ts.map +1 -1
- package/lib/test/utilities/TestNode.js +2 -12
- package/lib/test/utilities/TestNode.js.map +1 -1
- package/package.json +18 -18
- package/src/EditLog.ts +21 -23
- package/src/LogViewer.ts +1 -6
- package/src/SharedTree.ts +17 -16
- package/src/SharedTreeEncoder.ts +6 -17
- package/src/TransactionInternal.ts +11 -13
- package/src/id-compressor/IdCompressor.ts +46 -15
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
/* eslint-disable @typescript-eslint/restrict-plus-operands */
|
|
6
5
|
import BTree from 'sorted-btree';
|
|
7
6
|
import { assert, hasLength, assertNotUndefined, compareFiniteNumbers, compareFiniteNumbersReversed, compareMaps, compareStrings, fail, getOrCreate, setPropertyIfDefined, } from '../Common';
|
|
8
7
|
import { assertIsStableId, assertIsUuidString, isStableId } from '../UuidUtilities';
|
|
@@ -110,9 +109,10 @@ export class IdCompressor {
|
|
|
110
109
|
* this compressor will generate its own. An `AttributionId` is an `UuidString` which may be validated via
|
|
111
110
|
* {@link isUuidString} or generated via {@link generateStableId}.
|
|
112
111
|
*/
|
|
113
|
-
constructor(localSessionId, reservedIdCount, attributionId) {
|
|
112
|
+
constructor(localSessionId, reservedIdCount, attributionId, logger) {
|
|
114
113
|
this.localSessionId = localSessionId;
|
|
115
114
|
this.reservedIdCount = reservedIdCount;
|
|
115
|
+
this.logger = logger;
|
|
116
116
|
/**
|
|
117
117
|
* Trivially reach consensus on default cluster size and reserved IDs.
|
|
118
118
|
* These initial values must *NOT* change without careful consideration to compatibility.
|
|
@@ -321,7 +321,7 @@ export class IdCompressor {
|
|
|
321
321
|
* @param range - the range of session-local IDs to finalize.
|
|
322
322
|
*/
|
|
323
323
|
finalizeCreationRange(range) {
|
|
324
|
-
var _a, _b, _c, _d;
|
|
324
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
325
325
|
const { sessionId, attributionId } = range;
|
|
326
326
|
const isLocal = sessionId === this.localSessionId;
|
|
327
327
|
const session = (_a = this.sessions.get(sessionId)) !== null && _a !== void 0 ? _a : this.createSession(sessionId, attributionId);
|
|
@@ -342,6 +342,7 @@ export class IdCompressor {
|
|
|
342
342
|
// The total number of session-local IDs to finalize
|
|
343
343
|
const finalizeCount = normalizedLastFinalizedLocal - newLastFinalizedLocal;
|
|
344
344
|
assert(finalizeCount >= 1, 'Cannot finalize an empty range.');
|
|
345
|
+
let eagerFinalIdCount = 0;
|
|
345
346
|
let initialClusterCount = 0;
|
|
346
347
|
let remainingCount = finalizeCount;
|
|
347
348
|
let newBaseUuid;
|
|
@@ -352,6 +353,7 @@ export class IdCompressor {
|
|
|
352
353
|
Math.min(currentCluster.count + finalizeCount, currentCluster.capacity) -
|
|
353
354
|
1);
|
|
354
355
|
if (lastFinalInCluster > lastKnownFinal) {
|
|
356
|
+
eagerFinalIdCount = lastFinalInCluster - (lastKnownFinal + 1);
|
|
355
357
|
this.sessionIdNormalizer.addFinalIds((lastKnownFinal + 1), lastFinalInCluster, currentCluster);
|
|
356
358
|
}
|
|
357
359
|
}
|
|
@@ -367,6 +369,7 @@ export class IdCompressor {
|
|
|
367
369
|
// The cluster is full but is the last in the list of clusters.
|
|
368
370
|
// This allows it to be expanded instead of allocating a new one.
|
|
369
371
|
const expansionAmount = this.newClusterCapacity + overflow;
|
|
372
|
+
const previousCapacity = currentCluster.capacity;
|
|
370
373
|
currentCluster.capacity += expansionAmount;
|
|
371
374
|
this.nextClusterBaseFinalId = (this.nextClusterBaseFinalId + expansionAmount);
|
|
372
375
|
assert(this.nextClusterBaseFinalId < Number.MAX_SAFE_INTEGER, 'The number of allocated final IDs must not exceed the JS maximum safe integer.');
|
|
@@ -385,6 +388,13 @@ export class IdCompressor {
|
|
|
385
388
|
const lastFinalizedFinal = (currentBaseFinalId + currentCluster.count - 1);
|
|
386
389
|
const finalPivot = (lastFinalizedFinal - overflow + 1);
|
|
387
390
|
this.sessionIdNormalizer.addFinalIds(finalPivot, lastFinalizedFinal, currentCluster);
|
|
391
|
+
(_d = this.logger) === null || _d === void 0 ? void 0 : _d.sendTelemetryEvent({
|
|
392
|
+
eventName: 'IdCompressor:ClusterExpansion',
|
|
393
|
+
sessionId: this.localSessionId,
|
|
394
|
+
previousCapacity,
|
|
395
|
+
newCapacity: currentCluster.capacity,
|
|
396
|
+
overflow,
|
|
397
|
+
});
|
|
388
398
|
}
|
|
389
399
|
}
|
|
390
400
|
}
|
|
@@ -394,11 +404,19 @@ export class IdCompressor {
|
|
|
394
404
|
newBaseUuid = incrementUuid(currentCluster.baseUuid, currentCluster.capacity);
|
|
395
405
|
currentCluster.count += remainingCapacity;
|
|
396
406
|
remainingCount -= remainingCapacity;
|
|
407
|
+
(_e = this.logger) === null || _e === void 0 ? void 0 : _e.sendTelemetryEvent({
|
|
408
|
+
eventName: 'IdCompressor:OverfilledCluster',
|
|
409
|
+
sessionId: this.localSessionId,
|
|
410
|
+
});
|
|
397
411
|
}
|
|
398
412
|
}
|
|
399
413
|
else {
|
|
400
414
|
// Session has never made a cluster, form a new one with the session UUID as the baseUuid
|
|
401
415
|
newBaseUuid = session.sessionUuid;
|
|
416
|
+
(_f = this.logger) === null || _f === void 0 ? void 0 : _f.sendTelemetryEvent({
|
|
417
|
+
eventName: 'IdCompressor:FirstCluster',
|
|
418
|
+
sessionId: this.localSessionId,
|
|
419
|
+
});
|
|
402
420
|
}
|
|
403
421
|
// Finalizing a range results in one of three cases:
|
|
404
422
|
// 1. All local IDs are finalized into a new cluster (because there was either never a cluster for that session, or the current
|
|
@@ -419,15 +437,22 @@ export class IdCompressor {
|
|
|
419
437
|
fail('Cluster must be filled before another is allocated.');
|
|
420
438
|
}
|
|
421
439
|
newBaseFinalId = this.nextClusterBaseFinalId;
|
|
440
|
+
const newCapacity = Math.max(this.newClusterCapacity, remainingCount);
|
|
422
441
|
newCluster = {
|
|
423
442
|
baseUuid: newBaseUuid,
|
|
424
|
-
capacity:
|
|
443
|
+
capacity: newCapacity,
|
|
425
444
|
count: remainingCount,
|
|
426
445
|
session,
|
|
427
446
|
};
|
|
428
447
|
const usedCapacity = finalizeCount - remainingCount;
|
|
429
448
|
localIdPivot = (newFirstFinalizedLocal - usedCapacity);
|
|
430
449
|
if (isLocal) {
|
|
450
|
+
(_g = this.logger) === null || _g === void 0 ? void 0 : _g.sendTelemetryEvent({
|
|
451
|
+
eventName: 'IdCompressor:NewCluster',
|
|
452
|
+
sessionId: this.localSessionId,
|
|
453
|
+
clusterCapacity: newCapacity,
|
|
454
|
+
clusterCount: remainingCount,
|
|
455
|
+
});
|
|
431
456
|
const lastFinalizedFinal = (newBaseFinalId + newCluster.count - 1);
|
|
432
457
|
this.sessionIdNormalizer.addFinalIds(newBaseFinalId, lastFinalizedFinal, newCluster);
|
|
433
458
|
}
|
|
@@ -467,7 +492,7 @@ export class IdCompressor {
|
|
|
467
492
|
(normalizedLastFinalizedLocal - overriddenLocal) -
|
|
468
493
|
1);
|
|
469
494
|
}
|
|
470
|
-
(
|
|
495
|
+
(_h = cluster.overrides) !== null && _h !== void 0 ? _h : (cluster.overrides = new Map());
|
|
471
496
|
const inversionKey = IdCompressor.createInversionKey(override);
|
|
472
497
|
const existingIds = this.getExistingIdsForNewOverride(inversionKey, true);
|
|
473
498
|
let overrideForCluster;
|
|
@@ -533,6 +558,15 @@ export class IdCompressor {
|
|
|
533
558
|
}
|
|
534
559
|
}
|
|
535
560
|
}
|
|
561
|
+
if (isLocal) {
|
|
562
|
+
(_j = this.logger) === null || _j === void 0 ? void 0 : _j.sendTelemetryEvent({
|
|
563
|
+
eventName: 'IdCompressor:IdCompressorStatus',
|
|
564
|
+
eagerFinalIdCount,
|
|
565
|
+
localIdCount: remainingCount,
|
|
566
|
+
overridesCount: (_k = overrides === null || overrides === void 0 ? void 0 : overrides.length) !== null && _k !== void 0 ? _k : 0,
|
|
567
|
+
sessionId: this.localSessionId,
|
|
568
|
+
});
|
|
569
|
+
}
|
|
536
570
|
session.lastFinalizedLocalId = newLastFinalizedLocal;
|
|
537
571
|
}
|
|
538
572
|
checkClusterForCollision(cluster) {
|
|
@@ -750,12 +784,9 @@ export class IdCompressor {
|
|
|
750
784
|
// `localOverrides`s. Otherwise, it is a sequential allocation from the session UUID and can simply be negated and
|
|
751
785
|
// added to that UUID to obtain the stable ID associated with it.
|
|
752
786
|
const localOverride = (_a = this.localOverrides) === null || _a === void 0 ? void 0 : _a.get(id);
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
else {
|
|
757
|
-
return stableIdFromNumericUuid(this.localSession.sessionUuid, idOffset - 1);
|
|
758
|
-
}
|
|
787
|
+
return localOverride !== undefined
|
|
788
|
+
? localOverride
|
|
789
|
+
: stableIdFromNumericUuid(this.localSession.sessionUuid, idOffset - 1);
|
|
759
790
|
}
|
|
760
791
|
}
|
|
761
792
|
/**
|
|
@@ -789,12 +820,9 @@ export class IdCompressor {
|
|
|
789
820
|
const [key, compressionMapping] = closestMatch;
|
|
790
821
|
if (!IdCompressor.isClusterInfo(compressionMapping)) {
|
|
791
822
|
if (key === inversionKey) {
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
else {
|
|
796
|
-
return ((_a = compressionMapping.associatedLocalId) !== null && _a !== void 0 ? _a : compressionMapping.originalOverridingFinal);
|
|
797
|
-
}
|
|
823
|
+
return IdCompressor.isUnfinalizedOverride(compressionMapping)
|
|
824
|
+
? compressionMapping
|
|
825
|
+
: (_a = compressionMapping.associatedLocalId) !== null && _a !== void 0 ? _a : compressionMapping.originalOverridingFinal;
|
|
798
826
|
}
|
|
799
827
|
}
|
|
800
828
|
else {
|