-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathBankImpl.kt
executable file
·44 lines (39 loc) · 1.54 KB
/
BankImpl.kt
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
/**
* Bank implementation. This class is implemented using Software Transaction Manager (STM).
*/
class BankImpl(override val numberOfAccounts: Int) : Bank {
private val accounts = Array(numberOfAccounts) { TxVar(0L) }
override fun getAmount(index: Int): Long = atomic {
accounts[index].read()
}
override val totalAmount: Long get() = atomic {
accounts.fold(0L) { s, a -> s + a.read() }
}
override fun deposit(index: Int, amount: Long): Long = atomic {
require(amount > 0) { "Invalid amount: $amount" }
val a = accounts[index]
val update = a.read() + amount
check(update <= MAX_AMOUNT) { "Overflow" }
a.write(update)
}
override fun withdraw(index: Int, amount: Long): Long = atomic {
require(amount > 0) { "Invalid amount: $amount" }
val a = accounts[index]
val update = a.read() - amount
check(update >= 0) { "Underflow" }
a.write(update)
}
override fun transfer(fromIndex: Int, toIndex: Int, amount: Long) = atomic<Unit> {
require(amount > 0) { "Invalid amount: $amount" }
require(fromIndex != toIndex) { "fromIndex == toIndex" }
check(amount <= MAX_AMOUNT) { "Underflow/overflow" }
val from = accounts[fromIndex]
val to = accounts[toIndex]
val fromUpdate = from.read() - amount
val toUpdate = to.read() + amount
check(toUpdate <= MAX_AMOUNT) { "Overflow" }
check(fromUpdate >= 0) { "Underflow" }
from.write(fromUpdate)
to.write(toUpdate)
}
}