Skip to content

Commit 15c847d

Browse files
authored
Merge pull request scala/scala#9315 from mkeskells/2.12.x_RedBlack_reuse_fp
reuse common code for filter/partition for RedBlackTree based Set/Map
2 parents cfa7cae + 1966bee commit 15c847d

File tree

1 file changed

+39
-32
lines changed

1 file changed

+39
-32
lines changed

library/src/scala/collection/immutable/RedBlackTree.scala

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,41 +1021,48 @@ private[collection] object NewRedBlackTree {
10211021
blacken(fk(t))
10221022
}
10231023

1024-
def partitionEntries[A, B](t: Tree[A, B], p: (A, B) => Boolean): (Tree[A, B], Tree[A, B]) = if(t eq null) (null, null) else {
1025-
var tmpk, tmpd = null: Tree[A, B] // shared vars to avoid returning tuples from fk
1026-
def fk(t: Tree[A, B]): Unit = {
1027-
val k = t.key
1028-
val v = t.value
1029-
val l = t.left
1030-
val r = t.right
1031-
var l2k, l2d, r2k, r2d = null: Tree[A, B]
1032-
if(l ne null) {
1033-
fk(l)
1034-
l2k = tmpk
1035-
l2d = tmpd
1036-
}
1037-
val keep = p(k, v)
1038-
if(r ne null) {
1039-
fk(r)
1040-
r2k = tmpk
1041-
r2d = tmpd
1024+
private[this] val null2 = (null, null)
1025+
1026+
def partitionEntries[A, B](t: Tree[A, B], p: (A, B) => Boolean): (Tree[A, B], Tree[A, B]) = {
1027+
if (t eq null) null2
1028+
else {
1029+
object partitioner {
1030+
var tmpk, tmpd = null: Tree[A, B] // shared vars to avoid returning tuples from fk
1031+
def fk(t: Tree[A, B]): Unit = {
1032+
val k = t.key
1033+
val v = t.value
1034+
val l = t.left
1035+
val r = t.right
1036+
var l2k, l2d, r2k, r2d = null: Tree[A, B]
1037+
if (l ne null) {
1038+
fk(l)
1039+
l2k = tmpk
1040+
l2d = tmpd
1041+
}
1042+
val keep = p(k, v)
1043+
if (r ne null) {
1044+
fk(r)
1045+
r2k = tmpk
1046+
r2d = tmpd
1047+
}
1048+
val jk =
1049+
if (!keep) join2(l2k, r2k)
1050+
else if ((l2k eq l) && (r2k eq r)) t
1051+
else join(l2k, k, v, r2k)
1052+
val jd =
1053+
if (keep) join2(l2d, r2d)
1054+
else if ((l2d eq l) && (r2d eq r)) t
1055+
else join(l2d, k, v, r2d)
1056+
tmpk = jk
1057+
tmpd = jd
1058+
}
10421059
}
1043-
val jk =
1044-
if(!keep) join2(l2k, r2k)
1045-
else if((l2k eq l) && (r2k eq r)) t
1046-
else join(l2k, k, v, r2k)
1047-
val jd =
1048-
if(keep) join2(l2d, r2d)
1049-
else if((l2d eq l) && (r2d eq r)) t
1050-
else join(l2d, k, v, r2d)
1051-
tmpk = jk
1052-
tmpd = jd
1060+
1061+
partitioner.fk(t)
1062+
(blacken(partitioner.tmpk), blacken(partitioner.tmpd))
10531063
}
1054-
fk(t)
1055-
(blacken(tmpk), blacken(tmpd))
10561064
}
10571065

1058-
10591066
// Based on Stefan Kahrs' Haskell version of Okasaki's Red&Black Trees
10601067
// Constructing Red-Black Trees, Ralf Hinze: [[http://www.cs.ox.ac.uk/ralf.hinze/publications/WAAAPL99b.ps.gz]]
10611068
// Red-Black Trees in a Functional Setting, Chris Okasaki: [[https://wiki.rice.edu/confluence/download/attachments/2761212/Okasaki-Red-Black.pdf]] */
@@ -1253,4 +1260,4 @@ private[collection] object NewRedBlackTree {
12531260
val tr = _difference(r1, t2.right)
12541261
join2(tl, tr)
12551262
}
1256-
}
1263+
}

0 commit comments

Comments
 (0)