@@ -239,30 +239,30 @@ export class PartialSequenceLengths {
239
239
*
240
240
* As per doc comment on {@link PartialSequenceLengths}, the overall adjustment performed for the perspective of
241
241
* (clientId, refSeq) is given by the sum of length deltas in `perClientAdjustments[clientId]`
242
- * for all sequence numbers S such that S >= refSeq.
242
+ * for all sequence numbers S such that S \ >= refSeq.
243
243
*
244
244
* (since these are ordered by sequence number and we cache cumulative sums, this is implemented using two lookups and a subtraction).
245
245
*
246
246
* The specific adjustments that are made roughly categorize as follows:
247
247
*
248
248
* - Ops submitted by a given client generally receive a partial lengths entry corresponding to their sequence number.
249
- * e.g. insert of "ABC" at seq 5 will have a per-client adjustment entry of { seq: 5, seglen: 3 }.
249
+ * e.g. insert of "ABC" at seq 5 will have a per-client adjustment entry of \ { seq: 5, seglen: 3 \ }.
250
250
*
251
251
* - When client A deletes a segment concurrently with client B and loses the race (B's delete is sequenced first),
252
- * A's per-client adjustments will contain an entry with a negative `seglen` corresponding to the length of the segment
253
- * and a sequence number corresponding to that of B's delete. It will *not* receive a per-client adjustment for its own delete.
254
- * This ensures that for perspectives (A, refSeq), the deleted segment will show up as a negative delta for all values of refSeq, since:
255
- * - For refSeq < B's delete, the per-client adjustment will apply and be added to the total length
256
- * - For refSeq >= B's delete, B's partial length entry in the overall set will apply, and the per-client adjustment will not apply
252
+ * A's per-client adjustments will contain an entry with a negative `seglen` corresponding to the length of the segment
253
+ * and a sequence number corresponding to that of B's delete. It will *not* receive a per-client adjustment for its own delete.
254
+ * This ensures that for perspectives (A, refSeq), the deleted segment will show up as a negative delta for all values of refSeq, since:
255
+ * 1. For refSeq \ < B's delete, the per-client adjustment will apply and be added to the total length
256
+ * 2. For refSeq \ >= B's delete, B's partial length entry in the overall set will apply, and the per-client adjustment will not apply
257
257
*
258
258
* - When client A attempts to insert a segment into a location that is concurrently obliterated by client B immediately upon insertion,
259
- * A's per-client adjustments will again not include an entry for its own insert.
260
- * Instead, the entry which would normally contain `seq` equal to that of A's insert would instead have `seq` equal to that of B's obliterate.
261
- * This gives the overall correct behavior: for any perspective which isn't client A, there is no adjustment necessary anywhere (it's as if
262
- * the segment never existed). For client A's perspective, the segment should be considered visible until A has acked B's obliterate.
263
- * This is accomplished as for the perspective (A, refSeq):
264
- * - For refSeq < B's obliterate, the segment length will be included as part of the per-client adjustment for A
265
- * - For refSeq >= B's obliterate, the segment will be omitted from the per-client adjustment for A
259
+ * A's per-client adjustments will again not include an entry for its own insert.
260
+ * Instead, the entry which would normally contain `seq` equal to that of A's insert would instead have `seq` equal to that of B's obliterate.
261
+ * This gives the overall correct behavior: for any perspective which isn't client A, there is no adjustment necessary anywhere (it's as if
262
+ * the segment never existed). For client A's perspective, the segment should be considered visible until A has acked B's obliterate.
263
+ * This is accomplished as for the perspective (A, refSeq):
264
+ * 1. For refSeq \ < B's obliterate, the segment length will be included as part of the per-client adjustment for A
265
+ * 2. For refSeq \ >= B's obliterate, the segment will be omitted from the per-client adjustment for A
266
266
*
267
267
* Note that the special-casing for inserting segments that are immediately obliterated is only necessary for segments that never were visible
268
268
* in the tree. If an insert and obliterate are concurrent but the insert is sequenced first, the normal per-client adjustment is fine.
@@ -463,16 +463,7 @@ export class PartialSequenceLengths {
463
463
}
464
464
}
465
465
466
- // TODO: Consider putting the overall length post-process bit back, but for now this should be handled
467
- // by addOrUpdate
468
- try {
469
- PartialSequenceLengths . options . verifier ?.( combinedPartialLengths ) ;
470
- } catch ( err ) {
471
- if ( retry ) {
472
- this . fromLeaves ( block , collabWindow , computeLocalPartials , false ) ;
473
- }
474
- throw err ;
475
- }
466
+ PartialSequenceLengths . options . verifier ?.( combinedPartialLengths ) ;
476
467
return combinedPartialLengths ;
477
468
}
478
469
@@ -506,16 +497,18 @@ export class PartialSequenceLengths {
506
497
// Implication -> this is a local segment which will be obliterated as soon as it is acked.
507
498
// For refSeqs preceding that movedSeq and localSeqs following the localSeq, it will be visible.
508
499
// For the rest, it will not be visible.
500
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
501
+ const localSeq = segment . localSeq ! ;
509
502
partials . addOrUpdate ( {
510
- seq : segment . localSeq ! ,
503
+ seq : localSeq ,
511
504
len : 0 ,
512
505
seglen : segment . cachedLength ,
513
506
clientId,
514
507
} ) ;
515
508
516
509
combinedPartialLengths . addLocalAdjustment ( {
517
510
refSeq : moveInfo . movedSeq ,
518
- localSeq : segment . localSeq ! ,
511
+ localSeq,
519
512
seglen : - segment . cachedLength ,
520
513
} ) ;
521
514
} else {
@@ -850,18 +843,15 @@ export class PartialSequenceLengths {
850
843
}
851
844
segCount += branchPartialLengths . segmentCount ;
852
845
853
- // I kinda like the sparse loop, but Number.parseInt it forces is pretty ugly.
854
- for ( const clientId in branchPartialLengths . perClientAdjustments ) {
855
- const clientAdjustments = branchPartialLengths . perClientAdjustments [ clientId ] ;
856
- if ( clientAdjustments === undefined ) {
857
- continue ;
858
- }
859
-
860
- const leqPartial = clientAdjustments . latestLeq ( seq ) ;
861
- if ( leqPartial && leqPartial . seq === seq ) {
862
- this . addClientSeqNumber ( Number . parseInt ( clientId ) , seq , leqPartial . seglen ) ;
846
+ // The suggested for..of alternative doesn't give easy access to the index while
847
+ // exploiting sparseness.
848
+ // eslint-disable-next-line unicorn/no-array-for-each
849
+ branchPartialLengths . perClientAdjustments . forEach ( ( clientAdjustments , id ) => {
850
+ const leqBranchPartial = clientAdjustments . latestLeq ( seq ) ;
851
+ if ( leqBranchPartial && leqBranchPartial . seq === seq ) {
852
+ this . addClientSeqNumber ( id , seq , leqBranchPartial . seglen ) ;
863
853
}
864
- }
854
+ } ) ;
865
855
}
866
856
}
867
857
@@ -1041,7 +1031,7 @@ export class PartialSequenceLengths {
1041
1031
}
1042
1032
1043
1033
/**
1044
- * @returns The partial lengths associated with the latest change associated with `clientId` at or before `refSeq`.
1034
+ * Returns the partial lengths associated with the latest change associated with `clientId` at or before `refSeq`.
1045
1035
* Returns undefined if no such change exists.
1046
1036
*/
1047
1037
private latestClientEntryLEQ (
@@ -1052,7 +1042,7 @@ export class PartialSequenceLengths {
1052
1042
}
1053
1043
1054
1044
/**
1055
- * @returns The partial lengths associated with the most recent change received by `clientId`, or undefined
1045
+ * Get the partial lengths associated with the most recent change received by `clientId`, or undefined
1056
1046
* if this client has made no changes in this block within the collab window.
1057
1047
*/
1058
1048
private latestClientEntry ( clientId : number ) : PartialSequenceLength | undefined {
0 commit comments