1use std::{time::Duration, time::Instant};
16
17use crate::driver::{
18 AbortSignal, DefaultAbortSignal, DefaultDriver, Driver, TelemetryEvent, TreeStats,
19};
20use crate::error::Error;
21use crate::guid::Guid;
22use crate::merge::{MergedRoot, Merger};
23use crate::tree::Tree;
24
25pub trait Store {
29 type Ok;
31
32 type Error: From<Error>;
34
35 fn fetch_local_tree(&self) -> Result<Tree, Self::Error>;
38
39 fn fetch_remote_tree(&self) -> Result<Tree, Self::Error>;
42
43 fn apply<'t>(&mut self, root: MergedRoot<'t>) -> Result<Self::Ok, Self::Error>;
48
49 fn merge(&mut self) -> Result<Self::Ok, Self::Error> {
51 self.merge_with_driver(&DefaultDriver, &DefaultAbortSignal)
52 }
53
54 fn merge_with_driver(
58 &mut self,
59 driver: &impl Driver,
60 signal: &impl AbortSignal,
61 ) -> Result<Self::Ok, Self::Error> {
62 signal.err_if_aborted()?;
63 debug!(driver, "Building local tree");
64 let (local_tree, time) = with_timing(|| self.fetch_local_tree())?;
65 driver.record_telemetry_event(TelemetryEvent::FetchLocalTree(TreeStats {
66 items: local_tree.size(),
67 deletions: local_tree.deletions().len(),
68 problems: local_tree.problems().counts(),
69 time,
70 }));
71 trace!(driver, "Built local tree from mirror\n{}", local_tree);
72
73 signal.err_if_aborted()?;
74 debug!(driver, "Building remote tree");
75 let (remote_tree, time) = with_timing(|| self.fetch_remote_tree())?;
76 driver.record_telemetry_event(TelemetryEvent::FetchRemoteTree(TreeStats {
77 items: remote_tree.size(),
78 deletions: local_tree.deletions().len(),
79 problems: remote_tree.problems().counts(),
80 time,
81 }));
82 trace!(driver, "Built remote tree from mirror\n{}", remote_tree);
83
84 signal.err_if_aborted()?;
85 debug!(driver, "Building merged tree");
86 let merger = Merger::with_driver(driver, signal, &local_tree, &remote_tree);
87 let (merged_root, time) = with_timing(|| merger.merge())?;
88 driver.record_telemetry_event(TelemetryEvent::Merge(time, *merged_root.counts()));
89 trace!(
90 driver,
91 "Built new merged tree\n{}\nDelete Locally: [{}]\nDelete Remotely: [{}]",
92 merged_root.node().to_ascii_string(),
93 merged_root
94 .local_deletions()
95 .map(Guid::as_str)
96 .collect::<Vec<_>>()
97 .join(", "),
98 merged_root
99 .remote_deletions()
100 .map(Guid::as_str)
101 .collect::<Vec<_>>()
102 .join(", ")
103 );
104
105 signal.err_if_aborted()?;
106 debug!(driver, "Applying merged tree");
107 let (result, time) = with_timing(|| self.apply(merged_root))?;
108 driver.record_telemetry_event(TelemetryEvent::Apply(time));
109
110 Ok(result)
111 }
112}
113
114fn with_timing<T, E>(run: impl FnOnce() -> Result<T, E>) -> Result<(T, Duration), E> {
115 let now = Instant::now();
116 run().map(|value| (value, now.elapsed()))
117}