Skip to content

Commit

Permalink
Add RHTNode removal to converter for consistency (#182)
Browse files Browse the repository at this point in the history
* Fix incorrect indexes in TreeChange

* Update swift-integration.yml

* Update swift-integration.yml

* Update swift-integration.yml

* Add RHTNode removal to converter for consistency
  • Loading branch information
humdrum committed Jun 12, 2024
1 parent b5b7462 commit 01142d8
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 4 deletions.
5 changes: 3 additions & 2 deletions Sources/API/Converter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ extension Converter {
return pbTreeNodes
}
}

/**
* `toTreeNodes` converts the given model to Protobuf format.
*/
Expand Down Expand Up @@ -935,6 +935,7 @@ extension Converter {
var pbNodeAttr = PbNodeAttr()
pbNodeAttr.value = rhtNode.value
pbNodeAttr.updatedAt = toTimeTicket(rhtNode.updatedAt)
pbNodeAttr.isRemoved = rhtNode.isRemoved
pbTreeNode.attributes[rhtNode.key] = pbNodeAttr
}

Expand Down Expand Up @@ -1012,7 +1013,7 @@ extension Converter {
node.attrs = RHT()

pbTreeNode.attributes.forEach { key, value in
node.attrs?.set(key: key, value: value.value, executedAt: fromTimeTicket(value.updatedAt))
node.attrs?.setInternal(key: key, value: value.value, executedAt: fromTimeTicket(value.updatedAt), removed: value.isRemoved)
}
}

Expand Down
8 changes: 8 additions & 0 deletions Sources/API/V1/Generated/yorkie/v1/resources.pb.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1452,6 +1452,8 @@ public struct Yorkie_V1_NodeAttr {
/// Clears the value of `updatedAt`. Subsequent reads from it will return its default value.
public mutating func clearUpdatedAt() {self._updatedAt = nil}

public var isRemoved: Bool = false

public var unknownFields = SwiftProtobuf.UnknownStorage()

public init() {}
Expand Down Expand Up @@ -4133,6 +4135,7 @@ extension Yorkie_V1_NodeAttr: SwiftProtobuf.Message, SwiftProtobuf._MessageImple
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "value"),
2: .standard(proto: "updated_at"),
3: .standard(proto: "is_removed"),
]

public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
Expand All @@ -4143,6 +4146,7 @@ extension Yorkie_V1_NodeAttr: SwiftProtobuf.Message, SwiftProtobuf._MessageImple
switch fieldNumber {
case 1: try { try decoder.decodeSingularStringField(value: &self.value) }()
case 2: try { try decoder.decodeSingularMessageField(value: &self._updatedAt) }()
case 3: try { try decoder.decodeSingularBoolField(value: &self.isRemoved) }()
default: break
}
}
Expand All @@ -4159,12 +4163,16 @@ extension Yorkie_V1_NodeAttr: SwiftProtobuf.Message, SwiftProtobuf._MessageImple
try { if let v = self._updatedAt {
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
} }()
if self.isRemoved != false {
try visitor.visitSingularBoolField(value: self.isRemoved, fieldNumber: 3)
}
try unknownFields.traverse(visitor: &visitor)
}

public static func ==(lhs: Yorkie_V1_NodeAttr, rhs: Yorkie_V1_NodeAttr) -> Bool {
if lhs.value != rhs.value {return false}
if lhs._updatedAt != rhs._updatedAt {return false}
if lhs.isRemoved != rhs.isRemoved {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
Expand Down
1 change: 1 addition & 0 deletions Sources/API/V1/yorkie/v1/resources.proto
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ message RGANode {
message NodeAttr {
string value = 1;
TimeTicket updated_at = 2;
bool is_removed = 3;
}

message TextNode {
Expand Down
14 changes: 13 additions & 1 deletion Sources/Document/CRDT/RHT.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@ class RHT {
return (prev?.isRemoved ?? false ? prev : nil, nil)
}

/**
* SetInternal sets the value of the given key internally.
*/
func setInternal(key: String, value: String, executedAt: TimeTicket, removed: Bool) {
let node = RHTNode(key: key, value: value, updatedAt: executedAt, isRemoved: removed)
self.nodeMapByKey[key] = node

if removed {
self.numberOfRemovedElement += 1
}
}

/**
* `remove` removes the Element of the given key.
*/
Expand Down Expand Up @@ -147,7 +159,7 @@ class RHT {
func deepcopy() -> RHT {
let rht = RHT()
self.nodeMapByKey.forEach {
rht.set(key: $1.key, value: $1.value, executedAt: $1.updatedAt)
rht.setInternal(key: $1.key, value: $1.value, executedAt: $1.updatedAt, removed: $1.isRemoved)
}
return rht
}
Expand Down
10 changes: 9 additions & 1 deletion Tests/Unit/API/V1/ConverterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -376,12 +376,20 @@ class ConverterTests: XCTestCase {
]))

try (root.tree as? JSONTree)?.editByPath([0, 1], [1, 1])

try (root.tree as? JSONTree)?.style(0, 1, ["b": "t", "i": "t"])

let xml = (root.tree as? JSONTree)?.toXML()

XCTAssertEqual(xml, "<r><p b=\"t\" i=\"t\">14</p></r>")

try (root.tree as? JSONTree)?.removeStyle(0, 1, ["i"])
}

let xml = await(doc.getRoot().tree as? JSONTree)?.toXML()
let size = try await(doc.getRoot().tree as? JSONTree)?.getSize()

XCTAssertEqual(xml, "<r><p>14</p></r>")
XCTAssertEqual(xml, "<r><p b=\"t\">14</p></r>")
XCTAssertEqual(size, 4)

let bytes = try await Converter.objectToBytes(obj: doc.getRootObject())
Expand Down
10 changes: 10 additions & 0 deletions Tests/Unit/Document/CRDT/RHTTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,16 @@ class RHTTests: XCTestCase {
XCTAssertEqual(result[key]?.value, value)
}
}

func test_should_deepcopy_correctly() {
let rht = RHT()
rht.set(key: "key1", value: "value1", executedAt: timeT())
rht.remove(key: "key2", executedAt: timeT())

let rht2 = rht.deepcopy()
XCTAssertEqual(rht.toJSON(), rht2.toJSON())
XCTAssertEqual(rht.size, rht2.size)
}
}

final class GCTestsForRHT: XCTestCase {
Expand Down

0 comments on commit 01142d8

Please sign in to comment.