@@ -25,6 +25,21 @@ import scala.annotation.tailrec
25
25
* optimizations behind a reasonably clean API.
26
26
*/
27
27
private [collection] object NewRedBlackTree {
28
+ def validate [A ](tree : Tree [A , _])(implicit ordering : Ordering [A ]): tree.type = {
29
+ def impl (tree : Tree [A , _], keyProp : A => Boolean ): Int = {
30
+ assert(keyProp(tree.key), s " key check failed: $tree" )
31
+ if (tree.isRed) {
32
+ assert(tree.left == null || tree.left.isBlack, s " red-red left $tree" )
33
+ assert(tree.right == null || tree.right.isBlack, s " red-red right $tree" )
34
+ }
35
+ val leftBlacks = if (tree.left == null ) 0 else impl(tree.left, k => keyProp(k) && ordering.compare(k, tree.key) < 0 )
36
+ val rightBlacks = if (tree.right == null ) 0 else impl(tree.right, k => keyProp(k) && ordering.compare(k, tree.key) > 0 )
37
+ assert(leftBlacks == rightBlacks, s " not balanced: $tree" )
38
+ leftBlacks + (if (tree.isBlack) 1 else 0 )
39
+ }
40
+ if (tree != null ) impl(tree, _ => true )
41
+ tree
42
+ }
28
43
29
44
def isEmpty (tree : Tree [_, _]): Boolean = tree eq null
30
45
@@ -447,23 +462,23 @@ private[collection] object NewRedBlackTree {
447
462
if (ordering.lt(tree.key, from)) return doFrom(tree.right, from)
448
463
val newLeft = doFrom(tree.left, from)
449
464
if (newLeft eq tree.left) tree
450
- else if (newLeft eq null ) upd(tree.right, tree.key, tree.value, overwrite = false )
465
+ else if (newLeft eq null ) maybeBlacken( upd(tree.right, tree.key, tree.value, overwrite = false ) )
451
466
else join(newLeft, tree.key, tree.value, tree.right)
452
467
}
453
468
private [this ] def doTo [A , B ](tree : Tree [A , B ], to : A )(implicit ordering : Ordering [A ]): Tree [A , B ] = {
454
469
if (tree eq null ) return null
455
470
if (ordering.lt(to, tree.key)) return doTo(tree.left, to)
456
471
val newRight = doTo(tree.right, to)
457
472
if (newRight eq tree.right) tree
458
- else if (newRight eq null ) upd(tree.left, tree.key, tree.value, overwrite = false )
459
- else join (tree.left, tree.key, tree.value, newRight)
473
+ else if (newRight eq null ) maybeBlacken( upd(tree.left, tree.key, tree.value, overwrite = false ) )
474
+ else join(tree.left, tree.key, tree.value, newRight)
460
475
}
461
476
private [this ] def doUntil [A , B ](tree : Tree [A , B ], until : A )(implicit ordering : Ordering [A ]): Tree [A , B ] = {
462
477
if (tree eq null ) return null
463
478
if (ordering.lteq(until, tree.key)) return doUntil(tree.left, until)
464
479
val newRight = doUntil(tree.right, until)
465
480
if (newRight eq tree.right) tree
466
- else if (newRight eq null ) upd(tree.left, tree.key, tree.value, overwrite = false )
481
+ else if (newRight eq null ) maybeBlacken( upd(tree.left, tree.key, tree.value, overwrite = false ) )
467
482
else join(tree.left, tree.key, tree.value, newRight)
468
483
}
469
484
0 commit comments