Skip to content

Commit

Permalink
updated to newer Scala 3 syntax with fewer braces
Browse files Browse the repository at this point in the history
Signed-off-by: Konstantin Läufer <[email protected]>
  • Loading branch information
klaeufer committed Sep 30, 2023
1 parent cace90e commit 492fccc
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 142 deletions.
71 changes: 32 additions & 39 deletions src/main/scala/fakeps/fakeps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,23 @@ package object fakeps:
* using an immutable map. Unacceptably slow
* because of a bug in Map.+(vararg).
*/
def fakePsFoldSlow(n: Int): Iterator[(Int, Int)] = reverseEdges {
def fakePsFoldSlow(n: Int): Iterator[(Int, Int)] = reverseEdges:
require { n > 0 }
(2 to n).foldLeft {
Map(0 -> Seq(1), 1 -> Seq.empty)
} { (ps, nextPid) =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps + (randomPid -> (nextPid +: ps(randomPid))) + (nextPid -> Seq.empty)
}
}
(2 to n).foldLeft(Map(0 -> Seq(1), 1 -> Seq.empty)):
(ps, nextPid) =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps + (randomPid -> (nextPid +: ps(randomPid))) + (nextPid -> Seq.empty)

/**
* Generates a barebones process tree (ppid -> pid*) of size n
* using an immutable map.
*/
def fakePsFold(n: Int): Iterator[(Int, Int)] = reverseEdges {
def fakePsFold(n: Int): Iterator[(Int, Int)] = reverseEdges:
require { n > 0 }
(2 to n).foldLeft {
Map(0 -> Seq(1), 1 -> Seq.empty)
} { (ps, nextPid) =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps + (randomPid -> (nextPid +: ps(randomPid))) + (nextPid -> Seq.empty)
}
}
(2 to n).foldLeft(Map(0 -> Seq(1), 1 -> Seq.empty)):
(ps, nextPid) =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps + (randomPid -> (nextPid +: ps(randomPid))) + (nextPid -> Seq.empty)

/**
* Generates a barebones process tree (ppid -> pid*) of size n
Expand All @@ -46,27 +40,26 @@ package object fakeps:
require { n > 0 }
val ps0 = Vector.fill(n + 1)(Vector.empty[Int])
val ps1 = ps0.updated(0, Vector(1))
val ps = (2 to n).foldLeft(ps1) { (ps, nextPid) =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps.updated(randomPid, ps(randomPid) :+ nextPid)
}
val ps = (2 to n).foldLeft(ps1):
(ps, nextPid) =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps.updated(randomPid, ps(randomPid) :+ nextPid)
for ppid <- ps.indices.iterator; pid <- ps(ppid).iterator yield (pid, ppid)

/**
* Generates a barebones process tree (ppid -> pid*) of size n
* using a mutable map.
*/
def fakePsMutable(n: Int): Iterator[(Int, Int)] = reverseEdges {
def fakePsMutable(n: Int): Iterator[(Int, Int)] = reverseEdges:
require { n > 0 }
import scala.collection.mutable.Map
val ps = Map(0 -> ArrayBuffer(1), 1 -> ArrayBuffer.empty[Int])
(2 to n) foreach { nextPid =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps(nextPid) = ArrayBuffer.empty
ps(randomPid) += nextPid
}
(2 to n).foreach:
nextPid =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps(nextPid) = ArrayBuffer.empty
ps(randomPid) += nextPid
ps.toMap
}

/**
* Generates a barebones process tree (ppid -> pid*) of size n
Expand All @@ -76,10 +69,10 @@ package object fakeps:
require { n > 0 }
val ps = Vector.fill(n + 1)(ArrayBuffer.empty[Int])
ps(0) += 1
(2 to n) foreach { nextPid =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps(randomPid) += nextPid
}
(2 to n).foreach:
nextPid =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps(randomPid) += nextPid
for ppid <- ps.indices.iterator; pid <- ps(ppid).iterator yield (pid, ppid)

/**
Expand Down Expand Up @@ -113,10 +106,10 @@ package object fakeps:
import scala.jdk.CollectionConverters._
val ps = Vector.fill(n + 1)(new ConcurrentLinkedQueue[Int])
ps(0) add 1
new ParRange(2 to n) foreach { nextPid =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps(randomPid) add nextPid
}
new ParRange(2 to n) foreach:
nextPid =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps(randomPid) add nextPid
for ppid <- ps.indices.iterator; pid <- ps(ppid).iterator.nn.asScala yield (pid, ppid)

/**
Expand All @@ -129,10 +122,10 @@ package object fakeps:
import scala.collection.concurrent.TrieMap
val ps = Vector.fill(n + 1)(TrieMap.empty[Int, Unit])
ps(0) += (1 -> (()))
new ParRange(2 to n) foreach { nextPid =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps(randomPid) += (nextPid -> (()))
}
new ParRange(2 to n) foreach:
nextPid =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps(randomPid) += (nextPid -> (()))
for ppid <- ps.indices.iterator; (pid, _) <- ps(ppid).iterator yield (pid, ppid)

/**
Expand Down
11 changes: 6 additions & 5 deletions src/main/scala/fold/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ object Main extends common.Main with FoldTreeBuilder
*/
trait FoldTreeBuilder extends common.TreeBuilder:
override def buildTree(processes: Iterator[Process]): ProcessTree =
processes.foldLeft(Map.empty: ProcessTree) { (m, p) =>
val ppid = p._2
val children = m.getOrElse(ppid, Vector.empty) :+ p
m + (ppid -> children)
}
processes.foldLeft(Map.empty: ProcessTree):
(m, p) =>
val ppid = p._2
val children = m.getOrElse(ppid, Vector.empty) :+ p
m + (ppid -> children)

end FoldTreeBuilder
93 changes: 31 additions & 62 deletions src/test/scala/common/ParseLineSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,100 +6,69 @@ import org.scalatest.wordspec.AnyWordSpec
/** Tests for the `parseLine` method. */
class ParseLineSpec extends AnyWordSpec with IO:

"The line parser" when {
"given an empty header" should {
"reject this argument" in {
intercept[IllegalArgumentException] {
"The line parser" when:
"given an empty header" should:
"reject this argument" in:
intercept[IllegalArgumentException]:
parseLine("")
}
}
}

"given a header without PID" should {
"reject this argument" in {
intercept[IllegalArgumentException] {
"given a header without PID" should:
"reject this argument" in:
intercept[IllegalArgumentException]:
parseLine("PPID CMD")
}
}
}

"given a header without PPID" should {
"reject this argument" in {
intercept[IllegalArgumentException] {
"given a header without PPID" should:
"reject this argument" in:
intercept[IllegalArgumentException]:
parseLine("PID CMD")
}
}
}

"given a header without CMD" should {
"reject this argument" in {
intercept[IllegalArgumentException] {
"given a header without CMD" should:
"reject this argument" in:
intercept[IllegalArgumentException]:
parseLine("PPID PID")
}
}
}

"given an simple header" should {
"given an simple header" should:
val parser = parseLine("PPID PID CMD")

"reject an empty line" in {
intercept[RuntimeException] {
"reject an empty line" in:
intercept[RuntimeException]:
parser("")
}
}

"reject an invalid line" in {
intercept[RuntimeException] {
"reject an invalid line" in:
intercept[RuntimeException]:
parser("")
}
}

"parse a valid line" in {
"parse a valid line" in:
// PPID PID CMD
assert(parser("1 2 asdf") == (2, 1, "asdf"))
}
}

"given an complex header" should {
"given an complex header" should:
val parser = parseLine("i1 PPID i2 PID i3 CMD")

"reject an empty line" in {
intercept[RuntimeException] {
"reject an empty line" in:
intercept[RuntimeException]:
parser("")
}
}

"reject an invalid line" in {
intercept[RuntimeException] {
"reject an invalid line" in:
intercept[RuntimeException]:
parser("")
}
}

"parse a valid line" in {
"parse a valid line" in:
// i1 PPID i2 PID i3 CMD
assert(parser("i1 1 i2 2 i3 asdf") == (2, 1, "asdf"))
}
}

"given an actual header" should {
"given an actual header" should:
val parser = parseLine(" UID PID PPID C STIME TTY TIME CMD")

"reject an empty line" in {
intercept[RuntimeException] {
"reject an empty line" in:
intercept[RuntimeException]:
parser("")
}
}

"reject an invalid line" in {
intercept[RuntimeException] {
"reject an invalid line" in:
intercept[RuntimeException]:
parser(" 0 17 1 0 0:27.50 /usr/sbin/syslogd")
}
}

"parse a valid line" in {
"parse a valid line" in:
assert(parser(" 0 17 1 0 Thu04PM ?? 0:27.50 /usr/sbin/syslogd arg1 arg2") == (17, 1, "/usr/sbin/syslogd arg1 arg2"))
}
}
}

end ParseLineSpec
30 changes: 10 additions & 20 deletions src/test/scala/common/PrintSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,39 +13,32 @@ class PrintSpec extends AnyWordSpec with IO:

def fixture() = new StringWriter

"The string writer" when {
"when used through a buffered writer" should {
"return the output as a string" in {
"The string writer" when:
"when used through a buffered writer" should:
"return the output as a string" in:
val f = fixture()
val bw = swToBw(f)
bw.append("asdf")
bw.flush()
assert(f.toString == "asdf")
}
}
}

"The tree printer" when {
"given an empty tree" should {
"print this tree correctly" in {
"The tree printer" when:
"given an empty tree" should:
"print this tree correctly" in:
val f = fixture()
given BufferedWriter = swToBw(f)
printTree(TreeFixtures.empty)
assert(f.toString == "")
}
}

"given a simple tree" should {
"print this tree correctly" in {
"given a simple tree" should:
"print this tree correctly" in:
val f = fixture()
given BufferedWriter = swToBw(f)
printTree(TreeFixtures.simple)
assert(f.toString == "1: cmd" + EOL)
}
}

"given a complex tree" should {
"print this tree correctly" in {
"given a complex tree" should:
"print this tree correctly" in:
val f = fixture()
given BufferedWriter = swToBw(f)
printTree(TreeFixtures.complex)
Expand All @@ -55,8 +48,5 @@ class PrintSpec extends AnyWordSpec with IO:
| 3: cmd3
| 4: cmd4
|""".stripMargin)
}
}
}

end PrintSpec
21 changes: 7 additions & 14 deletions src/test/scala/common/TreeBuilderSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,21 @@ abstract class TreeBuilderSpec(label: String) extends AnyWordSpec with TreeBuild

given CanEqual[ProcessTree, ProcessTree] = CanEqual.derived

"The " + label + " tree builder" when {
"given an empty list of processes" should {
"build the correct process tree" in {
"The " + label + " tree builder" when:
"given an empty list of processes" should:
"build the correct process tree" in:
assert(buildTree(Iterator.empty) == TreeFixtures.empty)
}
}

"given a simple list of processes" should {
"build the correct process tree" in {
"given a simple list of processes" should:
"build the correct process tree" in:
val processes = Iterator((1, 0, "cmd"))
assert(buildTree(processes) == TreeFixtures.simple)
}
}

"given a complex list of processes" should {
"build the correct process tree" in {
"given a complex list of processes" should:
"build the correct process tree" in:
val processes = Iterator(
(1, 0, "cmd1"), (2, 1, "cmd2"), (3, 1, "cmd3"), (4, 3, "cmd4")
)
assert(buildTree(processes) == TreeFixtures.complex)
}
}
}

end TreeBuilderSpec
3 changes: 1 addition & 2 deletions src/test/scala/fakeps/Spec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ class Spec extends AnyFunSuite:
(ps.get(1) == Some(0)) && (ps - 1).values.forall(ps.contains(_))

def testFakePs(f: FakePS, label: String): Unit =
test(label + " should return a proper flattened ps tree") {
test(label + " should return a proper flattened ps tree"):
for s <- sizes do
assert(isFlattenedTree(f(s)))
}

testFakePs(fakePsFoldSlow, "fakePsFoldSlow")
testFakePs(fakePsFold, "fakePsFold")
Expand Down

0 comments on commit 492fccc

Please sign in to comment.