Skip to content

Commit

Permalink
refactor(crdt): update revert method and remove reset_to
Browse files Browse the repository at this point in the history
Modify revert to accept optional override parent, remove reset_to
method, and comment out revert-related test code in main function
  • Loading branch information
sinkingsugar committed Oct 10, 2024
1 parent 42b584e commit e68d948
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 34 deletions.
39 changes: 9 additions & 30 deletions crdt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,45 +301,24 @@ class CRDT : public std::enable_shared_from_this<CRDT<K, V, MergeRuleType, Chang
/// # Complexity
///
/// O(c), where c is the number of changes since `base_version_`
constexpr CrdtVector<Change<K, V>> revert() {
if (!parent_) {
throw std::runtime_error("Cannot revert without a parent CRDT.");
constexpr CrdtVector<Change<K, V>>
revert(const CRDT<K, V, MergeRuleType, ChangeComparatorType, SortFunctionType> *override_parent = nullptr) {
const CRDT<K, V, MergeRuleType, ChangeComparatorType, SortFunctionType> *reference_crdt =
override_parent ? override_parent : parent_;

if (!reference_crdt) {
throw std::runtime_error("Cannot revert without a parent CRDT or override parent.");
}

// Step 1: Retrieve all changes made by the child since base_version_
CrdtVector<Change<K, V>> child_changes = this->get_changes_since(base_version_);

// Step 2: Generate inverse changes using the parent as the reference CRDT
CrdtVector<Change<K, V>> inverse_changes = invert_changes(child_changes, *parent_);
// Step 2: Generate inverse changes using the reference CRDT
CrdtVector<Change<K, V>> inverse_changes = invert_changes(child_changes, *reference_crdt);

return inverse_changes;
}

/// Resets the CRDT to a state based on a reference CRDT and a set of changes.
///
/// # Arguments
///
/// * `reference_crdt` - A reference CRDT to use as the base state.
/// * `changes` - A vector of changes to apply after resetting to the reference state.
///
/// Complexity: O(n + m), where n is the number of records in the reference CRDT and m is the number of changes
constexpr void reset_to(const CRDT<K, V, MergeRuleType, ChangeComparatorType, SortFunctionType> &reference_crdt,
CrdtVector<Change<K, V>> &&changes = {}) {
// Clear existing data
data_.clear();
tombstones_.clear();

// Copy the state from the reference CRDT
data_ = reference_crdt.data_;
tombstones_ = reference_crdt.tombstones_;
clock_ = reference_crdt.clock_;

// Apply the provided changes
if (!changes.empty()) {
apply_changes(std::move(changes));
}
}

/// Inserts a new record or updates an existing record in the CRDT.
///
/// # Arguments
Expand Down
8 changes: 4 additions & 4 deletions tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1130,14 +1130,14 @@ int main() {
assert_true(child_crdt.get_data().at(record_id_parent).fields.at("child_field2") == "child_value2",
"Revert Test 1: Child should have 'child_field2' with 'child_value2'");

// Step 4: Revert Child CRDT
CrdtVector<Change<CrdtString, CrdtString>> inverse_changes = child_crdt.revert();
// // Step 4: Revert Child CRDT
// CrdtVector<Change<CrdtString, CrdtString>> inverse_changes = child_crdt.revert();

//! Cannot work because inverse_changes is in a special format that cannot be simply merged back into the CRDT
//! it is meant to be used by the application layer to revert changes, not by the CRDT itself for now

// Apply inverse changes to child CRDT to undo modifications
child_crdt.merge_changes(std::move(inverse_changes), true);
// // Apply inverse changes to child CRDT to undo modifications
// child_crdt.merge_changes(std::move(inverse_changes), true);

// // Step 5: Validate States
// // Child should now match the parent
Expand Down

0 comments on commit e68d948

Please sign in to comment.