@@ -8,8 +8,9 @@ import dev.yorkie.document.time.TimeTicket.Companion.compareTo
8
8
* For more details about RHT:
9
9
* @link http://csl.skku.edu/papers/jpdc11.pdf
10
10
*/
11
- internal class Rht : Iterable <Rht .Node > {
11
+ internal class Rht : Collection <Rht .Node > {
12
12
private val nodeMapByKey = mutableMapOf<String , Node >()
13
+ private var numberOfRemovedElements = 0
13
14
14
15
val nodeKeyValueMap: Map <String , String >
15
16
get() {
@@ -25,14 +26,41 @@ internal class Rht : Iterable<Rht.Node> {
25
26
) {
26
27
val prev = nodeMapByKey[key]
27
28
if (prev?.executedAt < executedAt) {
28
- val node = Node (key, value, executedAt)
29
+ if (prev?.isRemoved == false ) {
30
+ numberOfRemovedElements--
31
+ }
32
+ val node = Node (key, value, executedAt, false )
29
33
nodeMapByKey[key] = node
30
34
}
31
35
}
32
36
37
+ /* *
38
+ * Removes the Element of the given [key].
39
+ */
40
+ fun remove (key : String , executedAt : TimeTicket ): String {
41
+ val prev = nodeMapByKey[key]
42
+ return when {
43
+ prev == null -> {
44
+ numberOfRemovedElements++
45
+ nodeMapByKey[key] = Node (key, " " , executedAt, true )
46
+ " "
47
+ }
48
+
49
+ prev.executedAt < executedAt -> {
50
+ if (! prev.isRemoved) {
51
+ numberOfRemovedElements++
52
+ }
53
+ nodeMapByKey[key] = Node (key, prev.value, executedAt, true )
54
+ if (prev.isRemoved) " " else prev.value
55
+ }
56
+
57
+ else -> " "
58
+ }
59
+ }
60
+
33
61
operator fun get (key : String ): String? = nodeMapByKey[key]?.value
34
62
35
- fun has (key : String ): Boolean = key in nodeMapByKey
63
+ fun has (key : String ): Boolean = nodeMapByKey[ key]?.isRemoved == false
36
64
37
65
fun deepCopy (): Rht {
38
66
val rht = Rht ()
@@ -47,15 +75,23 @@ internal class Rht : Iterable<Rht.Node> {
47
75
* Converts the given [Rht] to XML String.
48
76
*/
49
77
fun toXml (): String {
50
- return nodeKeyValueMap.entries.joinToString(" " ) { (key, value) ->
51
- " $key =\" $value \" "
52
- }
78
+ return nodeMapByKey.filterValues { ! it.isRemoved }.entries
79
+ .joinToString(" " ) { (key, node) ->
80
+ " $key =\" ${node.value} \" "
81
+ }
53
82
}
54
83
55
84
override fun iterator (): Iterator <Node > {
56
85
return nodeMapByKey.values.iterator()
57
86
}
58
87
88
+ override val size: Int
89
+ get() = nodeMapByKey.size - numberOfRemovedElements
90
+
91
+ override fun containsAll (elements : Collection <Node >): Boolean = elements.all { contains(it) }
92
+
93
+ override fun contains (element : Node ): Boolean = nodeMapByKey[element.key]?.isRemoved == false
94
+
59
95
override fun equals (other : Any? ): Boolean {
60
96
if (other !is Rht ) {
61
97
return false
@@ -67,5 +103,12 @@ internal class Rht : Iterable<Rht.Node> {
67
103
return nodeMapByKey.hashCode()
68
104
}
69
105
70
- data class Node (val key : String , val value : String , val executedAt : TimeTicket )
106
+ override fun isEmpty (): Boolean = size == 0
107
+
108
+ data class Node (
109
+ val key : String ,
110
+ val value : String ,
111
+ val executedAt : TimeTicket ,
112
+ val isRemoved : Boolean ,
113
+ )
71
114
}
0 commit comments