@calcit/ternary-tree 0.0.23 → 0.0.25

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/lib/list.mjs CHANGED
@@ -41,7 +41,7 @@ export function makeTernaryTreeList(size, offset, xs) {
41
41
  let middle = xs[offset + 1];
42
42
  let result = {
43
43
  kind: TernaryTreeKind.ternaryTreeBranch,
44
- size: listLen(left) + listLen(middle),
44
+ size: left.size + middle.size,
45
45
  left: left,
46
46
  middle: middle,
47
47
  right: emptyBranch,
@@ -56,7 +56,7 @@ export function makeTernaryTreeList(size, offset, xs) {
56
56
  let right = xs[offset + 2];
57
57
  let result = {
58
58
  kind: TernaryTreeKind.ternaryTreeBranch,
59
- size: listLen(left) + listLen(middle) + listLen(right),
59
+ size: left.size + middle.size + right.size,
60
60
  left: left,
61
61
  middle: middle,
62
62
  right: right,
@@ -72,7 +72,7 @@ export function makeTernaryTreeList(size, offset, xs) {
72
72
  let right = makeTernaryTreeList(divided.right, offset + divided.left + divided.middle, xs);
73
73
  let result = {
74
74
  kind: TernaryTreeKind.ternaryTreeBranch,
75
- size: listLen(left) + listLen(middle) + listLen(right),
75
+ size: left.size + middle.size + right.size,
76
76
  depth: decideParentDepth(left, middle, right),
77
77
  left: left,
78
78
  middle: middle,
@@ -84,22 +84,22 @@ export function makeTernaryTreeList(size, offset, xs) {
84
84
  }
85
85
  }
86
86
  export function initTernaryTreeList(xs) {
87
- let ys = new Array(xs.length);
88
- let size = xs.length;
87
+ const size = xs.length;
88
+ let ys = new Array(size);
89
+ // Use cached size instead of accessing xs.length repeatedly
89
90
  for (let idx = 0; idx < size; idx++) {
90
- let x = xs[idx];
91
- ys[idx] = { kind: TernaryTreeKind.ternaryTreeLeaf, size: 1, value: x };
91
+ ys[idx] = { kind: TernaryTreeKind.ternaryTreeLeaf, size: 1, value: xs[idx] };
92
92
  }
93
- return makeTernaryTreeList(xs.length, 0, ys);
93
+ return makeTernaryTreeList(size, 0, ys);
94
94
  }
95
95
  // from a slice of an existed array
96
96
  export function initTernaryTreeListFromRange(xs, from, to) {
97
- let ys = new Array(to - from);
98
- for (let idx = from; idx < to; idx++) {
99
- let x = xs[idx];
100
- ys[idx - from] = { kind: TernaryTreeKind.ternaryTreeLeaf, size: 1, value: x };
97
+ const length = to - from;
98
+ let ys = new Array(length);
99
+ for (let idx = 0; idx < length; idx++) {
100
+ ys[idx] = { kind: TernaryTreeKind.ternaryTreeLeaf, size: 1, value: xs[idx + from] };
101
101
  }
102
- return makeTernaryTreeList(ys.length, 0, ys);
102
+ return makeTernaryTreeList(length, 0, ys);
103
103
  }
104
104
  export function initEmptyTernaryTreeList() {
105
105
  return { kind: TernaryTreeKind.ternaryTreeBranch, size: 0, depth: 1, middle: emptyBranch, left: emptyBranch, right: emptyBranch };
@@ -141,18 +141,22 @@ export function* listToItems(tree) {
141
141
  break;
142
142
  }
143
143
  case TernaryTreeKind.ternaryTreeBranch: {
144
- if (tree.left != null) {
145
- for (let x of listToItems(tree.left)) {
144
+ // Cache children to avoid repeated property access
145
+ const left = tree.left;
146
+ const middle = tree.middle;
147
+ const right = tree.right;
148
+ if (left != null) {
149
+ for (let x of listToItems(left)) {
146
150
  yield x;
147
151
  }
148
152
  }
149
- if (tree.middle != null) {
150
- for (let x of listToItems(tree.middle)) {
153
+ if (middle != null) {
154
+ for (let x of listToItems(middle)) {
151
155
  yield x;
152
156
  }
153
157
  }
154
- if (tree.right != null) {
155
- for (let x of listToItems(tree.right)) {
158
+ if (right != null) {
159
+ for (let x of listToItems(right)) {
156
160
  yield x;
157
161
  }
158
162
  }
@@ -176,17 +180,21 @@ export function findIndex(tree, f) {
176
180
  }
177
181
  }
178
182
  case TernaryTreeKind.ternaryTreeBranch: {
179
- let tryLeft = findIndex(tree.left, f);
183
+ // Cache children to avoid repeated property access
184
+ const left = tree.left;
185
+ const middle = tree.middle;
186
+ const right = tree.right;
187
+ let tryLeft = findIndex(left, f);
180
188
  if (tryLeft >= 0) {
181
189
  return tryLeft;
182
190
  }
183
- let tryMiddle = findIndex(tree.middle, f);
191
+ let tryMiddle = findIndex(middle, f);
184
192
  if (tryMiddle >= 0) {
185
- return tryMiddle + listLen(tree.left);
193
+ return tryMiddle + (left == null ? 0 : left.size);
186
194
  }
187
- let tryRight = findIndex(tree.right, f);
195
+ let tryRight = findIndex(right, f);
188
196
  if (tryRight >= 0) {
189
- return tryRight + listLen(tree.left) + listLen(tree.middle);
197
+ return tryRight + (left == null ? 0 : left.size) + (middle == null ? 0 : middle.size);
190
198
  }
191
199
  return -1;
192
200
  }
@@ -205,17 +213,21 @@ export function indexOf(tree, item) {
205
213
  default:
206
214
  return -1;
207
215
  case TernaryTreeKind.ternaryTreeBranch:
208
- let tryLeft = indexOf(tree.left, item);
216
+ // Cache children to avoid repeated property access
217
+ const left = tree.left;
218
+ const middle = tree.middle;
219
+ const right = tree.right;
220
+ let tryLeft = indexOf(left, item);
209
221
  if (tryLeft >= 0) {
210
222
  return tryLeft;
211
223
  }
212
- let tryMiddle = indexOf(tree.middle, item);
224
+ let tryMiddle = indexOf(middle, item);
213
225
  if (tryMiddle >= 0) {
214
- return tryMiddle + listLen(tree.left);
226
+ return tryMiddle + (left == null ? 0 : left.size);
215
227
  }
216
- let tryRight = indexOf(tree.right, item);
228
+ let tryRight = indexOf(right, item);
217
229
  if (tryRight >= 0) {
218
- return tryRight + listLen(tree.left) + listLen(tree.middle);
230
+ return tryRight + (left == null ? 0 : left.size) + (middle == null ? 0 : middle.size);
219
231
  }
220
232
  return -1;
221
233
  }
@@ -227,25 +239,28 @@ function writeLeavesArray(tree, acc, idx) {
227
239
  else {
228
240
  switch (tree.kind) {
229
241
  case TernaryTreeKind.ternaryTreeLeaf: {
230
- acc[idx.value] = tree;
231
- idx.value = idx.value + 1;
242
+ // Cache current index to reduce property access
243
+ const currentIdx = idx.value;
244
+ acc[currentIdx] = tree;
245
+ idx.value = currentIdx + 1;
232
246
  break;
233
247
  }
234
248
  case TernaryTreeKind.ternaryTreeBranch: {
235
- if (tree.left != null) {
236
- writeLeavesArray(tree.left, acc, idx);
249
+ // Cache children to avoid repeated property access
250
+ const left = tree.left;
251
+ const middle = tree.middle;
252
+ const right = tree.right;
253
+ if (left != null) {
254
+ writeLeavesArray(left, acc, idx);
237
255
  }
238
- if (tree.middle != null) {
239
- writeLeavesArray(tree.middle, acc, idx);
256
+ if (middle != null) {
257
+ writeLeavesArray(middle, acc, idx);
240
258
  }
241
- if (tree.right != null) {
242
- writeLeavesArray(tree.right, acc, idx);
259
+ if (right != null) {
260
+ writeLeavesArray(right, acc, idx);
243
261
  }
244
262
  break;
245
263
  }
246
- default: {
247
- throw new Error("Unknown");
248
- }
249
264
  }
250
265
  }
251
266
  }
@@ -285,17 +300,21 @@ export function listGet(originalTree, originalIdx) {
285
300
  if (idx > tree.size - 1) {
286
301
  throw new Error("Index too large");
287
302
  }
288
- let leftSize = tree.left == null ? 0 : tree.left.size;
289
- let middleSize = tree.middle == null ? 0 : tree.middle.size;
290
- let rightSize = tree.right == null ? 0 : tree.right.size;
303
+ // Cache child sizes to avoid repeated property access
304
+ const left = tree.left;
305
+ const middle = tree.middle;
306
+ const right = tree.right;
307
+ const leftSize = left == null ? 0 : left.size;
308
+ const middleSize = middle == null ? 0 : middle.size;
309
+ const rightSize = right == null ? 0 : right.size;
291
310
  if (leftSize + middleSize + rightSize !== tree.size) {
292
311
  throw new Error("tree.size does not match sum case branch sizes");
293
312
  }
294
313
  if (idx <= leftSize - 1) {
295
- tree = tree.left;
314
+ tree = left;
296
315
  }
297
316
  else if (idx <= leftSize + middleSize - 1) {
298
- tree = tree.middle;
317
+ tree = middle;
299
318
  idx = idx - leftSize;
300
319
  }
301
320
  else {
@@ -336,45 +355,49 @@ export function assocList(tree, idx, item) {
336
355
  throw new Error(`Cannot get from leaf with index ${idx}`);
337
356
  }
338
357
  }
339
- let leftSize = listLen(tree.left);
340
- let middleSize = listLen(tree.middle);
341
- let rightSize = listLen(tree.right);
358
+ // Cache children and their sizes to avoid repeated property access
359
+ const left = tree.left;
360
+ const middle = tree.middle;
361
+ const right = tree.right;
362
+ const leftSize = left == null ? 0 : left.size;
363
+ const middleSize = middle == null ? 0 : middle.size;
364
+ const rightSize = right == null ? 0 : right.size;
342
365
  if (leftSize + middleSize + rightSize !== tree.size)
343
366
  throw new Error("tree.size does not match sum case branch sizes");
344
367
  if (idx <= leftSize - 1) {
345
- let changedBranch = assocList(tree.left, idx, item);
368
+ let changedBranch = assocList(left, idx, item);
346
369
  let result = {
347
370
  kind: TernaryTreeKind.ternaryTreeBranch,
348
371
  size: tree.size,
349
- depth: decideParentDepth(changedBranch, tree.middle, tree.right),
372
+ depth: decideParentDepth(changedBranch, middle, right),
350
373
  left: changedBranch,
351
- middle: tree.middle,
352
- right: tree.right,
374
+ middle: middle,
375
+ right: right,
353
376
  };
354
377
  checkListStructure(result);
355
378
  return result;
356
379
  }
357
380
  else if (idx <= leftSize + middleSize - 1) {
358
- let changedBranch = assocList(tree.middle, idx - leftSize, item);
381
+ let changedBranch = assocList(middle, idx - leftSize, item);
359
382
  let result = {
360
383
  kind: TernaryTreeKind.ternaryTreeBranch,
361
384
  size: tree.size,
362
- depth: decideParentDepth(tree.left, changedBranch, tree.right),
363
- left: tree.left,
385
+ depth: decideParentDepth(left, changedBranch, right),
386
+ left: left,
364
387
  middle: changedBranch,
365
- right: tree.right,
388
+ right: right,
366
389
  };
367
390
  checkListStructure(result);
368
391
  return result;
369
392
  }
370
393
  else {
371
- let changedBranch = assocList(tree.right, idx - leftSize - middleSize, item);
394
+ let changedBranch = assocList(right, idx - leftSize - middleSize, item);
372
395
  let result = {
373
396
  kind: TernaryTreeKind.ternaryTreeBranch,
374
397
  size: tree.size,
375
- depth: decideParentDepth(tree.left, tree.middle, changedBranch),
376
- left: tree.left,
377
- middle: tree.middle,
398
+ depth: decideParentDepth(left, middle, changedBranch),
399
+ left: left,
400
+ middle: middle,
378
401
  right: changedBranch,
379
402
  };
380
403
  checkListStructure(result);
@@ -400,22 +423,26 @@ export function dissocList(tree, idx) {
400
423
  if (tree.kind === TernaryTreeKind.ternaryTreeLeaf) {
401
424
  throw new Error("dissoc should be handled at branches");
402
425
  }
403
- let leftSize = listLen(tree.left);
404
- let middleSize = listLen(tree.middle);
405
- let rightSize = listLen(tree.right);
426
+ // Cache children and their sizes to avoid repeated property access
427
+ const left = tree.left;
428
+ const middle = tree.middle;
429
+ const right = tree.right;
430
+ const leftSize = left == null ? 0 : left.size;
431
+ const middleSize = middle == null ? 0 : middle.size;
432
+ const rightSize = right == null ? 0 : right.size;
406
433
  if (leftSize + middleSize + rightSize !== tree.size) {
407
434
  throw new Error("tree.size does not match sum from branch sizes");
408
435
  }
409
436
  let result = emptyBranch;
410
437
  if (idx <= leftSize - 1) {
411
- let changedBranch = dissocList(tree.left, idx);
438
+ let changedBranch = dissocList(left, idx);
412
439
  if (changedBranch == null || changedBranch.size === 0) {
413
440
  result = {
414
441
  kind: TernaryTreeKind.ternaryTreeBranch,
415
442
  size: tree.size - 1,
416
- depth: decideParentDepth(tree.middle, tree.right),
417
- left: tree.middle,
418
- middle: tree.right,
443
+ depth: decideParentDepth(middle, right),
444
+ left: middle,
445
+ middle: right,
419
446
  right: emptyBranch,
420
447
  };
421
448
  }
@@ -423,22 +450,22 @@ export function dissocList(tree, idx) {
423
450
  result = {
424
451
  kind: TernaryTreeKind.ternaryTreeBranch,
425
452
  size: tree.size - 1,
426
- depth: decideParentDepth(changedBranch, tree.middle, tree.right),
453
+ depth: decideParentDepth(changedBranch, middle, right),
427
454
  left: changedBranch,
428
- middle: tree.middle,
429
- right: tree.right,
455
+ middle: middle,
456
+ right: right,
430
457
  };
431
458
  }
432
459
  }
433
460
  else if (idx <= leftSize + middleSize - 1) {
434
- let changedBranch = dissocList(tree.middle, idx - leftSize);
461
+ let changedBranch = dissocList(middle, idx - leftSize);
435
462
  if (changedBranch == null || changedBranch.size === 0) {
436
463
  result = {
437
464
  kind: TernaryTreeKind.ternaryTreeBranch,
438
465
  size: tree.size - 1,
439
- depth: decideParentDepth(tree.left, changedBranch, tree.right),
440
- left: tree.left,
441
- middle: tree.right,
466
+ depth: decideParentDepth(left, changedBranch, right),
467
+ left: left,
468
+ middle: right,
442
469
  right: emptyBranch,
443
470
  };
444
471
  }
@@ -446,24 +473,24 @@ export function dissocList(tree, idx) {
446
473
  result = {
447
474
  kind: TernaryTreeKind.ternaryTreeBranch,
448
475
  size: tree.size - 1,
449
- depth: decideParentDepth(tree.left, changedBranch, tree.right),
450
- left: tree.left,
476
+ depth: decideParentDepth(left, changedBranch, right),
477
+ left: left,
451
478
  middle: changedBranch,
452
- right: tree.right,
479
+ right: right,
453
480
  };
454
481
  }
455
482
  }
456
483
  else {
457
- let changedBranch = dissocList(tree.right, idx - leftSize - middleSize);
484
+ let changedBranch = dissocList(right, idx - leftSize - middleSize);
458
485
  if (changedBranch == null || changedBranch.size === 0) {
459
486
  changedBranch = emptyBranch;
460
487
  }
461
488
  result = {
462
489
  kind: TernaryTreeKind.ternaryTreeBranch,
463
490
  size: tree.size - 1,
464
- depth: decideParentDepth(tree.left, tree.middle, changedBranch),
465
- left: tree.left,
466
- middle: tree.middle,
491
+ depth: decideParentDepth(left, middle, changedBranch),
492
+ left: left,
493
+ middle: middle,
467
494
  right: changedBranch,
468
495
  };
469
496
  }
@@ -612,15 +639,19 @@ export function insert(tree, idx, item, after = false) {
612
639
  }
613
640
  }
614
641
  }
615
- let leftSize = listLen(tree.left);
616
- let middleSize = listLen(tree.middle);
617
- let rightSize = listLen(tree.right);
642
+ // Cache children and their sizes to avoid repeated property access
643
+ const left = tree.left;
644
+ const middle = tree.middle;
645
+ const right = tree.right;
646
+ const leftSize = left == null ? 0 : left.size;
647
+ const middleSize = middle == null ? 0 : middle.size;
648
+ const rightSize = right == null ? 0 : right.size;
618
649
  if (leftSize + middleSize + rightSize !== tree.size) {
619
650
  throw new Error("tree.size does not match sum case branch sizes");
620
651
  }
621
652
  // echo "picking: ", idx, " ", leftSize, " ", middleSize, " ", rightSize
622
653
  if (idx === 0 && !after) {
623
- if (listLen(tree.left) >= listLen(tree.middle) && listLen(tree.left) >= listLen(tree.right)) {
654
+ if (leftSize >= middleSize && leftSize >= rightSize) {
624
655
  let result = {
625
656
  kind: TernaryTreeKind.ternaryTreeBranch,
626
657
  size: tree.size + 1,
@@ -634,7 +665,7 @@ export function insert(tree, idx, item, after = false) {
634
665
  }
635
666
  }
636
667
  if (idx === listLen(tree) - 1 && after) {
637
- if (listLen(tree.right) >= listLen(tree.middle) && listLen(tree.right) >= listLen(tree.left)) {
668
+ if (rightSize >= middleSize && rightSize >= leftSize) {
638
669
  let result = {
639
670
  kind: TernaryTreeKind.ternaryTreeBranch,
640
671
  size: tree.size + 1,
@@ -665,46 +696,46 @@ export function insert(tree, idx, item, after = false) {
665
696
  size: tree.size + 1,
666
697
  depth: tree.depth,
667
698
  left: { kind: TernaryTreeKind.ternaryTreeLeaf, size: 1, value: item },
668
- middle: tree.left,
669
- right: tree.middle,
699
+ middle: left,
700
+ right: middle,
670
701
  };
671
702
  checkListStructure(result);
672
703
  return result;
673
704
  }
674
705
  if (idx <= leftSize - 1) {
675
- let changedBranch = insert(tree.left, idx, item, after);
706
+ let changedBranch = insert(left, idx, item, after);
676
707
  let result = {
677
708
  kind: TernaryTreeKind.ternaryTreeBranch,
678
709
  size: tree.size + 1,
679
- depth: decideParentDepth(changedBranch, tree.middle, tree.right),
710
+ depth: decideParentDepth(changedBranch, middle, right),
680
711
  left: changedBranch,
681
- middle: tree.middle,
682
- right: tree.right,
712
+ middle: middle,
713
+ right: right,
683
714
  };
684
715
  checkListStructure(result);
685
716
  return result;
686
717
  }
687
718
  else if (idx <= leftSize + middleSize - 1) {
688
- let changedBranch = insert(tree.middle, idx - leftSize, item, after);
719
+ let changedBranch = insert(middle, idx - leftSize, item, after);
689
720
  let result = {
690
721
  kind: TernaryTreeKind.ternaryTreeBranch,
691
722
  size: tree.size + 1,
692
- depth: decideParentDepth(tree.left, changedBranch, tree.right),
693
- left: tree.left,
723
+ depth: decideParentDepth(left, changedBranch, right),
724
+ left: left,
694
725
  middle: changedBranch,
695
- right: tree.right,
726
+ right: right,
696
727
  };
697
728
  checkListStructure(result);
698
729
  return result;
699
730
  }
700
731
  else {
701
- let changedBranch = insert(tree.right, idx - leftSize - middleSize, item, after);
732
+ let changedBranch = insert(right, idx - leftSize - middleSize, item, after);
702
733
  let result = {
703
734
  kind: TernaryTreeKind.ternaryTreeBranch,
704
735
  size: tree.size + 1,
705
- depth: decideParentDepth(tree.left, tree.middle, changedBranch),
706
- left: tree.left,
707
- middle: tree.middle,
736
+ depth: decideParentDepth(left, middle, changedBranch),
737
+ left: left,
738
+ middle: middle,
708
739
  right: changedBranch,
709
740
  };
710
741
  checkListStructure(result);
@@ -879,7 +910,15 @@ export function listEqual(xs, ys) {
879
910
  }
880
911
  return true;
881
912
  }
913
+ var skipListStructureCheck = false;
914
+ /** in some cases we disable for performance */
915
+ export let disableListStructureCheck = () => {
916
+ skipListStructureCheck = true;
917
+ };
882
918
  export function checkListStructure(tree) {
919
+ if (skipListStructureCheck) {
920
+ return true;
921
+ }
883
922
  if (tree == null || listLen(tree) === 0) {
884
923
  return true;
885
924
  }
@@ -894,22 +933,29 @@ export function checkListStructure(tree) {
894
933
  if (tree.size >= 6 && tree.depth >= tree.size) {
895
934
  throw new Error(`Bad depth at branch ${formatListInline(tree)}`);
896
935
  }
897
- if (tree.size !== listLen(tree.left) + listLen(tree.middle) + listLen(tree.right)) {
936
+ // Cache children and their sizes to avoid repeated property access
937
+ const left = tree.left;
938
+ const middle = tree.middle;
939
+ const right = tree.right;
940
+ const leftSize = left == null ? 0 : left.size;
941
+ const middleSize = middle == null ? 0 : middle.size;
942
+ const rightSize = right == null ? 0 : right.size;
943
+ if (tree.size !== leftSize + middleSize + rightSize) {
898
944
  throw new Error(`Bad size at branch ${formatListInline(tree)}`);
899
945
  }
900
- if (tree.left == null && tree.middle != null) {
946
+ if (left == null && middle != null) {
901
947
  throw new Error("morformed tree");
902
948
  }
903
- if (tree.middle == null && tree.right != null) {
949
+ if (middle == null && right != null) {
904
950
  throw new Error("morformed tree");
905
951
  }
906
- if (tree.depth !== decideParentDepth(tree.left, tree.middle, tree.right)) {
907
- let x = decideParentDepth(tree.left, tree.middle, tree.right);
952
+ if (tree.depth !== decideParentDepth(left, middle, right)) {
953
+ let x = decideParentDepth(left, middle, right);
908
954
  throw new Error(`Bad depth at branch ${formatListInline(tree)}`);
909
955
  }
910
- checkListStructure(tree.left);
911
- checkListStructure(tree.middle);
912
- checkListStructure(tree.right);
956
+ checkListStructure(left);
957
+ checkListStructure(middle);
958
+ checkListStructure(right);
913
959
  break;
914
960
  }
915
961
  }
@@ -941,34 +987,38 @@ export function slice(tree, startIdx, endIdx) {
941
987
  if (startIdx === 0 && endIdx === listLen(tree)) {
942
988
  return tree;
943
989
  }
944
- let leftSize = listLen(tree.left);
945
- let middleSize = listLen(tree.middle);
946
- let rightSize = listLen(tree.right);
990
+ // Cache children and their sizes to avoid repeated property access
991
+ const left = tree.left;
992
+ const middle = tree.middle;
993
+ const right = tree.right;
994
+ const leftSize = left == null ? 0 : left.size;
995
+ const middleSize = middle == null ? 0 : middle.size;
996
+ const rightSize = right == null ? 0 : right.size;
947
997
  // echo "sizes: {leftSize} {middleSize} {rightSize}"
948
998
  if (startIdx >= leftSize + middleSize) {
949
- return slice(tree.right, startIdx - leftSize - middleSize, endIdx - leftSize - middleSize);
999
+ return slice(right, startIdx - leftSize - middleSize, endIdx - leftSize - middleSize);
950
1000
  }
951
1001
  if (startIdx >= leftSize)
952
1002
  if (endIdx <= leftSize + middleSize) {
953
- return slice(tree.middle, startIdx - leftSize, endIdx - leftSize);
1003
+ return slice(middle, startIdx - leftSize, endIdx - leftSize);
954
1004
  }
955
1005
  else {
956
- let middleCut = slice(tree.middle, startIdx - leftSize, middleSize);
957
- let rightCut = slice(tree.right, 0, endIdx - leftSize - middleSize);
1006
+ let middleCut = slice(middle, startIdx - leftSize, middleSize);
1007
+ let rightCut = slice(right, 0, endIdx - leftSize - middleSize);
958
1008
  return concat(middleCut, rightCut);
959
1009
  }
960
1010
  if (endIdx <= leftSize) {
961
- return slice(tree.left, startIdx, endIdx);
1011
+ return slice(left, startIdx, endIdx);
962
1012
  }
963
1013
  if (endIdx <= leftSize + middleSize) {
964
- let leftCut = slice(tree.left, startIdx, leftSize);
965
- let middleCut = slice(tree.middle, 0, endIdx - leftSize);
1014
+ let leftCut = slice(left, startIdx, leftSize);
1015
+ let middleCut = slice(middle, 0, endIdx - leftSize);
966
1016
  return concat(leftCut, middleCut);
967
1017
  }
968
1018
  if (endIdx <= leftSize + middleSize + rightSize) {
969
- let leftCut = slice(tree.left, startIdx, leftSize);
970
- let rightCut = slice(tree.right, 0, endIdx - leftSize - middleSize);
971
- return concat(concat(leftCut, tree.middle), rightCut);
1019
+ let leftCut = slice(left, startIdx, leftSize);
1020
+ let rightCut = slice(right, 0, endIdx - leftSize - middleSize);
1021
+ return concat(concat(leftCut, middle), rightCut);
972
1022
  }
973
1023
  throw new Error("Unknown");
974
1024
  }
@@ -1011,13 +1061,17 @@ export function listMapValues(tree, f) {
1011
1061
  return result;
1012
1062
  }
1013
1063
  case TernaryTreeKind.ternaryTreeBranch: {
1064
+ // Cache children to avoid repeated property access
1065
+ const left = tree.left;
1066
+ const middle = tree.middle;
1067
+ const right = tree.right;
1014
1068
  let result = {
1015
1069
  kind: TernaryTreeKind.ternaryTreeBranch,
1016
1070
  size: tree.size,
1017
1071
  depth: tree.depth,
1018
- left: tree.left == null ? emptyBranch : listMapValues(tree.left, f),
1019
- middle: tree.middle == null ? emptyBranch : listMapValues(tree.middle, f),
1020
- right: tree.right == null ? emptyBranch : listMapValues(tree.right, f),
1072
+ left: left == null ? emptyBranch : listMapValues(left, f),
1073
+ middle: middle == null ? emptyBranch : listMapValues(middle, f),
1074
+ right: right == null ? emptyBranch : listMapValues(right, f),
1021
1075
  };
1022
1076
  return result;
1023
1077
  }