-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSynchronousTransactionalKeyValueStore.kt
72 lines (61 loc) · 2.14 KB
/
SynchronousTransactionalKeyValueStore.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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package com.antonshillov.transactionalkv.store
import com.antonshillov.transactionalkv.util.ConsoleLogger
import com.antonshillov.transactionalkv.util.Logger
// Non tread-safe implementation to illustrate difference in concurrent env
class SynchronousTransactionalKeyValueStore(
private val store: MutableMap<String, String?> = mutableMapOf<String, String?>(),
private val logger: Logger = ConsoleLogger()
) : TransactionalKeyValueStore {
private val transactions = ArrayDeque<MutableMap<String, String?>>()
override fun set(key: String, value: String) {
getCurrentStore()[key] = value
logger.log("SET $key = $value")
}
override fun get(key: String): String? {
return getCurrentStore()[key].also { value ->
logger.log("GET $key = $value")
}
}
override fun delete(key: String) {
getCurrentStore().remove(key).also {
logger.log("DELETE $key")
}
}
override fun count(value: String): Int {
return getCurrentStore().count { it.value == value }.also { count ->
logger.log("COUNT $value = $count")
}
}
override fun begin() {
transactions.add(mutableMapOf())
logger.log("BEGIN transaction")
}
override fun commit(): Boolean {
if (transactions.isEmpty()) {
logger.log("no transaction")
return false
}
val lastTransaction = transactions.removeLast()
if (transactions.isNotEmpty()) {
transactions.last().putAll(lastTransaction)
} else {
lastTransaction.forEach { (key, value) ->
if (value == null) store.remove(key) else store[key] = value
}
}
logger.log("Transaction committed.")
return true
}
override fun rollback(): Boolean {
if (transactions.isEmpty()) {
logger.log("no transaction")
return false
}
transactions.removeLast()
logger.log("Transaction rolled back.")
return true
}
private fun getCurrentStore(): MutableMap<String, String?> {
return transactions.lastOrNull() ?: store
}
}