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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
//!
//! Three-way merge for persistent B+ trees.
//!
//! # Merge semantics: source wins on conflicts
//!
//! Given an **ancestor** (common base), a **source** branch, and a
//! **target** branch, the merge compares each key across all three
//! snapshots and applies these rules:
//!
//! 1. **Non-conflict (single-sided change):** if only one side differs
//! from the ancestor, keep that side's change.
//! 2. **Conflict (both sides changed the same key differently):**
//! **source wins**.
//!
//! A deletion is treated as "assigning the empty value ∅". This means
//! delete-vs-modify is also a regular conflict, so source-side delete
//! wins over target-side modify.
//!
//! ## Complete decision matrix
//!
//! | ancestor | source | target | result | rationale |
//! |----------|--------|--------|-----------------|-------------------------------|
//! | A | A | A | A (keep) | no change on either side |
//! | A | **S** | A | **S** | only source changed |
//! | A | A | **T** | **T** | only target changed |
//! | A | **S** | **S** | **S** | both changed to same value |
//! | A | **S** | **T** | **S** ⚠ | conflict → source wins |
//! | A | ∅ | A | ∅ (delete) | source deleted, target unchanged → source wins |
//! | A | A | ∅ | ∅ (delete) | target deleted, source unchanged → target wins (no conflict) |
//! | A | ∅ | **T** | ∅ (delete) ⚠ | conflict → source wins (delete beats modify) |
//! | A | **S** | ∅ | **S** ⚠ | conflict → source wins (modify beats delete) |
//! | A | ∅ | ∅ | ∅ (delete) | both deleted |
//! | ∅ | **S** | ∅ | **S** | only source added |
//! | ∅ | ∅ | **T** | **T** | only target added |
//! | ∅ | **S** | **S** | **S** | both added same value |
//! | ∅ | **S** | **T** | **S** ⚠ | conflict → source wins |
//!
//! Rows marked ⚠ are conflict cases (source wins). Non-⚠ rows are
//! single-sided or non-conflicting updates determined by ancestor
//! comparison. The caller controls priority by choosing which branch
//! to pass as `source` vs `target` in
//! [`VerMap::merge(source, target)`](crate::versioned::map::VerMap::merge).
//!
//! ## Implementation: replay the source delta onto the target
//!
//! Every row of the matrix reduces to one rule: a key whose source state
//! differs from the ancestor takes the source state (added, modified, or
//! deleted); every other key keeps the target state. The merge therefore
//! computes `diff(ancestor → source)` — which skips shared subtrees — and
//! applies exactly those keys to the target tree by copy-on-write. Replay
//! work and buffering follow the changed paths. Diff traversal depends on
//! structural sharing and can scan an entire unshared tree; untouched
//! subtrees of the target remain shared where the COW paths permit it.
//!
use BTreeMap;
use ;
/// Performs a three-way merge.
///
/// Deletion is treated as "assigning ∅", so all conflicts — including
/// delete-vs-modify — are resolved uniformly: **source wins**.
///
/// See the [module-level documentation](self) for the full decision
/// matrix.
///
/// Like [`PersistentBTree::bulk_load`], a newly built result root is
/// returned **unowned**: the caller adopts it with
/// [`PersistentBTree::acquire_node`].
/// Performs a three-way merge against one or more merge bases.
///
/// When multiple lowest common ancestors exist, keys whose base values differ
/// are treated as criss-cross conflicts; if source and target differ, source
/// wins. Keys whose base values agree use the normal decision matrix.
///
/// A key whose bases disagree necessarily differs from at least one base
/// on the source side, so replaying the union of the per-base source
/// deltas yields exactly that rule.
/// Every key where `source` differs from any of `bases`, mapped to the
/// source state (`None` = absent), in ascending key order.
/// Applies `changes` to `target_root` by copy-on-write and returns the
/// resulting root (unowned when newly built; `target_root` itself when
/// nothing changed).
///
/// All steps share one write buffer: each intermediate version is held
/// only until the next one exists, and its superseded nodes are dropped
/// from the buffer before they reach the engine — only nodes reachable
/// from the final root are written.