19
19
import static org .truffleruby .core .rope .CodeRange .CR_UNKNOWN ;
20
20
import static org .truffleruby .core .rope .CodeRange .CR_VALID ;
21
21
22
- import java .util .ArrayDeque ;
23
22
import java .util .Arrays ;
24
- import java .util .Deque ;
25
23
26
24
import org .jcodings .Encoding ;
27
25
import org .jcodings .specific .ASCIIEncoding ;
@@ -425,8 +423,6 @@ public static ConcatNode create() {
425
423
return RopeNodesFactory .ConcatNodeGen .create ();
426
424
}
427
425
428
- @ Child private FlattenNode flattenNode ;
429
-
430
426
public abstract Rope executeConcat (Rope left , Rope right , Encoding encoding );
431
427
432
428
@ Specialization
@@ -467,8 +463,7 @@ protected Rope concatRightEmpty(ManagedRope left, Rope right, Encoding encoding,
467
463
@ Specialization (guards = { "!left.isEmpty()" , "!right.isEmpty()" , "!isCodeRangeBroken(left, right)" })
468
464
protected Rope concat (ManagedRope left , ManagedRope right , Encoding encoding ,
469
465
@ Cached ConditionProfile sameCodeRangeProfile ,
470
- @ Cached ConditionProfile brokenCodeRangeProfile ,
471
- @ Cached ConditionProfile shouldRebalanceProfile ) {
466
+ @ Cached ConditionProfile brokenCodeRangeProfile ) {
472
467
try {
473
468
Math .addExact (left .byteLength (), right .byteLength ());
474
469
} catch (ArithmeticException e ) {
@@ -477,18 +472,7 @@ protected Rope concat(ManagedRope left, ManagedRope right, Encoding encoding,
477
472
getContext ().getCoreExceptions ().argumentErrorTooLargeString (this ));
478
473
}
479
474
480
- if (shouldRebalanceProfile .profile (
481
- left .depth () >= getContext ().getOptions ().ROPE_DEPTH_THRESHOLD && left instanceof ConcatRope )) {
482
- left = rebalance ((ConcatRope ) left , getContext ().getOptions ().ROPE_DEPTH_THRESHOLD , getFlattenNode ());
483
- }
484
-
485
- if (shouldRebalanceProfile .profile (
486
- right .depth () >= getContext ().getOptions ().ROPE_DEPTH_THRESHOLD && right instanceof ConcatRope )) {
487
- right = rebalance ((ConcatRope ) right , getContext ().getOptions ().ROPE_DEPTH_THRESHOLD , getFlattenNode ());
488
- }
489
-
490
475
int depth = depth (left , right );
491
- /* if (depth >= 10) { System.out.println("ConcatRope depth: " + depth); } */
492
476
493
477
return new ConcatRope (
494
478
left ,
@@ -503,14 +487,6 @@ protected Rope concat(ManagedRope left, ManagedRope right, Encoding encoding,
503
487
isBalanced (left , right ));
504
488
}
505
489
506
- private FlattenNode getFlattenNode () {
507
- if (flattenNode == null ) {
508
- CompilerDirectives .transferToInterpreterAndInvalidate ();
509
- flattenNode = insert (FlattenNode .create ());
510
- }
511
- return flattenNode ;
512
- }
513
-
514
490
private boolean isBalanced (Rope left , Rope right ) {
515
491
// Our definition of balanced is centered around the notion of rebalancing. We could have a simple structure
516
492
// such as ConcatRope(ConcatRope(LeafRope, LeafRope), LeafRope) that is balanced on its own but may contribute
@@ -532,81 +508,6 @@ private boolean isBalanced(Rope left, Rope right) {
532
508
}
533
509
}
534
510
535
- @ TruffleBoundary
536
- private ManagedRope rebalance (ConcatRope rope , int depthThreshold , FlattenNode flattenNode ) {
537
- Deque <ManagedRope > currentRopeQueue = new ArrayDeque <>();
538
- Deque <ManagedRope > nextLevelQueue = new ArrayDeque <>();
539
-
540
- linearizeTree (rope .getLeft (), currentRopeQueue );
541
- linearizeTree (rope .getRight (), currentRopeQueue );
542
-
543
- final int flattenThreshold = depthThreshold / 2 ;
544
-
545
- ManagedRope root = null ;
546
- while (!currentRopeQueue .isEmpty ()) {
547
- ManagedRope left = currentRopeQueue .pop ();
548
-
549
- if (left .depth () >= flattenThreshold ) {
550
- // TODO (eregon, 15 June 2020): should this cache the resulting bytes by using getBytes()?
551
- left = flattenNode .executeFlatten (left );
552
- }
553
-
554
- if (currentRopeQueue .isEmpty ()) {
555
- if (nextLevelQueue .isEmpty ()) {
556
- root = left ;
557
- } else {
558
- // If a rope can't be paired with another rope at the current level (i.e., odd numbers of ropes),
559
- // it needs to be promoted to the next level where it will be tried again. Since by definition
560
- // every rope already present in the next level must have occurred before this rope in the current
561
- // level, this rope must be added to the end of the list in the next level to maintain proper
562
- // position.
563
- nextLevelQueue .add (left );
564
- }
565
- } else {
566
- ManagedRope right = currentRopeQueue .pop ();
567
-
568
- if (right .depth () >= flattenThreshold ) {
569
- // TODO (eregon, 15 June 2020): should this cache the resulting bytes by using getBytes()?
570
- right = flattenNode .executeFlatten (right );
571
- }
572
-
573
- final ManagedRope child = new ConcatRope (
574
- left ,
575
- right ,
576
- rope .getEncoding (),
577
- commonCodeRange (left .getCodeRange (), right .getCodeRange ()),
578
- depth (left , right ),
579
- isBalanced (left , right ));
580
-
581
- nextLevelQueue .add (child );
582
- }
583
-
584
- if (currentRopeQueue .isEmpty () && !nextLevelQueue .isEmpty ()) {
585
- currentRopeQueue = nextLevelQueue ;
586
- nextLevelQueue = new ArrayDeque <>();
587
- }
588
- }
589
-
590
- return root ;
591
- }
592
-
593
- @ TruffleBoundary
594
- private void linearizeTree (ManagedRope rope , Deque <ManagedRope > ropeQueue ) {
595
- if (rope instanceof ConcatRope ) {
596
- final ConcatRope concatRope = (ConcatRope ) rope ;
597
-
598
- // If a rope is known to be balanced, there's no need to rebalance it.
599
- if (concatRope .isBalanced ()) {
600
- ropeQueue .add (concatRope );
601
- } else {
602
- linearizeTree (concatRope .getLeft (), ropeQueue );
603
- linearizeTree (concatRope .getRight (), ropeQueue );
604
- }
605
- } else {
606
- // We never rebalance non-ConcatRopes since that requires per-rope type logic with likely minimal benefit.
607
- ropeQueue .add (rope );
608
- }
609
- }
610
511
611
512
@ SuppressFBWarnings ("RV" )
612
513
@ Specialization (guards = { "!left.isEmpty()" , "!right.isEmpty()" , "isCodeRangeBroken(left, right)" })
0 commit comments