1use backend::*;
2use patch::*;
3use rand;
4use std::collections::HashSet;
5use Result;
6
7impl<'env, T: rand::Rng> MutTxn<'env, T> {
8 pub fn apply(
11 &mut self,
12 branch: &mut Branch,
13 patch: &Patch,
14 patch_id: PatchId,
15 timestamp: ApplyTimestamp,
16 ) -> Result<()> {
17 assert!(self.put_patches(&mut branch.patches, patch_id, timestamp)?);
18 assert!(self.put_revpatches(&mut branch.revpatches, timestamp, patch_id)?);
19 debug!("apply_raw");
20 for ch in patch.changes().iter() {
25 if let Change::NewNodes {
26 ref up_context,
27 ref down_context,
28 ref line_num,
29 flag,
30 ref nodes,
31 ..
32 } = *ch
33 {
34 assert!(!nodes.is_empty());
35 debug!("apply: newnodes");
36 self.add_new_nodes(
37 branch,
38 patch_id,
39 up_context,
40 down_context,
41 line_num,
42 flag,
43 nodes,
44 )?;
45 }
46 }
47 let mut parents: HashSet<Key<PatchId>> = HashSet::new();
48 let mut children: HashSet<Edge> = HashSet::new();
49 for ch in patch.changes().iter() {
50 if let Change::NewEdges {
51 previous,
52 flag,
53 ref edges,
54 ..
55 } = *ch
56 {
57 self.add_new_edges(
58 branch,
59 patch_id,
60 Some(previous),
61 flag,
62 edges,
63 &mut parents,
64 &mut children,
65 )?;
66 debug!("apply_raw:edges.done");
67 }
68 }
69
70 self.repair_deleted_contexts(branch, patch, patch_id)?;
74
75 Ok(())
76 }
77
78 fn delete_old_edge(
80 &mut self,
81 branch: &mut Branch,
82 patch_id: PatchId,
83 previous: EdgeFlags,
84 from: Key<PatchId>,
85 to: Key<PatchId>,
86 introduced_by: PatchId,
87 ) -> Result<()> {
88 debug!(
89 "delete {:?} -> {:?} ({:?}) {:?}",
90 from, to, previous, introduced_by
91 );
92 let mut deleted_e = Edge {
94 flag: previous,
95 dest: to,
96 introduced_by,
97 };
98 self.put_cemetery(from, &deleted_e, patch_id)?;
99 if !self.del_nodes_with_rev(branch, from, deleted_e)? {
100 debug!("killing pseudo instead {:?} {:?}", from, deleted_e);
101 deleted_e.flag |= EdgeFlags::PSEUDO_EDGE;
102 let result = self.del_nodes_with_rev(branch, from, deleted_e)?;
103 debug!("killed ? {:?}", result);
104 }
105 Ok(())
106 }
107
108 fn add_new_edges(
109 &mut self,
110 branch: &mut Branch,
111 patch_id: PatchId,
112 previous: Option<EdgeFlags>,
113 flag: EdgeFlags,
114 edges: &[NewEdge],
115 parents: &mut HashSet<Key<PatchId>>,
116 children: &mut HashSet<Edge>,
117 ) -> Result<()> {
118 for e in edges {
119 debug!("add_new_edges {:?}", e);
120 let e_from = self.internal_key(&e.from, patch_id);
123 let e_to = self.internal_key(&e.to, patch_id);
124 assert!(e_from != e_to);
125 let to = if flag.contains(EdgeFlags::PARENT_EDGE) {
126 e_from
127 } else {
128 e_to
129 };
130
131 if flag.contains(EdgeFlags::DELETED_EDGE) && !flag.contains(EdgeFlags::FOLDER_EDGE) {
133 self.reconnect_parents_children(branch, patch_id, to, parents, children)?;
134 }
135
136 let introduced_by = self.internal_hash(&e.introduced_by, patch_id);
137
138 if let Some(previous) = previous {
139 self.delete_old_edge(branch, patch_id, previous, e_from, e_to, introduced_by)?
140 }
141
142 if flag.contains(EdgeFlags::DELETED_EDGE) && !flag.contains(EdgeFlags::FOLDER_EDGE) {
143 self.delete_old_pseudo_edges(branch, patch_id, to, children)?
144 }
145
146 let e = Edge {
148 flag,
149 dest: e_to,
150 introduced_by: patch_id.clone(),
151 };
152
153 self.put_nodes_with_rev(branch, e_from, e)?;
155 }
156 Ok(())
157 }
158
159 pub fn reconnect_parents_children(
163 &mut self,
164 branch: &mut Branch,
165 patch_id: PatchId,
166 to: Key<PatchId>,
167 parents: &mut HashSet<Key<PatchId>>,
168 children: &mut HashSet<Edge>,
169 ) -> Result<()> {
170 let mut edge = Edge::zero(EdgeFlags::PARENT_EDGE);
172 parents.clear();
173 parents.extend(
174 self.iter_nodes(&branch, Some((to, Some(&edge))))
175 .take_while(|&(k, v)| {
176 k == to && v.flag <= EdgeFlags::PARENT_EDGE | EdgeFlags::PSEUDO_EDGE
177 })
178 .filter_map(|(_, v)| {
179 if !v.flag.contains(EdgeFlags::EPSILON_EDGE)
180 && self.is_alive_or_zombie(branch, v.dest)
181 {
182 Some(v.dest)
183 } else {
184 None
185 }
186 }),
187 );
188
189 edge.flag = EdgeFlags::empty();
191 children.clear();
192 children.extend(
193 self.iter_nodes(&branch, Some((to, Some(&edge))))
194 .take_while(|&(k, v)| {
195 k == to && v.flag <= EdgeFlags::PSEUDO_EDGE | EdgeFlags::FOLDER_EDGE
196 })
197 .map(|(_, e)| *e),
198 );
199
200 debug!("reconnecting {:?} {:?}", parents, children);
201
202 for &parent in parents.iter() {
203 for e in children.iter() {
204 if parent != e.dest && !self.is_connected(branch, parent, e.dest) {
208 let pseudo_edge = Edge {
209 flag: e.flag | EdgeFlags::PSEUDO_EDGE,
210 dest: e.dest,
211 introduced_by: patch_id.clone(),
212 };
213 debug!("reconnect_parents_children: {:?} {:?}", parent, pseudo_edge);
214 self.put_nodes_with_rev(branch, parent, pseudo_edge)?;
215 }
216 }
217 }
218 Ok(())
219 }
220
221 fn delete_old_pseudo_edges(
222 &mut self,
223 branch: &mut Branch,
224 patch_id: PatchId,
225 to: Key<PatchId>,
226 pseudo_edges: &mut HashSet<Edge>,
227 ) -> Result<()> {
228 pseudo_edges.clear();
230 for (_, to_edge) in self.iter_nodes(branch, Some((to, None)))
231 .take_while(|&(k, v)| k == to && v.flag < EdgeFlags::DELETED_EDGE)
232 .filter(|&(_, v)| v.flag.contains(EdgeFlags::PSEUDO_EDGE))
233 {
234 let mut e = Edge::zero(
239 EdgeFlags::DELETED_EDGE
240 | (to_edge.flag & (EdgeFlags::PARENT_EDGE | EdgeFlags::FOLDER_EDGE)),
241 );
242 e.dest = to_edge.dest;
243 let mut is_zombie_marker = to_edge.introduced_by != patch_id
244 && (match self.iter_nodes(branch, Some((to, Some(&e)))).next() {
245 Some((k, v)) if k == to && v.dest == e.dest && v.flag == e.flag => {
246 v.introduced_by != patch_id
247 }
248 _ => false,
249 });
250 debug!(
251 "is_zombie_marker {:?}: {:?}",
252 to_edge.dest, is_zombie_marker
253 );
254 if !is_zombie_marker {
255 pseudo_edges.insert(*to_edge);
257 }
258 }
259 debug!("killing pseudo-edges from {:?}: {:?}", to, pseudo_edges);
260 for edge in pseudo_edges.drain() {
261 self.del_nodes_with_rev(branch, to, edge)?;
263 }
264 Ok(())
265 }
266
267 fn add_new_nodes(
269 &mut self,
270 branch: &mut Branch,
271 patch_id: PatchId,
272 up_context: &[Key<Option<Hash>>],
273 down_context: &[Key<Option<Hash>>],
274 line_num: &LineId,
275 flag: EdgeFlags,
276 nodes: &[Vec<u8>],
277 ) -> Result<()> {
278 debug!("up_context {:?}", up_context);
279 debug!("down_context {:?}", up_context);
280 let mut v = Key {
281 patch: patch_id.clone(),
282 line: line_num.clone(),
283 };
284 let mut e = Edge {
285 flag: flag ^ EdgeFlags::PARENT_EDGE,
286 dest: ROOT_KEY,
287 introduced_by: patch_id,
288 };
289
290 for c in up_context {
292 e.dest = self.internal_key(c, patch_id);
293 debug!("up_context: put_nodes {:?} {:?}", v, e);
294 self.put_nodes_with_rev(branch, v, e)?;
295 }
296 debug!("up context done");
297
298 e.flag = flag;
300 e.dest.patch = patch_id;
301
302 let mut nodes = nodes.iter();
303 if let Some(first_line) = nodes.next() {
304 debug!("first_line = {:?}", first_line);
305 let value = self.alloc_value(&first_line)?;
306 debug!("put_contents {:?} {:?}", v, value);
307 self.put_contents(v, value)?;
308 }
309 for content in nodes {
310 e.dest.line = v.line + 1;
311 self.put_nodes_with_rev(branch, v, e)?;
312
313 v.line = e.dest.line;
314
315 if !content.is_empty() {
316 let value = self.alloc_value(&content)?;
317 debug!("put_contents {:?} {:?}", v, value);
318 self.put_contents(v, value)?;
319 }
320 }
321 debug!("newnodes core done");
322
323 for c in down_context {
325 e.dest = self.internal_key(c, patch_id);
326 self.put_nodes_with_rev(branch, v, e)?;
327 }
328 debug!("down context done");
329 Ok(())
330 }
331}