@@ -546,12 +546,15 @@ private[collection] object NewRedBlackTree {
546
546
@ (inline @ getter @ setter) private var _right : Tree [A , _],
547
547
@ (inline @ getter @ setter) private var _count : Int )
548
548
{
549
- private [NewRedBlackTree ] def isMutable : Boolean = (_count & 0x7FFFFFFF ) == 0
549
+ @ `inline` private [NewRedBlackTree ] def isMutable : Boolean = (_count & colourMask ) == 0
550
550
// read only APIs
551
551
@ `inline` private [NewRedBlackTree ] final def count = {
552
552
// devTimeAssert((_count & 0x7FFFFFFF) != 0)
553
- _count & 0x7FFFFFFF
553
+ _count & colourMask
554
554
}
555
+ // retain the colour, and mark as mutable
556
+ @ `inline` private def mutableRetainingColour = _count & colourBit
557
+
555
558
// inlined here to avoid outer object null checks
556
559
@ `inline` private [NewRedBlackTree ] final def sizeOf (tree: Tree [_,_]) = if (tree eq null ) 0 else tree.count
557
560
@ `inline` private [immutable] final def key = _key
@@ -567,11 +570,6 @@ private[collection] object NewRedBlackTree {
567
570
568
571
override def toString : String = s " ${if (isRed) " RedTree" else " BlackTree" }( $key, $value, $left, $right) "
569
572
570
- @ `inline` private def initialCount = _count & 0x80000000
571
- @ `inline` private [NewRedBlackTree ] def colourBit = 0x80000000
572
- @ `inline` private [NewRedBlackTree ] def initialBlackCount = 0x80000000
573
- @ `inline` private [NewRedBlackTree ] def initialRedCount = 0
574
-
575
573
// mutable APIs
576
574
private [NewRedBlackTree ] def makeImmutable : Tree [A , B ] = {
577
575
def makeImmutableImpl () = {
@@ -616,14 +614,14 @@ private[collection] object NewRedBlackTree {
616
614
else if (isMutable) {
617
615
_key = newKey
618
616
this
619
- } else new Tree (newKey, _value.asInstanceOf [AnyRef ], _left, _right, initialCount )
617
+ } else new Tree (newKey, _value.asInstanceOf [AnyRef ], _left, _right, mutableRetainingColour )
620
618
}
621
619
private [NewRedBlackTree ] def mutableWithV [B1 >: B ](newValue : B1 ): Tree [A , B1 ] = {
622
620
if (newValue.asInstanceOf [AnyRef ] eq _value.asInstanceOf [AnyRef ]) this
623
621
else if (isMutable) {
624
622
_value = newValue.asInstanceOf [AnyRef ]
625
623
this
626
- } else new Tree (_key, newValue.asInstanceOf [AnyRef ], _left, _right, initialCount )
624
+ } else new Tree (_key, newValue.asInstanceOf [AnyRef ], _left, _right, mutableRetainingColour )
627
625
}
628
626
// Note - in 2.13 remove his method
629
627
// due to the handling of keys in 2.13 we never replace a key
@@ -634,29 +632,29 @@ private[collection] object NewRedBlackTree {
634
632
_key = newKey
635
633
_value = newValue.asInstanceOf [AnyRef ]
636
634
this
637
- } else new Tree (newKey, newValue.asInstanceOf [AnyRef ], _left, _right, initialCount )
635
+ } else new Tree (newKey, newValue.asInstanceOf [AnyRef ], _left, _right, mutableRetainingColour )
638
636
}
639
637
private [NewRedBlackTree ] def mutableWithLeft [B1 >: B ](newLeft : Tree [A , B1 ]): Tree [A , B1 ] = {
640
638
if (_left eq newLeft) this
641
639
else if (isMutable) {
642
640
_left = newLeft
643
641
this
644
- } else new Tree (_key, _value, newLeft, _right, initialCount )
642
+ } else new Tree (_key, _value, newLeft, _right, mutableRetainingColour )
645
643
}
646
644
private [NewRedBlackTree ] def mutableWithRight [B1 >: B ](newRight : Tree [A , B1 ]): Tree [A , B1 ] = {
647
645
if (_right eq newRight) this
648
646
else if (isMutable) {
649
647
_right = newRight
650
648
this
651
- } else new Tree (_key, _value, _left, newRight, initialCount )
649
+ } else new Tree (_key, _value, _left, newRight, mutableRetainingColour )
652
650
}
653
651
private [NewRedBlackTree ] def mutableWithLeftRight [B1 >: B ](newLeft : Tree [A , B1 ], newRight : Tree [A , B1 ]): Tree [A , B1 ] = {
654
652
if ((_left eq newLeft) && (_right eq newRight)) this
655
653
else if (isMutable) {
656
654
_left = newLeft
657
655
_right = newRight
658
656
this
659
- } else new Tree (_key, _value, newLeft, newRight, initialCount )
657
+ } else new Tree (_key, _value, newLeft, newRight, mutableRetainingColour )
660
658
}
661
659
private [NewRedBlackTree ] def mutableBlackWithLeft [B1 >: B ](newLeft : Tree [A , B1 ]): Tree [A , B1 ] = {
662
660
if ((_left eq newLeft) && isBlack) this
@@ -744,8 +742,13 @@ private[collection] object NewRedBlackTree {
744
742
}
745
743
}
746
744
}
747
- @ `inline` private [NewRedBlackTree ] def initialBlackCount = 0x80000000
748
- @ `inline` private [NewRedBlackTree ] def initialRedCount = 0
745
+ // see #Tree docs "Colour, mutablity and size encoding"
746
+ // we make these final vals because the optimiser inlines them, without reference to the enclosing module
747
+ private [NewRedBlackTree ] final val colourBit = 0x80000000
748
+ // really its ~colourBit but that doesnt get inlined
749
+ private [NewRedBlackTree ] final val colourMask = colourBit - 1
750
+ private [NewRedBlackTree ] final val initialBlackCount = colourBit
751
+ private [NewRedBlackTree ] final val initialRedCount = 0
749
752
750
753
@ `inline` private [NewRedBlackTree ] def mutableRedTree [A , B ](key : A , value : B , left : Tree [A , B ], right : Tree [A , B ]) = new Tree [A ,B ](key, value.asInstanceOf [AnyRef ], left, right, initialRedCount)
751
754
@ `inline` private [NewRedBlackTree ] def mutableBlackTree [A , B ](key : A , value : B , left : Tree [A , B ], right : Tree [A , B ]) = new Tree [A ,B ](key, value.asInstanceOf [AnyRef ], left, right, initialBlackCount)
0 commit comments