1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// Copyright (c) 2025-2026 Adrian Robinson. Licensed under the AGPL-3.0.
// See LICENSE file in the project root for full license text.
//! Path-based Merkle tree for efficient sync verification.
//!
//! # Design
//!
//! Uses reverse DNS object IDs to create a natural tree structure:
//!
//! ```text
//! uk.nhs.patient.record.123
//!
//! Becomes:
//!
//! uk ─────────────────── hash(nhs)
//! └── nhs ───────────── hash(patient)
//! └── patient ───── hash(record)
//! └── record ── hash(123, 456, ...)
//! ├── 123 ─ leaf hash
//! └── 456 ─ leaf hash
//! ```
//!
//! # Storage Strategy
//!
//! Merkle nodes are stored **separately** from data in Redis:
//!
//! - `data:uk.nhs.patient.record.123` → SyncItem (evictable by tan curve)
//! - `merkle:hash:uk.nhs.patient.record` → 32-byte hash (NEVER evicted)
//! - `merkle:children:uk.nhs.patient.record` → sorted set of child:hash pairs
//!
//! This allows efficient sync verification even when data is evicted from cache.
//!
//! # Sync Protocol
//!
//! 1. Client sends their root hash
//! 2. If different, server sends top-level children with hashes
//! 3. Client identifies differing branches
//! 4. Drill down until leaves are reached
//! 5. Transfer only the differing items
//!
//! This is O(diff_size × tree_depth) instead of O(total_items).
// Keep redis_store for backwards compatibility during migration
pub use ;
pub use MerkleCacheStore;
pub use SqlMerkleStore;
// Re-export old name for backwards compatibility
pub use RedisMerkleStore;