@@ -44,11 +44,11 @@ private[collection] object NewRedBlackTree {
44
44
private [immutable] abstract class Helper [A ](implicit val ordering : Ordering [A ]) {
45
45
def beforePublish [B ](tree : Tree [A , B ]): Tree [A , B ] = {
46
46
if (tree eq null ) tree
47
- else {
47
+ else if (tree.isMutable) {
48
48
val res = tree.mutableBlack.makeImmutable
49
49
VM .releaseFence()
50
50
res
51
- }
51
+ } else tree.black
52
52
}
53
53
/** Create a new balanced tree where `newLeft` replaces `tree.left`.
54
54
* tree and newLeft are never null */
@@ -159,18 +159,14 @@ private[collection] object NewRedBlackTree {
159
159
if (tree eq null ) {
160
160
mutableRedTree(k, v, null , null )
161
161
} else if (k.asInstanceOf [AnyRef ] eq tree.key.asInstanceOf [AnyRef ]) {
162
- if (v.asInstanceOf [AnyRef ] ne tree.value.asInstanceOf [AnyRef ])
163
- tree.mutableWithKV(tree.key, v)
164
- else tree
162
+ tree.mutableWithV(v)
165
163
} else {
166
164
val cmp = ordering.compare(k, tree.key)
167
165
if (cmp < 0 )
168
166
mutableBalanceLeft(tree, mutableUpd(tree.left, k, v))
169
167
else if (cmp > 0 )
170
168
mutableBalanceRight(tree, mutableUpd(tree.right, k, v))
171
- else if (v.asInstanceOf [AnyRef ] ne tree.value.asInstanceOf [AnyRef ])
172
- tree.mutableWithKV(tree.key, v)
173
- else tree
169
+ else tree.mutableWithV(v)
174
170
}
175
171
}
176
172
@@ -403,8 +399,8 @@ private[collection] object NewRedBlackTree {
403
399
private [this ] def upd [A , B , B1 >: B ](tree : Tree [A , B ], k : A , v : B1 , overwrite : Boolean )(implicit ordering : Ordering [A ]): Tree [A , B1 ] = if (tree eq null ) {
404
400
RedTree (k, v, null , null )
405
401
} else if (k.asInstanceOf [AnyRef ] eq tree.key.asInstanceOf [AnyRef ]) {
406
- if (overwrite && (v. asInstanceOf [ AnyRef ] ne tree.value. asInstanceOf [ AnyRef ]) )
407
- tree.withKV(tree.key, v)
402
+ if (overwrite)
403
+ tree.withV( v)
408
404
else tree
409
405
} else {
410
406
val cmp = ordering.compare(k, tree.key)
@@ -414,6 +410,9 @@ private[collection] object NewRedBlackTree {
414
410
balanceRight(tree, upd(tree.right, k, v, overwrite))
415
411
else if (overwrite || k != tree.key)
416
412
tree.withKV(k, v)
413
+ // Note - in 2.13 this is
414
+ // else if (overwrite) tree.withV(v)
415
+ // due to the changes in handling of keys
417
416
else tree
418
417
}
419
418
private [this ] def updNth [A , B , B1 >: B ](tree : Tree [A , B ], idx : Int , k : A , v : B1 ): Tree [A , B1 ] = if (tree eq null ) {
@@ -510,11 +509,14 @@ private[collection] object NewRedBlackTree {
510
509
@ (inline @ getter @ setter) private var _right : Tree [A , _],
511
510
@ (inline @ getter @ setter) private var _count : Int )
512
511
{
512
+ def isMutable : Boolean = (_count & 0x7FFFFFFF ) == 0
513
513
// read only APIs
514
514
@ `inline` final def count = {
515
- devTimeAssert((_count & 0x7FFFFFFF ) != 0 )
515
+ // devTimeAssert((_count & 0x7FFFFFFF) != 0)
516
516
_count & 0x7FFFFFFF
517
517
}
518
+ // inlined here to avoid outer object null checks
519
+ @ `inline` final def sizeOf (tree: Tree [_,_]) = if (tree eq null ) 0 else tree.count
518
520
@ `inline` final def key = _key
519
521
@ `inline` final def value = _value.asInstanceOf [B ]
520
522
@ `inline` final def left = _left.asInstanceOf [Tree [A , B ]]
@@ -567,91 +569,119 @@ private[collection] object NewRedBlackTree {
567
569
// }
568
570
// else new Tree(_key, _value, _left, _right, initialRedCount)
569
571
// }
570
- def mutableWithKV [B1 >: B ](key : A , value : B1 ): Tree [A , B1 ] = {
571
- if (mutable) {
572
- _key = key
572
+ def mutableWithV [B1 >: B ](value : B1 ): Tree [A , B1 ] = {
573
+ if (value. asInstanceOf [ AnyRef ] eq _value. asInstanceOf [ AnyRef ]) this
574
+ else if (mutable) {
573
575
_value = value.asInstanceOf [AnyRef ]
574
576
this
575
- } else new Tree (key , value.asInstanceOf [AnyRef ], _left, _right, _count)
577
+ } else new Tree (_key , value.asInstanceOf [AnyRef ], _left, _right, _count)
576
578
}
577
579
def mutableWithLeft [B1 >: B ](newLeft : Tree [A , B1 ]): Tree [A , B1 ] = {
578
- if (mutable) {
580
+ if (_left eq newLeft) this
581
+ else if (mutable) {
579
582
_left = newLeft
580
583
this
581
584
} else new Tree (_key, _value, newLeft, _right, initialCount)
582
585
}
583
586
def mutableWithRight [B1 >: B ](newRight : Tree [A , B1 ]): Tree [A , B1 ] = {
584
- if (mutable) {
587
+ if (_right eq newRight) this
588
+ else if (mutable) {
585
589
_right = newRight
586
590
this
587
591
} else new Tree (_key, _value, _left, newRight, initialCount)
588
592
}
589
593
def mutableWithLeftRight [B1 >: B ](newLeft : Tree [A , B1 ], newRight : Tree [A , B1 ]): Tree [A , B1 ] = {
590
- if (mutable) {
594
+ if ((_left eq newLeft) && (_right eq newRight)) this
595
+ else if (mutable) {
591
596
_left = newLeft
592
597
_right = newRight
593
598
this
594
599
} else new Tree (_key, _value, newLeft, newRight, initialCount)
595
600
}
596
601
def mutableBlackWithLeft [B1 >: B ](newLeft : Tree [A , B1 ]): Tree [A , B1 ] = {
597
- if (mutable) {
602
+ if ((_left eq newLeft) && isBlack) this
603
+ else if (mutable) {
598
604
_count = initialBlackCount
599
605
_left = newLeft
600
606
this
601
607
} else new Tree (_key, _value, newLeft, _right, initialBlackCount)
602
608
}
603
609
def mutableBlackWithRight [B1 >: B ](newRight : Tree [A , B1 ]): Tree [A , B1 ] = {
604
- if (mutable) {
610
+ if ((_right eq newRight) && isBlack) this
611
+ else if (mutable) {
605
612
_count = initialBlackCount
606
613
_right = newRight
607
614
this
608
615
} else new Tree (_key, _value, _left, newRight, initialBlackCount)
609
616
}
610
617
611
618
def black : Tree [A , B ] = {
612
- assertNotMutable(this )
619
+ // assertNotMutable(this)
613
620
if (isBlack) this
614
621
else new Tree (_key, _value, _left, _right, _count ^ colourBit)
615
622
}
616
623
def red : Tree [A , B ] = {
617
- assertNotMutable(this )
624
+ // assertNotMutable(this)
618
625
if (isRed) this
619
626
else new Tree (_key, _value, _left, _right, _count ^ colourBit)
620
627
}
621
- def withKV [B1 >: B ](key : A , value : B1 ): Tree [A , B1 ] = {
622
- assertNotMutable(this )
623
- new Tree (key, value.asInstanceOf [AnyRef ], _left, _right, _count)
628
+ def withKV [B1 >: B ](newKey : A , newValue : B1 ): Tree [A , B1 ] = {
629
+ // assertNotMutable(this)
630
+ if ((newKey.asInstanceOf [AnyRef ] eq _key.asInstanceOf [AnyRef ]) &&
631
+ (newValue.asInstanceOf [AnyRef ] eq _value.asInstanceOf [AnyRef ])) this
632
+ else new Tree (newKey, newValue.asInstanceOf [AnyRef ], _left, _right, _count)
633
+ }
634
+ def withV [B1 >: B ](newValue : B1 ): Tree [A , B1 ] = {
635
+ // assertNotMutable(this)
636
+ if (newValue.asInstanceOf [AnyRef ] eq _value.asInstanceOf [AnyRef ]) this
637
+ else new Tree (_key, newValue.asInstanceOf [AnyRef ], _left, _right, _count)
624
638
}
639
+
625
640
def withLeft [B1 >: B ](newLeft : Tree [A , B1 ]): Tree [A , B1 ] = {
626
- assertNotMutable(this )
627
- assertNotMutable(newLeft)
628
- val size = sizeOf(newLeft) + sizeOf(_right) + 1
629
- new Tree (key, value.asInstanceOf [AnyRef ], newLeft, _right, (_count & colourBit) | size)
641
+ // assertNotMutable(this)
642
+ // assertNotMutable(newLeft)
643
+ if (newLeft eq _left) this
644
+ else {
645
+ val size = sizeOf(newLeft) + sizeOf(_right) + 1
646
+ new Tree (key, value.asInstanceOf [AnyRef ], newLeft, _right, (_count & colourBit) | size)
647
+ }
630
648
}
631
649
def withRight [B1 >: B ](newRight : Tree [A , B1 ]): Tree [A , B1 ] = {
632
- assertNotMutable(this )
633
- assertNotMutable(newRight)
634
- val size = sizeOf(_left) + sizeOf(newRight) + 1
635
- new Tree (key, value.asInstanceOf [AnyRef ], _left, newRight, (_count & colourBit) | size)
650
+ // assertNotMutable(this)
651
+ // assertNotMutable(newRight)
652
+ if (newRight eq _right) this
653
+ else {
654
+ val size = sizeOf(_left) + sizeOf(newRight) + 1
655
+ new Tree (key, value.asInstanceOf [AnyRef ], _left, newRight, (_count & colourBit) | size)
656
+ }
636
657
}
637
658
def blackWithLeft [B1 >: B ](newLeft : Tree [A , B1 ]): Tree [A , B1 ] = {
638
- assertNotMutable(this )
639
- assertNotMutable(newLeft)
640
- val size = sizeOf(newLeft) + sizeOf(_right) + 1
641
- new Tree (key, value.asInstanceOf [AnyRef ], newLeft, _right, initialBlackCount | size)
659
+ // assertNotMutable(this)
660
+ // assertNotMutable(newLeft)
661
+ if ((newLeft eq _left) && isBlack) this
662
+ else {
663
+ val size = sizeOf(newLeft) + sizeOf(_right) + 1
664
+ new Tree (key, value.asInstanceOf [AnyRef ], newLeft, _right, initialBlackCount | size)
665
+ }
642
666
}
643
667
def blackWithRight [B1 >: B ](newRight : Tree [A , B1 ]): Tree [A , B1 ] = {
644
- assertNotMutable(this )
645
- assertNotMutable(newRight)
646
- val size = sizeOf(_left) + sizeOf(newRight) + 1
647
- new Tree (key, value.asInstanceOf [AnyRef ], _left, newRight, initialBlackCount | size)
668
+ // assertNotMutable(this)
669
+ // assertNotMutable(newRight)
670
+ if ((newRight eq _right) && isBlack) this
671
+ else {
672
+ val size = sizeOf(_left) + sizeOf(newRight) + 1
673
+ new Tree (key, value.asInstanceOf [AnyRef ], _left, newRight, initialBlackCount | size)
674
+ }
648
675
}
649
676
def withLeftRight [B1 >: B ](newLeft : Tree [A , B1 ], newRight : Tree [A , B1 ]): Tree [A , B1 ] = {
650
- assertNotMutable(this )
651
- assertNotMutable(newLeft)
652
- assertNotMutable(newRight)
653
- val size = sizeOf(newLeft) + sizeOf(newRight) + 1
654
- new Tree (key, value.asInstanceOf [AnyRef ], newLeft, newRight, (_count & colourBit) | size)
677
+ // assertNotMutable(this)
678
+ // assertNotMutable(newLeft)
679
+ // assertNotMutable(newRight)
680
+ if ((newLeft eq _left) && (newRight eq _right)) this
681
+ else {
682
+ val size = sizeOf(newLeft) + sizeOf(newRight) + 1
683
+ new Tree (key, value.asInstanceOf [AnyRef ], newLeft, newRight, (_count & colourBit) | size)
684
+ }
655
685
}
656
686
}
657
687
@ `inline` def initialBlackCount = 0x80000000
@@ -664,27 +694,27 @@ private[collection] object NewRedBlackTree {
664
694
* left and right may be null
665
695
*/
666
696
def RedTree [A , B ](key : A , value : B , left : Tree [A , B ], right : Tree [A , B ]): Tree [A , B ] = {
667
- assertNotMutable(left)
668
- assertNotMutable(right)
697
+ // assertNotMutable(left)
698
+ // assertNotMutable(right)
669
699
val size = sizeOf(left) + sizeOf(right) + 1
670
700
new Tree (key, value.asInstanceOf [AnyRef ], left, right, initialRedCount | size)
671
701
}
672
702
def BlackTree [A , B ](key : A , value : B , left : Tree [A , B ], right : Tree [A , B ]): Tree [A , B ] = {
673
- assertNotMutable(left)
674
- assertNotMutable(right)
703
+ // assertNotMutable(left)
704
+ // assertNotMutable(right)
675
705
val size = sizeOf(left) + sizeOf(right) + 1
676
706
new Tree (key, value.asInstanceOf [AnyRef ], left, right, initialBlackCount | size)
677
707
}
678
- @ `inline` private def sizeOf (tree: Tree [_,_]) = if (tree eq null ) 0 else tree.count
708
+ @ `inline` private def sizeOf (tree: Tree [_,_]) = if (tree eq null ) 0 else tree.count
679
709
// immutable APIs
680
- // assertions - either elide or remove before merge
681
- //
682
- private def devTimeAssert ( assertion : Boolean ) = {
683
- // uncomment this during developement of the functionality
684
- assert(assertion)
685
- }
686
- private def assertNotMutable (t : Tree [_,_]) = devTimeAssert ((t eq null ) || t.count > 0 )
687
-
710
+ // assertions - uncomment decls and callers when changing functionality
711
+ // private def devTimeAssert(assertion: Boolean) = {
712
+ // //uncomment this during development of the functionality
713
+ // assert(assertion)
714
+ // }
715
+ // private def assertNotMutable(t:Tree[_,_]) = {
716
+ // devTimeAssert ((t eq null) || t.count > 0)
717
+ // }
688
718
private [this ] abstract class TreeIterator [A , B , R ](root : Tree [A , B ], start : Option [A ])(protected implicit val ordering : Ordering [A ]) extends Iterator [R ] {
689
719
protected [this ] def nextResult (tree : Tree [A , B ]): R
690
720
0 commit comments