Crate crdt_lite

Crate crdt_lite 

Source
Expand description

§crdt-lite

A lightweight, column-based CRDT (Conflict-free Replicated Data Type) implementation in Rust.

This library provides a generic CRDT with last-write-wins semantics, supporting:

  • Generic key and value types
  • Logical clock for causality tracking
  • Tombstone-based deletion
  • Parent-child CRDT hierarchies
  • Custom merge rules and comparators
  • Change compression
  • Optional serialization support via Serde

§Features

This crate provides optional features through feature flags:

  • std - Enables standard library support (enabled by default)
  • alloc - Enables allocator support for no_std environments (pulls in hashbrown for HashMap)
  • serde - Enables Serde support for all CRDT types
  • json - Enables JSON serialization (includes serde + serde_json)
  • binary - Enables binary serialization (includes serde + bincode)
  • persist - Enables persistence layer with WAL and hooks (includes binary + std)
  • node-id-u128 - Uses u128 for NodeId instead of u64 (useful for UUID-based node IDs)

§no_std Support

For no_std environments, disable default features and enable the alloc feature:

[dependencies]
crdt-lite = { version = "0.2", default-features = false, features = ["alloc"] }

§Usage Example with Serialization

[dependencies]
crdt-lite = { version = "0.1", features = ["json", "binary"] }
use crdt_lite::CRDT;

// Create and populate a CRDT
let mut crdt: CRDT<String, String> = CRDT::new(1, None);
let fields = vec![("name".to_string(), "Alice".to_string())];
crdt.insert_or_update(&"user1".to_string(), fields);

// Serialize to JSON (requires "json" feature)
let json = crdt.to_json().unwrap();

// Deserialize from JSON
let restored: CRDT<String, String> = CRDT::from_json(&json).unwrap();

// Serialize to binary (requires "binary" feature)
let bytes = crdt.to_bytes().unwrap();
let restored: CRDT<String, String> = CRDT::from_bytes(&bytes).unwrap();

// Or use generic serde with any format (requires "serde" feature)
let json = serde_json::to_string(&crdt).unwrap();
let restored: CRDT<String, String> = serde_json::from_str(&json).unwrap();

Note on Parent Relationships: Parent-child CRDT hierarchies are not serialized. After deserialization, the parent field will always be None. Applications must rebuild parent-child relationships if needed.

§Security and Resource Management

§Logical Clock Overflow

The logical clock uses u64 for version numbers. While overflow is theoretically possible after 2^64 operations (extremely unlikely in practice), applications with extreme longevity should be aware of this limitation.

§DoS Protection and Tombstone Management

Tombstones accumulate indefinitely unless manually compacted. To prevent memory exhaustion:

  • Call compact_tombstones() periodically after all nodes have acknowledged a version
  • Implement application-level rate limiting for operations
  • Consider setting resource limits on the number of records and tombstones

Important: Only compact tombstones when ALL participating nodes have acknowledged the minimum version. Compacting too early may cause deleted records to reappear on nodes that haven’t received the deletion yet.

Structs§

CRDT
Main CRDT structure, generic over key (K), column (C), and value (V) types.
Change
Represents a single change in the CRDT.
ColumnVersion
Represents version information for a column.
DefaultChangeComparator
Default change comparator.
DefaultMergeRule
Default merge rule implementing last-write-wins semantics.
LogicalClock
Represents a logical clock for maintaining causality.
Record
Represents a record in the CRDT.
TombstoneInfo
Minimal version information for tombstones.
TombstoneStorage
Storage for tombstones (deleted records).

Traits§

ChangeComparator
Trait for change comparators used in sorting and compression.
MergeRule
Trait for merge rules that determine conflict resolution.

Type Aliases§

ColumnKey
Type alias for column keys (field names)
NodeId