Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply GCPair to TreeNode, TextNode #174

Merged
merged 1 commit into from
May 28, 2024
Merged

Apply GCPair to TreeNode, TextNode #174

merged 1 commit into from
May 28, 2024

Conversation

humdrum
Copy link
Contributor

@humdrum humdrum commented May 28, 2024

What this PR does / why we need it:

Which issue(s) this PR fixes:

Fixes #

Special notes for your reviewer:

Does this PR introduce a user-facing change?:


Additional documentation:


Checklist:

  • Added relevant tests or not required
  • Didn't break anything

Summary by CodeRabbit

  • New Features

    • Enhanced garbage collection handling within CRDT elements.
    • Improved text and tree node editing operations with better garbage collection support.
  • Refactor

    • Renamed TextValue to CRDTTextValue.
    • Renamed removedElementSetByCreatedAt to gcElementSetByCreatedAt.
    • Removed CRDTGCElement protocol and associated methods.
  • Bug Fixes

    • Improved garbage collection logic to handle removed nodes more efficiently.
  • Tests

    • Updated test cases to reflect changes in garbage collection and element editing.
    • Added new test scenarios for garbage collection in tree nodes.

@humdrum humdrum self-assigned this May 28, 2024
Copy link
Contributor

coderabbitai bot commented May 28, 2024

Walkthrough

The recent updates focus on enhancing the CRDT (Conflict-free Replicated Data Type) implementation by refining garbage collection (GC) mechanisms, renaming elements for clarity, and improving type consistency across various components. Key changes include renaming TextValue to CRDTTextValue, removing the CRDTGCElement protocol, and updating GC-related methods and properties.

Changes

File(s) Change Summary
Sources/API/Converter.swift Updated generic type from TextValue to CRDTTextValue in several functions.
Sources/Document/CRDT/CRDTElement.swift Removed the CRDTGCElement protocol.
Sources/Document/CRDT/CRDTRoot.swift Renamed removedElementSetByCreatedAt to gcElementSetByCreatedAt and refactored GC logic.
Sources/Document/CRDT/CRDTText.swift Renamed TextValue to CRDTTextValue, updated methods, and introduced RHT for attributes.
Sources/Document/CRDT/CRDTTree.swift Added GC handling functions and updated edit method signature to include [GCPair].
Sources/Document/CRDT/GC.swift Added CRDTGCPairContainable protocol for elements with GC pairs.
Sources/Document/CRDT/RGATreeSplit.swift Refactored GC handling in edit method, added GCChild and GCParent extensions, and introduced purge method.
Sources/Document/Change/ChangeContext.swift Removed registerElementHasRemovedNodes function.
Sources/Document/Document.swift Renamed removedElementSetSize to garbageElementSetSize in logging output.
Sources/Document/Json/JSONText.swift Updated edit method to handle pairs and modified values property type.
Sources/Document/Json/JSONTree.swift Updated edit method to handle pairs and adjusted logic for registering changes.
Sources/Document/Operation/EditOperation.swift Modified edit handling to process and register pairs.
Sources/Document/Operation/TreeEditOperation.swift Updated edit method to handle pairs and adjusted logic for registering changes.
Tests/Unit/Document/CRDT/CRDTRootTests.swift Updated test case to use garbageElementSetSize instead of removedElementSetSize.
Tests/Unit/Document/GCTests.swift Renamed and added test functions to handle new GC logic for text and tree nodes.

In the code where bytes do play,
Changes bring a brighter day.
Text and nodes, they now align,
Garbage gone, the code refined.
With each merge, the future's bright,
Bugs take flight, in the coder's night.
🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to full the review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented May 28, 2024

Codecov Report

Attention: Patch coverage is 70.37037% with 48 lines in your changes are missing coverage. Please review.

Project coverage is 42.91%. Comparing base (1008774) to head (5762032).

Files Patch % Lines
Sources/Document/CRDT/CRDTTree.swift 45.71% 19 Missing ⚠️
Sources/Document/CRDT/CRDTText.swift 33.33% 14 Missing ⚠️
Sources/API/Converter.swift 0.00% 4 Missing ⚠️
Sources/Document/CRDT/CRDTRoot.swift 85.71% 3 Missing ⚠️
Sources/Document/CRDT/RGATreeSplit.swift 88.23% 2 Missing ⚠️
Sources/Document/Document.swift 0.00% 2 Missing ⚠️
Tests/Unit/Document/GCTests.swift 95.74% 2 Missing ⚠️
Sources/Document/CRDT/RHT.swift 0.00% 1 Missing ⚠️
Sources/Document/Json/JSONText.swift 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #174      +/-   ##
==========================================
- Coverage   43.01%   42.91%   -0.11%     
==========================================
  Files         106      106              
  Lines       19252    19272      +20     
==========================================
- Hits         8282     8270      -12     
- Misses      10970    11002      +32     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@humdrum
Copy link
Contributor Author

humdrum commented May 28, 2024

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented May 28, 2024

Actions Performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Outside diff range and nitpick comments (4)
Sources/Document/CRDT/RGATreeSplit.swift (1)

Line range hint 441-484: Enhancements to the edit method to support garbage collection.

The edit method has been significantly extended to handle garbage collection. However, the method is quite long and handles multiple responsibilities. Consider refactoring it to improve modularity and maintainability:

@discardableResult
public func edit(_ range: RGATreeSplitPosRange, _ editedAt: TimeTicket, _ value: T?, _ maxCreatedAtMapByActor: [String: TimeTicket]? = nil) throws -> (RGATreeSplitPos, [String: TimeTicket], [GCPair], [ContentChange<T>]) {
    let splitResults = try splitNodes(range, editedAt)
    let deletionResults = try deleteNodes(splitResults.nodesToDelete, editedAt, maxCreatedAtMapByActor)
    let insertionResults = insertNode(splitResults.fromLeft, value)
    let gcPairs = generateGCPairs(deletionResults.removedNodes)

    return (insertionResults.caretPos, deletionResults.maxCreatedAtMap, gcPairs, insertionResults.changes)
}

This refactor breaks down the edit method into smaller, more focused methods like splitNodes, deleteNodes, insertNode, and generateGCPairs, each handling a specific part of the editing process.

Sources/Document/CRDT/CRDTTree.swift (3)

511-523: Add documentation for getGCPairs method.

The getGCPairs method lacks detailed documentation. It would be beneficial to explain what constitutes a "GC pair" and under what conditions a pair is added to the list. This will help future maintainers understand the logic and intent behind this method.


536-543: Clarify the purpose of toIDString in the context of garbage collection.

The toIDString method in the GCChild extension returns a string representation of the node's ID. It would be helpful to document how this ID string is utilized, particularly in the context of garbage collection processes, to ensure clarity for future developers.


Line range hint 725-871: Review the complex edit method for potential refactoring.

The edit method is quite lengthy and handles multiple responsibilities, including node deletion, merging, and insertion. Consider refactoring this method into smaller, more manageable functions. This can improve readability and maintainability. For instance, the deletion logic could be extracted into a separate method, as could the logic for node merging and insertion.

- func edit(_ range: TreePosRange, _ contents: [CRDTTreeNode]?, _ splitLevel: Int32, _ editedAt: TimeTicket, _ maxCreatedAtMapByActor: [String: TimeTicket] = [:], _ issueTimeTicket: () -> TimeTicket) throws -> ([TreeChange], [GCPair], [String: TimeTicket]) {
+ func edit(_ range: TreePosRange, _ contents: [CRDTTreeNode]?, _ splitLevel: Int32, _ editedAt: TimeTicket, _ maxCreatedAtMapByActor: [String: TimeTimeTicket] = [:], _ issueTimeTicket: () -> TimeTicket) throws -> ([TreeChange], [GCPair], [String: TimeTicket]) {
+    // Refactored code here...
+ }
Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 1008774 and 5762032.
Files selected for processing (16)
  • Sources/API/Converter.swift (3 hunks)
  • Sources/Document/CRDT/CRDTElement.swift (1 hunks)
  • Sources/Document/CRDT/CRDTRoot.swift (7 hunks)
  • Sources/Document/CRDT/CRDTText.swift (10 hunks)
  • Sources/Document/CRDT/CRDTTree.swift (9 hunks)
  • Sources/Document/CRDT/GC.swift (1 hunks)
  • Sources/Document/CRDT/RGATreeSplit.swift (8 hunks)
  • Sources/Document/CRDT/RHT.swift (1 hunks)
  • Sources/Document/Change/ChangeContext.swift (1 hunks)
  • Sources/Document/Document.swift (2 hunks)
  • Sources/Document/Json/JSONText.swift (3 hunks)
  • Sources/Document/Json/JSONTree.swift (2 hunks)
  • Sources/Document/Operation/EditOperation.swift (1 hunks)
  • Sources/Document/Operation/TreeEditOperation.swift (2 hunks)
  • Tests/Unit/Document/CRDT/CRDTRootTests.swift (1 hunks)
  • Tests/Unit/Document/GCTests.swift (3 hunks)
Files skipped from review due to trivial changes (3)
  • Sources/Document/CRDT/CRDTElement.swift
  • Sources/Document/CRDT/RHT.swift
  • Tests/Unit/Document/CRDT/CRDTRootTests.swift
Additional comments not posted (22)
Sources/Document/CRDT/GC.swift (1)

43-45: The addition of CRDTGCPairContainable protocol aligns well with the PR's objectives to enhance garbage collection mechanisms.

Sources/Document/Operation/EditOperation.swift (1)

76-79: The changes to handle GCPair registration after an edit operation are correctly implemented and align with the PR's objectives.

Verification successful

The registerGCPair function is correctly implemented in both ChangeContext.swift and CRDTRoot.swift. The function in ChangeContext.swift delegates the registration to the root, while the function in CRDTRoot.swift handles the registration logic, including checking and updating the gcPairMap.

The changes in EditOperation.swift to handle GCPair registration after an edit operation are consistent with the overall garbage collection system.

  • ChangeContext.swift implementation:

    func registerGCPair(_ pair: GCPair) {
        self.root.registerGCPair(pair)
    }
  • CRDTRoot.swift implementation:

    func registerGCPair(_ pair: GCPair) {
        guard let childID = pair.child?.toIDString else {
            return
        }
    
        if self.gcPairMap[childID] != nil {
            self.gcPairMap.removeValue(forKey: childID)
            return
        }
    
        self.gcPairMap[childID] = pair
    }

The integration of GCPair handling with the garbage collection system is properly implemented.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the integration of GCPair handling with the garbage collection system.

# Test: Search for the usage of `registerGCPair`. Expect: Proper handling in all occurrences.
rg --type swift $'registerGCPair'

Length of output: 1342



Script:

#!/bin/bash
# Description: Verify the implementation of `registerGCPair` in `ChangeContext.swift` and `CRDTRoot.swift`.

# Extract the implementation of `registerGCPair` in `ChangeContext.swift`
ast-grep --lang swift --pattern $'func registerGCPair($_) {
  $$$
}' --json

# Extract the implementation of `registerGCPair` in `CRDTRoot.swift`
ast-grep --lang swift --pattern $'func registerGCPair($_) {
  $$$
}' --json

Length of output: 2993

Sources/Document/Operation/TreeEditOperation.swift (1)

Line range hint 74-87: The changes to handle GCPair registration after a tree edit operation are correctly implemented and align with the PR's objectives.

Verification successful

The registerGCPair function is implemented correctly in both CRDTRoot and ChangeContext. The function in CRDTRoot ensures that the GCPair is properly managed within the gcPairMap, and the function in ChangeContext delegates the registration to CRDTRoot.

  • CRDTRoot.swift:

    • The function checks if the childID exists in gcPairMap.
    • If it exists, it removes the entry; otherwise, it adds the GCPair to the map.
  • ChangeContext.swift:

    • The function simply calls registerGCPair on self.root, ensuring the pair is registered in the root context.

These implementations confirm that the GCPair handling is integrated correctly with the garbage collection system.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the integration of GCPair handling with the garbage collection system in tree operations.

# Test: Search for the usage of `registerGCPair`. Expect: Proper handling in all occurrences.
rg --type swift $'registerGCPair'

Length of output: 1342



Script:

#!/bin/bash
# Extract the implementation of `registerGCPair` in `CRDTRoot.swift`
ast-grep --lang swift --pattern $'func registerGCPair(_ pair: GCPair) {
  $$$
}' Sources/Document/CRDT/CRDTRoot.swift

# Extract the implementation of `registerGCPair` in `ChangeContext.swift`
ast-grep --lang swift --pattern $'func registerGCPair(_ pair: GCPair) {
  $$$
}' Sources/Document/Change/ChangeContext.swift

Length of output: 1269

Sources/Document/Json/JSONText.swift (1)

89-97: The changes to handle GCPair registration after an edit operation in JSONText are correctly implemented and align with the PR's objectives.

Sources/Document/CRDT/CRDTRoot.swift (1)

Line range hint 38-64: The updates to CRDTRoot for handling garbage collection elements and GCPair registration are correctly implemented and align with the PR's objectives.

Also applies to: 123-130, 157-176, 210-226

Verification successful

The script output indicates that gcElementSetByCreatedAt and registerGCPair are used in multiple files, including CRDTRoot.swift, ChangeContext.swift, and various JSON and Operation files. This suggests a widespread integration of these elements.

To ensure proper integration, we need to verify the context in which these elements are used. Specifically, we should check if they are being used correctly for garbage collection purposes.

Let's proceed by examining the context of these occurrences in the relevant files.


The context provided by the script output shows that gcElementSetByCreatedAt and registerGCPair are used consistently across various files, including CRDTRoot.swift, ChangeContext.swift, and several JSON and Operation files. The usage aligns with the intended garbage collection mechanism, ensuring that elements are properly registered and managed for garbage collection.

The integration appears to be thorough and correctly implemented, with registerGCPair being called in appropriate contexts to register garbage collection pairs, and gcElementSetByCreatedAt being used to track elements for garbage collection.

Based on this detailed context, the changes to CRDTRoot.swift and related files are verified to be correctly implemented and consistent with the PR's objectives.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the integration of garbage collection handling in `CRDTRoot`.

# Test: Search for the usage of `gcElementSetByCreatedAt` and `registerGCPair`. Expect: Proper handling in all occurrences.
rg --type swift $'gcElementSetByCreatedAt|registerGCPair'

Length of output: 1980



Script:

#!/bin/bash
# Description: Verify the context of `gcElementSetByCreatedAt` and `registerGCPair` usage.

# Extract lines around the occurrences of `gcElementSetByCreatedAt` and `registerGCPair` for context.
rg --type swift --context 5 'gcElementSetByCreatedAt|registerGCPair'

Length of output: 13982

Sources/Document/CRDT/CRDTText.swift (8)

47-50: Renaming TextValue to CRDTTextValue aligns with the broader refactoring across the project.


78-79: The substring method correctly returns a new instance of CRDTTextValue, ensuring immutability.


143-151: The getGCPairs method efficiently collects garbage collection pairs, which is crucial for managing memory in CRDT structures.


154-154: The extension of CRDTTextValue to conform to GCParent is well-implemented, allowing for effective garbage collection.


176-176: The constructor and edit method in CRDTText have been updated to handle CRDTTextValue. The return type of the edit method now includes garbage collection pairs, which is a significant enhancement for memory management.

Also applies to: 190-190, 214-214


225-225: The setStyle method's implementation is robust, ensuring that only nodes that can be styled are processed. This method now also returns garbage collection pairs, enhancing the garbage management.

Also applies to: 241-241


358-358: The values property getter has been correctly updated to filter out removed nodes, which is essential for accurate data representation.


379-396: The extension of CRDTText to conform to CRDTGCPairContainable is correctly implemented, ensuring that all removable nodes and their attributes are considered for garbage collection.

Sources/Document/Json/JSONTree.swift (1)

481-487: The edit method in JSONTree has been enhanced to handle garbage collection pairs, which is crucial for maintaining the integrity and performance of the CRDT structure.

Tests/Unit/Document/GCTests.swift (2)

179-211: The test implementation for checking garbage collection with already removed text nodes is correct and well-structured.


368-418: The test implementation for checking garbage collection with already removed tree nodes is correct and well-structured.

Sources/Document/Document.swift (1)

Line range hint 436-510: The implementation of the applyChanges function correctly handles the application of changes and updates the garbage collection metrics appropriately.

Sources/Document/CRDT/RGATreeSplit.swift (2)

403-407: Implementation of GCChild protocol in RGATreeSplitNode.

The extension of RGATreeSplitNode to conform to GCChild with the toIDString property is well-implemented. It leverages the existing toIDString method of RGATreeSplitNodeID, ensuring consistency with ID string generation across the application.


844-850: Implementation of purge method in GCParent protocol.

The purge method correctly handles the disconnection of a node from its neighbors in the linked list structure, ensuring that all references are properly cleared to avoid memory leaks. This is crucial for the correct management of garbage collection.

Sources/API/Converter.swift (3)

1015-1015: Updated type in toTextNodes function to CRDTTextValue maintains consistency with the new class definition.

Verification successful

The renaming of TextValue to CRDTTextValue has been consistently applied across the codebase. No remaining instances of TextValue were found.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that the renaming of `TextValue` to `CRDTTextValue` is consistently applied across the codebase.

# Test: Search for any remaining instances of `TextValue`. Expect: No occurrences.
rg --type swift "TextValue"

Length of output: 1581


1039-1040: Updated type in fromTextNode function to CRDTTextValue ensures consistency with the new class definition.

Verification successful

The renaming of TextValue to CRDTTextValue has been consistently applied across the codebase. No remaining instances of TextValue were found.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that the renaming of `TextValue` to `CRDTTextValue` is consistently applied across the codebase.

# Test: Search for any remaining instances of `TextValue`. Expect: No occurrences.
rg --type swift "TextValue"

Length of output: 1581


701-701: Renaming TextValue to CRDTTextValue aligns with the broader refactoring goals.

Verification successful

The renaming of TextValue to CRDTTextValue has been consistently applied across the codebase.

  • Sources/Document/Json/JSONText.swift
  • Sources/Document/CRDT/CRDTText.swift
  • Sources/API/Converter.swift
Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that the renaming of `TextValue` to `CRDTTextValue` is consistently applied across the codebase.

# Test: Search for any remaining instances of `TextValue`. Expect: No occurrences.
rg --type swift "TextValue"

Length of output: 1581

Comment on lines +352 to +356
let justRemoved = self.removedAt == nil
if !self.createdAt.after(maxCreatedAt) && (self.removedAt == nil || editedAt.after(self.removedAt!)) {
return justRemoved
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider simplifying the canDelete method's logic.

The current implementation of canDelete uses a temporary variable justRemoved and a somewhat complex conditional structure. This can be simplified for better readability and efficiency:

func canDelete(_ editedAt: TimeTicket, _ maxCreatedAt: TimeTicket) -> Bool {
    return self.removedAt == nil && !self.createdAt.after(maxCreatedAt) && (self.removedAt == nil || editedAt.after(self.removedAt!))
}

This version directly returns the result of the logical condition, making the code cleaner and easier to understand.

Comment on lines +1254 to +1271
extension CRDTTree: CRDTGCPairContainable {
/**
* `getGCPairs` returns the pairs of GC.
*/
func getGCPairs() -> [GCPair] {
var pairs = [GCPair]()
self.indexTree.traverse { node, _ in
if node.removedAt != nil {
pairs.append(GCPair(parent: self, child: node))
}

for pair in node.getGCPairs() {
pairs.append(pair)
}
}

return pairs
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

The search results indicate that there are numerous tests related to CRDTTree and garbage collection, but none specifically named test_getGCPairs. This suggests that while there may be indirect tests covering the functionality of getGCPairs, there are no direct unit tests for this method.

To ensure the traversal logic in getGCPairs is thoroughly validated, it would be prudent to add specific unit tests for this method. This will help verify that the method correctly identifies all nodes that should be collected.

  • Consider adding unit tests for getGCPairs to ensure the traversal logic is accurate and no nodes are missed.
Analysis chain

Validate the traversal logic in getGCPairs.

The getGCPairs method in the CRDTTree class performs a traversal to collect garbage collection pairs. It's crucial to ensure that this traversal correctly identifies all nodes that should be collected. Consider adding unit tests to verify that the traversal logic is accurate and that no nodes are missed.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the traversal logic in `getGCPairs`.

# Test: Search for unit tests related to `getGCPairs`. Expect: Tests that cover various tree configurations.
rg --type swift 'func test_getGCPairs'

Length of output: 40



Script:

#!/bin/bash
# Description: Verify the traversal logic in `getGCPairs` by searching for tests related to `CRDTTree`.

# Test: Search for unit tests related to `CRDTTree`. Expect: Tests that cover various tree configurations.
rg --type swift 'CRDTTree' --files-with-matches | xargs rg --type swift 'func test'

Length of output: 15388

@humdrum humdrum merged commit ec867c8 into main May 28, 2024
3 checks passed
@humdrum humdrum deleted the apply-gc branch May 28, 2024 11:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants