@@ -25,6 +25,21 @@ import scala.annotation.tailrec
2525 * optimizations behind a reasonably clean API.
2626 */
2727private [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+ }
2843
2944 def isEmpty (tree : Tree [_, _]): Boolean = tree eq null
3045
@@ -447,23 +462,23 @@ private[collection] object NewRedBlackTree {
447462 if (ordering.lt(tree.key, from)) return doFrom(tree.right, from)
448463 val newLeft = doFrom(tree.left, from)
449464 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 ) )
451466 else join(newLeft, tree.key, tree.value, tree.right)
452467 }
453468 private [this ] def doTo [A , B ](tree : Tree [A , B ], to : A )(implicit ordering : Ordering [A ]): Tree [A , B ] = {
454469 if (tree eq null ) return null
455470 if (ordering.lt(to, tree.key)) return doTo(tree.left, to)
456471 val newRight = doTo(tree.right, to)
457472 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)
460475 }
461476 private [this ] def doUntil [A , B ](tree : Tree [A , B ], until : A )(implicit ordering : Ordering [A ]): Tree [A , B ] = {
462477 if (tree eq null ) return null
463478 if (ordering.lteq(until, tree.key)) return doUntil(tree.left, until)
464479 val newRight = doUntil(tree.right, until)
465480 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 ) )
467482 else join(tree.left, tree.key, tree.value, newRight)
468483 }
469484
0 commit comments