1 use crate::change::*;
2 use crate::small_string::*;
3 use crate::{HashMap, HashSet};
4 use parking_lot::{Mutex, RwLock};
5 use std::io::Write;
6 use std::sync::Arc;
7 
8 mod change_id;
9 pub use change_id::*;
10 mod vertex;
11 pub use vertex::*;
12 mod edge;
13 pub use edge::*;
14 mod hash;
15 pub use hash::*;
16 mod inode;
17 pub use inode::*;
18 mod inode_metadata;
19 pub use inode_metadata::*;
20 mod path_id;
21 pub use path_id::*;
22 mod merkle;
23 pub use merkle::*;
24 
25 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
26 pub struct L64(pub u64);
27 
28 impl From<usize> for L64 {
from(u: usize) -> Self29     fn from(u: usize) -> Self {
30         L64((u as u64).to_le())
31     }
32 }
33 
34 impl From<u64> for L64 {
from(u: u64) -> Self35     fn from(u: u64) -> Self {
36         L64(u.to_le())
37     }
38 }
39 
40 impl From<L64> for u64 {
from(u: L64) -> Self41     fn from(u: L64) -> Self {
42         u64::from_le(u.0)
43     }
44 }
45 
46 impl From<L64> for usize {
from(u: L64) -> Self47     fn from(u: L64) -> Self {
48         u64::from_le(u.0) as usize
49     }
50 }
51 
52 impl L64 {
as_u64(&self) -> u6453     pub fn as_u64(&self) -> u64 {
54         u64::from_le(self.0)
55     }
as_usize(&self) -> usize56     pub fn as_usize(&self) -> usize {
57         u64::from_le(self.0) as usize
58     }
59 }
60 
61 impl std::fmt::Display for L64 {
fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result62     fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
63         self.0.fmt(fmt)
64     }
65 }
66 
67 impl Ord for L64 {
cmp(&self, x: &Self) -> std::cmp::Ordering68     fn cmp(&self, x: &Self) -> std::cmp::Ordering {
69         u64::from_le(self.0).cmp(&u64::from_le(x.0))
70     }
71 }
72 
73 impl PartialOrd for L64 {
partial_cmp(&self, x: &Self) -> Option<std::cmp::Ordering>74     fn partial_cmp(&self, x: &Self) -> Option<std::cmp::Ordering> {
75         Some(u64::from_le(self.0).cmp(&u64::from_le(x.0)))
76     }
77 }
78 
79 impl std::ops::Add<L64> for L64 {
80     type Output = Self;
add(self, x: L64) -> L6481     fn add(self, x: L64) -> L64 {
82         L64((u64::from_le(self.0) + u64::from_le(x.0)).to_le())
83     }
84 }
85 
86 impl std::ops::Add<usize> for L64 {
87     type Output = Self;
add(self, x: usize) -> L6488     fn add(self, x: usize) -> L64 {
89         L64((u64::from_le(self.0) + x as u64).to_le())
90     }
91 }
92 
93 impl std::ops::SubAssign<usize> for L64 {
sub_assign(&mut self, x: usize)94     fn sub_assign(&mut self, x: usize) {
95         self.0 = ((u64::from_le(self.0)) - x as u64).to_le()
96     }
97 }
98 
99 impl L64 {
from_slice_le(s: &[u8]) -> Self100     pub fn from_slice_le(s: &[u8]) -> Self {
101         let mut u = 0u64;
102         assert!(s.len() >= 8);
103         unsafe { std::ptr::copy_nonoverlapping(s.as_ptr(), &mut u as *mut u64 as *mut u8, 8) }
104         L64(u)
105     }
to_slice_le(&self, s: &mut [u8])106     pub fn to_slice_le(&self, s: &mut [u8]) {
107         assert!(s.len() >= 8);
108         unsafe {
109             std::ptr::copy_nonoverlapping(&self.0 as *const u64 as *const u8, s.as_mut_ptr(), 8)
110         }
111     }
112 }
113 
114 #[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
115 #[repr(C)]
116 pub struct SerializedRemote {
117     remote: L64,
118     rev: L64,
119     states: L64,
120     id_rev: L64,
121     path: SmallStr,
122 }
123 
124 #[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
125 #[repr(C)]
126 pub struct SerializedChannel {
127     graph: L64,
128     changes: L64,
129     revchanges: L64,
130     states: L64,
131     tags: L64,
132     apply_counter: L64,
133     last_modified: L64,
134     id: RemoteId,
135 }
136 
137 #[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
138 #[repr(C)]
139 pub struct Pair<A, B> {
140     pub a: A,
141     pub b: B,
142 }
143 
144 pub trait Base32: Sized {
to_base32(&self) -> String145     fn to_base32(&self) -> String;
from_base32(b: &[u8]) -> Option<Self>146     fn from_base32(b: &[u8]) -> Option<Self>;
147 }
148 
149 pub mod sanakirja;
150 
151 pub type ApplyTimestamp = u64;
152 
153 pub struct ChannelRef<T: ChannelTxnT> {
154     pub(crate) r: Arc<RwLock<T::Channel>>,
155 }
156 
157 pub struct ArcTxn<T>(pub Arc<RwLock<T>>);
158 
159 impl<T> Clone for ArcTxn<T> {
clone(&self) -> Self160     fn clone(&self) -> Self {
161         ArcTxn(self.0.clone())
162     }
163 }
164 
165 impl<T: MutTxnT> ArcTxn<T> {
commit(self) -> Result<(), T::GraphError>166     pub fn commit(self) -> Result<(), T::GraphError> {
167         if let Ok(txn) = Arc::try_unwrap(self.0) {
168             txn.into_inner().commit()
169         } else {
170             unreachable!()
171         }
172     }
173 }
174 
175 impl<T> std::ops::Deref for ArcTxn<T> {
176     type Target = RwLock<T>;
deref(&self) -> &Self::Target177     fn deref(&self) -> &Self::Target {
178         &self.0
179     }
180 }
181 
182 #[derive(Debug, Error)]
183 #[error("Mutex poison error")]
184 pub struct PoisonError {}
185 
186 impl<T: ChannelTxnT> ChannelRef<T> {
read(&self) -> parking_lot::RwLockReadGuard<T::Channel>187     pub fn read(&self) -> parking_lot::RwLockReadGuard<T::Channel> {
188         self.r.read()
189     }
write(&self) -> parking_lot::RwLockWriteGuard<T::Channel>190     pub fn write(&self) -> parking_lot::RwLockWriteGuard<T::Channel> {
191         self.r.write()
192     }
193 }
194 
195 impl<T: ChannelTxnT> Clone for ChannelRef<T> {
clone(&self) -> Self196     fn clone(&self) -> Self {
197         ChannelRef { r: self.r.clone() }
198     }
199 }
200 
201 impl<T: TxnT> RemoteRef<T> {
id(&self) -> &RemoteId202     pub fn id(&self) -> &RemoteId {
203         &self.id
204     }
205 
lock(&self) -> parking_lot::MutexGuard<Remote<T>>206     pub fn lock(&self) -> parking_lot::MutexGuard<Remote<T>> {
207         self.db.lock()
208     }
209 
id_revision(&self) -> u64210     pub fn id_revision(&self) -> u64 {
211         self.lock().id_rev.into()
212     }
213 
set_id_revision(&self, rev: u64) -> ()214     pub fn set_id_revision(&self, rev: u64) -> () {
215         self.lock().id_rev = rev.into()
216     }
217 }
218 
219 pub struct Remote<T: TxnT> {
220     pub remote: T::Remote,
221     pub rev: T::Revremote,
222     pub states: T::Remotestates,
223     pub id_rev: L64,
224     pub path: SmallString,
225 }
226 
227 pub struct RemoteRef<T: TxnT> {
228     db: Arc<Mutex<Remote<T>>>,
229     id: RemoteId,
230 }
231 
232 impl<T: TxnT> Clone for RemoteRef<T> {
clone(&self) -> Self233     fn clone(&self) -> Self {
234         RemoteRef {
235             db: self.db.clone(),
236             id: self.id.clone(),
237         }
238     }
239 }
240 
241 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
242 pub struct RemoteId(pub(crate) [u8; 16]);
243 
244 impl RemoteId {
nil() -> Self245     pub fn nil() -> Self {
246         RemoteId([0; 16])
247     }
from_bytes(b: &[u8]) -> Option<Self>248     pub fn from_bytes(b: &[u8]) -> Option<Self> {
249         if b.len() < 16 {
250             return None;
251         }
252         let mut x = RemoteId([0; 16]);
253         unsafe {
254             std::ptr::copy_nonoverlapping(b.as_ptr(), x.0.as_mut_ptr(), 16);
255         }
256         Some(x)
257     }
as_bytes(&self) -> &[u8; 16]258     pub fn as_bytes(&self) -> &[u8; 16] {
259         &self.0
260     }
261 
from_base32(b: &[u8]) -> Option<Self>262     pub fn from_base32(b: &[u8]) -> Option<Self> {
263         let mut bb = RemoteId([0; 16]);
264         if b.len() != data_encoding::BASE32_NOPAD.encode_len(16) {
265             return None;
266         }
267         if data_encoding::BASE32_NOPAD.decode_mut(b, &mut bb.0).is_ok() {
268             Some(bb)
269         } else {
270             None
271         }
272     }
273 }
274 
275 impl std::fmt::Display for RemoteId {
fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result276     fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
277         write!(fmt, "{}", data_encoding::BASE32_NOPAD.encode(&self.0))
278     }
279 }
280 
281 #[derive(Debug, Error)]
282 pub enum HashPrefixError<T: std::error::Error + 'static> {
283     #[error("Failed to parse hash prefix: {0}")]
284     Parse(String),
285     #[error("Ambiguous hash prefix: {0}")]
286     Ambiguous(String),
287     #[error("Change not found: {0}")]
288     NotFound(String),
289     #[error(transparent)]
290     Txn(T),
291 }
292 
293 #[derive(Debug, Error)]
294 pub enum ForkError<T: std::error::Error + 'static> {
295     #[error("Channel name already exists: {0}")]
296     ChannelNameExists(String),
297     #[error(transparent)]
298     Txn(T),
299 }
300 
301 #[derive(Debug, Error)]
302 #[error(transparent)]
303 pub struct TxnErr<E: std::error::Error + 'static>(pub E);
304 
305 pub trait GraphTxnT: Sized {
306     type GraphError: std::error::Error + Send + Sync + 'static;
307     table!(graph);
308     get!(graph, Vertex<ChangeId>, SerializedEdge, GraphError);
309     /// Returns the external hash of an internal change identifier, if
310     /// the change is known.
get_external( &self, p: &ChangeId, ) -> Result<Option<&SerializedHash>, TxnErr<Self::GraphError>>311     fn get_external(
312         &self,
313         p: &ChangeId,
314     ) -> Result<Option<&SerializedHash>, TxnErr<Self::GraphError>>;
315 
316     /// Returns the internal change identifier of change with external
317     /// hash `hash`, if the change is known.
get_internal( &self, p: &SerializedHash, ) -> Result<Option<&ChangeId>, TxnErr<Self::GraphError>>318     fn get_internal(
319         &self,
320         p: &SerializedHash,
321     ) -> Result<Option<&ChangeId>, TxnErr<Self::GraphError>>;
322 
323     type Adj;
init_adj( &self, g: &Self::Graph, v: Vertex<ChangeId>, dest: Position<ChangeId>, min: EdgeFlags, max: EdgeFlags, ) -> Result<Self::Adj, TxnErr<Self::GraphError>>324     fn init_adj(
325         &self,
326         g: &Self::Graph,
327         v: Vertex<ChangeId>,
328         dest: Position<ChangeId>,
329         min: EdgeFlags,
330         max: EdgeFlags,
331     ) -> Result<Self::Adj, TxnErr<Self::GraphError>>;
next_adj<'a>( &'a self, g: &Self::Graph, a: &mut Self::Adj, ) -> Option<Result<&'a SerializedEdge, TxnErr<Self::GraphError>>>332     fn next_adj<'a>(
333         &'a self,
334         g: &Self::Graph,
335         a: &mut Self::Adj,
336     ) -> Option<Result<&'a SerializedEdge, TxnErr<Self::GraphError>>>;
337 
find_block<'a>( &'a self, graph: &Self::Graph, p: Position<ChangeId>, ) -> Result<&'a Vertex<ChangeId>, BlockError<Self::GraphError>>338     fn find_block<'a>(
339         &'a self,
340         graph: &Self::Graph,
341         p: Position<ChangeId>,
342     ) -> Result<&'a Vertex<ChangeId>, BlockError<Self::GraphError>>;
343 
find_block_end<'a>( &'a self, graph: &Self::Graph, p: Position<ChangeId>, ) -> Result<&'a Vertex<ChangeId>, BlockError<Self::GraphError>>344     fn find_block_end<'a>(
345         &'a self,
346         graph: &Self::Graph,
347         p: Position<ChangeId>,
348     ) -> Result<&'a Vertex<ChangeId>, BlockError<Self::GraphError>>;
349 }
350 
351 pub trait ChannelTxnT: GraphTxnT {
352     type Channel: Sync + Send;
353 
name<'a>(&self, channel: &'a Self::Channel) -> &'a str354     fn name<'a>(&self, channel: &'a Self::Channel) -> &'a str;
id<'a>(&self, c: &'a Self::Channel) -> &'a RemoteId355     fn id<'a>(&self, c: &'a Self::Channel) -> &'a RemoteId;
graph<'a>(&self, channel: &'a Self::Channel) -> &'a Self::Graph356     fn graph<'a>(&self, channel: &'a Self::Channel) -> &'a Self::Graph;
apply_counter(&self, channel: &Self::Channel) -> u64357     fn apply_counter(&self, channel: &Self::Channel) -> u64;
last_modified(&self, channel: &Self::Channel) -> u64358     fn last_modified(&self, channel: &Self::Channel) -> u64;
changes<'a>(&self, channel: &'a Self::Channel) -> &'a Self::Changeset359     fn changes<'a>(&self, channel: &'a Self::Channel) -> &'a Self::Changeset;
rev_changes<'a>(&self, channel: &'a Self::Channel) -> &'a Self::RevChangeset360     fn rev_changes<'a>(&self, channel: &'a Self::Channel) -> &'a Self::RevChangeset;
tags<'a>(&self, channel: &'a Self::Channel) -> &'a Self::Tags361     fn tags<'a>(&self, channel: &'a Self::Channel) -> &'a Self::Tags;
states<'a>(&self, channel: &'a Self::Channel) -> &'a Self::States362     fn states<'a>(&self, channel: &'a Self::Channel) -> &'a Self::States;
363 
364     type Changeset;
365     type RevChangeset;
get_changeset( &self, channel: &Self::Changeset, c: &ChangeId, ) -> Result<Option<&L64>, TxnErr<Self::GraphError>>366     fn get_changeset(
367         &self,
368         channel: &Self::Changeset,
369         c: &ChangeId,
370     ) -> Result<Option<&L64>, TxnErr<Self::GraphError>>;
get_revchangeset( &self, channel: &Self::RevChangeset, c: &L64, ) -> Result<Option<&Pair<ChangeId, SerializedMerkle>>, TxnErr<Self::GraphError>>371     fn get_revchangeset(
372         &self,
373         channel: &Self::RevChangeset,
374         c: &L64,
375     ) -> Result<Option<&Pair<ChangeId, SerializedMerkle>>, TxnErr<Self::GraphError>>;
376 
377     type ChangesetCursor;
cursor_changeset<'txn>( &'txn self, channel: &Self::Changeset, pos: Option<ChangeId>, ) -> Result< crate::pristine::Cursor<Self, &'txn Self, Self::ChangesetCursor, ChangeId, L64>, TxnErr<Self::GraphError>, >378     fn cursor_changeset<'txn>(
379         &'txn self,
380         channel: &Self::Changeset,
381         pos: Option<ChangeId>,
382     ) -> Result<
383         crate::pristine::Cursor<Self, &'txn Self, Self::ChangesetCursor, ChangeId, L64>,
384         TxnErr<Self::GraphError>,
385     >;
cursor_changeset_next( &self, cursor: &mut Self::ChangesetCursor, ) -> Result<Option<(&ChangeId, &L64)>, TxnErr<Self::GraphError>>386     fn cursor_changeset_next(
387         &self,
388         cursor: &mut Self::ChangesetCursor,
389     ) -> Result<Option<(&ChangeId, &L64)>, TxnErr<Self::GraphError>>;
390 
cursor_changeset_prev( &self, cursor: &mut Self::ChangesetCursor, ) -> Result<Option<(&ChangeId, &L64)>, TxnErr<Self::GraphError>>391     fn cursor_changeset_prev(
392         &self,
393         cursor: &mut Self::ChangesetCursor,
394     ) -> Result<Option<(&ChangeId, &L64)>, TxnErr<Self::GraphError>>;
395 
396     type RevchangesetCursor;
cursor_revchangeset_ref<RT: std::ops::Deref<Target = Self>>( txn: RT, channel: &Self::RevChangeset, pos: Option<L64>, ) -> Result< Cursor<Self, RT, Self::RevchangesetCursor, L64, Pair<ChangeId, SerializedMerkle>>, TxnErr<Self::GraphError>, >397     fn cursor_revchangeset_ref<RT: std::ops::Deref<Target = Self>>(
398         txn: RT,
399         channel: &Self::RevChangeset,
400         pos: Option<L64>,
401     ) -> Result<
402         Cursor<Self, RT, Self::RevchangesetCursor, L64, Pair<ChangeId, SerializedMerkle>>,
403         TxnErr<Self::GraphError>,
404     >;
rev_cursor_revchangeset<'txn>( &'txn self, channel: &Self::RevChangeset, pos: Option<L64>, ) -> Result< RevCursor< Self, &'txn Self, Self::RevchangesetCursor, L64, Pair<ChangeId, SerializedMerkle>, >, TxnErr<Self::GraphError>, >405     fn rev_cursor_revchangeset<'txn>(
406         &'txn self,
407         channel: &Self::RevChangeset,
408         pos: Option<L64>,
409     ) -> Result<
410         RevCursor<
411             Self,
412             &'txn Self,
413             Self::RevchangesetCursor,
414             L64,
415             Pair<ChangeId, SerializedMerkle>,
416         >,
417         TxnErr<Self::GraphError>,
418     >;
cursor_revchangeset_next( &self, cursor: &mut Self::RevchangesetCursor, ) -> Result<Option<(&L64, &Pair<ChangeId, SerializedMerkle>)>, TxnErr<Self::GraphError>>419     fn cursor_revchangeset_next(
420         &self,
421         cursor: &mut Self::RevchangesetCursor,
422     ) -> Result<Option<(&L64, &Pair<ChangeId, SerializedMerkle>)>, TxnErr<Self::GraphError>>;
423 
cursor_revchangeset_prev( &self, cursor: &mut Self::RevchangesetCursor, ) -> Result<Option<(&L64, &Pair<ChangeId, SerializedMerkle>)>, TxnErr<Self::GraphError>>424     fn cursor_revchangeset_prev(
425         &self,
426         cursor: &mut Self::RevchangesetCursor,
427     ) -> Result<Option<(&L64, &Pair<ChangeId, SerializedMerkle>)>, TxnErr<Self::GraphError>>;
428 
429     type States;
channel_has_state( &self, channel: &Self::States, hash: &SerializedMerkle, ) -> Result<Option<L64>, TxnErr<Self::GraphError>>430     fn channel_has_state(
431         &self,
432         channel: &Self::States,
433         hash: &SerializedMerkle,
434     ) -> Result<Option<L64>, TxnErr<Self::GraphError>>;
435 
436     type Tags;
get_tags( &self, channel: &Self::Tags, c: &L64, ) -> Result<Option<&SerializedHash>, TxnErr<Self::GraphError>>437     fn get_tags(
438         &self,
439         channel: &Self::Tags,
440         c: &L64,
441     ) -> Result<Option<&SerializedHash>, TxnErr<Self::GraphError>>;
442 
443     type TagsCursor;
cursor_tags<'txn>( &'txn self, channel: &Self::Tags, pos: Option<L64>, ) -> Result< crate::pristine::Cursor<Self, &'txn Self, Self::TagsCursor, L64, SerializedHash>, TxnErr<Self::GraphError>, >444     fn cursor_tags<'txn>(
445         &'txn self,
446         channel: &Self::Tags,
447         pos: Option<L64>,
448     ) -> Result<
449         crate::pristine::Cursor<Self, &'txn Self, Self::TagsCursor, L64, SerializedHash>,
450         TxnErr<Self::GraphError>,
451     >;
452 
cursor_tags_next( &self, cursor: &mut Self::TagsCursor, ) -> Result<Option<(&L64, &SerializedHash)>, TxnErr<Self::GraphError>>453     fn cursor_tags_next(
454         &self,
455         cursor: &mut Self::TagsCursor,
456     ) -> Result<Option<(&L64, &SerializedHash)>, TxnErr<Self::GraphError>>;
457 
cursor_tags_prev( &self, cursor: &mut Self::TagsCursor, ) -> Result<Option<(&L64, &SerializedHash)>, TxnErr<Self::GraphError>>458     fn cursor_tags_prev(
459         &self,
460         cursor: &mut Self::TagsCursor,
461     ) -> Result<Option<(&L64, &SerializedHash)>, TxnErr<Self::GraphError>>;
462 
iter_tags( &self, channel: &Self::Tags, from: u64, ) -> Result<Cursor<Self, &Self, Self::TagsCursor, L64, SerializedHash>, TxnErr<Self::GraphError>>463     fn iter_tags(
464         &self,
465         channel: &Self::Tags,
466         from: u64,
467     ) -> Result<Cursor<Self, &Self, Self::TagsCursor, L64, SerializedHash>, TxnErr<Self::GraphError>>;
468 
rev_iter_tags( &self, channel: &Self::Tags, from: Option<u64>, ) -> Result< RevCursor<Self, &Self, Self::TagsCursor, L64, SerializedHash>, TxnErr<Self::GraphError>, >469     fn rev_iter_tags(
470         &self,
471         channel: &Self::Tags,
472         from: Option<u64>,
473     ) -> Result<
474         RevCursor<Self, &Self, Self::TagsCursor, L64, SerializedHash>,
475         TxnErr<Self::GraphError>,
476     >;
477 }
478 
479 pub trait GraphIter: GraphTxnT {
480     type GraphCursor;
graph_cursor( &self, g: &Self::Graph, s: Option<&Vertex<ChangeId>>, ) -> Result<Self::GraphCursor, TxnErr<Self::GraphError>>481     fn graph_cursor(
482         &self,
483         g: &Self::Graph,
484         s: Option<&Vertex<ChangeId>>,
485     ) -> Result<Self::GraphCursor, TxnErr<Self::GraphError>>;
next_graph<'txn>( &'txn self, g: &Self::Graph, a: &mut Self::GraphCursor, ) -> Option<Result<(&'txn Vertex<ChangeId>, &'txn SerializedEdge), TxnErr<Self::GraphError>>>486     fn next_graph<'txn>(
487         &'txn self,
488         g: &Self::Graph,
489         a: &mut Self::GraphCursor,
490     ) -> Option<Result<(&'txn Vertex<ChangeId>, &'txn SerializedEdge), TxnErr<Self::GraphError>>>;
491 
iter_graph<'a>( &'a self, g: &'a Self::Graph, s: Option<&Vertex<ChangeId>>, ) -> Result<GraphIterator<'a, Self>, TxnErr<Self::GraphError>>492     fn iter_graph<'a>(
493         &'a self,
494         g: &'a Self::Graph,
495         s: Option<&Vertex<ChangeId>>,
496     ) -> Result<GraphIterator<'a, Self>, TxnErr<Self::GraphError>> {
497         Ok(GraphIterator {
498             cursor: self.graph_cursor(g, s)?,
499             txn: self,
500             g: g,
501         })
502     }
503 }
504 
505 pub struct GraphIterator<'a, T: GraphIter> {
506     txn: &'a T,
507     g: &'a T::Graph,
508     cursor: T::GraphCursor,
509 }
510 
511 impl<'a, T: GraphIter> Iterator for GraphIterator<'a, T> {
512     type Item = Result<(&'a Vertex<ChangeId>, &'a SerializedEdge), TxnErr<T::GraphError>>;
next(&mut self) -> Option<Self::Item>513     fn next(&mut self) -> Option<Self::Item> {
514         self.txn.next_graph(self.g, &mut self.cursor)
515     }
516 }
517 
518 #[derive(Debug, Error)]
519 pub enum BlockError<T: std::error::Error + 'static> {
520     #[error(transparent)]
521     Txn(T),
522     #[error("Block error: {:?}", block)]
523     Block { block: Position<ChangeId> },
524 }
525 
526 impl<T: std::error::Error + 'static> std::convert::From<TxnErr<T>> for BlockError<T> {
from(e: TxnErr<T>) -> Self527     fn from(e: TxnErr<T>) -> Self {
528         BlockError::Txn(e.0)
529     }
530 }
531 
532 pub trait DepsTxnT: Sized {
533     type DepsError: std::error::Error + Send + Sync + 'static;
534     table!(revdep);
535     table!(dep);
536     table_get!(dep, ChangeId, ChangeId, DepsError);
537     cursor_ref!(dep, ChangeId, ChangeId, DepsError);
538     table_get!(revdep, ChangeId, ChangeId, DepsError);
iter_revdep( &self, p: &ChangeId, ) -> Result<Cursor<Self, &Self, Self::DepCursor, ChangeId, ChangeId>, TxnErr<Self::DepsError>>539     fn iter_revdep(
540         &self,
541         p: &ChangeId,
542     ) -> Result<Cursor<Self, &Self, Self::DepCursor, ChangeId, ChangeId>, TxnErr<Self::DepsError>>;
iter_dep( &self, p: &ChangeId, ) -> Result<Cursor<Self, &Self, Self::DepCursor, ChangeId, ChangeId>, TxnErr<Self::DepsError>>543     fn iter_dep(
544         &self,
545         p: &ChangeId,
546     ) -> Result<Cursor<Self, &Self, Self::DepCursor, ChangeId, ChangeId>, TxnErr<Self::DepsError>>;
iter_dep_ref<RT: std::ops::Deref<Target = Self> + Clone>( txn: RT, p: &ChangeId, ) -> Result<Cursor<Self, RT, Self::DepCursor, ChangeId, ChangeId>, TxnErr<Self::DepsError>>547     fn iter_dep_ref<RT: std::ops::Deref<Target = Self> + Clone>(
548         txn: RT,
549         p: &ChangeId,
550     ) -> Result<Cursor<Self, RT, Self::DepCursor, ChangeId, ChangeId>, TxnErr<Self::DepsError>>;
iter_touched( &self, p: &Position<ChangeId>, ) -> Result< Cursor<Self, &Self, Self::Touched_filesCursor, Position<ChangeId>, ChangeId>, TxnErr<Self::DepsError>, >551     fn iter_touched(
552         &self,
553         p: &Position<ChangeId>,
554     ) -> Result<
555         Cursor<Self, &Self, Self::Touched_filesCursor, Position<ChangeId>, ChangeId>,
556         TxnErr<Self::DepsError>,
557     >;
iter_rev_touched( &self, p: &ChangeId, ) -> Result< Cursor<Self, &Self, Self::Rev_touched_filesCursor, ChangeId, Position<ChangeId>>, TxnErr<Self::DepsError>, >558     fn iter_rev_touched(
559         &self,
560         p: &ChangeId,
561     ) -> Result<
562         Cursor<Self, &Self, Self::Rev_touched_filesCursor, ChangeId, Position<ChangeId>>,
563         TxnErr<Self::DepsError>,
564     >;
565     table!(touched_files);
566     table!(rev_touched_files);
567     table_get!(touched_files, Position<ChangeId>, ChangeId, DepsError);
568     table_get!(rev_touched_files, ChangeId, Position<ChangeId>, DepsError);
569     iter!(touched_files, Position<ChangeId>, ChangeId, DepsError);
570     iter!(rev_touched_files, ChangeId, Position<ChangeId>, DepsError);
571 }
572 
573 pub trait TreeTxnT: Sized {
574     type TreeError: std::error::Error + Send + Sync + 'static;
575     table!(tree);
576     table_get!(tree, PathId, Inode, TreeError);
577     iter!(tree, PathId, Inode, TreeError);
578 
579     table!(revtree);
580     table_get!(revtree, Inode, PathId, TreeError);
581     iter!(revtree, Inode, PathId, TreeError);
582 
583     table!(inodes);
584     table!(revinodes);
585     table_get!(inodes, Inode, Position<ChangeId>, TreeError);
586     table_get!(revinodes, Position<ChangeId>, Inode, TreeError);
587 
588     table!(partials);
589     cursor!(partials, SmallStr, Position<ChangeId>, TreeError);
590     cursor!(inodes, Inode, Position<ChangeId>, TreeError);
iter_inodes( &self, ) -> Result< Cursor<Self, &Self, Self::InodesCursor, Inode, Position<ChangeId>>, TxnErr<Self::TreeError>, >591     fn iter_inodes(
592         &self,
593     ) -> Result<
594         Cursor<Self, &Self, Self::InodesCursor, Inode, Position<ChangeId>>,
595         TxnErr<Self::TreeError>,
596     >;
597 
598     // #[cfg(debug_assertions)]
599     cursor!(revinodes, Position<ChangeId>, Inode, TreeError);
600     // #[cfg(debug_assertions)]
iter_revinodes( &self, ) -> Result< Cursor<Self, &Self, Self::RevinodesCursor, Position<ChangeId>, Inode>, TxnErr<Self::TreeError>, >601     fn iter_revinodes(
602         &self,
603     ) -> Result<
604         Cursor<Self, &Self, Self::RevinodesCursor, Position<ChangeId>, Inode>,
605         TxnErr<Self::TreeError>,
606     >;
iter_partials<'txn>( &'txn self, channel: &str, ) -> Result< Cursor<Self, &'txn Self, Self::PartialsCursor, SmallStr, Position<ChangeId>>, TxnErr<Self::TreeError>, >607     fn iter_partials<'txn>(
608         &'txn self,
609         channel: &str,
610     ) -> Result<
611         Cursor<Self, &'txn Self, Self::PartialsCursor, SmallStr, Position<ChangeId>>,
612         TxnErr<Self::TreeError>,
613     >;
614 }
615 
616 /// The trait of immutable transactions.
617 pub trait TxnT:
618     GraphTxnT
619     + ChannelTxnT
620     + DepsTxnT<DepsError = <Self as GraphTxnT>::GraphError>
621     + TreeTxnT<TreeError = <Self as GraphTxnT>::GraphError>
622 {
623     table!(channels);
624     cursor!(channels, SmallStr, SerializedChannel);
625 
hash_from_prefix( &self, prefix: &str, ) -> Result<(Hash, ChangeId), HashPrefixError<Self::GraphError>>626     fn hash_from_prefix(
627         &self,
628         prefix: &str,
629     ) -> Result<(Hash, ChangeId), HashPrefixError<Self::GraphError>>;
hash_from_prefix_remote( &self, remote: &RemoteRef<Self>, prefix: &str, ) -> Result<Hash, HashPrefixError<Self::GraphError>>630     fn hash_from_prefix_remote(
631         &self,
632         remote: &RemoteRef<Self>,
633         prefix: &str,
634     ) -> Result<Hash, HashPrefixError<Self::GraphError>>;
635 
load_channel( &self, name: &str, ) -> Result<Option<ChannelRef<Self>>, TxnErr<Self::GraphError>>636     fn load_channel(
637         &self,
638         name: &str,
639     ) -> Result<Option<ChannelRef<Self>>, TxnErr<Self::GraphError>>;
640 
load_remote( &self, name: &RemoteId, ) -> Result<Option<RemoteRef<Self>>, TxnErr<Self::GraphError>>641     fn load_remote(
642         &self,
643         name: &RemoteId,
644     ) -> Result<Option<RemoteRef<Self>>, TxnErr<Self::GraphError>>;
645 
646     /// Iterate a function over all channels. The loop stops the first
647     /// time `f` returns `false`.
iter_channels<'txn>( &'txn self, start: &str, ) -> Result<ChannelIterator<'txn, Self>, TxnErr<Self::GraphError>>648     fn iter_channels<'txn>(
649         &'txn self,
650         start: &str,
651     ) -> Result<ChannelIterator<'txn, Self>, TxnErr<Self::GraphError>>;
652 
iter_remotes<'txn>( &'txn self, start: &RemoteId, ) -> Result<RemotesIterator<'txn, Self>, TxnErr<Self::GraphError>>653     fn iter_remotes<'txn>(
654         &'txn self,
655         start: &RemoteId,
656     ) -> Result<RemotesIterator<'txn, Self>, TxnErr<Self::GraphError>>;
657 
658     table!(remotes);
659     cursor!(remotes, RemoteId, SerializedRemote);
660     table!(remote);
661     table!(revremote);
662     table!(remotestates);
663     cursor!(remote, L64, Pair<SerializedHash, SerializedMerkle>);
664     rev_cursor!(remote, L64, Pair<SerializedHash, SerializedMerkle>);
665 
iter_remote<'txn>( &'txn self, remote: &Self::Remote, k: u64, ) -> Result< Cursor<Self, &'txn Self, Self::RemoteCursor, L64, Pair<SerializedHash, SerializedMerkle>>, TxnErr<Self::GraphError>, >666     fn iter_remote<'txn>(
667         &'txn self,
668         remote: &Self::Remote,
669         k: u64,
670     ) -> Result<
671         Cursor<Self, &'txn Self, Self::RemoteCursor, L64, Pair<SerializedHash, SerializedMerkle>>,
672         TxnErr<Self::GraphError>,
673     >;
674 
iter_rev_remote<'txn>( &'txn self, remote: &Self::Remote, k: Option<L64>, ) -> Result< RevCursor< Self, &'txn Self, Self::RemoteCursor, L64, Pair<SerializedHash, SerializedMerkle>, >, TxnErr<Self::GraphError>, >675     fn iter_rev_remote<'txn>(
676         &'txn self,
677         remote: &Self::Remote,
678         k: Option<L64>,
679     ) -> Result<
680         RevCursor<
681             Self,
682             &'txn Self,
683             Self::RemoteCursor,
684             L64,
685             Pair<SerializedHash, SerializedMerkle>,
686         >,
687         TxnErr<Self::GraphError>,
688     >;
689 
get_remote( &mut self, name: RemoteId, ) -> Result<Option<RemoteRef<Self>>, TxnErr<Self::GraphError>>690     fn get_remote(
691         &mut self,
692         name: RemoteId,
693     ) -> Result<Option<RemoteRef<Self>>, TxnErr<Self::GraphError>>;
694 
last_remote( &self, remote: &Self::Remote, ) -> Result<Option<(u64, &Pair<SerializedHash, SerializedMerkle>)>, TxnErr<Self::GraphError>>695     fn last_remote(
696         &self,
697         remote: &Self::Remote,
698     ) -> Result<Option<(u64, &Pair<SerializedHash, SerializedMerkle>)>, TxnErr<Self::GraphError>>;
699 
get_remote_state( &self, remote: &Self::Remote, n: u64, ) -> Result<Option<(u64, &Pair<SerializedHash, SerializedMerkle>)>, TxnErr<Self::GraphError>>700     fn get_remote_state(
701         &self,
702         remote: &Self::Remote,
703         n: u64,
704     ) -> Result<Option<(u64, &Pair<SerializedHash, SerializedMerkle>)>, TxnErr<Self::GraphError>>;
705 
remote_has_change( &self, remote: &RemoteRef<Self>, hash: &SerializedHash, ) -> Result<bool, TxnErr<Self::GraphError>>706     fn remote_has_change(
707         &self,
708         remote: &RemoteRef<Self>,
709         hash: &SerializedHash,
710     ) -> Result<bool, TxnErr<Self::GraphError>>;
remote_has_state( &self, remote: &RemoteRef<Self>, hash: &SerializedMerkle, ) -> Result<bool, TxnErr<Self::GraphError>>711     fn remote_has_state(
712         &self,
713         remote: &RemoteRef<Self>,
714         hash: &SerializedMerkle,
715     ) -> Result<bool, TxnErr<Self::GraphError>>;
716 
current_channel(&self) -> Result<&str, Self::GraphError>717     fn current_channel(&self) -> Result<&str, Self::GraphError>;
718 }
719 
720 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
721 pub struct SerializedPublicKey {
722     algorithm: crate::key::Algorithm,
723     key: [u8; 32],
724 }
725 
726 /// Iterate the graph between `(key, min_flag)` and `(key,
727 /// max_flag)`, where both bounds are included.
iter_adjacent<'txn, T: GraphTxnT>( txn: &'txn T, graph: &'txn T::Graph, key: Vertex<ChangeId>, min_flag: EdgeFlags, max_flag: EdgeFlags, ) -> Result<AdjacentIterator<'txn, T>, TxnErr<T::GraphError>>728 pub(crate) fn iter_adjacent<'txn, T: GraphTxnT>(
729     txn: &'txn T,
730     graph: &'txn T::Graph,
731     key: Vertex<ChangeId>,
732     min_flag: EdgeFlags,
733     max_flag: EdgeFlags,
734 ) -> Result<AdjacentIterator<'txn, T>, TxnErr<T::GraphError>> {
735     Ok(AdjacentIterator {
736         it: txn.init_adj(graph, key, Position::ROOT, min_flag, max_flag)?,
737         graph,
738         txn,
739     })
740 }
741 
iter_alive_children<'txn, T: GraphTxnT>( txn: &'txn T, graph: &'txn T::Graph, key: Vertex<ChangeId>, ) -> Result<AdjacentIterator<'txn, T>, TxnErr<T::GraphError>>742 pub(crate) fn iter_alive_children<'txn, T: GraphTxnT>(
743     txn: &'txn T,
744     graph: &'txn T::Graph,
745     key: Vertex<ChangeId>,
746 ) -> Result<AdjacentIterator<'txn, T>, TxnErr<T::GraphError>> {
747     iter_adjacent(
748         txn,
749         graph,
750         key,
751         EdgeFlags::empty(),
752         EdgeFlags::alive_children(),
753     )
754 }
755 
iter_deleted_parents<'txn, T: GraphTxnT>( txn: &'txn T, graph: &'txn T::Graph, key: Vertex<ChangeId>, ) -> Result<AdjacentIterator<'txn, T>, TxnErr<T::GraphError>>756 pub(crate) fn iter_deleted_parents<'txn, T: GraphTxnT>(
757     txn: &'txn T,
758     graph: &'txn T::Graph,
759     key: Vertex<ChangeId>,
760 ) -> Result<AdjacentIterator<'txn, T>, TxnErr<T::GraphError>> {
761     iter_adjacent(
762         txn,
763         graph,
764         key,
765         EdgeFlags::DELETED | EdgeFlags::PARENT,
766         EdgeFlags::all(),
767     )
768 }
769 
iter_adj_all<'txn, T: GraphTxnT>( txn: &'txn T, graph: &'txn T::Graph, key: Vertex<ChangeId>, ) -> Result<AdjacentIterator<'txn, T>, TxnErr<T::GraphError>>770 pub fn iter_adj_all<'txn, T: GraphTxnT>(
771     txn: &'txn T,
772     graph: &'txn T::Graph,
773     key: Vertex<ChangeId>,
774 ) -> Result<AdjacentIterator<'txn, T>, TxnErr<T::GraphError>> {
775     iter_adjacent(txn, graph, key, EdgeFlags::empty(), EdgeFlags::all())
776 }
777 
tree_path<T: TreeTxnT>( txn: &T, v: &Position<ChangeId>, ) -> Result<Option<String>, TxnErr<T::TreeError>>778 pub(crate) fn tree_path<T: TreeTxnT>(
779     txn: &T,
780     v: &Position<ChangeId>,
781 ) -> Result<Option<String>, TxnErr<T::TreeError>> {
782     if let Some(mut inode) = txn.get_revinodes(v, None)? {
783         let mut components = Vec::new();
784         while !inode.is_root() {
785             if let Some(next) = txn.get_revtree(inode, None)? {
786                 components.push(next.basename.as_str().to_string());
787                 inode = &next.parent_inode;
788             } else {
789                 assert!(components.is_empty());
790                 return Ok(None);
791             }
792         }
793         if let Some(mut result) = components.pop() {
794             while let Some(c) = components.pop() {
795                 result = result + "/" + c.as_str()
796             }
797             return Ok(Some(result));
798         }
799     }
800     Ok(None)
801 }
802 
internal<T: GraphTxnT>( txn: &T, h: &Option<Hash>, p: ChangeId, ) -> Result<Option<ChangeId>, TxnErr<T::GraphError>>803 pub(crate) fn internal<T: GraphTxnT>(
804     txn: &T,
805     h: &Option<Hash>,
806     p: ChangeId,
807 ) -> Result<Option<ChangeId>, TxnErr<T::GraphError>> {
808     match *h {
809         Some(Hash::None) => Ok(Some(ChangeId::ROOT)),
810         Some(ref h) => Ok(txn.get_internal(&h.into())?.map(|x| *x)),
811         None => Ok(Some(p)),
812     }
813 }
814 
815 #[derive(Error, Debug)]
816 pub enum InconsistentChange<T: std::error::Error + 'static> {
817     #[error("Undeclared dependency")]
818     UndeclaredDep,
819     #[error(transparent)]
820     Txn(T),
821 }
822 
823 impl<T: std::error::Error + 'static> std::convert::From<TxnErr<T>> for InconsistentChange<T> {
from(e: TxnErr<T>) -> Self824     fn from(e: TxnErr<T>) -> Self {
825         InconsistentChange::Txn(e.0)
826     }
827 }
828 
internal_pos<T: GraphTxnT>( txn: &T, pos: &Position<Option<Hash>>, change_id: ChangeId, ) -> Result<Position<ChangeId>, InconsistentChange<T::GraphError>>829 pub fn internal_pos<T: GraphTxnT>(
830     txn: &T,
831     pos: &Position<Option<Hash>>,
832     change_id: ChangeId,
833 ) -> Result<Position<ChangeId>, InconsistentChange<T::GraphError>> {
834     let change = if let Some(p) = pos.change {
835         if let Some(&p) = txn.get_internal(&p.into())? {
836             p
837         } else {
838             return Err(InconsistentChange::UndeclaredDep);
839         }
840     } else {
841         change_id
842     };
843 
844     Ok(Position {
845         change,
846         pos: pos.pos,
847     })
848 }
849 
internal_vertex<T: GraphTxnT>( txn: &T, v: &Vertex<Option<Hash>>, change_id: ChangeId, ) -> Result<Vertex<ChangeId>, InconsistentChange<T::GraphError>>850 pub fn internal_vertex<T: GraphTxnT>(
851     txn: &T,
852     v: &Vertex<Option<Hash>>,
853     change_id: ChangeId,
854 ) -> Result<Vertex<ChangeId>, InconsistentChange<T::GraphError>> {
855     let change = if let Some(p) = v.change {
856         if let Some(&p) = txn.get_internal(&p.into())? {
857             p
858         } else {
859             return Err(InconsistentChange::UndeclaredDep);
860         }
861     } else {
862         change_id
863     };
864 
865     Ok(Vertex {
866         change,
867         start: v.start,
868         end: v.end,
869     })
870 }
871 
changeid_log<'db, 'txn: 'db, T: ChannelTxnT>( txn: &'txn T, channel: &'db T::Channel, from: L64, ) -> Result< Cursor<T, &'txn T, T::RevchangesetCursor, L64, Pair<ChangeId, SerializedMerkle>>, TxnErr<T::GraphError>, >872 pub fn changeid_log<'db, 'txn: 'db, T: ChannelTxnT>(
873     txn: &'txn T,
874     channel: &'db T::Channel,
875     from: L64,
876 ) -> Result<
877     Cursor<T, &'txn T, T::RevchangesetCursor, L64, Pair<ChangeId, SerializedMerkle>>,
878     TxnErr<T::GraphError>,
879 > {
880     T::cursor_revchangeset_ref(txn, txn.rev_changes(&channel), Some(from))
881 }
882 
current_state<'db, 'txn: 'db, T: ChannelTxnT>( txn: &'txn T, channel: &'db T::Channel, ) -> Result<Merkle, TxnErr<T::GraphError>>883 pub(crate) fn current_state<'db, 'txn: 'db, T: ChannelTxnT>(
884     txn: &'txn T,
885     channel: &'db T::Channel,
886 ) -> Result<Merkle, TxnErr<T::GraphError>> {
887     if let Some(e) = txn
888         .rev_cursor_revchangeset(txn.rev_changes(&channel), None)?
889         .next()
890     {
891         Ok((&(e?.1).b).into())
892     } else {
893         Ok(Merkle::zero())
894     }
895 }
896 
changeid_rev_log<'db, 'txn: 'db, T: ChannelTxnT>( txn: &'txn T, channel: &'db T::Channel, from: Option<L64>, ) -> Result< RevCursor<T, &'txn T, T::RevchangesetCursor, L64, Pair<ChangeId, SerializedMerkle>>, TxnErr<T::GraphError>, >897 pub(crate) fn changeid_rev_log<'db, 'txn: 'db, T: ChannelTxnT>(
898     txn: &'txn T,
899     channel: &'db T::Channel,
900     from: Option<L64>,
901 ) -> Result<
902     RevCursor<T, &'txn T, T::RevchangesetCursor, L64, Pair<ChangeId, SerializedMerkle>>,
903     TxnErr<T::GraphError>,
904 > {
905     Ok(txn.rev_cursor_revchangeset(txn.rev_changes(&channel), from)?)
906 }
907 
log_for_path< 'txn, 'channel, T: ChannelTxnT + DepsTxnT<DepsError = <T as GraphTxnT>::GraphError>, >( txn: &'txn T, channel: &'channel T::Channel, key: Position<ChangeId>, from_timestamp: u64, ) -> Result<PathChangeset<'channel, 'txn, T>, TxnErr<T::GraphError>>908 pub(crate) fn log_for_path<
909     'txn,
910     'channel,
911     T: ChannelTxnT + DepsTxnT<DepsError = <T as GraphTxnT>::GraphError>,
912 >(
913     txn: &'txn T,
914     channel: &'channel T::Channel,
915     key: Position<ChangeId>,
916     from_timestamp: u64,
917 ) -> Result<PathChangeset<'channel, 'txn, T>, TxnErr<T::GraphError>> {
918     Ok(PathChangeset {
919         iter: T::cursor_revchangeset_ref(
920             txn,
921             txn.rev_changes(&channel),
922             Some(from_timestamp.into()),
923         )?,
924         txn,
925         channel,
926         key,
927     })
928 }
929 
rev_log_for_path< 'txn, 'channel, T: ChannelTxnT + DepsTxnT<DepsError = <T as GraphTxnT>::GraphError>, >( txn: &'txn T, channel: &'channel T::Channel, key: Position<ChangeId>, from_timestamp: u64, ) -> Result<RevPathChangeset<'channel, 'txn, T>, TxnErr<T::GraphError>>930 pub(crate) fn rev_log_for_path<
931     'txn,
932     'channel,
933     T: ChannelTxnT + DepsTxnT<DepsError = <T as GraphTxnT>::GraphError>,
934 >(
935     txn: &'txn T,
936     channel: &'channel T::Channel,
937     key: Position<ChangeId>,
938     from_timestamp: u64,
939 ) -> Result<RevPathChangeset<'channel, 'txn, T>, TxnErr<T::GraphError>> {
940     Ok(RevPathChangeset {
941         iter: txn
942             .rev_cursor_revchangeset(txn.rev_changes(&channel), Some(from_timestamp.into()))?,
943         txn,
944         channel,
945         key,
946     })
947 }
948 
949 /// Is there an alive/pseudo edge from `a` to `b`.
test_edge<T: GraphTxnT>( txn: &T, channel: &T::Graph, a: Position<ChangeId>, b: Position<ChangeId>, min: EdgeFlags, max: EdgeFlags, ) -> Result<bool, TxnErr<T::GraphError>>950 pub(crate) fn test_edge<T: GraphTxnT>(
951     txn: &T,
952     channel: &T::Graph,
953     a: Position<ChangeId>,
954     b: Position<ChangeId>,
955     min: EdgeFlags,
956     max: EdgeFlags,
957 ) -> Result<bool, TxnErr<T::GraphError>> {
958     debug!("is_connected {:?} {:?}", a, b);
959     let mut adj = txn.init_adj(channel, a.inode_vertex(), b, min, max)?;
960     match txn.next_adj(channel, &mut adj) {
961         Some(Ok(dest)) => Ok(dest.dest() == b),
962         Some(Err(e)) => Err(e.into()),
963         None => Ok(false),
964     }
965 }
966 
967 /// Is there an alive/pseudo edge to `a`.
is_alive<T: GraphTxnT>( txn: &T, channel: &T::Graph, a: &Vertex<ChangeId>, ) -> Result<bool, TxnErr<T::GraphError>>968 pub(crate) fn is_alive<T: GraphTxnT>(
969     txn: &T,
970     channel: &T::Graph,
971     a: &Vertex<ChangeId>,
972 ) -> Result<bool, TxnErr<T::GraphError>> {
973     if a.is_root() {
974         return Ok(true);
975     }
976     for e in iter_adjacent(
977         txn,
978         channel,
979         *a,
980         EdgeFlags::PARENT,
981         EdgeFlags::all() - EdgeFlags::DELETED,
982     )? {
983         let e = e?;
984         if !e.flag().contains(EdgeFlags::PSEUDO)
985             && (e.flag().contains(EdgeFlags::BLOCK) || a.is_empty())
986         {
987             return Ok(true);
988         }
989     }
990     Ok(false)
991 }
992 
make_changeid<T: GraphTxnT>( txn: &T, h: &Hash, ) -> Result<ChangeId, TxnErr<T::GraphError>>993 pub(crate) fn make_changeid<T: GraphTxnT>(
994     txn: &T,
995     h: &Hash,
996 ) -> Result<ChangeId, TxnErr<T::GraphError>> {
997     if let Some(h_) = txn.get_internal(&h.into())? {
998         debug!("make_changeid, found = {:?} {:?}", h, h_);
999         return Ok(*h_);
1000     }
1001     use byteorder::{ByteOrder, LittleEndian};
1002     let mut p = match h {
1003         Hash::None => return Ok(ChangeId::ROOT),
1004         Hash::Blake3(ref s) => LittleEndian::read_u64(&s[..]),
1005     };
1006     let mut pp = ChangeId(L64(p));
1007     while let Some(ext) = txn.get_external(&pp)? {
1008         debug!("ext = {:?}", ext);
1009         p = u64::from_le(p) + 1;
1010         pp = ChangeId(L64(p.to_le()));
1011     }
1012     Ok(pp)
1013 }
1014 
1015 // #[cfg(debug_assertions)]
debug_tree<P: AsRef<std::path::Path>, T: TreeTxnT>( txn: &T, file: P, ) -> Result<(), std::io::Error>1016 pub fn debug_tree<P: AsRef<std::path::Path>, T: TreeTxnT>(
1017     txn: &T,
1018     file: P,
1019 ) -> Result<(), std::io::Error> {
1020     let root = OwnedPathId {
1021         parent_inode: Inode::ROOT,
1022         basename: SmallString::from_str(""),
1023     };
1024     let mut f = std::fs::File::create(file)?;
1025     for t in txn.iter_tree(&root, None).unwrap() {
1026         writeln!(f, "{:?}", t.unwrap())?
1027     }
1028     Ok(())
1029 }
1030 
1031 // #[cfg(debug_assertions)]
debug_tree_print<T: TreeTxnT>(txn: &T)1032 pub fn debug_tree_print<T: TreeTxnT>(txn: &T) {
1033     let root = OwnedPathId {
1034         parent_inode: Inode::ROOT,
1035         basename: SmallString::from_str(""),
1036     };
1037     for t in txn.iter_tree(&root, None).unwrap() {
1038         debug!("{:?}", t.unwrap())
1039     }
1040 }
1041 
1042 // #[cfg(debug_assertions)]
debug_remotes<T: TxnT>(txn: &T)1043 pub fn debug_remotes<T: TxnT>(txn: &T) {
1044     for t in txn.iter_remotes(&RemoteId([0; 16])).unwrap() {
1045         let rem = t.unwrap();
1046         debug!("{:?}", rem.id());
1047         for x in txn.iter_remote(&rem.lock().remote, 0).unwrap() {
1048             debug!("    {:?}", x.unwrap());
1049         }
1050     }
1051 }
1052 
1053 /// Write the graph of a channel to file `f` in graphviz
1054 /// format. **Warning:** this can be really large on old channels.
1055 // #[cfg(debug_assertions)]
debug_to_file<P: AsRef<std::path::Path>, T: GraphIter + ChannelTxnT>( txn: &T, channel: &ChannelRef<T>, f: P, ) -> Result<bool, std::io::Error>1056 pub fn debug_to_file<P: AsRef<std::path::Path>, T: GraphIter + ChannelTxnT>(
1057     txn: &T,
1058     channel: &ChannelRef<T>,
1059     f: P,
1060 ) -> Result<bool, std::io::Error> {
1061     info!("debug {:?}", f.as_ref());
1062     let mut f = std::fs::File::create(f)?;
1063     let channel = channel.r.read();
1064     let done = debug(txn, txn.graph(&*channel), &mut f)?;
1065     f.flush()?;
1066     info!("done debugging {:?}", done);
1067     Ok(done)
1068 }
1069 
1070 // #[cfg(debug_assertions)]
debug_revtree<P: AsRef<std::path::Path>, T: TreeTxnT>( txn: &T, file: P, ) -> Result<(), std::io::Error>1071 pub fn debug_revtree<P: AsRef<std::path::Path>, T: TreeTxnT>(
1072     txn: &T,
1073     file: P,
1074 ) -> Result<(), std::io::Error> {
1075     let mut f = std::fs::File::create(file)?;
1076     for t in txn.iter_revtree(&Inode::ROOT, None).unwrap() {
1077         writeln!(f, "{:?}", t.unwrap())?
1078     }
1079     Ok(())
1080 }
1081 
1082 // #[cfg(debug_assertions)]
debug_revtree_print<T: TreeTxnT>(txn: &T)1083 pub fn debug_revtree_print<T: TreeTxnT>(txn: &T) {
1084     for t in txn.iter_revtree(&Inode::ROOT, None).unwrap() {
1085         debug!("{:?}", t.unwrap())
1086     }
1087 }
1088 
1089 // #[cfg(debug_assertions)]
debug_inodes<T: TreeTxnT>(txn: &T)1090 pub fn debug_inodes<T: TreeTxnT>(txn: &T) {
1091     debug!("debug_inodes");
1092     for t in txn.iter_inodes().unwrap() {
1093         debug!("debug_inodes = {:?}", t.unwrap())
1094     }
1095     debug!("/debug_inodes");
1096 }
1097 
1098 // #[cfg(debug_assertions)]
debug_revinodes<T: TreeTxnT>(txn: &T)1099 pub fn debug_revinodes<T: TreeTxnT>(txn: &T) {
1100     debug!("debug_revinodes");
1101     for t in txn.iter_revinodes().unwrap() {
1102         debug!("debug_revinodes = {:?}", t.unwrap())
1103     }
1104     debug!("/debug_revinodes");
1105 }
1106 
1107 /// Write the graph of a channel to write `W` in graphviz
1108 /// format. **Warning:** this can be really large on old channels.
1109 // #[cfg(debug_assertions)]
debug<W: Write, T: GraphIter>( txn: &T, channel: &T::Graph, mut f: W, ) -> Result<bool, std::io::Error>1110 pub fn debug<W: Write, T: GraphIter>(
1111     txn: &T,
1112     channel: &T::Graph,
1113     mut f: W,
1114 ) -> Result<bool, std::io::Error> {
1115     let mut cursor = txn.graph_cursor(&channel, None).unwrap();
1116     writeln!(f, "digraph {{")?;
1117     let mut keys = std::collections::HashSet::new();
1118     let mut at_least_one = false;
1119     while let Some(x) = txn.next_graph(&channel, &mut cursor) {
1120         let (k, v) = x.unwrap();
1121         at_least_one = true;
1122         debug!("debug {:?} {:?}", k, v);
1123         if keys.insert(k) {
1124             debug_vertex(&mut f, *k)?
1125         }
1126         debug_edge(txn, channel, &mut f, *k, *v)?
1127     }
1128     writeln!(f, "}}")?;
1129     Ok(at_least_one)
1130 }
1131 
check_alive<T: ChannelTxnT + GraphIter>( txn: &T, channel: &T::Graph, ) -> ( HashMap<Vertex<ChangeId>, Option<Vertex<ChangeId>>>, Vec<(Vertex<ChangeId>, Option<Vertex<ChangeId>>)>, )1132 pub fn check_alive<T: ChannelTxnT + GraphIter>(
1133     txn: &T,
1134     channel: &T::Graph,
1135 ) -> (
1136     HashMap<Vertex<ChangeId>, Option<Vertex<ChangeId>>>,
1137     Vec<(Vertex<ChangeId>, Option<Vertex<ChangeId>>)>,
1138 ) {
1139     // Find the reachable with a DFS.
1140     let mut reachable = HashSet::default();
1141     let mut stack = vec![Vertex::ROOT];
1142     while let Some(v) = stack.pop() {
1143         if !reachable.insert(v) {
1144             continue;
1145         }
1146         for e in iter_adjacent(
1147             txn,
1148             &channel,
1149             v,
1150             EdgeFlags::empty(),
1151             EdgeFlags::all() - EdgeFlags::DELETED - EdgeFlags::PARENT,
1152         )
1153         .unwrap()
1154         {
1155             let e = e.unwrap();
1156             stack.push(*txn.find_block(&channel, e.dest()).unwrap());
1157         }
1158     }
1159     debug!("reachable = {:#?}", reachable);
1160 
1161     // Find the alive
1162     let mut alive_unreachable = HashMap::default();
1163     let mut cursor = txn.graph_cursor(&channel, None).unwrap();
1164 
1165     let mut visited = HashSet::default();
1166     let mut k0 = Vertex::ROOT;
1167     let mut k0_has_pseudo_parents = false;
1168     let mut k0_has_regular_parents = false;
1169     let mut reachable_pseudo = Vec::new();
1170     while let Some(x) = txn.next_graph(&channel, &mut cursor) {
1171         let (&k, &v) = x.unwrap();
1172         debug!("check_alive, k = {:?}, v = {:?}", k, v);
1173         if k0 != k {
1174             if k0_has_pseudo_parents && !k0_has_regular_parents {
1175                 reachable_pseudo.push((
1176                     k0,
1177                     find_file(txn, &channel, k0, &mut stack, &mut visited).unwrap(),
1178                 ))
1179             }
1180             k0 = k;
1181             k0_has_pseudo_parents = false;
1182             k0_has_regular_parents = false;
1183         }
1184         if v.flag().contains(EdgeFlags::PARENT)
1185             && !v.flag().contains(EdgeFlags::FOLDER)
1186             && !v.flag().contains(EdgeFlags::DELETED)
1187         {
1188             if v.flag().contains(EdgeFlags::PSEUDO) {
1189                 k0_has_pseudo_parents = true
1190             } else {
1191                 k0_has_regular_parents = true
1192             }
1193         }
1194 
1195         if v.flag().contains(EdgeFlags::PARENT)
1196             && (v.flag().contains(EdgeFlags::BLOCK) || k.is_empty())
1197             && !v.flag().contains(EdgeFlags::DELETED)
1198             && !reachable.contains(&k)
1199         {
1200             let file = find_file(txn, &channel, k, &mut stack, &mut visited).unwrap();
1201             alive_unreachable.insert(k, file);
1202         }
1203     }
1204     if !k0.is_root() && k0_has_pseudo_parents && !k0_has_regular_parents {
1205         reachable_pseudo.push((
1206             k0,
1207             find_file(txn, &channel, k0, &mut stack, &mut visited).unwrap(),
1208         ));
1209     }
1210 
1211     (alive_unreachable, reachable_pseudo)
1212 }
1213 
find_file<T: GraphTxnT>( txn: &T, channel: &T::Graph, k: Vertex<ChangeId>, stack: &mut Vec<Vertex<ChangeId>>, visited: &mut HashSet<Vertex<ChangeId>>, ) -> Result<Option<Vertex<ChangeId>>, TxnErr<T::GraphError>>1214 fn find_file<T: GraphTxnT>(
1215     txn: &T,
1216     channel: &T::Graph,
1217     k: Vertex<ChangeId>,
1218     stack: &mut Vec<Vertex<ChangeId>>,
1219     visited: &mut HashSet<Vertex<ChangeId>>,
1220 ) -> Result<Option<Vertex<ChangeId>>, TxnErr<T::GraphError>> {
1221     let mut file = None;
1222     stack.clear();
1223     stack.push(k);
1224     visited.clear();
1225     'outer: while let Some(kk) = stack.pop() {
1226         if !visited.insert(kk) {
1227             continue;
1228         }
1229         for e in iter_adjacent(txn, &channel, kk, EdgeFlags::PARENT, EdgeFlags::all())? {
1230             let e = e?;
1231             if e.flag().contains(EdgeFlags::PARENT) {
1232                 if e.flag().contains(EdgeFlags::FOLDER) {
1233                     file = Some(kk);
1234                     break 'outer;
1235                 }
1236                 stack.push(*txn.find_block_end(&channel, e.dest()).unwrap());
1237             }
1238         }
1239     }
1240     Ok(file)
1241 }
1242 
debug_root<W: Write, T: GraphTxnT>( txn: &T, channel: &T::Graph, root: Vertex<ChangeId>, mut f: W, down: bool, ) -> Result<(), std::io::Error>1243 pub fn debug_root<W: Write, T: GraphTxnT>(
1244     txn: &T,
1245     channel: &T::Graph,
1246     root: Vertex<ChangeId>,
1247     mut f: W,
1248     down: bool,
1249 ) -> Result<(), std::io::Error> {
1250     writeln!(f, "digraph {{")?;
1251     let mut visited = HashSet::default();
1252     let mut stack = vec![root];
1253     while let Some(v) = stack.pop() {
1254         if !visited.insert(v) {
1255             continue;
1256         }
1257         debug_vertex(&mut f, v)?;
1258         for e in iter_adj_all(txn, &channel, v).unwrap() {
1259             let e = e.unwrap();
1260             if e.flag().contains(EdgeFlags::PARENT) ^ down {
1261                 debug_edge(txn, &channel, &mut f, v, *e)?;
1262                 let v = if e.flag().contains(EdgeFlags::PARENT) {
1263                     txn.find_block_end(&channel, e.dest()).unwrap()
1264                 } else {
1265                     txn.find_block(&channel, e.dest()).unwrap()
1266                 };
1267                 stack.push(*v);
1268             }
1269         }
1270     }
1271     writeln!(f, "}}")?;
1272     Ok(())
1273 }
1274 
debug_vertex<W: std::io::Write>(mut f: W, k: Vertex<ChangeId>) -> Result<(), std::io::Error>1275 fn debug_vertex<W: std::io::Write>(mut f: W, k: Vertex<ChangeId>) -> Result<(), std::io::Error> {
1276     writeln!(
1277         f,
1278         "node_{}_{}_{}[label=\"{} [{};{}[\"];",
1279         k.change.to_base32(),
1280         k.start.0,
1281         k.end.0,
1282         k.change.to_base32(),
1283         k.start.0,
1284         k.end.0,
1285     )
1286 }
1287 
debug_edge<T: GraphTxnT, W: std::io::Write>( txn: &T, channel: &T::Graph, mut f: W, k: Vertex<ChangeId>, v: SerializedEdge, ) -> Result<(), std::io::Error>1288 fn debug_edge<T: GraphTxnT, W: std::io::Write>(
1289     txn: &T,
1290     channel: &T::Graph,
1291     mut f: W,
1292     k: Vertex<ChangeId>,
1293     v: SerializedEdge,
1294 ) -> Result<(), std::io::Error> {
1295     let style = if v.flag().contains(EdgeFlags::DELETED) {
1296         ", style=dashed"
1297     } else if v.flag().contains(EdgeFlags::PSEUDO) {
1298         ", style=dotted"
1299     } else {
1300         ""
1301     };
1302     let color = if v.flag().contains(EdgeFlags::PARENT) {
1303         if v.flag().contains(EdgeFlags::FOLDER) {
1304             "orange"
1305         } else {
1306             "red"
1307         }
1308     } else if v.flag().contains(EdgeFlags::FOLDER) {
1309         "royalblue"
1310     } else {
1311         "forestgreen"
1312     };
1313 
1314     if v.flag().contains(EdgeFlags::PARENT) {
1315         let dest = if v.dest().change.is_root() {
1316             Vertex::ROOT
1317         } else if let Ok(&dest) = txn.find_block_end(channel, v.dest()) {
1318             dest
1319         } else {
1320             return Ok(());
1321         };
1322         writeln!(
1323             f,
1324             "node_{}_{}_{} -> node_{}_{}_{} [label=\"{}{}{}\", color=\"{}\"{}];",
1325             k.change.to_base32(),
1326             k.start.0,
1327             k.end.0,
1328             dest.change.to_base32(),
1329             dest.start.0,
1330             dest.end.0,
1331             if v.flag().contains(EdgeFlags::BLOCK) {
1332                 "["
1333             } else {
1334                 ""
1335             },
1336             v.introduced_by().to_base32(),
1337             if v.flag().contains(EdgeFlags::BLOCK) {
1338                 "]"
1339             } else {
1340                 ""
1341             },
1342             color,
1343             style
1344         )?;
1345     } else if let Ok(dest) = txn.find_block(&channel, v.dest()) {
1346         writeln!(
1347             f,
1348             "node_{}_{}_{} -> node_{}_{}_{} [label=\"{}{}{}\", color=\"{}\"{}];",
1349             k.change.to_base32(),
1350             k.start.0,
1351             k.end.0,
1352             dest.change.to_base32(),
1353             dest.start.0,
1354             dest.end.0,
1355             if v.flag().contains(EdgeFlags::BLOCK) {
1356                 "["
1357             } else {
1358                 ""
1359             },
1360             v.introduced_by().to_base32(),
1361             if v.flag().contains(EdgeFlags::BLOCK) {
1362                 "]"
1363             } else {
1364                 ""
1365             },
1366             color,
1367             style
1368         )?;
1369     } else {
1370         writeln!(
1371             f,
1372             "node_{}_{}_{} -> node_{}_{} [label=\"{}{}{}\", color=\"{}\"{}];",
1373             k.change.to_base32(),
1374             k.start.0,
1375             k.end.0,
1376             v.dest().change.to_base32(),
1377             v.dest().pos.0,
1378             if v.flag().contains(EdgeFlags::BLOCK) {
1379                 "["
1380             } else {
1381                 ""
1382             },
1383             v.introduced_by().to_base32(),
1384             if v.flag().contains(EdgeFlags::BLOCK) {
1385                 "]"
1386             } else {
1387                 ""
1388             },
1389             color,
1390             style
1391         )?;
1392     }
1393     Ok(())
1394 }
1395 
1396 /// A cursor over a table, initialised at a certain value.
1397 pub struct Cursor<T: Sized, RT: std::ops::Deref<Target = T>, Cursor, K: ?Sized, V: ?Sized> {
1398     pub cursor: Cursor,
1399     pub txn: RT,
1400     pub t: std::marker::PhantomData<T>,
1401     pub k: std::marker::PhantomData<K>,
1402     pub v: std::marker::PhantomData<V>,
1403 }
1404 
1405 pub struct RevCursor<T: Sized, RT: std::ops::Deref<Target = T>, Cursor, K: ?Sized, V: ?Sized> {
1406     pub cursor: Cursor,
1407     pub txn: RT,
1408     pub t: std::marker::PhantomData<T>,
1409     pub k: std::marker::PhantomData<K>,
1410     pub v: std::marker::PhantomData<V>,
1411 }
1412 
1413 initialized_cursor!(changeset, ChangeId, L64, ChannelTxnT, GraphError);
1414 initialized_cursor!(
1415     revchangeset,
1416     L64,
1417     Pair<ChangeId, SerializedMerkle>,
1418     ChannelTxnT,
1419     GraphError
1420 );
1421 initialized_rev_cursor!(
1422     revchangeset,
1423     L64,
1424     Pair<ChangeId, SerializedMerkle>,
1425     ChannelTxnT,
1426     GraphError
1427 );
1428 initialized_cursor!(tree, PathId, Inode, TreeTxnT, TreeError);
1429 initialized_cursor!(revtree, Inode, PathId, TreeTxnT, TreeError);
1430 initialized_cursor!(dep, ChangeId, ChangeId, DepsTxnT, DepsError);
1431 initialized_cursor!(partials, SmallStr, Position<ChangeId>, TreeTxnT, TreeError);
1432 initialized_cursor!(
1433     rev_touched_files,
1434     ChangeId,
1435     Position<ChangeId>,
1436     DepsTxnT,
1437     DepsError
1438 );
1439 initialized_cursor!(
1440     touched_files,
1441     Position<ChangeId>,
1442     ChangeId,
1443     DepsTxnT,
1444     DepsError
1445 );
1446 initialized_cursor!(remote, L64, Pair<SerializedHash, SerializedMerkle>);
1447 initialized_rev_cursor!(remote, L64, Pair<SerializedHash, SerializedMerkle>);
1448 initialized_cursor!(inodes, Inode, Position<ChangeId>, TreeTxnT, TreeError);
1449 initialized_cursor!(revinodes, Position<ChangeId>, Inode, TreeTxnT, TreeError);
1450 initialized_cursor!(tags, L64, SerializedHash, ChannelTxnT, GraphError);
1451 initialized_rev_cursor!(tags, L64, SerializedHash, ChannelTxnT, GraphError);
1452 
1453 /// An iterator for nodes adjacent to `key` through an edge with flags smaller than `max_flag`.
1454 pub struct AdjacentIterator<'txn, T: GraphTxnT> {
1455     it: T::Adj,
1456     graph: &'txn T::Graph,
1457     txn: &'txn T,
1458 }
1459 
1460 impl<'txn, T: GraphTxnT> Iterator for AdjacentIterator<'txn, T> {
1461     type Item = Result<&'txn SerializedEdge, TxnErr<T::GraphError>>;
next(&mut self) -> Option<Self::Item>1462     fn next(&mut self) -> Option<Self::Item> {
1463         self.txn.next_adj(self.graph, &mut self.it)
1464     }
1465 }
1466 
1467 pub struct PathChangeset<'channel, 'txn: 'channel, T: ChannelTxnT + DepsTxnT> {
1468     txn: &'txn T,
1469     channel: &'channel T::Channel,
1470     iter: Cursor<T, &'txn T, T::RevchangesetCursor, L64, Pair<ChangeId, SerializedMerkle>>,
1471     key: Position<ChangeId>,
1472 }
1473 
1474 pub struct RevPathChangeset<'channel, 'txn: 'channel, T: ChannelTxnT + DepsTxnT> {
1475     txn: &'txn T,
1476     channel: &'channel T::Channel,
1477     iter: RevCursor<T, &'txn T, T::RevchangesetCursor, L64, Pair<ChangeId, SerializedMerkle>>,
1478     key: Position<ChangeId>,
1479 }
1480 
1481 impl<
1482         'channel,
1483         'txn: 'channel,
1484         T: ChannelTxnT + DepsTxnT<DepsError = <T as GraphTxnT>::GraphError>,
1485     > Iterator for PathChangeset<'channel, 'txn, T>
1486 {
1487     type Item = Result<Hash, TxnErr<T::GraphError>>;
next(&mut self) -> Option<Self::Item>1488     fn next(&mut self) -> Option<Self::Item> {
1489         while let Some(x) = self.iter.next() {
1490             let changeid = match x {
1491                 Ok(x) => (x.1).a,
1492                 Err(e) => return Some(Err(e)),
1493             };
1494             let iter = match self.txn.iter_rev_touched_files(&changeid, None) {
1495                 Ok(iter) => iter,
1496                 Err(e) => return Some(Err(e)),
1497             };
1498             for x in iter {
1499                 let (p, touched) = match x {
1500                     Ok(x) => x,
1501                     Err(e) => return Some(Err(e)),
1502                 };
1503                 if *p > changeid {
1504                     break;
1505                 } else if *p < changeid {
1506                     continue;
1507                 }
1508                 match is_ancestor_of(self.txn, self.txn.graph(&self.channel), self.key, *touched) {
1509                     Ok(true) => {
1510                         return self
1511                             .txn
1512                             .get_external(&changeid)
1513                             .transpose()
1514                             .map(|x| x.map(|x| x.into()))
1515                     }
1516                     Err(e) => return Some(Err(e)),
1517                     Ok(false) => {}
1518                 }
1519             }
1520         }
1521         None
1522     }
1523 }
1524 
1525 impl<
1526         'channel,
1527         'txn: 'channel,
1528         T: ChannelTxnT + DepsTxnT<DepsError = <T as GraphTxnT>::GraphError>,
1529     > Iterator for RevPathChangeset<'channel, 'txn, T>
1530 {
1531     type Item = Result<Hash, TxnErr<T::GraphError>>;
next(&mut self) -> Option<Self::Item>1532     fn next(&mut self) -> Option<Self::Item> {
1533         loop {
1534             let changeid = match self.iter.next()? {
1535                 Err(e) => return Some(Err(e)),
1536                 Ok((_, p)) => p.a,
1537             };
1538             let iter = match self.txn.iter_rev_touched_files(&changeid, None) {
1539                 Ok(iter) => iter,
1540                 Err(e) => return Some(Err(e)),
1541             };
1542             for x in iter {
1543                 let (p, touched) = match x {
1544                     Ok(x) => x,
1545                     Err(e) => return Some(Err(e)),
1546                 };
1547                 if *p > changeid {
1548                     break;
1549                 } else if *p < changeid {
1550                     continue;
1551                 }
1552                 match is_ancestor_of(self.txn, self.txn.graph(&self.channel), self.key, *touched) {
1553                     Ok(true) => {
1554                         return self
1555                             .txn
1556                             .get_external(&changeid)
1557                             .transpose()
1558                             .map(|x| x.map(From::from))
1559                     }
1560                     Err(e) => return Some(Err(e)),
1561                     Ok(false) => {}
1562                 }
1563             }
1564         }
1565     }
1566 }
1567 
is_ancestor_of<T: GraphTxnT>( txn: &T, channel: &T::Graph, a: Position<ChangeId>, b: Position<ChangeId>, ) -> Result<bool, TxnErr<T::GraphError>>1568 fn is_ancestor_of<T: GraphTxnT>(
1569     txn: &T,
1570     channel: &T::Graph,
1571     a: Position<ChangeId>,
1572     b: Position<ChangeId>,
1573 ) -> Result<bool, TxnErr<T::GraphError>> {
1574     let mut stack = vec![b];
1575     let mut visited = std::collections::HashSet::new();
1576     debug!("a = {:?}", a);
1577     while let Some(b) = stack.pop() {
1578         debug!("pop {:?}", b);
1579         if a == b {
1580             return Ok(true);
1581         }
1582         if !visited.insert(b) {
1583             continue;
1584         }
1585         for p in iter_adjacent(
1586             txn,
1587             channel,
1588             b.inode_vertex(),
1589             EdgeFlags::FOLDER | EdgeFlags::PARENT,
1590             EdgeFlags::FOLDER | EdgeFlags::PARENT | EdgeFlags::PSEUDO,
1591         )? {
1592             let p = p?;
1593             // Ok, since `p` is in the channel.
1594             let parent = txn.find_block_end(channel, p.dest()).unwrap();
1595             for pp in iter_adjacent(
1596                 txn,
1597                 channel,
1598                 *parent,
1599                 EdgeFlags::FOLDER | EdgeFlags::PARENT,
1600                 EdgeFlags::FOLDER | EdgeFlags::PARENT | EdgeFlags::PSEUDO,
1601             )? {
1602                 let pp = pp?;
1603                 if pp.dest() == a {
1604                     return Ok(true);
1605                 }
1606                 stack.push(pp.dest())
1607             }
1608         }
1609     }
1610     Ok(false)
1611 }
1612 
1613 pub struct ChannelIterator<'txn, T: TxnT> {
1614     txn: &'txn T,
1615     cursor: T::ChannelsCursor,
1616 }
1617 
1618 impl<'txn, T: TxnT> Iterator for ChannelIterator<'txn, T> {
1619     type Item = Result<(&'txn SmallStr, ChannelRef<T>), TxnErr<T::GraphError>>;
next(&mut self) -> Option<Self::Item>1620     fn next(&mut self) -> Option<Self::Item> {
1621         // Option<(SmallString, (u64, u64, u64, u64, u64, u64))>
1622         match self.txn.cursor_channels_next(&mut self.cursor) {
1623             Err(e) => Some(Err(e)),
1624             Ok(Some((name, _))) => Some(Ok((name, self.txn.load_channel(name.as_str()).unwrap()?))),
1625             Ok(None) => None,
1626         }
1627     }
1628 }
1629 
1630 pub struct RemotesIterator<'txn, T: TxnT> {
1631     txn: &'txn T,
1632     cursor: T::RemotesCursor,
1633 }
1634 
1635 impl<'txn, T: TxnT> Iterator for RemotesIterator<'txn, T> {
1636     type Item = Result<RemoteRef<T>, TxnErr<T::GraphError>>;
next(&mut self) -> Option<Self::Item>1637     fn next(&mut self) -> Option<Self::Item> {
1638         match self.txn.cursor_remotes_next(&mut self.cursor) {
1639             Ok(Some((name, _))) => self.txn.load_remote(name).transpose(),
1640             Ok(None) => None,
1641             Err(e) => Some(Err(e)),
1642         }
1643     }
1644 }
1645 
1646 pub trait GraphMutTxnT: GraphTxnT {
1647     put_del!(internal, SerializedHash, ChangeId, GraphError);
1648     put_del!(external, ChangeId, SerializedHash, GraphError);
1649 
1650     /// Insert a key and a value to a graph. Returns `false` if and only if `(k, v)` was already in the graph, in which case no insertion happened.
put_graph( &mut self, channel: &mut Self::Graph, k: &Vertex<ChangeId>, v: &SerializedEdge, ) -> Result<bool, TxnErr<Self::GraphError>>1651     fn put_graph(
1652         &mut self,
1653         channel: &mut Self::Graph,
1654         k: &Vertex<ChangeId>,
1655         v: &SerializedEdge,
1656     ) -> Result<bool, TxnErr<Self::GraphError>>;
1657 
1658     /// Delete a key and a value from a graph. Returns `true` if and only if `(k, v)` was in the graph.
del_graph( &mut self, channel: &mut Self::Graph, k: &Vertex<ChangeId>, v: Option<&SerializedEdge>, ) -> Result<bool, TxnErr<Self::GraphError>>1659     fn del_graph(
1660         &mut self,
1661         channel: &mut Self::Graph,
1662         k: &Vertex<ChangeId>,
1663         v: Option<&SerializedEdge>,
1664     ) -> Result<bool, TxnErr<Self::GraphError>>;
1665 
debug(&mut self, channel: &mut Self::Graph, extra: &str)1666     fn debug(&mut self, channel: &mut Self::Graph, extra: &str);
1667 
1668     /// Split a key `[a, b[` at position `pos`, yielding two keys `[a,
1669     /// pos[` and `[pos, b[` linked by an edge.
split_block( &mut self, graph: &mut Self::Graph, key: &Vertex<ChangeId>, pos: ChangePosition, buf: &mut Vec<SerializedEdge>, ) -> Result<(), TxnErr<Self::GraphError>>1670     fn split_block(
1671         &mut self,
1672         graph: &mut Self::Graph,
1673         key: &Vertex<ChangeId>,
1674         pos: ChangePosition,
1675         buf: &mut Vec<SerializedEdge>,
1676     ) -> Result<(), TxnErr<Self::GraphError>>;
1677 }
1678 
1679 pub trait ChannelMutTxnT: ChannelTxnT + GraphMutTxnT {
graph_mut(channel: &mut Self::Channel) -> &mut Self::Graph1680     fn graph_mut(channel: &mut Self::Channel) -> &mut Self::Graph;
touch_channel(&mut self, channel: &mut Self::Channel, t: Option<u64>)1681     fn touch_channel(&mut self, channel: &mut Self::Channel, t: Option<u64>);
1682 
1683     /// Add a change and a timestamp to a change table. Returns `None` if and only if `(p, t)` was already in the change table, in which case no insertion happened. Returns the new state else.
put_changes( &mut self, channel: &mut Self::Channel, p: ChangeId, t: ApplyTimestamp, h: &Hash, ) -> Result<Option<Merkle>, TxnErr<Self::GraphError>>1684     fn put_changes(
1685         &mut self,
1686         channel: &mut Self::Channel,
1687         p: ChangeId,
1688         t: ApplyTimestamp,
1689         h: &Hash,
1690     ) -> Result<Option<Merkle>, TxnErr<Self::GraphError>>;
1691 
1692     /// Delete a change from a change table. Returns `true` if and only if `(p, t)` was in the change table.
del_changes( &mut self, channel: &mut Self::Channel, p: ChangeId, t: ApplyTimestamp, ) -> Result<bool, TxnErr<Self::GraphError>>1693     fn del_changes(
1694         &mut self,
1695         channel: &mut Self::Channel,
1696         p: ChangeId,
1697         t: ApplyTimestamp,
1698     ) -> Result<bool, TxnErr<Self::GraphError>>;
1699 
put_tags( &mut self, channel: &mut Self::Channel, t: ApplyTimestamp, h: &Hash, ) -> Result<(), TxnErr<Self::GraphError>>1700     fn put_tags(
1701         &mut self,
1702         channel: &mut Self::Channel,
1703         t: ApplyTimestamp,
1704         h: &Hash,
1705     ) -> Result<(), TxnErr<Self::GraphError>>;
1706 
del_tags( &mut self, channel: &mut Self::Channel, t: ApplyTimestamp, ) -> Result<(), TxnErr<Self::GraphError>>1707     fn del_tags(
1708         &mut self,
1709         channel: &mut Self::Channel,
1710         t: ApplyTimestamp,
1711     ) -> Result<(), TxnErr<Self::GraphError>>;
1712 }
1713 
1714 pub trait DepsMutTxnT: DepsTxnT {
1715     put_del!(dep, ChangeId, ChangeId, DepsError);
1716     put_del!(revdep, ChangeId, ChangeId, DepsError);
1717     put_del!(touched_files, Position<ChangeId>, ChangeId, DepsError);
1718     put_del!(rev_touched_files, ChangeId, Position<ChangeId>, DepsError);
1719 }
1720 
1721 pub trait TreeMutTxnT: TreeTxnT {
1722     put_del!(inodes, Inode, Position<ChangeId>, TreeError);
1723     put_del!(revinodes, Position<ChangeId>, Inode, TreeError);
1724     put_del!(tree, PathId, Inode, TreeError);
1725     put_del!(revtree, Inode, PathId, TreeError);
put_partials( &mut self, k: &str, e: Position<ChangeId>, ) -> Result<bool, TxnErr<Self::TreeError>>1726     fn put_partials(
1727         &mut self,
1728         k: &str,
1729         e: Position<ChangeId>,
1730     ) -> Result<bool, TxnErr<Self::TreeError>>;
1731 
del_partials( &mut self, k: &str, e: Option<Position<ChangeId>>, ) -> Result<bool, TxnErr<Self::TreeError>>1732     fn del_partials(
1733         &mut self,
1734         k: &str,
1735         e: Option<Position<ChangeId>>,
1736     ) -> Result<bool, TxnErr<Self::TreeError>>;
1737 }
1738 
1739 /// The trait of immutable transactions.
1740 pub trait MutTxnT:
1741     GraphMutTxnT
1742     + ChannelMutTxnT
1743     + DepsMutTxnT<DepsError = <Self as GraphTxnT>::GraphError>
1744     + TreeMutTxnT<TreeError = <Self as GraphTxnT>::GraphError>
1745     + TxnT
1746 {
1747     /// Open a channel, creating it if it is missing. The return type
1748     /// is a `Rc<RefCell<…>>` in order to avoid:
1749     /// - opening the same channel twice. Since a channel contains pointers, that could potentially lead to double-borrow issues. We absolutely have to check that at runtime (hence the `RefCell`).
1750     /// - writing the channel to disk (if the backend is written on the disk) for every minor operation on the channel.
1751     ///
1752     /// Additionally, the `Rc` is used to:
1753     /// - avoid having to commit channels explicitly (channels are
1754     /// committed automatically upon committing the transaction), and
1755     /// - to return a value that doesn't borrow the transaction, so
1756     /// that the channel can actually be used in a mutable transaction.
open_or_create_channel(&mut self, name: &str) -> Result<ChannelRef<Self>, Self::GraphError>1757     fn open_or_create_channel(&mut self, name: &str) -> Result<ChannelRef<Self>, Self::GraphError>;
1758 
fork( &mut self, channel: &ChannelRef<Self>, name: &str, ) -> Result<ChannelRef<Self>, ForkError<Self::GraphError>>1759     fn fork(
1760         &mut self,
1761         channel: &ChannelRef<Self>,
1762         name: &str,
1763     ) -> Result<ChannelRef<Self>, ForkError<Self::GraphError>>;
1764 
rename_channel( &mut self, channel: &mut ChannelRef<Self>, name: &str, ) -> Result<(), ForkError<Self::GraphError>>1765     fn rename_channel(
1766         &mut self,
1767         channel: &mut ChannelRef<Self>,
1768         name: &str,
1769     ) -> Result<(), ForkError<Self::GraphError>>;
1770 
drop_channel(&mut self, name: &str) -> Result<bool, Self::GraphError>1771     fn drop_channel(&mut self, name: &str) -> Result<bool, Self::GraphError>;
1772 
1773     /// Commit this transaction.
commit(self) -> Result<(), Self::GraphError>1774     fn commit(self) -> Result<(), Self::GraphError>;
1775 
open_or_create_remote( &mut self, id: RemoteId, path: &str, ) -> Result<RemoteRef<Self>, Self::GraphError>1776     fn open_or_create_remote(
1777         &mut self,
1778         id: RemoteId,
1779         path: &str,
1780     ) -> Result<RemoteRef<Self>, Self::GraphError>;
1781 
put_remote( &mut self, remote: &mut RemoteRef<Self>, k: u64, v: (Hash, Merkle), ) -> Result<bool, Self::GraphError>1782     fn put_remote(
1783         &mut self,
1784         remote: &mut RemoteRef<Self>,
1785         k: u64,
1786         v: (Hash, Merkle),
1787     ) -> Result<bool, Self::GraphError>;
1788 
del_remote( &mut self, remote: &mut RemoteRef<Self>, k: u64, ) -> Result<bool, Self::GraphError>1789     fn del_remote(
1790         &mut self,
1791         remote: &mut RemoteRef<Self>,
1792         k: u64,
1793     ) -> Result<bool, Self::GraphError>;
1794 
drop_remote(&mut self, remote: RemoteRef<Self>) -> Result<bool, Self::GraphError>1795     fn drop_remote(&mut self, remote: RemoteRef<Self>) -> Result<bool, Self::GraphError>;
1796 
drop_named_remote(&mut self, id: RemoteId) -> Result<bool, Self::GraphError>1797     fn drop_named_remote(&mut self, id: RemoteId) -> Result<bool, Self::GraphError>;
1798 
set_current_channel(&mut self, cur: &str) -> Result<(), Self::GraphError>1799     fn set_current_channel(&mut self, cur: &str) -> Result<(), Self::GraphError>;
1800 }
1801 
put_inodes_with_rev<T: TreeMutTxnT>( txn: &mut T, inode: &Inode, position: &Position<ChangeId>, ) -> Result<(), TxnErr<T::TreeError>>1802 pub(crate) fn put_inodes_with_rev<T: TreeMutTxnT>(
1803     txn: &mut T,
1804     inode: &Inode,
1805     position: &Position<ChangeId>,
1806 ) -> Result<(), TxnErr<T::TreeError>> {
1807     txn.put_inodes(inode, position)?;
1808     txn.put_revinodes(position, inode)?;
1809     Ok(())
1810 }
1811 
del_inodes_with_rev<T: TreeMutTxnT>( txn: &mut T, inode: &Inode, position: &Position<ChangeId>, ) -> Result<bool, TxnErr<T::TreeError>>1812 pub(crate) fn del_inodes_with_rev<T: TreeMutTxnT>(
1813     txn: &mut T,
1814     inode: &Inode,
1815     position: &Position<ChangeId>,
1816 ) -> Result<bool, TxnErr<T::TreeError>> {
1817     if txn.del_inodes(inode, Some(position))? {
1818         assert!(txn.del_revinodes(position, Some(inode))?);
1819         Ok(true)
1820     } else {
1821         Ok(false)
1822     }
1823 }
1824 
put_tree_with_rev<T: TreeMutTxnT>( txn: &mut T, file_id: &PathId, inode: &Inode, ) -> Result<(), TxnErr<T::TreeError>>1825 pub(crate) fn put_tree_with_rev<T: TreeMutTxnT>(
1826     txn: &mut T,
1827     file_id: &PathId,
1828     inode: &Inode,
1829 ) -> Result<(), TxnErr<T::TreeError>> {
1830     if txn.put_tree(file_id, inode)? {
1831         txn.put_revtree(inode, file_id)?;
1832     }
1833     Ok(())
1834 }
1835 
del_tree_with_rev<T: TreeMutTxnT>( txn: &mut T, file_id: &PathId, inode: &Inode, ) -> Result<bool, TxnErr<T::TreeError>>1836 pub(crate) fn del_tree_with_rev<T: TreeMutTxnT>(
1837     txn: &mut T,
1838     file_id: &PathId,
1839     inode: &Inode,
1840 ) -> Result<bool, TxnErr<T::TreeError>> {
1841     if txn.del_tree(file_id, Some(inode))? {
1842         if !file_id.basename.is_empty() {
1843             assert!(txn.del_revtree(inode, Some(file_id))?);
1844         }
1845         Ok(true)
1846     } else {
1847         Ok(false)
1848     }
1849 }
1850 
del_graph_with_rev<T: GraphMutTxnT>( txn: &mut T, graph: &mut T::Graph, mut flag: EdgeFlags, mut k0: Vertex<ChangeId>, mut k1: Vertex<ChangeId>, introduced_by: ChangeId, ) -> Result<bool, TxnErr<T::GraphError>>1851 pub(crate) fn del_graph_with_rev<T: GraphMutTxnT>(
1852     txn: &mut T,
1853     graph: &mut T::Graph,
1854     mut flag: EdgeFlags,
1855     mut k0: Vertex<ChangeId>,
1856     mut k1: Vertex<ChangeId>,
1857     introduced_by: ChangeId,
1858 ) -> Result<bool, TxnErr<T::GraphError>> {
1859     if flag.contains(EdgeFlags::PARENT) {
1860         std::mem::swap(&mut k0, &mut k1);
1861         flag -= EdgeFlags::PARENT
1862     }
1863     debug!("del_graph_with_rev {:?} {:?} {:?}", flag, k0, k1);
1864     let v0 = SerializedEdge::new(flag, k1.change, k1.start, introduced_by);
1865     let a = txn.del_graph(graph, &k0, Some(&v0))?;
1866     {
1867         if let Some(&ee) = txn.get_graph(graph, &k0, Some(&v0))? {
1868             if ee == v0 {
1869                 txn.debug(graph, ".3");
1870                 panic!("Not deleted: {:?} {:?}", k0, v0);
1871             }
1872         }
1873     }
1874     let v1 = SerializedEdge::new(flag | EdgeFlags::PARENT, k0.change, k0.end, introduced_by);
1875     let b = txn.del_graph(graph, &k1, Some(&v1))?;
1876     {
1877         if let Some(&ee) = txn.get_graph(graph, &k1, Some(&v1))? {
1878             if ee == v1 {
1879                 txn.debug(graph, ".3");
1880                 panic!("Not deleted: {:?} {:?}", k1, v1);
1881             }
1882         }
1883     }
1884     if a != b {
1885         txn.debug(graph, ".2");
1886         panic!(
1887             "Failed: {:?} {:?} for {:?} {:?} {:?} {:?}",
1888             a, b, flag, k0, k1, introduced_by
1889         )
1890     }
1891     Ok(a && b)
1892 }
1893 
put_graph_with_rev<T: GraphMutTxnT>( txn: &mut T, graph: &mut T::Graph, flag: EdgeFlags, k0: Vertex<ChangeId>, k1: Vertex<ChangeId>, introduced_by: ChangeId, ) -> Result<bool, TxnErr<T::GraphError>>1894 pub(crate) fn put_graph_with_rev<T: GraphMutTxnT>(
1895     txn: &mut T,
1896     graph: &mut T::Graph,
1897     flag: EdgeFlags,
1898     k0: Vertex<ChangeId>,
1899     k1: Vertex<ChangeId>,
1900     introduced_by: ChangeId,
1901 ) -> Result<bool, TxnErr<T::GraphError>> {
1902     debug_assert!(!flag.contains(EdgeFlags::PARENT));
1903     if k0.change == k1.change {
1904         assert_ne!(k0.start_pos(), k1.start_pos());
1905     }
1906     if introduced_by == ChangeId::ROOT {
1907         assert!(flag.contains(EdgeFlags::PSEUDO));
1908     }
1909 
1910     let gaeul = ChangeId::from_base32(b"GAEULYDRSLJSC").unwrap();
1911     let has_gaeul1 = {
1912         let v = Vertex {
1913             change: gaeul,
1914             start: ChangePosition(L64(1677892)),
1915             end: ChangePosition(L64(1677893)),
1916         };
1917         let e = SerializedEdge::new(
1918             EdgeFlags::PSEUDO | EdgeFlags::PARENT,
1919             gaeul,
1920             ChangePosition(L64(1677837)),
1921             ChangeId::ROOT,
1922         );
1923         if let Some(&ee) = txn.get_graph(graph, &v, Some(&e))? {
1924             ee == e
1925         } else {
1926             false
1927         }
1928     };
1929 
1930     debug!("put_graph_with_rev {:?} {:?} {:?}", k0, k1, flag);
1931     let a = txn.put_graph(
1932         graph,
1933         &k0,
1934         &SerializedEdge::new(flag, k1.change, k1.start, introduced_by),
1935     )?;
1936     let b = txn.put_graph(
1937         graph,
1938         &k1,
1939         &SerializedEdge::new(flag | EdgeFlags::PARENT, k0.change, k0.end, introduced_by),
1940     )?;
1941     assert!((a && b) || (!a && !b));
1942 
1943     let has_gaeul1_ = {
1944         let v = Vertex {
1945             change: gaeul,
1946             start: ChangePosition(L64(1677892)),
1947             end: ChangePosition(L64(1677893)),
1948         };
1949         let e = SerializedEdge::new(
1950             EdgeFlags::PSEUDO | EdgeFlags::PARENT,
1951             gaeul,
1952             ChangePosition(L64(1677837)),
1953             ChangeId::ROOT,
1954         );
1955         if let Some(&ee) = txn.get_graph(graph, &v, Some(&e))? {
1956             ee == e
1957         } else {
1958             false
1959         }
1960     };
1961 
1962     if has_gaeul1 && !has_gaeul1_ {
1963         txn.debug(graph, ".GAEUL");
1964         panic!("GAEULT");
1965     }
1966 
1967     Ok(a && b)
1968 }
1969 
register_change< T: GraphMutTxnT + DepsMutTxnT<DepsError = <T as GraphTxnT>::GraphError>, >( txn: &mut T, internal: &ChangeId, hash: &Hash, change: &Change, ) -> Result<(), TxnErr<T::GraphError>>1970 pub(crate) fn register_change<
1971     T: GraphMutTxnT + DepsMutTxnT<DepsError = <T as GraphTxnT>::GraphError>,
1972 >(
1973     txn: &mut T,
1974     internal: &ChangeId,
1975     hash: &Hash,
1976     change: &Change,
1977 ) -> Result<(), TxnErr<T::GraphError>> {
1978     debug!("registering change {:?}", hash);
1979     let shash = hash.into();
1980     txn.put_external(internal, &shash)?;
1981     txn.put_internal(&shash, internal)?;
1982     for dep in change.dependencies.iter() {
1983         debug!("dep = {:?}", dep);
1984         let dep_internal = *txn.get_internal(&dep.into())?.unwrap();
1985         debug!("{:?} depends on {:?}", internal, dep_internal);
1986         txn.put_revdep(&dep_internal, internal)?;
1987         txn.put_dep(internal, &dep_internal)?;
1988     }
1989     for hunk in change.changes.iter().flat_map(|r| r.iter()) {
1990         let (inode, pos) = match *hunk {
1991             Atom::NewVertex(NewVertex {
1992                 ref inode,
1993                 ref flag,
1994                 ref start,
1995                 ref end,
1996                 ..
1997             }) => {
1998                 if flag.contains(EdgeFlags::FOLDER) && start == end {
1999                     (inode, Some(*start))
2000                 } else {
2001                     (inode, None)
2002                 }
2003             }
2004             Atom::EdgeMap(EdgeMap { ref inode, .. }) => (inode, None),
2005         };
2006         let change = if let Some(c) = inode.change {
2007             txn.get_internal(&c.into())?.unwrap_or(internal)
2008         } else {
2009             internal
2010         };
2011         let inode = Position {
2012             change: *change,
2013             pos: inode.pos,
2014         };
2015         debug!("touched: {:?} {:?}", inode, internal);
2016         txn.put_touched_files(&inode, internal)?;
2017         txn.put_rev_touched_files(internal, &inode)?;
2018         if let Some(pos) = pos {
2019             let inode = Position {
2020                 change: *internal,
2021                 pos,
2022             };
2023             txn.put_touched_files(&inode, internal)?;
2024             txn.put_rev_touched_files(internal, &inode)?;
2025         }
2026     }
2027     Ok(())
2028 }
2029 
first_state_after<T: ChannelTxnT>( txn: &T, c: &T::Channel, pos: u64, ) -> Result<Option<(u64, SerializedMerkle)>, TxnErr<T::GraphError>>2030 fn first_state_after<T: ChannelTxnT>(
2031     txn: &T,
2032     c: &T::Channel,
2033     pos: u64,
2034 ) -> Result<Option<(u64, SerializedMerkle)>, TxnErr<T::GraphError>> {
2035     for x in T::cursor_revchangeset_ref(txn, txn.rev_changes(&c), Some(pos.into()))? {
2036         let (&n, m) = x?;
2037         let n: u64 = n.into();
2038         if n >= pos {
2039             return Ok(Some((n, m.b.clone())));
2040         }
2041     }
2042     Ok(None)
2043 }
2044 
last_state<T: ChannelTxnT>( txn: &T, c: &T::Channel, ) -> Result<Option<(u64, SerializedMerkle)>, TxnErr<T::GraphError>>2045 fn last_state<T: ChannelTxnT>(
2046     txn: &T,
2047     c: &T::Channel,
2048 ) -> Result<Option<(u64, SerializedMerkle)>, TxnErr<T::GraphError>> {
2049     if let Some(e) = txn
2050         .rev_cursor_revchangeset(txn.rev_changes(&c), None)?
2051         .next()
2052     {
2053         let (&b, state) = e?;
2054         let b: u64 = b.into();
2055         Ok(Some((b, state.b.clone())))
2056     } else {
2057         Ok(None)
2058     }
2059 }
2060 
2061 /// Find the last state of c1 that is also in c0.
last_common_state<T: ChannelTxnT>( txn: &T, c0: &T::Channel, c1: &T::Channel, ) -> Result<(u64, u64, SerializedMerkle), TxnErr<T::GraphError>>2062 pub fn last_common_state<T: ChannelTxnT>(
2063     txn: &T,
2064     c0: &T::Channel,
2065     c1: &T::Channel,
2066 ) -> Result<(u64, u64, SerializedMerkle), TxnErr<T::GraphError>> {
2067     let mut a = 0;
2068     let (mut b, mut state) = if let Some(x) = last_state(txn, c1)? {
2069         x
2070     } else {
2071         return Ok((0, 0, Merkle::zero().into()));
2072     };
2073     if let Some(aa) = txn.channel_has_state(txn.states(c0), &state)? {
2074         return Ok((aa.into(), b, state));
2075     }
2076     let mut aa = 0;
2077     let mut a_was_found = false;
2078     while a < b {
2079         let mid = (a + b) / 2;
2080         let (_, s) = first_state_after(txn, c1, mid)?.unwrap();
2081         state = s;
2082         if let Some(aa_) = txn.channel_has_state(txn.states(c0), &state)? {
2083             aa = aa_.into();
2084             a_was_found = true;
2085             a = mid
2086         } else {
2087             b = mid
2088         }
2089     }
2090     if a_was_found {
2091         Ok((aa, a, state))
2092     } else {
2093         Ok((0, 0, Merkle::zero().into()))
2094     }
2095 }
2096 
2097 /// Check that each inode in the inodes table maps to an alive vertex,
2098 /// and that each inode in the tree table is reachable by only one
2099 /// path.
check_tree_inodes<T: GraphTxnT + TreeTxnT>(txn: &T, channel: &T::Graph)2100 pub fn check_tree_inodes<T: GraphTxnT + TreeTxnT>(txn: &T, channel: &T::Graph) {
2101     // Sanity check
2102     for x in txn.iter_inodes().unwrap() {
2103         let (inode, vertex) = x.unwrap();
2104         let mut inode_ = *inode;
2105         while !inode_.is_root() {
2106             if let Some(next) = txn.get_revtree(&inode_, None).unwrap() {
2107                 inode_ = next.parent_inode;
2108             } else {
2109                 panic!("inode = {:?}, inode_ = {:?}", inode, inode_);
2110             }
2111         }
2112         if !is_alive(txn, &channel, &vertex.inode_vertex()).unwrap() {
2113             for e in iter_adj_all(txn, channel, vertex.inode_vertex()).unwrap() {
2114                 error!("{:?} {:?} {:?}", inode, vertex, e.unwrap())
2115             }
2116             panic!(
2117                 "inode {:?}, vertex {:?}, is not alive, {:?}",
2118                 inode,
2119                 vertex,
2120                 tree_path(txn, vertex)
2121             )
2122         }
2123     }
2124     let mut h = HashMap::default();
2125     let id0 = OwnedPathId {
2126         parent_inode: Inode::ROOT,
2127         basename: crate::small_string::SmallString::new(),
2128     };
2129     for x in txn.iter_tree(&id0, None).unwrap() {
2130         let (id, inode) = x.unwrap();
2131         if let Some(inode_) = h.insert(id.to_owned(), inode) {
2132             panic!("id {:?} maps to two inodes: {:?} {:?}", id, inode, inode_);
2133         }
2134     }
2135 }
2136 
2137 /// Check that each alive vertex in the graph is reachable, and vice-versa.
check_alive_debug<T: GraphIter + ChannelTxnT, C: crate::changestore::ChangeStore>( changes: &C, txn: &T, channel: &T::Channel, line: u32, ) -> Result<(), std::io::Error>2138 pub fn check_alive_debug<T: GraphIter + ChannelTxnT, C: crate::changestore::ChangeStore>(
2139     changes: &C,
2140     txn: &T,
2141     channel: &T::Channel,
2142     line: u32,
2143 ) -> Result<(), std::io::Error> {
2144     let (alive, reachable) = crate::pristine::check_alive(txn, txn.graph(channel));
2145     let mut h = HashSet::default();
2146     if !alive.is_empty() {
2147         for (k, file) in alive.iter() {
2148             debug!("alive = {:?}, file = {:?}", k, file);
2149             h.insert(file);
2150         }
2151     }
2152     if !reachable.is_empty() {
2153         for (k, file) in reachable.iter() {
2154             debug!("reachable = {:?}, file = {:?}", k, file);
2155             h.insert(file);
2156         }
2157     }
2158     for file in h.iter() {
2159         let file_ = file.unwrap().start_pos();
2160 
2161         let (path, _) = crate::fs::find_path(changes, txn, channel, true, file_)
2162             .unwrap()
2163             .unwrap();
2164         let path = path.replace("/", "_");
2165         let name = format!(
2166             "debug_{:?}_{}_{}",
2167             path,
2168             file_.change.to_base32(),
2169             file_.pos.0
2170         );
2171         let mut f = std::fs::File::create(&name)?;
2172         let graph = crate::alive::retrieve::retrieve(txn, txn.graph(channel), file_).unwrap();
2173         graph.debug(changes, txn, txn.graph(channel), false, false, &mut f)?;
2174 
2175         let mut f = std::fs::File::create(&format!("{}_all", name))?;
2176         debug_root(txn, txn.graph(channel), file.unwrap(), &mut f, false)?;
2177     }
2178     if !h.is_empty() {
2179         if !alive.is_empty() {
2180             panic!("alive call line {}: {:?}", line, alive);
2181         } else {
2182             panic!("reachable: {:?}", reachable);
2183         }
2184     }
2185     Ok(())
2186 }
2187