Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package midterm23
import instrumentation.{MockedMonitor, Monitor, Scheduler}
import java.util.concurrent.ConcurrentLinkedQueue
import scala.jdk.CollectionConverters.IterableHasAsScala
import scala.annotation.tailrec
trait ScheduledBarberShopSolution(scheduler0: Scheduler)
extends AbstractBarberShopSolution:
enum Event:
case HairCut
case CustomerLeaves
val trace = ConcurrentLinkedQueue[Event]()
override def notifyBarber = scheduler0.exec { super.notifyBarber }(
"",
Some(res => f"read notifyBarber == $res")
)
override def notifyBarber_=(v: Boolean) =
scheduler0.exec { super.notifyBarber = v }(
f"write notifyBarber = $v"
)
override def notifyCustomer = scheduler0.exec { super.notifyCustomer }(
"",
Some(res => f"read notifyCustomer == $res")
)
override def notifyCustomer_=(v: Boolean) =
scheduler0.exec { super.notifyCustomer = v }(
f"write notifyCustomer = $v"
)
override def hairCut() =
log("hair cut")
trace.add(Event.HairCut)
def customerTrace(n: Int): Unit =
this.customer(n)
log("customer leaves")
trace.add(Event.CustomerLeaves)
private val _lockObj = new MockedMonitor:
override def scheduler: Scheduler = scheduler0
override def lockObj: Monitor = _lockObj
override def log(s: String): Unit = scheduler0.log(s)
def nHaircuts: Int =
trace.asScala.filter(_ == Event.HairCut).size
def customerLeftEarly(): Boolean =
@tailrec
def loop(it: Iterable[Event], n: Int): Boolean =
if it.isEmpty then false
else
val newN = it.head match
case Event.HairCut => n + 1
case Event.CustomerLeaves => n - 1
if newN < 0 then true
else loop(it.tail, newN)
loop(trace.asScala, 0)