Skip to main content

ConflictFreeMerger

Trait ConflictFreeMerger 

Source
pub trait ConflictFreeMerger<S: Store> {
    // Required method
    fn crdt_merge(
        &self,
        store: &S,
        base: &Tree,
        left: &Tree,
        right: &Tree,
        config: &CrdtConfig,
    ) -> Result<Tree, Error>;
}
Expand description

Trait for conflict-free merge operations using CRDT semantics.

Unlike the standard merge which can return Error::Conflict, implementations of this trait guarantee that merges always succeed by applying deterministic resolution strategies. This makes it suitable for distributed systems where concurrent modifications are common and automatic resolution is preferred.

This API performs a conflict-free three-way merge over immutable tree snapshots. The built-in LWW and multi-value resolvers are symmetric and deterministic for a fixed base. This is not an operation-log CRDT: callers must still retain ancestry, and custom resolvers are responsible for their own determinism and symmetry.

§Guarantees

  • Never returns Error::Conflict: All conflicts are automatically resolved
  • Deterministic built-ins: Same inputs produce the same output
  • Preserves non-conflicting changes: Changes to different keys are always preserved

§Type Parameters

  • S - The storage backend type implementing Store

§Example

use prolly::{Prolly, MemStore, Config, ConflictFreeMerger, DefaultConflictFreeMerger, CrdtConfig};

let store = MemStore::new();
let prolly = Prolly::new(store, Config::default());

let base = prolly.create();
let base = prolly.put(&base, b"key".to_vec(), b"value".to_vec()).unwrap();

// Create divergent branches
let left = prolly.put(&base, b"key".to_vec(), b"left".to_vec()).unwrap();
let right = prolly.put(&base, b"key".to_vec(), b"right".to_vec()).unwrap();

// CRDT merge never fails
let merger = DefaultConflictFreeMerger;
let config = CrdtConfig::default();
// merged = merger.crdt_merge(&store, &base, &left, &right, &config).unwrap();

Required Methods§

Source

fn crdt_merge( &self, store: &S, base: &Tree, left: &Tree, right: &Tree, config: &CrdtConfig, ) -> Result<Tree, Error>

Merge two trees without conflicts using CRDT semantics.

Performs a three-way merge using base as the common ancestor. All conflicts are automatically resolved using the configured strategy.

§Arguments
  • store - The storage backend
  • base - The common ancestor tree
  • left - The left branch tree
  • right - The right branch tree
  • config - CRDT configuration specifying merge strategy and policies
§Returns
  • Ok(Tree) - The merged tree (never returns Error::Conflict)
  • Err(Error) - Only on storage or deserialization errors
§Conflict Resolution

When both branches modify the same key differently:

  • LWW: Value with higher timestamp wins; ties broken lexicographically
  • MV: Both values are combined into a MultiValueSet
  • Custom: User-provided function determines the result

When one branch deletes and another modifies:

  • DeleteWins: Key is absent from result
  • UpdateWins: Key is present with the updated value

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§