Skip to content

Commit

Permalink
Remove node from indexes during GC (#191)
Browse files Browse the repository at this point in the history
* Remove node from indexes during GC

* Add test case for removing node from indexes during GC
  • Loading branch information
hiddenviewer authored Nov 4, 2024
1 parent 13ac1a5 commit 128ccae
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 14 deletions.
14 changes: 10 additions & 4 deletions Sources/Document/CRDT/CRDTText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -313,11 +313,17 @@ final class CRDTText: CRDTElement {
}

/**
* `checkWeight` returns false when there is an incorrect weight node.
* for debugging purpose.
* `getTreeByIndex` returns the tree by index for debugging.
*/
func getTreeByIndex() -> SplayTree<CRDTTextValue> {
return self.rgaTreeSplit.getTreeByIndex()
}

/**
* `getTreeByID` returns the tree by ID for debugging.
*/
func checkWeight() -> Bool {
self.rgaTreeSplit.checkWeight()
func getTreeByID() -> LLRBTree<RGATreeSplitNodeID, RGATreeSplitNode<CRDTTextValue>> {
return self.rgaTreeSplit.getTreeByID()
}

/**
Expand Down
16 changes: 12 additions & 4 deletions Sources/Document/CRDT/RGATreeSplit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -535,11 +535,17 @@ class RGATreeSplit<T: RGATreeSplitValue> {
}

/**
* `checkWeight` returns false when there is an incorrect weight node.
* for debugging purpose.
* `getTreeByIndex` returns the tree by index for debugging purpose.
*/
public func getTreeByIndex() -> SplayTree<T> {
return self.treeByIndex
}

/**
* `getTreeByID` returns the tree by ID for debugging purpose.
*/
public func checkWeight() -> Bool {
self.treeByIndex.checkWeight()
public func getTreeByID() -> LLRBTree<RGATreeSplitNodeID, RGATreeSplitNode<T>> {
return self.treeByID
}

/**
Expand Down Expand Up @@ -849,6 +855,8 @@ extension RGATreeSplit: GCParent {
guard let node = node as? RGATreeSplitNode<T> else {
return
}
self.treeByIndex.delete(node)
self.treeByID.remove(node.id)

node.prev?.setNext(node.next)
node.next?.setPrev(node.prev)
Expand Down
14 changes: 10 additions & 4 deletions Sources/Document/Json/JSONText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,17 @@ public class JSONText {
}

/**
* `checkWeight` returns false when there is an incorrect weight node.
* for debugging purpose.
* `getTreeByIndex` returns the tree by index for debugging.
*/
func getTreeByIndex() -> SplayTree<CRDTTextValue>? {
return self.text?.getTreeByIndex()
}

/**
* `getTreeByID` returns the tree by ID for debugging.
*/
public func checkWeight() -> Bool {
self.text?.checkWeight() ?? false
func getTreeByID() -> LLRBTree<RGATreeSplitNodeID, RGATreeSplitNode<CRDTTextValue>>? {
return self.text?.getTreeByID()
}

/**
Expand Down
4 changes: 2 additions & 2 deletions Tests/Integration/TextIntegrationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@ final class TextIntegrationTests: XCTestCase {
try await c2.sync()
try await c1.sync()

let d1Check = await(d1.getRoot().k1 as? JSONText)?.checkWeight() ?? false
let d2Check = await(d2.getRoot().k1 as? JSONText)?.checkWeight() ?? false
let d1Check = await(d1.getRoot().k1 as? JSONText)?.getTreeByIndex()?.checkWeight() ?? false
let d2Check = await(d2.getRoot().k1 as? JSONText)?.getTreeByIndex()?.checkWeight() ?? false
XCTAssertTrue(d1Check)
XCTAssertTrue(d2Check)
}
Expand Down
26 changes: 26 additions & 0 deletions Tests/Unit/Document/DocumentTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,32 @@ class DocumentTests: XCTestCase {
XCTAssertEqual(length, 0)
}

func test_should_purge_node_from_indexes_during_GC() async throws {
let doc = Document(key: "test-doc")

try await doc.update { root, _ in
root.k1 = JSONText()
}
var size = await(doc.getRoot().k1 as? JSONText)?.getTreeByID()?.size
XCTAssertEqual(size, 1)

try await doc.update { root, _ in
(root.k1 as? JSONText)?.edit(0, 0, "ABC")
}
size = await(doc.getRoot().k1 as? JSONText)?.getTreeByID()?.size
XCTAssertEqual(size, 2)

try await doc.update { root, _ in
(root.k1 as? JSONText)?.edit(1, 3, "")
}
size = await(doc.getRoot().k1 as? JSONText)?.getTreeByID()?.size
XCTAssertEqual(size, 3)

await doc.garbageCollect(TimeTicket.max)
size = await(doc.getRoot().k1 as? JSONText)?.getTreeByID()?.size
XCTAssertEqual(size, 2)
}

func test_escapes_string_for_object() async throws {
let target = Document(key: "test-doc")
try await target.update { root, _ in
Expand Down

0 comments on commit 128ccae

Please sign in to comment.