1 use super::*;
2 use crate::HashMap;
3 use ::sanakirja::*;
4 use parking_lot::Mutex;
5 use std::collections::hash_map::Entry;
6 use std::path::Path;
7 use std::sync::Arc;
8 
9 /// A Sanakirja pristine.
10 pub struct Pristine {
11     pub env: Arc<::sanakirja::Env>,
12 }
13 
14 pub(crate) type P<K, V> = btree::page::Page<K, V>;
15 type Db<K, V> = btree::Db<K, V>;
16 pub(crate) type UP<K, V> = btree::page_unsized::Page<K, V>;
17 type UDb<K, V> = btree::Db_<K, V, UP<K, V>>;
18 
19 #[derive(Debug, Error)]
20 pub enum SanakirjaError {
21     #[error(transparent)]
22     Sanakirja(#[from] ::sanakirja::Error),
23     #[error("Pristine locked")]
24     PristineLocked,
25     #[error("Pristine corrupt")]
26     PristineCorrupt,
27     #[error(transparent)]
28     Borrow(#[from] std::cell::BorrowError),
29     #[error("Cannot dropped a borrowed channel: {:?}", c)]
30     ChannelRc { c: String },
31     #[error("Pristine version mismatch. Cloning over the network can fix this.")]
32     Version,
33 }
34 
35 impl std::convert::From<::sanakirja::CRCError> for SanakirjaError {
from(_: ::sanakirja::CRCError) -> Self36     fn from(_: ::sanakirja::CRCError) -> Self {
37         SanakirjaError::PristineCorrupt
38     }
39 }
40 
41 impl std::convert::From<::sanakirja::CRCError> for TxnErr<SanakirjaError> {
from(_: ::sanakirja::CRCError) -> Self42     fn from(_: ::sanakirja::CRCError) -> Self {
43         TxnErr(SanakirjaError::PristineCorrupt)
44     }
45 }
46 
47 impl std::convert::From<::sanakirja::Error> for TxnErr<SanakirjaError> {
from(e: ::sanakirja::Error) -> Self48     fn from(e: ::sanakirja::Error) -> Self {
49         TxnErr(e.into())
50     }
51 }
52 
53 impl std::convert::From<TxnErr<::sanakirja::Error>> for TxnErr<SanakirjaError> {
from(e: TxnErr<::sanakirja::Error>) -> Self54     fn from(e: TxnErr<::sanakirja::Error>) -> Self {
55         TxnErr(e.0.into())
56     }
57 }
58 
59 impl Pristine {
new<P: AsRef<Path>>(name: P) -> Result<Self, SanakirjaError>60     pub fn new<P: AsRef<Path>>(name: P) -> Result<Self, SanakirjaError> {
61         Self::new_with_size(name, 1 << 20)
62     }
new_nolock<P: AsRef<Path>>(name: P) -> Result<Self, SanakirjaError>63     pub unsafe fn new_nolock<P: AsRef<Path>>(name: P) -> Result<Self, SanakirjaError> {
64         Self::new_with_size_nolock(name, 1 << 20)
65     }
new_with_size<P: AsRef<Path>>(name: P, size: u64) -> Result<Self, SanakirjaError>66     pub fn new_with_size<P: AsRef<Path>>(name: P, size: u64) -> Result<Self, SanakirjaError> {
67         let env = ::sanakirja::Env::new(name, size, 2);
68         match env {
69             Ok(env) => Ok(Pristine { env: Arc::new(env) }),
70             Err(::sanakirja::Error::IO(e)) => {
71                 if let std::io::ErrorKind::WouldBlock = e.kind() {
72                     Err(SanakirjaError::PristineLocked)
73                 } else {
74                     Err(SanakirjaError::Sanakirja(::sanakirja::Error::IO(e)))
75                 }
76             }
77             Err(e) => Err(SanakirjaError::Sanakirja(e)),
78         }
79     }
new_with_size_nolock<P: AsRef<Path>>( name: P, size: u64, ) -> Result<Self, SanakirjaError>80     pub unsafe fn new_with_size_nolock<P: AsRef<Path>>(
81         name: P,
82         size: u64,
83     ) -> Result<Self, SanakirjaError> {
84         Ok(Pristine {
85             env: Arc::new(::sanakirja::Env::new_nolock(name, size, 2)?),
86         })
87     }
new_anon() -> Result<Self, SanakirjaError>88     pub fn new_anon() -> Result<Self, SanakirjaError> {
89         Self::new_anon_with_size(1 << 20)
90     }
new_anon_with_size(size: u64) -> Result<Self, SanakirjaError>91     pub fn new_anon_with_size(size: u64) -> Result<Self, SanakirjaError> {
92         Ok(Pristine {
93             env: Arc::new(::sanakirja::Env::new_anon(size, 2)?),
94         })
95     }
96 }
97 
98 #[derive(Debug, PartialEq, Clone, Copy)]
99 #[repr(usize)]
100 pub enum Root {
101     Version,
102     Tree,
103     RevTree,
104     Inodes,
105     RevInodes,
106     Internal,
107     External,
108     RevDep,
109     Channels,
110     TouchedFiles,
111     Dep,
112     RevTouchedFiles,
113     Partials,
114     Remotes,
115 }
116 
117 const VERSION: L64 = L64(1u64.to_le());
118 
119 impl Pristine {
txn_begin(&self) -> Result<Txn, SanakirjaError>120     pub fn txn_begin(&self) -> Result<Txn, SanakirjaError> {
121         let txn = ::sanakirja::Env::txn_begin(self.env.clone())?;
122         if L64(txn.root(Root::Version as usize)) != VERSION {
123             return Err(SanakirjaError::Version);
124         }
125         fn begin(txn: ::sanakirja::Txn<Arc<::sanakirja::Env>>) -> Option<Txn> {
126             Some(Txn {
127                 channels: txn.root_db(Root::Channels as usize)?,
128                 external: txn.root_db(Root::External as usize)?,
129                 internal: txn.root_db(Root::Internal as usize)?,
130                 inodes: txn.root_db(Root::Inodes as usize)?,
131                 revinodes: txn.root_db(Root::RevInodes as usize)?,
132                 tree: txn.root_db(Root::Tree as usize)?,
133                 revtree: txn.root_db(Root::RevTree as usize)?,
134                 revdep: txn.root_db(Root::RevDep as usize)?,
135                 touched_files: txn.root_db(Root::TouchedFiles as usize)?,
136                 rev_touched_files: txn.root_db(Root::RevTouchedFiles as usize)?,
137                 partials: txn.root_db(Root::Partials as usize)?,
138                 dep: txn.root_db(Root::Dep as usize)?,
139                 remotes: txn.root_db(Root::Remotes as usize)?,
140                 open_channels: Mutex::new(HashMap::default()),
141                 open_remotes: Mutex::new(HashMap::default()),
142                 txn,
143                 counter: 0,
144                 cur_channel: None,
145             })
146         }
147         if let Some(txn) = begin(txn) {
148             Ok(txn)
149         } else {
150             Err(SanakirjaError::PristineCorrupt)
151         }
152     }
153 
arc_txn_begin(&self) -> Result<ArcTxn<MutTxn<()>>, SanakirjaError>154     pub fn arc_txn_begin(&self) -> Result<ArcTxn<MutTxn<()>>, SanakirjaError> {
155         Ok(ArcTxn(Arc::new(RwLock::new(self.mut_txn_begin()?))))
156     }
157 
mut_txn_begin(&self) -> Result<MutTxn<()>, SanakirjaError>158     pub fn mut_txn_begin(&self) -> Result<MutTxn<()>, SanakirjaError> {
159         let mut txn = ::sanakirja::Env::mut_txn_begin(self.env.clone()).unwrap();
160         if let Some(version) = txn.root(Root::Version as usize) {
161             if L64(version) != VERSION {
162                 return Err(SanakirjaError::Version.into());
163             }
164         } else {
165             txn.set_root(Root::Version as usize, VERSION.0);
166         }
167         Ok(MutTxn {
168             channels: if let Some(db) = txn.root_db(Root::Channels as usize) {
169                 db
170             } else {
171                 btree::create_db_(&mut txn)?
172             },
173             external: if let Some(db) = txn.root_db(Root::External as usize) {
174                 db
175             } else {
176                 btree::create_db_(&mut txn)?
177             },
178             internal: if let Some(db) = txn.root_db(Root::Internal as usize) {
179                 db
180             } else {
181                 btree::create_db_(&mut txn)?
182             },
183             inodes: if let Some(db) = txn.root_db(Root::Inodes as usize) {
184                 db
185             } else {
186                 btree::create_db_(&mut txn)?
187             },
188             revinodes: if let Some(db) = txn.root_db(Root::RevInodes as usize) {
189                 db
190             } else {
191                 btree::create_db_(&mut txn)?
192             },
193             tree: if let Some(db) = txn.root_db(Root::Tree as usize) {
194                 db
195             } else {
196                 btree::create_db_(&mut txn)?
197             },
198             revtree: if let Some(db) = txn.root_db(Root::RevTree as usize) {
199                 db
200             } else {
201                 btree::create_db_(&mut txn)?
202             },
203             revdep: if let Some(db) = txn.root_db(Root::RevDep as usize) {
204                 db
205             } else {
206                 btree::create_db_(&mut txn)?
207             },
208             dep: if let Some(db) = txn.root_db(Root::Dep as usize) {
209                 db
210             } else {
211                 btree::create_db_(&mut txn)?
212             },
213             touched_files: if let Some(db) = txn.root_db(Root::TouchedFiles as usize) {
214                 db
215             } else {
216                 btree::create_db_(&mut txn)?
217             },
218             rev_touched_files: if let Some(db) = txn.root_db(Root::RevTouchedFiles as usize) {
219                 db
220             } else {
221                 btree::create_db_(&mut txn)?
222             },
223             partials: if let Some(db) = txn.root_db(Root::Partials as usize) {
224                 db
225             } else {
226                 btree::create_db_(&mut txn)?
227             },
228             remotes: if let Some(db) = txn.root_db(Root::Remotes as usize) {
229                 db
230             } else {
231                 btree::create_db_(&mut txn)?
232             },
233             open_channels: Mutex::new(HashMap::default()),
234             open_remotes: Mutex::new(HashMap::default()),
235             txn,
236             counter: 0,
237             cur_channel: None,
238         })
239     }
240 }
241 
242 pub type Txn = GenericTxn<::sanakirja::Txn<Arc<::sanakirja::Env>>>;
243 pub type MutTxn<T> = GenericTxn<::sanakirja::MutTxn<Arc<::sanakirja::Env>, T>>;
244 
245 /// A transaction, used both for mutable and immutable transactions,
246 /// depending on type parameter `T`.
247 ///
248 /// In Sanakirja, both `sanakirja::Txn` and `sanakirja::MutTxn`
249 /// implement `sanakirja::Transaction`, explaining our implementation
250 /// of `TxnT` for `Txn<T>` for all `T: sanakirja::Transaction`. This
251 /// covers both mutable and immutable transactions in a single
252 /// implementation.
253 pub struct GenericTxn<T: ::sanakirja::LoadPage<Error = ::sanakirja::Error> + ::sanakirja::RootPage>
254 {
255     #[doc(hidden)]
256     pub txn: T,
257     #[doc(hidden)]
258     pub internal: UDb<SerializedHash, ChangeId>,
259     #[doc(hidden)]
260     pub external: UDb<ChangeId, SerializedHash>,
261     inodes: Db<Inode, Position<ChangeId>>,
262     revinodes: Db<Position<ChangeId>, Inode>,
263 
264     pub tree: UDb<PathId, Inode>,
265     revtree: UDb<Inode, PathId>,
266 
267     revdep: Db<ChangeId, ChangeId>,
268     dep: Db<ChangeId, ChangeId>,
269 
270     touched_files: Db<Position<ChangeId>, ChangeId>,
271     rev_touched_files: Db<ChangeId, Position<ChangeId>>,
272 
273     partials: UDb<SmallStr, Position<ChangeId>>,
274     channels: UDb<SmallStr, SerializedChannel>,
275     remotes: UDb<RemoteId, SerializedRemote>,
276 
277     pub(crate) open_channels: Mutex<HashMap<SmallString, ChannelRef<Self>>>,
278     open_remotes: Mutex<HashMap<RemoteId, RemoteRef<Self>>>,
279     counter: usize,
280     cur_channel: Option<String>,
281 }
282 
283 direct_repr!(SerializedPublicKey);
284 
285 /// This is actually safe because the only non-Send fields are
286 /// `open_channels` and `open_remotes`, but we can't do anything with
287 /// a `ChannelRef` whose transaction has been moved to another thread.
288 unsafe impl<T: ::sanakirja::LoadPage<Error = ::sanakirja::Error> + ::sanakirja::RootPage> Send
289     for GenericTxn<T>
290 {
291 }
292 
293 impl Txn {
check_database(&self)294     pub fn check_database(&self) {
295         let mut refs = std::collections::BTreeMap::new();
296         debug!("check: internal 0x{:x}", self.internal.db);
297         ::sanakirja::debug::add_refs(&self.txn, &self.internal, &mut refs).unwrap();
298         debug!("check: external 0x{:x}", self.external.db);
299         ::sanakirja::debug::add_refs(&self.txn, &self.external, &mut refs).unwrap();
300         debug!("check: inodes 0x{:x}", self.inodes.db);
301         ::sanakirja::debug::add_refs(&self.txn, &self.inodes, &mut refs).unwrap();
302         debug!("check: revinodes 0x{:x}", self.revinodes.db);
303         ::sanakirja::debug::add_refs(&self.txn, &self.revinodes, &mut refs).unwrap();
304         debug!("check: tree 0x{:x}", self.tree.db);
305         ::sanakirja::debug::add_refs(&self.txn, &self.tree, &mut refs).unwrap();
306         debug!("check: revtree 0x{:x}", self.revtree.db);
307         ::sanakirja::debug::add_refs(&self.txn, &self.revtree, &mut refs).unwrap();
308         debug!("check: revdep 0x{:x}", self.revdep.db);
309         ::sanakirja::debug::add_refs(&self.txn, &self.revdep, &mut refs).unwrap();
310         debug!("check: dep 0x{:x}", self.dep.db);
311         ::sanakirja::debug::add_refs(&self.txn, &self.dep, &mut refs).unwrap();
312         debug!("check: touched_files 0x{:x}", self.touched_files.db);
313         ::sanakirja::debug::add_refs(&self.txn, &self.touched_files, &mut refs).unwrap();
314         debug!("check: rev_touched_files 0x{:x}", self.rev_touched_files.db);
315         ::sanakirja::debug::add_refs(&self.txn, &self.rev_touched_files, &mut refs).unwrap();
316         debug!("check: partials 0x{:x}", self.partials.db);
317         ::sanakirja::debug::add_refs(&self.txn, &self.partials, &mut refs).unwrap();
318         debug!("check: channels 0x{:x}", self.channels.db);
319         ::sanakirja::debug::add_refs(&self.txn, &self.channels, &mut refs).unwrap();
320         for x in btree::iter(&self.txn, &self.channels, None).unwrap() {
321             let (name, tup) = x.unwrap();
322             debug!("check: channel name: {:?}", name.as_str());
323             let graph: Db<Vertex<ChangeId>, SerializedEdge> = Db::from_page(tup.graph.into());
324             let changes: Db<ChangeId, L64> = Db::from_page(tup.changes.into());
325             let revchanges: UDb<L64, Pair<ChangeId, SerializedMerkle>> =
326                 UDb::from_page(tup.revchanges.into());
327             let states: UDb<SerializedMerkle, L64> = UDb::from_page(tup.states.into());
328             let tags: UDb<L64, SerializedHash> = UDb::from_page(tup.tags.into());
329             debug!("check: graph 0x{:x}", graph.db);
330             ::sanakirja::debug::add_refs(&self.txn, &graph, &mut refs).unwrap();
331             debug!("check: changes 0x{:x}", changes.db);
332             ::sanakirja::debug::add_refs(&self.txn, &changes, &mut refs).unwrap();
333             debug!("check: revchanges 0x{:x}", revchanges.db);
334             ::sanakirja::debug::add_refs(&self.txn, &revchanges, &mut refs).unwrap();
335             debug!("check: states 0x{:x}", states.db);
336             ::sanakirja::debug::add_refs(&self.txn, &states, &mut refs).unwrap();
337             debug!("check: tags 0x{:x}", tags.db);
338             ::sanakirja::debug::add_refs(&self.txn, &tags, &mut refs).unwrap();
339         }
340         debug!("check: remotes 0x{:x}", self.remotes.db);
341         ::sanakirja::debug::add_refs(&self.txn, &self.remotes, &mut refs).unwrap();
342         for x in btree::iter(&self.txn, &self.remotes, None).unwrap() {
343             let (name, tup) = x.unwrap();
344             debug!("check: remote name: {:?}", name);
345             let remote: UDb<L64, Pair<SerializedHash, SerializedMerkle>> =
346                 UDb::from_page(tup.remote.into());
347 
348             let rev: UDb<SerializedHash, L64> = UDb::from_page(tup.rev.into());
349             let states: UDb<SerializedMerkle, L64> = UDb::from_page(tup.states.into());
350             debug!("check: remote 0x{:x}", remote.db);
351             ::sanakirja::debug::add_refs(&self.txn, &remote, &mut refs).unwrap();
352             debug!("check: rev 0x{:x}", rev.db);
353             ::sanakirja::debug::add_refs(&self.txn, &rev, &mut refs).unwrap();
354             debug!("check: states 0x{:x}", states.db);
355             ::sanakirja::debug::add_refs(&self.txn, &states, &mut refs).unwrap();
356         }
357         ::sanakirja::debug::add_free_refs(&self.txn, &mut refs).unwrap();
358         ::sanakirja::debug::check_free(&self.txn, &refs);
359     }
360 }
361 
362 impl<T: ::sanakirja::LoadPage<Error = ::sanakirja::Error> + ::sanakirja::RootPage> GraphTxnT
363     for GenericTxn<T>
364 {
365     type Graph = Db<Vertex<ChangeId>, SerializedEdge>;
366     type GraphError = SanakirjaError;
367 
368     sanakirja_get!(graph, Vertex<ChangeId>, SerializedEdge, GraphError);
get_external( &self, p: &ChangeId, ) -> Result<Option<&SerializedHash>, TxnErr<Self::GraphError>>369     fn get_external(
370         &self,
371         p: &ChangeId,
372     ) -> Result<Option<&SerializedHash>, TxnErr<Self::GraphError>> {
373         debug!("get_external {:?}", p);
374         if p.is_root() {
375             Ok(Some(&HASH_NONE))
376         } else {
377             match btree::get(&self.txn, &self.external, p, None) {
378                 Ok(Some((k, v))) if k == p => Ok(Some(v)),
379                 Ok(_) => Ok(None),
380                 Err(e) => {
381                     error!("{:?}", e);
382                     Err(TxnErr(SanakirjaError::PristineCorrupt))
383                 }
384             }
385         }
386     }
387 
get_internal( &self, p: &SerializedHash, ) -> Result<Option<&ChangeId>, TxnErr<Self::GraphError>>388     fn get_internal(
389         &self,
390         p: &SerializedHash,
391     ) -> Result<Option<&ChangeId>, TxnErr<Self::GraphError>> {
392         if p.t == HashAlgorithm::None as u8 {
393             Ok(Some(&ChangeId::ROOT))
394         } else {
395             match btree::get(&self.txn, &self.internal, &p, None) {
396                 Ok(Some((k, v))) if k == p => Ok(Some(v)),
397                 Ok(_) => Ok(None),
398                 Err(e) => {
399                     error!("{:?}", e);
400                     Err(TxnErr(SanakirjaError::PristineCorrupt))
401                 }
402             }
403         }
404     }
405 
406     type Adj = Adj;
407 
init_adj( &self, g: &Self::Graph, key: Vertex<ChangeId>, dest: Position<ChangeId>, min_flag: EdgeFlags, max_flag: EdgeFlags, ) -> Result<Self::Adj, TxnErr<Self::GraphError>>408     fn init_adj(
409         &self,
410         g: &Self::Graph,
411         key: Vertex<ChangeId>,
412         dest: Position<ChangeId>,
413         min_flag: EdgeFlags,
414         max_flag: EdgeFlags,
415     ) -> Result<Self::Adj, TxnErr<Self::GraphError>> {
416         let edge = SerializedEdge::new(min_flag, dest.change, dest.pos, ChangeId::ROOT);
417         let mut cursor = btree::cursor::Cursor::new(&self.txn, g).map_err(TxnErr)?;
418         cursor.set(&self.txn, &key, Some(&edge))?;
419         Ok(Adj {
420             cursor,
421             key,
422             min_flag,
423             max_flag,
424         })
425     }
426 
next_adj<'a>( &'a self, _: &Self::Graph, a: &mut Self::Adj, ) -> Option<Result<&'a SerializedEdge, TxnErr<Self::GraphError>>>427     fn next_adj<'a>(
428         &'a self,
429         _: &Self::Graph,
430         a: &mut Self::Adj,
431     ) -> Option<Result<&'a SerializedEdge, TxnErr<Self::GraphError>>> {
432         next_adj(&self.txn, a)
433     }
434 
find_block( &self, graph: &Self::Graph, p: Position<ChangeId>, ) -> Result<&Vertex<ChangeId>, BlockError<Self::GraphError>>435     fn find_block(
436         &self,
437         graph: &Self::Graph,
438         p: Position<ChangeId>,
439     ) -> Result<&Vertex<ChangeId>, BlockError<Self::GraphError>> {
440         find_block(&self.txn, graph, p)
441     }
442 
find_block_end( &self, graph: &Self::Graph, p: Position<ChangeId>, ) -> Result<&Vertex<ChangeId>, BlockError<Self::GraphError>>443     fn find_block_end(
444         &self,
445         graph: &Self::Graph,
446         p: Position<ChangeId>,
447     ) -> Result<&Vertex<ChangeId>, BlockError<Self::GraphError>> {
448         find_block_end(&self.txn, graph, p)
449     }
450 }
451 
452 #[doc(hidden)]
next_adj<'a, T: ::sanakirja::LoadPage<Error = ::sanakirja::Error>>( txn: &'a T, a: &mut Adj, ) -> Option<Result<&'a SerializedEdge, TxnErr<SanakirjaError>>>453 pub fn next_adj<'a, T: ::sanakirja::LoadPage<Error = ::sanakirja::Error>>(
454     txn: &'a T,
455     a: &mut Adj,
456 ) -> Option<Result<&'a SerializedEdge, TxnErr<SanakirjaError>>> {
457     loop {
458         let x: Result<Option<(&Vertex<ChangeId>, &SerializedEdge)>, _> = a.cursor.next(txn);
459         match x {
460             Ok(Some((v, e))) => {
461                 if *v == a.key {
462                     if e.flag() >= a.min_flag {
463                         if e.flag() <= a.max_flag {
464                             return Some(Ok(e));
465                         } else {
466                             return None;
467                         }
468                     }
469                 } else if *v > a.key {
470                     return None;
471                 }
472             }
473             Err(e) => return Some(Err(TxnErr(e.into()))),
474             Ok(None) => {
475                 return None;
476             }
477         }
478     }
479 }
480 
481 #[doc(hidden)]
find_block<'a, T: ::sanakirja::LoadPage<Error = ::sanakirja::Error>>( txn: &'a T, graph: &::sanakirja::btree::Db<Vertex<ChangeId>, SerializedEdge>, p: Position<ChangeId>, ) -> Result<&'a Vertex<ChangeId>, BlockError<SanakirjaError>>482 pub fn find_block<'a, T: ::sanakirja::LoadPage<Error = ::sanakirja::Error>>(
483     txn: &'a T,
484     graph: &::sanakirja::btree::Db<Vertex<ChangeId>, SerializedEdge>,
485     p: Position<ChangeId>,
486 ) -> Result<&'a Vertex<ChangeId>, BlockError<SanakirjaError>> {
487     if p.change.is_root() {
488         return Ok(&Vertex::ROOT);
489     }
490     let key = Vertex {
491         change: p.change,
492         start: p.pos,
493         end: p.pos,
494     };
495     let mut cursor =
496         btree::cursor::Cursor::new(txn, &graph).map_err(|x| BlockError::Txn(x.into()))?;
497     let mut k = if let Some((k, _)) = cursor
498         .set(txn, &key, None)
499         .map_err(|x| BlockError::Txn(x.into()))?
500     {
501         k
502     } else if let Some((k, _)) = cursor.prev(txn).map_err(|x| BlockError::Txn(x.into()))? {
503         k
504     } else {
505         debug!("find_block: BLOCK ERROR");
506         return Err(BlockError::Block { block: p });
507     };
508     // The only guarantee here is that k is either the first key >=
509     // `key`. We might need to rewind by one step if key is strictly
510     // larger than the result (i.e. if `p` is in the middle of the
511     // key).
512     while k.change > p.change || (k.change == p.change && k.start > p.pos) {
513         if let Some((k_, _)) = cursor.prev(txn).map_err(|x| BlockError::Txn(x.into()))? {
514             k = k_
515         } else {
516             break;
517         }
518     }
519     loop {
520         if k.change == p.change && k.start <= p.pos {
521             if k.end > p.pos || (k.start == k.end && k.end == p.pos) {
522                 return Ok(k);
523             }
524         } else if k.change > p.change {
525             debug!("find_block: BLOCK ERROR");
526             return Err(BlockError::Block { block: p });
527         }
528         if let Some((k_, _)) = cursor.next(txn).map_err(|x| BlockError::Txn(x.into()))? {
529             k = k_
530         } else {
531             break;
532         }
533     }
534     debug!("find_block: BLOCK ERROR");
535     Err(BlockError::Block { block: p })
536 }
537 
538 #[doc(hidden)]
find_block_end<'a, T: ::sanakirja::LoadPage<Error = ::sanakirja::Error>>( txn: &'a T, graph: &::sanakirja::btree::Db<Vertex<ChangeId>, SerializedEdge>, p: Position<ChangeId>, ) -> Result<&'a Vertex<ChangeId>, BlockError<SanakirjaError>>539 pub fn find_block_end<'a, T: ::sanakirja::LoadPage<Error = ::sanakirja::Error>>(
540     txn: &'a T,
541     graph: &::sanakirja::btree::Db<Vertex<ChangeId>, SerializedEdge>,
542     p: Position<ChangeId>,
543 ) -> Result<&'a Vertex<ChangeId>, BlockError<SanakirjaError>> {
544     if p.change.is_root() {
545         return Ok(&Vertex::ROOT);
546     }
547     let key = Vertex {
548         change: p.change,
549         start: p.pos,
550         end: p.pos,
551     };
552     let mut cursor =
553         btree::cursor::Cursor::new(txn, graph).map_err(|x| BlockError::Txn(x.into()))?;
554     let mut k = match cursor.set(txn, &key, None) {
555         Ok(Some((k, _))) => k,
556         Ok(None) => {
557             if let Some((k, _)) = cursor.prev(txn).map_err(|x| BlockError::Txn(x.into()))? {
558                 k
559             } else {
560                 debug!("find_block_end, no prev");
561                 return Err(BlockError::Block { block: p });
562             }
563         }
564         Err(e) => {
565             debug!("find_block_end: BLOCK ERROR");
566             return Err(BlockError::Txn(e.into()));
567         }
568     };
569     loop {
570         debug!("find_block_end, loop, k = {:?}, p = {:?}", k, p);
571         if k.change < p.change {
572             break;
573         } else if k.change == p.change {
574             // Here we want to create an edge pointing between `p`
575             // and its successor. If k.start == p.pos, the only
576             // case where that's what we want is if k.start ==
577             // k.end.
578             if k.start == p.pos && k.end == p.pos {
579                 return Ok(k);
580             } else if k.start < p.pos {
581                 break;
582             }
583         }
584         if let Some((k_, _)) = cursor.prev(txn).map_err(|x| BlockError::Txn(x.into()))? {
585             k = k_
586         } else {
587             break;
588         }
589     }
590     // We also want k.end >= p.pos, so we just call next() until
591     // we have that.
592     debug!("find_block_end, {:?} {:?}", k, p);
593     while k.change < p.change || (k.change == p.change && p.pos > k.end) {
594         if let Some((k_, _)) = cursor.next(txn).map_err(|x| BlockError::Txn(x.into()))? {
595             k = k_
596         } else {
597             break;
598         }
599     }
600     debug!("find_block_end, {:?} {:?}", k, p);
601     if k.change == p.change
602         && ((k.start < p.pos && p.pos <= k.end) || (k.start == k.end && k.start == p.pos))
603     {
604         Ok(k)
605     } else {
606         debug!("find_block_end: BLOCK ERROR");
607         Err(BlockError::Block { block: p })
608     }
609 }
610 
611 pub struct Adj {
612     pub cursor: ::sanakirja::btree::cursor::Cursor<
613         Vertex<ChangeId>,
614         SerializedEdge,
615         P<Vertex<ChangeId>, SerializedEdge>,
616     >,
617     pub key: Vertex<ChangeId>,
618     pub min_flag: EdgeFlags,
619     pub max_flag: EdgeFlags,
620 }
621 
622 impl<T: ::sanakirja::LoadPage<Error = ::sanakirja::Error> + ::sanakirja::RootPage> GraphIter
623     for GenericTxn<T>
624 {
625     type GraphCursor = ::sanakirja::btree::cursor::Cursor<
626         Vertex<ChangeId>,
627         SerializedEdge,
628         P<Vertex<ChangeId>, SerializedEdge>,
629     >;
630 
graph_cursor( &self, g: &Self::Graph, s: Option<&Vertex<ChangeId>>, ) -> Result<Self::GraphCursor, TxnErr<Self::GraphError>>631     fn graph_cursor(
632         &self,
633         g: &Self::Graph,
634         s: Option<&Vertex<ChangeId>>,
635     ) -> Result<Self::GraphCursor, TxnErr<Self::GraphError>> {
636         let mut c = ::sanakirja::btree::cursor::Cursor::new(&self.txn, &g)?;
637         if let Some(s) = s {
638             c.set(&self.txn, s, None)?;
639         }
640         Ok(c)
641     }
642 
next_graph<'txn>( &'txn self, _: &Self::Graph, a: &mut Self::GraphCursor, ) -> Option<Result<(&'txn Vertex<ChangeId>, &'txn SerializedEdge), TxnErr<Self::GraphError>>>643     fn next_graph<'txn>(
644         &'txn self,
645         _: &Self::Graph,
646         a: &mut Self::GraphCursor,
647     ) -> Option<Result<(&'txn Vertex<ChangeId>, &'txn SerializedEdge), TxnErr<Self::GraphError>>>
648     {
649         match a.next(&self.txn) {
650             Ok(Some(x)) => Some(Ok(x)),
651             Ok(None) => None,
652             Err(e) => {
653                 error!("{:?}", e);
654                 Some(Err(TxnErr(SanakirjaError::PristineCorrupt)))
655             }
656         }
657     }
658 }
659 
660 // There is a choice here: the datastructure for `revchanges` is
661 // intuitively a list. Moreover, when removing a change, we must
662 // recompute the entire merkle tree after the removed change.
663 //
664 // This seems to indicate that a linked list could be an appropriate
665 // structure (a growable array is excluded because amortised
666 // complexity is not really acceptable here).
667 //
668 // However, we want to be able to answers queries such as "when was
669 // change X introduced?" without having to read the entire database.
670 //
671 // Additionally, even though `SerializedMerkle` has only one
672 // implementation, and is therefore sized in the current
673 // implementation, we can't exclude that other algorithms may be
674 // added, which means that the pages inside linked lists won't even be
675 // randomly-accessible arrays.
676 pub struct Channel {
677     pub graph: Db<Vertex<ChangeId>, SerializedEdge>,
678     pub changes: Db<ChangeId, L64>,
679     pub revchanges: UDb<L64, Pair<ChangeId, SerializedMerkle>>,
680     pub states: UDb<SerializedMerkle, L64>,
681     pub tags: UDb<L64, SerializedHash>,
682     pub apply_counter: ApplyTimestamp,
683     pub name: SmallString,
684     pub last_modified: u64,
685     pub id: RemoteId,
686 }
687 
688 impl<T: ::sanakirja::LoadPage<Error = ::sanakirja::Error> + ::sanakirja::RootPage> ChannelTxnT
689     for GenericTxn<T>
690 {
691     type Channel = Channel;
692 
graph<'a>(&self, c: &'a Self::Channel) -> &'a Db<Vertex<ChangeId>, SerializedEdge>693     fn graph<'a>(&self, c: &'a Self::Channel) -> &'a Db<Vertex<ChangeId>, SerializedEdge> {
694         &c.graph
695     }
name<'a>(&self, c: &'a Self::Channel) -> &'a str696     fn name<'a>(&self, c: &'a Self::Channel) -> &'a str {
697         c.name.as_str()
698     }
id<'a>(&self, c: &'a Self::Channel) -> &'a RemoteId699     fn id<'a>(&self, c: &'a Self::Channel) -> &'a RemoteId {
700         &c.id
701     }
apply_counter(&self, channel: &Self::Channel) -> u64702     fn apply_counter(&self, channel: &Self::Channel) -> u64 {
703         channel.apply_counter.into()
704     }
last_modified(&self, channel: &Self::Channel) -> u64705     fn last_modified(&self, channel: &Self::Channel) -> u64 {
706         channel.last_modified.into()
707     }
changes<'a>(&self, channel: &'a Self::Channel) -> &'a Self::Changeset708     fn changes<'a>(&self, channel: &'a Self::Channel) -> &'a Self::Changeset {
709         &channel.changes
710     }
rev_changes<'a>(&self, channel: &'a Self::Channel) -> &'a Self::RevChangeset711     fn rev_changes<'a>(&self, channel: &'a Self::Channel) -> &'a Self::RevChangeset {
712         &channel.revchanges
713     }
tags<'a>(&self, channel: &'a Self::Channel) -> &'a Self::Tags714     fn tags<'a>(&self, channel: &'a Self::Channel) -> &'a Self::Tags {
715         &channel.tags
716     }
717 
718     type Changeset = Db<ChangeId, L64>;
719     type RevChangeset = UDb<L64, Pair<ChangeId, SerializedMerkle>>;
720 
get_changeset( &self, channel: &Self::Changeset, c: &ChangeId, ) -> Result<Option<&L64>, TxnErr<Self::GraphError>>721     fn get_changeset(
722         &self,
723         channel: &Self::Changeset,
724         c: &ChangeId,
725     ) -> Result<Option<&L64>, TxnErr<Self::GraphError>> {
726         match btree::get(&self.txn, channel, c, None) {
727             Ok(Some((k, x))) if k == c => Ok(Some(x)),
728             Ok(x) => {
729                 debug!("get_changeset = {:?}", x);
730                 Ok(None)
731             }
732             Err(e) => {
733                 error!("{:?}", e);
734                 Err(TxnErr(SanakirjaError::PristineCorrupt))
735             }
736         }
737     }
get_revchangeset( &self, revchanges: &Self::RevChangeset, c: &L64, ) -> Result<Option<&Pair<ChangeId, SerializedMerkle>>, TxnErr<Self::GraphError>>738     fn get_revchangeset(
739         &self,
740         revchanges: &Self::RevChangeset,
741         c: &L64,
742     ) -> Result<Option<&Pair<ChangeId, SerializedMerkle>>, TxnErr<Self::GraphError>> {
743         match btree::get(&self.txn, revchanges, c, None) {
744             Ok(Some((k, x))) if k == c => Ok(Some(x)),
745             Ok(_) => Ok(None),
746             Err(e) => {
747                 error!("{:?}", e);
748                 Err(TxnErr(SanakirjaError::PristineCorrupt))
749             }
750         }
751     }
752 
753     type ChangesetCursor = ::sanakirja::btree::cursor::Cursor<ChangeId, L64, P<ChangeId, L64>>;
754 
cursor_changeset<'a>( &'a self, channel: &Self::Changeset, pos: Option<ChangeId>, ) -> Result<Cursor<Self, &'a Self, Self::ChangesetCursor, ChangeId, L64>, TxnErr<SanakirjaError>>755     fn cursor_changeset<'a>(
756         &'a self,
757         channel: &Self::Changeset,
758         pos: Option<ChangeId>,
759     ) -> Result<Cursor<Self, &'a Self, Self::ChangesetCursor, ChangeId, L64>, TxnErr<SanakirjaError>>
760     {
761         let mut cursor = btree::cursor::Cursor::new(&self.txn, &channel)?;
762         if let Some(k) = pos {
763             cursor.set(&self.txn, &k, None)?;
764         }
765         Ok(Cursor {
766             cursor,
767             txn: self,
768             k: std::marker::PhantomData,
769             v: std::marker::PhantomData,
770             t: std::marker::PhantomData,
771         })
772     }
773 
774     type RevchangesetCursor = ::sanakirja::btree::cursor::Cursor<
775         L64,
776         Pair<ChangeId, SerializedMerkle>,
777         UP<L64, Pair<ChangeId, SerializedMerkle>>,
778     >;
779 
cursor_revchangeset_ref<'a, 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<SanakirjaError>, >780     fn cursor_revchangeset_ref<'a, RT: std::ops::Deref<Target = Self>>(
781         txn: RT,
782         channel: &Self::RevChangeset,
783         pos: Option<L64>,
784     ) -> Result<
785         Cursor<Self, RT, Self::RevchangesetCursor, L64, Pair<ChangeId, SerializedMerkle>>,
786         TxnErr<SanakirjaError>,
787     > {
788         let mut cursor = btree::cursor::Cursor::new(&txn.txn, channel)?;
789         if let Some(k) = pos {
790             cursor.set(&txn.txn, &k, None)?;
791         }
792         Ok(Cursor {
793             cursor,
794             txn,
795             k: std::marker::PhantomData,
796             v: std::marker::PhantomData,
797             t: std::marker::PhantomData,
798         })
799     }
800 
rev_cursor_revchangeset<'a>( &'a self, channel: &Self::RevChangeset, pos: Option<L64>, ) -> Result< RevCursor<Self, &'a Self, Self::RevchangesetCursor, L64, Pair<ChangeId, SerializedMerkle>>, TxnErr<SanakirjaError>, >801     fn rev_cursor_revchangeset<'a>(
802         &'a self,
803         channel: &Self::RevChangeset,
804         pos: Option<L64>,
805     ) -> Result<
806         RevCursor<Self, &'a Self, Self::RevchangesetCursor, L64, Pair<ChangeId, SerializedMerkle>>,
807         TxnErr<SanakirjaError>,
808     > {
809         let mut cursor = btree::cursor::Cursor::new(&self.txn, channel)?;
810         if let Some(ref pos) = pos {
811             cursor.set(&self.txn, pos, None)?;
812         } else {
813             cursor.set_last(&self.txn)?;
814         };
815         Ok(RevCursor {
816             cursor,
817             txn: self,
818             k: std::marker::PhantomData,
819             v: std::marker::PhantomData,
820             t: std::marker::PhantomData,
821         })
822     }
823 
cursor_revchangeset_next( &self, cursor: &mut Self::RevchangesetCursor, ) -> Result<Option<(&L64, &Pair<ChangeId, SerializedMerkle>)>, TxnErr<SanakirjaError>>824     fn cursor_revchangeset_next(
825         &self,
826         cursor: &mut Self::RevchangesetCursor,
827     ) -> Result<Option<(&L64, &Pair<ChangeId, SerializedMerkle>)>, TxnErr<SanakirjaError>> {
828         if let Ok(x) = cursor.next(&self.txn) {
829             Ok(x)
830         } else {
831             Err(TxnErr(SanakirjaError::PristineCorrupt))
832         }
833     }
cursor_revchangeset_prev( &self, cursor: &mut Self::RevchangesetCursor, ) -> Result<Option<(&L64, &Pair<ChangeId, SerializedMerkle>)>, TxnErr<SanakirjaError>>834     fn cursor_revchangeset_prev(
835         &self,
836         cursor: &mut Self::RevchangesetCursor,
837     ) -> Result<Option<(&L64, &Pair<ChangeId, SerializedMerkle>)>, TxnErr<SanakirjaError>> {
838         if let Ok(x) = cursor.prev(&self.txn) {
839             Ok(x)
840         } else {
841             Err(TxnErr(SanakirjaError::PristineCorrupt))
842         }
843     }
844 
cursor_changeset_next( &self, cursor: &mut Self::ChangesetCursor, ) -> Result<Option<(&ChangeId, &L64)>, TxnErr<SanakirjaError>>845     fn cursor_changeset_next(
846         &self,
847         cursor: &mut Self::ChangesetCursor,
848     ) -> Result<Option<(&ChangeId, &L64)>, TxnErr<SanakirjaError>> {
849         if let Ok(x) = cursor.next(&self.txn) {
850             Ok(x)
851         } else {
852             Err(TxnErr(SanakirjaError::PristineCorrupt))
853         }
854     }
cursor_changeset_prev( &self, cursor: &mut Self::ChangesetCursor, ) -> Result<Option<(&ChangeId, &L64)>, TxnErr<SanakirjaError>>855     fn cursor_changeset_prev(
856         &self,
857         cursor: &mut Self::ChangesetCursor,
858     ) -> Result<Option<(&ChangeId, &L64)>, TxnErr<SanakirjaError>> {
859         if let Ok(x) = cursor.prev(&self.txn) {
860             Ok(x)
861         } else {
862             Err(TxnErr(SanakirjaError::PristineCorrupt))
863         }
864     }
865 
866     type States = UDb<SerializedMerkle, L64>;
states<'a>(&self, channel: &'a Self::Channel) -> &'a Self::States867     fn states<'a>(&self, channel: &'a Self::Channel) -> &'a Self::States {
868         &channel.states
869     }
channel_has_state( &self, channel: &Self::States, m: &SerializedMerkle, ) -> Result<Option<L64>, TxnErr<Self::GraphError>>870     fn channel_has_state(
871         &self,
872         channel: &Self::States,
873         m: &SerializedMerkle,
874     ) -> Result<Option<L64>, TxnErr<Self::GraphError>> {
875         match btree::get(&self.txn, channel, m, None)? {
876             Some((k, v)) if k == m => Ok(Some(*v)),
877             _ => Ok(None),
878         }
879     }
880 
881     type Tags = UDb<L64, SerializedHash>;
get_tags( &self, channel: &Self::Tags, c: &L64, ) -> Result<Option<&SerializedHash>, TxnErr<Self::GraphError>>882     fn get_tags(
883         &self,
884         channel: &Self::Tags,
885         c: &L64,
886     ) -> Result<Option<&SerializedHash>, TxnErr<Self::GraphError>> {
887         match btree::get(&self.txn, channel, c, None)? {
888             Some((k, v)) if k == c => Ok(Some(v)),
889             _ => Ok(None),
890         }
891     }
892 
893     type TagsCursor =
894         ::sanakirja::btree::cursor::Cursor<L64, SerializedHash, UP<L64, SerializedHash>>;
cursor_tags<'txn>( &'txn self, channel: &Self::Tags, k: Option<L64>, ) -> Result< crate::pristine::Cursor<Self, &'txn Self, Self::TagsCursor, L64, SerializedHash>, TxnErr<Self::GraphError>, >895     fn cursor_tags<'txn>(
896         &'txn self,
897         channel: &Self::Tags,
898         k: Option<L64>,
899     ) -> Result<
900         crate::pristine::Cursor<Self, &'txn Self, Self::TagsCursor, L64, SerializedHash>,
901         TxnErr<Self::GraphError>,
902     > {
903         let mut cursor = btree::cursor::Cursor::new(&self.txn, channel)?;
904         if let Some(k) = k {
905             cursor.set(&self.txn, &k, None)?;
906         }
907         Ok(Cursor {
908             cursor,
909             txn: self,
910             k: std::marker::PhantomData,
911             v: std::marker::PhantomData,
912             t: std::marker::PhantomData,
913         })
914     }
cursor_tags_next( &self, cursor: &mut Self::TagsCursor, ) -> Result<Option<(&L64, &SerializedHash)>, TxnErr<Self::GraphError>>915     fn cursor_tags_next(
916         &self,
917         cursor: &mut Self::TagsCursor,
918     ) -> Result<Option<(&L64, &SerializedHash)>, TxnErr<Self::GraphError>> {
919         if let Ok(x) = cursor.next(&self.txn) {
920             Ok(x)
921         } else {
922             Err(TxnErr(SanakirjaError::PristineCorrupt))
923         }
924     }
925 
cursor_tags_prev( &self, cursor: &mut Self::TagsCursor, ) -> Result<Option<(&L64, &SerializedHash)>, TxnErr<Self::GraphError>>926     fn cursor_tags_prev(
927         &self,
928         cursor: &mut Self::TagsCursor,
929     ) -> Result<Option<(&L64, &SerializedHash)>, TxnErr<Self::GraphError>> {
930         if let Ok(x) = cursor.prev(&self.txn) {
931             Ok(x)
932         } else {
933             Err(TxnErr(SanakirjaError::PristineCorrupt))
934         }
935     }
936 
iter_tags( &self, channel: &Self::Tags, from: u64, ) -> Result< super::Cursor<Self, &Self, Self::TagsCursor, L64, SerializedHash>, TxnErr<Self::GraphError>, >937     fn iter_tags(
938         &self,
939         channel: &Self::Tags,
940         from: u64,
941     ) -> Result<
942         super::Cursor<Self, &Self, Self::TagsCursor, L64, SerializedHash>,
943         TxnErr<Self::GraphError>,
944     > {
945         self.cursor_tags(channel, Some(from.into()))
946     }
947 
rev_iter_tags( &self, channel: &Self::Tags, from: Option<u64>, ) -> Result< super::RevCursor<Self, &Self, Self::TagsCursor, L64, SerializedHash>, TxnErr<Self::GraphError>, >948     fn rev_iter_tags(
949         &self,
950         channel: &Self::Tags,
951         from: Option<u64>,
952     ) -> Result<
953         super::RevCursor<Self, &Self, Self::TagsCursor, L64, SerializedHash>,
954         TxnErr<Self::GraphError>,
955     > {
956         let mut cursor = btree::cursor::Cursor::new(&self.txn, channel)?;
957         if let Some(from) = from {
958             cursor.set(&self.txn, &from.into(), None)?;
959         } else {
960             cursor.set_last(&self.txn)?;
961         };
962         Ok(RevCursor {
963             cursor,
964             txn: self,
965             k: std::marker::PhantomData,
966             v: std::marker::PhantomData,
967             t: std::marker::PhantomData,
968         })
969     }
970 }
971 
972 impl<T: ::sanakirja::LoadPage<Error = ::sanakirja::Error> + ::sanakirja::RootPage> DepsTxnT
973     for GenericTxn<T>
974 {
975     type DepsError = SanakirjaError;
976     type Dep = Db<ChangeId, ChangeId>;
977     type Revdep = Db<ChangeId, ChangeId>;
978 
979     sanakirja_table_get!(dep, ChangeId, ChangeId, DepsError);
980     sanakirja_table_get!(revdep, ChangeId, ChangeId, DepsError);
981     type DepCursor = ::sanakirja::btree::cursor::Cursor<ChangeId, ChangeId, P<ChangeId, ChangeId>>;
982     sanakirja_cursor_ref!(dep, ChangeId, ChangeId);
iter_dep_ref<RT: std::ops::Deref<Target = Self> + Clone>( txn: RT, p: &ChangeId, ) -> Result<super::Cursor<Self, RT, Self::DepCursor, ChangeId, ChangeId>, TxnErr<Self::DepsError>>983     fn iter_dep_ref<RT: std::ops::Deref<Target = Self> + Clone>(
984         txn: RT,
985         p: &ChangeId,
986     ) -> Result<super::Cursor<Self, RT, Self::DepCursor, ChangeId, ChangeId>, TxnErr<Self::DepsError>>
987     {
988         Self::cursor_dep_ref(txn.clone(), &txn.dep, Some((p, None)))
989     }
990 
991     sanakirja_table_get!(touched_files, Position<ChangeId>, ChangeId, DepsError);
992     sanakirja_table_get!(rev_touched_files, ChangeId, Position<ChangeId>, DepsError);
993 
994     type Touched_files = Db<Position<ChangeId>, ChangeId>;
995 
996     type Rev_touched_files = Db<ChangeId, Position<ChangeId>>;
997 
998     type Touched_filesCursor = ::sanakirja::btree::cursor::Cursor<
999         Position<ChangeId>,
1000         ChangeId,
1001         P<Position<ChangeId>, ChangeId>,
1002     >;
1003     sanakirja_iter!(touched_files, Position<ChangeId>, ChangeId);
1004 
1005     type Rev_touched_filesCursor = ::sanakirja::btree::cursor::Cursor<
1006         ChangeId,
1007         Position<ChangeId>,
1008         P<ChangeId, Position<ChangeId>>,
1009     >;
1010     sanakirja_iter!(rev_touched_files, ChangeId, Position<ChangeId>);
iter_revdep( &self, k: &ChangeId, ) -> Result< super::Cursor<Self, &Self, Self::DepCursor, ChangeId, ChangeId>, TxnErr<Self::DepsError>, >1011     fn iter_revdep(
1012         &self,
1013         k: &ChangeId,
1014     ) -> Result<
1015         super::Cursor<Self, &Self, Self::DepCursor, ChangeId, ChangeId>,
1016         TxnErr<Self::DepsError>,
1017     > {
1018         self.cursor_dep(&self.revdep, Some((k, None)))
1019     }
1020 
iter_dep( &self, k: &ChangeId, ) -> Result< super::Cursor<Self, &Self, Self::DepCursor, ChangeId, ChangeId>, TxnErr<Self::DepsError>, >1021     fn iter_dep(
1022         &self,
1023         k: &ChangeId,
1024     ) -> Result<
1025         super::Cursor<Self, &Self, Self::DepCursor, ChangeId, ChangeId>,
1026         TxnErr<Self::DepsError>,
1027     > {
1028         self.cursor_dep(&self.dep, Some((k, None)))
1029     }
1030 
iter_touched( &self, k: &Position<ChangeId>, ) -> Result< super::Cursor<Self, &Self, Self::Touched_filesCursor, Position<ChangeId>, ChangeId>, TxnErr<Self::DepsError>, >1031     fn iter_touched(
1032         &self,
1033         k: &Position<ChangeId>,
1034     ) -> Result<
1035         super::Cursor<Self, &Self, Self::Touched_filesCursor, Position<ChangeId>, ChangeId>,
1036         TxnErr<Self::DepsError>,
1037     > {
1038         self.cursor_touched_files(&self.touched_files, Some((k, None)))
1039     }
1040 
iter_rev_touched( &self, k: &ChangeId, ) -> Result< super::Cursor<Self, &Self, Self::Rev_touched_filesCursor, ChangeId, Position<ChangeId>>, TxnErr<Self::DepsError>, >1041     fn iter_rev_touched(
1042         &self,
1043         k: &ChangeId,
1044     ) -> Result<
1045         super::Cursor<Self, &Self, Self::Rev_touched_filesCursor, ChangeId, Position<ChangeId>>,
1046         TxnErr<Self::DepsError>,
1047     > {
1048         self.cursor_rev_touched_files(&self.rev_touched_files, Some((k, None)))
1049     }
1050 }
1051 
1052 impl<T: ::sanakirja::LoadPage<Error = ::sanakirja::Error> + ::sanakirja::RootPage> TreeTxnT
1053     for GenericTxn<T>
1054 {
1055     type TreeError = SanakirjaError;
1056     type Inodes = Db<Inode, Position<ChangeId>>;
1057     type Revinodes = Db<Position<ChangeId>, Inode>;
1058     sanakirja_table_get!(inodes, Inode, Position<ChangeId>, TreeError);
1059     sanakirja_table_get!(revinodes, Position<ChangeId>, Inode, TreeError);
1060     sanakirja_cursor!(inodes, Inode, Position<ChangeId>);
1061     // #[cfg(debug_assertions)]
1062     sanakirja_cursor!(revinodes, Position<ChangeId>, Inode);
1063 
1064     type Tree = UDb<PathId, Inode>;
1065     sanakirja_table_get!(tree, PathId, Inode, TreeError,);
1066     type TreeCursor = ::sanakirja::btree::cursor::Cursor<PathId, Inode, UP<PathId, Inode>>;
1067     sanakirja_iter!(tree, PathId, Inode,);
1068     type RevtreeCursor = ::sanakirja::btree::cursor::Cursor<Inode, PathId, UP<Inode, PathId>>;
1069     sanakirja_iter!(revtree, Inode, PathId);
1070 
1071     type Revtree = UDb<Inode, PathId>;
1072     sanakirja_table_get!(revtree, Inode, PathId, TreeError,);
1073 
1074     type Partials = UDb<SmallStr, Position<ChangeId>>;
1075     type PartialsCursor = ::sanakirja::btree::cursor::Cursor<
1076         SmallStr,
1077         Position<ChangeId>,
1078         UP<SmallStr, Position<ChangeId>>,
1079     >;
1080     sanakirja_cursor!(partials, SmallStr, Position<ChangeId>,);
1081     type InodesCursor =
1082         ::sanakirja::btree::cursor::Cursor<Inode, Position<ChangeId>, P<Inode, Position<ChangeId>>>;
iter_inodes( &self, ) -> Result< super::Cursor<Self, &Self, Self::InodesCursor, Inode, Position<ChangeId>>, TxnErr<Self::TreeError>, >1083     fn iter_inodes(
1084         &self,
1085     ) -> Result<
1086         super::Cursor<Self, &Self, Self::InodesCursor, Inode, Position<ChangeId>>,
1087         TxnErr<Self::TreeError>,
1088     > {
1089         self.cursor_inodes(&self.inodes, None)
1090     }
1091 
1092     // #[cfg(debug_assertions)]
1093     type RevinodesCursor =
1094         ::sanakirja::btree::cursor::Cursor<Position<ChangeId>, Inode, P<Position<ChangeId>, Inode>>;
1095     // #[cfg(debug_assertions)]
iter_revinodes( &self, ) -> Result< super::Cursor<Self, &Self, Self::RevinodesCursor, Position<ChangeId>, Inode>, TxnErr<SanakirjaError>, >1096     fn iter_revinodes(
1097         &self,
1098     ) -> Result<
1099         super::Cursor<Self, &Self, Self::RevinodesCursor, Position<ChangeId>, Inode>,
1100         TxnErr<SanakirjaError>,
1101     > {
1102         self.cursor_revinodes(&self.revinodes, None)
1103     }
1104 
iter_partials<'txn>( &'txn self, k: &str, ) -> Result< super::Cursor<Self, &'txn Self, Self::PartialsCursor, SmallStr, Position<ChangeId>>, TxnErr<SanakirjaError>, >1105     fn iter_partials<'txn>(
1106         &'txn self,
1107         k: &str,
1108     ) -> Result<
1109         super::Cursor<Self, &'txn Self, Self::PartialsCursor, SmallStr, Position<ChangeId>>,
1110         TxnErr<SanakirjaError>,
1111     > {
1112         let k0 = SmallString::from_str(k);
1113         self.cursor_partials(&self.partials, Some((&k0, None)))
1114     }
1115 }
1116 
1117 impl<T: ::sanakirja::LoadPage<Error = ::sanakirja::Error> + ::sanakirja::RootPage> GenericTxn<T> {
1118     #[doc(hidden)]
unsafe_load_channel( &self, name: SmallString, ) -> Result<Option<Channel>, TxnErr<SanakirjaError>>1119     pub unsafe fn unsafe_load_channel(
1120         &self,
1121         name: SmallString,
1122     ) -> Result<Option<Channel>, TxnErr<SanakirjaError>> {
1123         match btree::get(&self.txn, &self.channels, &name, None)? {
1124             Some((name_, tup)) if name_ == name.as_ref() => {
1125                 debug!("load_channel: {:?} {:?}", name, tup);
1126                 Ok(Some(Channel {
1127                     graph: Db::from_page(tup.graph.into()),
1128                     changes: Db::from_page(tup.changes.into()),
1129                     revchanges: UDb::from_page(tup.revchanges.into()),
1130                     states: UDb::from_page(tup.states.into()),
1131                     tags: UDb::from_page(tup.tags.into()),
1132                     apply_counter: tup.apply_counter.into(),
1133                     last_modified: tup.last_modified.into(),
1134                     id: tup.id,
1135                     name,
1136                 }))
1137             }
1138             _ => {
1139                 debug!("unsafe_load_channel: not found");
1140                 Ok(None)
1141             }
1142         }
1143     }
1144 }
1145 
1146 impl<T: ::sanakirja::LoadPage<Error = ::sanakirja::Error> + ::sanakirja::RootPage> TxnT
1147     for GenericTxn<T>
1148 {
hash_from_prefix( &self, s: &str, ) -> Result<(Hash, ChangeId), super::HashPrefixError<Self::GraphError>>1149     fn hash_from_prefix(
1150         &self,
1151         s: &str,
1152     ) -> Result<(Hash, ChangeId), super::HashPrefixError<Self::GraphError>> {
1153         let h: SerializedHash = if let Some(ref h) = Hash::from_prefix(s) {
1154             h.into()
1155         } else {
1156             return Err(super::HashPrefixError::Parse(s.to_string()));
1157         };
1158         let mut result = None;
1159         debug!("h = {:?}", h);
1160         for x in btree::iter(&self.txn, &self.internal, Some((&h, None)))
1161             .map_err(|e| super::HashPrefixError::Txn(e.into()))?
1162         {
1163             let (e, i) = x.map_err(|e| super::HashPrefixError::Txn(e.into()))?;
1164             debug!("{:?} {:?}", e, i);
1165             if e < &h {
1166                 continue;
1167             } else {
1168                 let e: Hash = e.into();
1169                 let b32 = e.to_base32();
1170                 debug!("{:?}", b32);
1171                 let (b32, _) = b32.split_at(s.len().min(b32.len()));
1172                 if b32 != s {
1173                     break;
1174                 } else if result.is_none() {
1175                     result = Some((e, *i))
1176                 } else {
1177                     return Err(super::HashPrefixError::Ambiguous(s.to_string()));
1178                 }
1179             }
1180         }
1181         if let Some(result) = result {
1182             Ok(result)
1183         } else {
1184             Err(super::HashPrefixError::NotFound(s.to_string()))
1185         }
1186     }
1187 
hash_from_prefix_remote<'txn>( &'txn self, remote: &RemoteRef<Self>, s: &str, ) -> Result<Hash, super::HashPrefixError<Self::GraphError>>1188     fn hash_from_prefix_remote<'txn>(
1189         &'txn self,
1190         remote: &RemoteRef<Self>,
1191         s: &str,
1192     ) -> Result<Hash, super::HashPrefixError<Self::GraphError>> {
1193         let remote = remote.db.lock();
1194         let h: SerializedHash = if let Some(h) = Hash::from_prefix(s) {
1195             (&h).into()
1196         } else {
1197             return Err(super::HashPrefixError::Parse(s.to_string()));
1198         };
1199         let mut result = None;
1200         debug!("h = {:?}", h);
1201         for x in btree::iter(&self.txn, &remote.rev, Some((&h, None)))
1202             .map_err(|e| super::HashPrefixError::Txn(e.into()))?
1203         {
1204             let (e, _) = x.map_err(|e| super::HashPrefixError::Txn(e.into()))?;
1205             debug!("{:?}", e);
1206             if e < &h {
1207                 continue;
1208             } else {
1209                 let e: Hash = e.into();
1210                 let b32 = e.to_base32();
1211                 debug!("{:?}", b32);
1212                 let (b32, _) = b32.split_at(s.len().min(b32.len()));
1213                 if b32 != s {
1214                     break;
1215                 } else if result.is_none() {
1216                     result = Some(e)
1217                 } else {
1218                     return Err(super::HashPrefixError::Ambiguous(s.to_string()));
1219                 }
1220             }
1221         }
1222         if let Some(result) = result {
1223             Ok(result)
1224         } else {
1225             Err(super::HashPrefixError::NotFound(s.to_string()))
1226         }
1227     }
1228 
load_channel( &self, name: &str, ) -> Result<Option<ChannelRef<Self>>, TxnErr<Self::GraphError>>1229     fn load_channel(
1230         &self,
1231         name: &str,
1232     ) -> Result<Option<ChannelRef<Self>>, TxnErr<Self::GraphError>> {
1233         let name = SmallString::from_str(name);
1234         match self.open_channels.lock().entry(name.clone()) {
1235             Entry::Vacant(v) => {
1236                 if let Some(c) = unsafe { self.unsafe_load_channel(name)? } {
1237                     Ok(Some(
1238                         v.insert(ChannelRef {
1239                             r: Arc::new(RwLock::new(c)),
1240                         })
1241                         .clone(),
1242                     ))
1243                 } else {
1244                     Ok(None)
1245                 }
1246             }
1247             Entry::Occupied(occ) => Ok(Some(occ.get().clone())),
1248         }
1249     }
1250 
load_remote( &self, name: &RemoteId, ) -> Result<Option<RemoteRef<Self>>, TxnErr<Self::GraphError>>1251     fn load_remote(
1252         &self,
1253         name: &RemoteId,
1254     ) -> Result<Option<RemoteRef<Self>>, TxnErr<Self::GraphError>> {
1255         let name = name.to_owned();
1256         match self.open_remotes.lock().entry(name.clone()) {
1257             Entry::Vacant(v) => match btree::get(&self.txn, &self.remotes, &name, None)? {
1258                 Some((name_, remote)) if name == *name_ => {
1259                     debug!("load_remote: {:?} {:?}", name_, remote);
1260                     let r = Remote {
1261                         remote: UDb::from_page(remote.remote.into()),
1262                         rev: UDb::from_page(remote.rev.into()),
1263                         states: UDb::from_page(remote.states.into()),
1264                         id_rev: remote.id_rev.into(),
1265                         path: remote.path.to_owned(),
1266                     };
1267                     for x in btree::iter(&self.txn, &r.remote, None).unwrap() {
1268                         debug!("remote -> {:?}", x);
1269                     }
1270                     for x in btree::iter(&self.txn, &r.rev, None).unwrap() {
1271                         debug!("rev -> {:?}", x);
1272                     }
1273                     for x in btree::iter(&self.txn, &r.states, None).unwrap() {
1274                         debug!("states -> {:?}", x);
1275                     }
1276 
1277                     for x in self.iter_remote(&r.remote, 0).unwrap() {
1278                         debug!("ITER {:?}", x);
1279                     }
1280 
1281                     let r = RemoteRef {
1282                         db: Arc::new(Mutex::new(r)),
1283                         id: name,
1284                     };
1285                     Ok(Some(v.insert(r).clone()))
1286                 }
1287                 _ => return Ok(None),
1288             },
1289             Entry::Occupied(occ) => Ok(Some(occ.get().clone())),
1290         }
1291     }
1292 
1293     ///
1294     type Channels = UDb<SmallStr, SerializedChannel>;
1295     type ChannelsCursor = ::sanakirja::btree::cursor::Cursor<
1296         SmallStr,
1297         SerializedChannel,
1298         UP<SmallStr, SerializedChannel>,
1299     >;
1300     sanakirja_cursor!(channels, SmallStr, SerializedChannel);
iter_channels<'txn>( &'txn self, start: &str, ) -> Result<ChannelIterator<'txn, Self>, TxnErr<Self::GraphError>>1301     fn iter_channels<'txn>(
1302         &'txn self,
1303         start: &str,
1304     ) -> Result<ChannelIterator<'txn, Self>, TxnErr<Self::GraphError>> {
1305         let name = SmallString::from_str(start);
1306         let mut cursor = btree::cursor::Cursor::new(&self.txn, &self.channels)?;
1307         cursor.set(&self.txn, &name, None)?;
1308         Ok(ChannelIterator { cursor, txn: self })
1309     }
1310 
1311     type Remotes = UDb<RemoteId, SerializedRemote>;
1312     type RemotesCursor = ::sanakirja::btree::cursor::Cursor<
1313         RemoteId,
1314         SerializedRemote,
1315         UP<RemoteId, SerializedRemote>,
1316     >;
1317     sanakirja_cursor!(remotes, RemoteId, SerializedRemote);
iter_remotes<'txn>( &'txn self, start: &RemoteId, ) -> Result<RemotesIterator<'txn, Self>, TxnErr<Self::GraphError>>1318     fn iter_remotes<'txn>(
1319         &'txn self,
1320         start: &RemoteId,
1321     ) -> Result<RemotesIterator<'txn, Self>, TxnErr<Self::GraphError>> {
1322         let mut cursor = btree::cursor::Cursor::new(&self.txn, &self.remotes)?;
1323         cursor.set(&self.txn, start, None)?;
1324         Ok(RemotesIterator { cursor, txn: self })
1325     }
1326 
1327     type Remote = UDb<L64, Pair<SerializedHash, SerializedMerkle>>;
1328     type Revremote = UDb<SerializedHash, L64>;
1329     type Remotestates = UDb<SerializedMerkle, L64>;
1330     type RemoteCursor = ::sanakirja::btree::cursor::Cursor<
1331         L64,
1332         Pair<SerializedHash, SerializedMerkle>,
1333         UP<L64, Pair<SerializedHash, SerializedMerkle>>,
1334     >;
1335     sanakirja_cursor!(remote, L64, Pair<SerializedHash, SerializedMerkle>);
1336     sanakirja_rev_cursor!(remote, L64, Pair<SerializedHash, SerializedMerkle>);
1337 
iter_remote<'txn>( &'txn self, remote: &Self::Remote, k: u64, ) -> Result< super::Cursor< Self, &'txn Self, Self::RemoteCursor, L64, Pair<SerializedHash, SerializedMerkle>, >, TxnErr<Self::GraphError>, >1338     fn iter_remote<'txn>(
1339         &'txn self,
1340         remote: &Self::Remote,
1341         k: u64,
1342     ) -> Result<
1343         super::Cursor<
1344             Self,
1345             &'txn Self,
1346             Self::RemoteCursor,
1347             L64,
1348             Pair<SerializedHash, SerializedMerkle>,
1349         >,
1350         TxnErr<Self::GraphError>,
1351     > {
1352         self.cursor_remote(remote, Some((&k.into(), None)))
1353     }
1354 
iter_rev_remote<'txn>( &'txn self, remote: &Self::Remote, k: Option<L64>, ) -> Result< super::RevCursor< Self, &'txn Self, Self::RemoteCursor, L64, Pair<SerializedHash, SerializedMerkle>, >, TxnErr<Self::GraphError>, >1355     fn iter_rev_remote<'txn>(
1356         &'txn self,
1357         remote: &Self::Remote,
1358         k: Option<L64>,
1359     ) -> Result<
1360         super::RevCursor<
1361             Self,
1362             &'txn Self,
1363             Self::RemoteCursor,
1364             L64,
1365             Pair<SerializedHash, SerializedMerkle>,
1366         >,
1367         TxnErr<Self::GraphError>,
1368     > {
1369         self.rev_cursor_remote(remote, k.as_ref().map(|k| (k, None)))
1370     }
1371 
get_remote( &mut self, name: RemoteId, ) -> Result<Option<RemoteRef<Self>>, TxnErr<Self::GraphError>>1372     fn get_remote(
1373         &mut self,
1374         name: RemoteId,
1375     ) -> Result<Option<RemoteRef<Self>>, TxnErr<Self::GraphError>> {
1376         let name = name.to_owned();
1377         match self.open_remotes.lock().entry(name.clone()) {
1378             Entry::Vacant(v) => match btree::get(&self.txn, &self.remotes, &name, None)? {
1379                 Some((name_, remote)) if *name_ == name => {
1380                     let r = RemoteRef {
1381                         db: Arc::new(Mutex::new(Remote {
1382                             remote: UDb::from_page(remote.remote.into()),
1383                             rev: UDb::from_page(remote.rev.into()),
1384                             states: UDb::from_page(remote.states.into()),
1385                             id_rev: remote.id_rev.into(),
1386                             path: remote.path.to_owned(),
1387                         })),
1388                         id: name,
1389                     };
1390                     v.insert(r);
1391                 }
1392                 _ => return Ok(None),
1393             },
1394             Entry::Occupied(_) => {}
1395         }
1396         Ok(self.open_remotes.lock().get(&name).cloned())
1397     }
1398 
last_remote( &self, remote: &Self::Remote, ) -> Result<Option<(u64, &Pair<SerializedHash, SerializedMerkle>)>, TxnErr<Self::GraphError>>1399     fn last_remote(
1400         &self,
1401         remote: &Self::Remote,
1402     ) -> Result<Option<(u64, &Pair<SerializedHash, SerializedMerkle>)>, TxnErr<Self::GraphError>>
1403     {
1404         if let Some(x) = btree::rev_iter(&self.txn, remote, None)?.next() {
1405             let (&k, v) = x?;
1406             Ok(Some((k.into(), v)))
1407         } else {
1408             Ok(None)
1409         }
1410     }
1411 
get_remote_state( &self, remote: &Self::Remote, n: u64, ) -> Result<Option<(u64, &Pair<SerializedHash, SerializedMerkle>)>, TxnErr<Self::GraphError>>1412     fn get_remote_state(
1413         &self,
1414         remote: &Self::Remote,
1415         n: u64,
1416     ) -> Result<Option<(u64, &Pair<SerializedHash, SerializedMerkle>)>, TxnErr<Self::GraphError>>
1417     {
1418         let n = n.into();
1419         for x in btree::iter(&self.txn, remote, Some((&n, None)))? {
1420             let (&k, m) = x?;
1421             if k >= n {
1422                 return Ok(Some((k.into(), m)));
1423             }
1424         }
1425         Ok(None)
1426     }
1427 
remote_has_change( &self, remote: &RemoteRef<Self>, hash: &SerializedHash, ) -> Result<bool, TxnErr<Self::GraphError>>1428     fn remote_has_change(
1429         &self,
1430         remote: &RemoteRef<Self>,
1431         hash: &SerializedHash,
1432     ) -> Result<bool, TxnErr<Self::GraphError>> {
1433         match btree::get(&self.txn, &remote.db.lock().rev, hash, None)? {
1434             Some((k, _)) if k == hash => Ok(true),
1435             _ => Ok(false),
1436         }
1437     }
remote_has_state( &self, remote: &RemoteRef<Self>, m: &SerializedMerkle, ) -> Result<bool, TxnErr<Self::GraphError>>1438     fn remote_has_state(
1439         &self,
1440         remote: &RemoteRef<Self>,
1441         m: &SerializedMerkle,
1442     ) -> Result<bool, TxnErr<Self::GraphError>> {
1443         match btree::get(&self.txn, &remote.db.lock().states, m, None)? {
1444             Some((k, _)) if k == m => Ok(true),
1445             _ => Ok(false),
1446         }
1447     }
current_channel(&self) -> Result<&str, Self::GraphError>1448     fn current_channel(&self) -> Result<&str, Self::GraphError> {
1449         if let Some(ref c) = self.cur_channel {
1450             Ok(c)
1451         } else {
1452             unsafe {
1453                 let b = self.txn.root_page();
1454                 let len = b[4096 - 256] as usize;
1455                 if len == 0 {
1456                     Ok("main")
1457                 } else {
1458                     let s = std::slice::from_raw_parts(b.as_ptr().add(4096 - 255), len);
1459                     Ok(std::str::from_utf8(s).unwrap_or("main"))
1460                 }
1461             }
1462         }
1463     }
1464 }
1465 
1466 impl GraphMutTxnT for MutTxn<()> {
put_graph( &mut self, graph: &mut Self::Graph, k: &Vertex<ChangeId>, e: &SerializedEdge, ) -> Result<bool, TxnErr<Self::GraphError>>1467     fn put_graph(
1468         &mut self,
1469         graph: &mut Self::Graph,
1470         k: &Vertex<ChangeId>,
1471         e: &SerializedEdge,
1472     ) -> Result<bool, TxnErr<Self::GraphError>> {
1473         Ok(btree::put(&mut self.txn, graph, k, e)?)
1474     }
1475 
del_graph( &mut self, graph: &mut Self::Graph, k: &Vertex<ChangeId>, e: Option<&SerializedEdge>, ) -> Result<bool, TxnErr<Self::GraphError>>1476     fn del_graph(
1477         &mut self,
1478         graph: &mut Self::Graph,
1479         k: &Vertex<ChangeId>,
1480         e: Option<&SerializedEdge>,
1481     ) -> Result<bool, TxnErr<Self::GraphError>> {
1482         Ok(btree::del(&mut self.txn, graph, k, e)?)
1483     }
1484 
debug(&mut self, graph: &mut Self::Graph, extra: &str)1485     fn debug(&mut self, graph: &mut Self::Graph, extra: &str) {
1486         ::sanakirja::debug::debug(
1487             &self.txn,
1488             &[graph],
1489             format!("debug{}{}", self.counter, extra),
1490             true,
1491         );
1492     }
1493 
1494     sanakirja_put_del!(internal, SerializedHash, ChangeId, GraphError);
1495     sanakirja_put_del!(external, ChangeId, SerializedHash, GraphError);
1496 
split_block( &mut self, graph: &mut Self::Graph, key: &Vertex<ChangeId>, pos: ChangePosition, buf: &mut Vec<SerializedEdge>, ) -> Result<(), TxnErr<Self::GraphError>>1497     fn split_block(
1498         &mut self,
1499         graph: &mut Self::Graph,
1500         key: &Vertex<ChangeId>,
1501         pos: ChangePosition,
1502         buf: &mut Vec<SerializedEdge>,
1503     ) -> Result<(), TxnErr<Self::GraphError>> {
1504         assert!(pos > key.start);
1505         assert!(pos < key.end);
1506         let mut cursor = btree::cursor::Cursor::new(&self.txn, graph)?;
1507         cursor.set(&self.txn, key, None)?;
1508         loop {
1509             match cursor.next(&self.txn) {
1510                 Ok(Some((k, v))) => {
1511                     if k > key {
1512                         break;
1513                     } else if k < key {
1514                         continue;
1515                     }
1516                     buf.push(*v)
1517                 }
1518                 Ok(None) => break,
1519                 Err(e) => {
1520                     error!("{:?}", e);
1521                     return Err(TxnErr(SanakirjaError::PristineCorrupt));
1522                 }
1523             }
1524         }
1525         for chi in buf.drain(..) {
1526             assert!(
1527                 chi.introduced_by() != ChangeId::ROOT || chi.flag().contains(EdgeFlags::PSEUDO)
1528             );
1529             if chi.flag().contains(EdgeFlags::PARENT | EdgeFlags::BLOCK) {
1530                 put_graph_with_rev(
1531                     self,
1532                     graph,
1533                     chi.flag() - EdgeFlags::PARENT,
1534                     Vertex {
1535                         change: key.change,
1536                         start: key.start,
1537                         end: pos,
1538                     },
1539                     Vertex {
1540                         change: key.change,
1541                         start: pos,
1542                         end: key.end,
1543                     },
1544                     chi.introduced_by(),
1545                 )?;
1546             }
1547 
1548             self.del_graph(graph, key, Some(&chi))?;
1549             self.put_graph(
1550                 graph,
1551                 &if chi.flag().contains(EdgeFlags::PARENT) {
1552                     Vertex {
1553                         change: key.change,
1554                         start: key.start,
1555                         end: pos,
1556                     }
1557                 } else {
1558                     Vertex {
1559                         change: key.change,
1560                         start: pos,
1561                         end: key.end,
1562                     }
1563                 },
1564                 &chi,
1565             )?;
1566         }
1567         Ok(())
1568     }
1569 }
1570 
1571 impl ChannelMutTxnT for MutTxn<()> {
graph_mut(c: &mut Self::Channel) -> &mut Self::Graph1572     fn graph_mut(c: &mut Self::Channel) -> &mut Self::Graph {
1573         &mut c.graph
1574     }
touch_channel(&mut self, channel: &mut Self::Channel, t: Option<u64>)1575     fn touch_channel(&mut self, channel: &mut Self::Channel, t: Option<u64>) {
1576         use std::time::SystemTime;
1577         debug!("touch_channel: {:?}", t);
1578         if let Some(t) = t {
1579             channel.last_modified = t.into()
1580         } else if let Ok(duration) = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
1581             channel.last_modified = duration.as_secs().into()
1582         }
1583     }
1584 
put_changes( &mut self, channel: &mut Self::Channel, p: ChangeId, t: ApplyTimestamp, h: &Hash, ) -> Result<Option<Merkle>, TxnErr<Self::GraphError>>1585     fn put_changes(
1586         &mut self,
1587         channel: &mut Self::Channel,
1588         p: ChangeId,
1589         t: ApplyTimestamp,
1590         h: &Hash,
1591     ) -> Result<Option<Merkle>, TxnErr<Self::GraphError>> {
1592         debug!("put_changes {:?} {:?}", p, h);
1593         if let Some(m) = self.get_changeset(&channel.changes, &p)? {
1594             debug!("found m = {:?}, p = {:?}", m, p);
1595             Ok(None)
1596         } else {
1597             channel.apply_counter += 1;
1598             debug!("put_changes {:?} {:?}", t, p);
1599             let m = if let Some(x) = btree::rev_iter(&self.txn, &channel.revchanges, None)?.next() {
1600                 (&(x?.1).b).into()
1601             } else {
1602                 Merkle::zero()
1603             };
1604             let m = m.next(h);
1605             assert!(self
1606                 .get_revchangeset(&channel.revchanges, &t.into())?
1607                 .is_none());
1608             assert!(btree::put(
1609                 &mut self.txn,
1610                 &mut channel.changes,
1611                 &p,
1612                 &t.into()
1613             )?);
1614             assert!(btree::put(
1615                 &mut self.txn,
1616                 &mut channel.revchanges,
1617                 &t.into(),
1618                 &Pair { a: p, b: m.into() }
1619             )?);
1620             Ok(Some(m.into()))
1621         }
1622     }
1623 
del_changes( &mut self, channel: &mut Self::Channel, p: ChangeId, t: ApplyTimestamp, ) -> Result<bool, TxnErr<Self::GraphError>>1624     fn del_changes(
1625         &mut self,
1626         channel: &mut Self::Channel,
1627         p: ChangeId,
1628         t: ApplyTimestamp,
1629     ) -> Result<bool, TxnErr<Self::GraphError>> {
1630         let mut repl = Vec::new();
1631         let tl = t.into();
1632         for x in btree::iter(&self.txn, &channel.revchanges, Some((&tl, None)))? {
1633             let (t_, p) = x?;
1634             if *t_ >= tl {
1635                 repl.push((*t_, p.a))
1636             }
1637         }
1638         let mut m = Merkle::zero();
1639         for x in btree::rev_iter(&self.txn, &channel.revchanges, Some((&tl, None)))? {
1640             let (t_, mm) = x?;
1641             if t_ < &tl {
1642                 m = (&mm.b).into();
1643                 break;
1644             }
1645         }
1646         for (t_, p) in repl.iter() {
1647             debug!("del_changes {:?} {:?}", t_, p);
1648             btree::del(&mut self.txn, &mut channel.revchanges, t_, None)?;
1649             if *t_ > tl {
1650                 m = m.next(&self.get_external(p)?.unwrap().into());
1651                 btree::put(
1652                     &mut self.txn,
1653                     &mut channel.revchanges,
1654                     t_,
1655                     &Pair { a: *p, b: m.into() },
1656                 )?;
1657             }
1658         }
1659         btree::del(&mut self.txn, &mut channel.tags, &t.into(), None)?;
1660         Ok(btree::del(
1661             &mut self.txn,
1662             &mut channel.changes,
1663             &p,
1664             Some(&t.into()),
1665         )?)
1666     }
1667 
put_tags( &mut self, channel: &mut Self::Channel, t: ApplyTimestamp, h: &Hash, ) -> Result<(), TxnErr<Self::GraphError>>1668     fn put_tags(
1669         &mut self,
1670         channel: &mut Self::Channel,
1671         t: ApplyTimestamp,
1672         h: &Hash,
1673     ) -> Result<(), TxnErr<Self::GraphError>> {
1674         btree::put(&mut self.txn, &mut channel.tags, &t.into(), &h.into())?;
1675         Ok(())
1676     }
1677 
del_tags( &mut self, channel: &mut Self::Channel, t: ApplyTimestamp, ) -> Result<(), TxnErr<Self::GraphError>>1678     fn del_tags(
1679         &mut self,
1680         channel: &mut Self::Channel,
1681         t: ApplyTimestamp,
1682     ) -> Result<(), TxnErr<Self::GraphError>> {
1683         btree::del(&mut self.txn, &mut channel.tags, &t.into(), None)?;
1684         Ok(())
1685     }
1686 }
1687 
1688 impl DepsMutTxnT for MutTxn<()> {
1689     sanakirja_put_del!(dep, ChangeId, ChangeId, DepsError);
1690     sanakirja_put_del!(revdep, ChangeId, ChangeId, DepsError);
1691     sanakirja_put_del!(touched_files, Position<ChangeId>, ChangeId, DepsError);
1692     sanakirja_put_del!(rev_touched_files, ChangeId, Position<ChangeId>, DepsError);
1693 }
1694 
1695 impl TreeMutTxnT for MutTxn<()> {
1696     sanakirja_put_del!(inodes, Inode, Position<ChangeId>, TreeError);
1697     sanakirja_put_del!(revinodes, Position<ChangeId>, Inode, TreeError);
1698 
1699     sanakirja_put_del!(tree, PathId, Inode, TreeError,);
1700     sanakirja_put_del!(revtree, Inode, PathId, TreeError,);
1701 
put_partials( &mut self, k: &str, e: Position<ChangeId>, ) -> Result<bool, TxnErr<Self::TreeError>>1702     fn put_partials(
1703         &mut self,
1704         k: &str,
1705         e: Position<ChangeId>,
1706     ) -> Result<bool, TxnErr<Self::TreeError>> {
1707         let k = SmallString::from_str(k);
1708         Ok(btree::put(&mut self.txn, &mut self.partials, &k, &e)?)
1709     }
1710 
del_partials( &mut self, k: &str, e: Option<Position<ChangeId>>, ) -> Result<bool, TxnErr<Self::TreeError>>1711     fn del_partials(
1712         &mut self,
1713         k: &str,
1714         e: Option<Position<ChangeId>>,
1715     ) -> Result<bool, TxnErr<Self::TreeError>> {
1716         let k = SmallString::from_str(k);
1717         Ok(btree::del(
1718             &mut self.txn,
1719             &mut self.partials,
1720             &k,
1721             e.as_ref(),
1722         )?)
1723     }
1724 }
1725 
1726 impl MutTxnT for MutTxn<()> {
put_remote( &mut self, remote: &mut RemoteRef<Self>, k: u64, v: (Hash, Merkle), ) -> Result<bool, Self::GraphError>1727     fn put_remote(
1728         &mut self,
1729         remote: &mut RemoteRef<Self>,
1730         k: u64,
1731         v: (Hash, Merkle),
1732     ) -> Result<bool, Self::GraphError> {
1733         let mut remote = remote.db.lock();
1734         let h = (&v.0).into();
1735         let m: SerializedMerkle = (&v.1).into();
1736         btree::put(
1737             &mut self.txn,
1738             &mut remote.remote,
1739             &k.into(),
1740             &Pair { a: h, b: m.clone() },
1741         )?;
1742         btree::put(&mut self.txn, &mut remote.states, &m, &k.into())?;
1743         Ok(btree::put(&mut self.txn, &mut remote.rev, &h, &k.into())?)
1744     }
1745 
del_remote( &mut self, remote: &mut RemoteRef<Self>, k: u64, ) -> Result<bool, Self::GraphError>1746     fn del_remote(
1747         &mut self,
1748         remote: &mut RemoteRef<Self>,
1749         k: u64,
1750     ) -> Result<bool, Self::GraphError> {
1751         let mut remote = remote.db.lock();
1752         let k = k.into();
1753         match btree::get(&self.txn, &remote.remote, &k, None)? {
1754             Some((k0, p)) if k0 == &k => {
1755                 debug!("del_remote {:?} {:?}", k0, p);
1756                 let p = p.clone();
1757                 btree::del(&mut self.txn, &mut remote.rev, &p.a, None)?;
1758                 btree::del(&mut self.txn, &mut remote.states, &p.b, None)?;
1759                 Ok(btree::del(
1760                     &mut self.txn,
1761                     &mut remote.remote,
1762                     &k.into(),
1763                     None,
1764                 )?)
1765             }
1766             x => {
1767                 debug!("not found, {:?}", x);
1768                 Ok(false)
1769             }
1770         }
1771     }
1772 
open_or_create_channel(&mut self, name: &str) -> Result<ChannelRef<Self>, Self::GraphError>1773     fn open_or_create_channel(&mut self, name: &str) -> Result<ChannelRef<Self>, Self::GraphError> {
1774         let name = crate::small_string::SmallString::from_str(name);
1775         let mut commit = None;
1776         let result = match self.open_channels.lock().entry(name.clone()) {
1777             Entry::Vacant(v) => {
1778                 let r = match btree::get(&self.txn, &self.channels, &name, None)? {
1779                     Some((name_, b)) if name_ == name.as_ref() => ChannelRef {
1780                         r: Arc::new(RwLock::new(Channel {
1781                             graph: Db::from_page(b.graph.into()),
1782                             changes: Db::from_page(b.changes.into()),
1783                             revchanges: UDb::from_page(b.revchanges.into()),
1784                             states: UDb::from_page(b.states.into()),
1785                             tags: UDb::from_page(b.tags.into()),
1786                             apply_counter: b.apply_counter.into(),
1787                             last_modified: b.last_modified.into(),
1788                             id: b.id,
1789                             name: name.clone(),
1790                         })),
1791                     },
1792                     _ => {
1793                         let br = ChannelRef {
1794                             r: Arc::new(RwLock::new(Channel {
1795                                 graph: btree::create_db_(&mut self.txn)?,
1796                                 changes: btree::create_db_(&mut self.txn)?,
1797                                 revchanges: btree::create_db_(&mut self.txn)?,
1798                                 states: btree::create_db_(&mut self.txn)?,
1799                                 tags: btree::create_db_(&mut self.txn)?,
1800                                 id: {
1801                                     let mut rng = rand::thread_rng();
1802                                     use rand::Rng;
1803                                     let mut x = RemoteId([0; 16]);
1804                                     for x in x.0.iter_mut() {
1805                                         *x = rng.gen()
1806                                     }
1807                                     x
1808                                 },
1809                                 apply_counter: 0,
1810                                 last_modified: 0,
1811                                 name: name.clone(),
1812                             })),
1813                         };
1814                         commit = Some(br.clone());
1815                         br
1816                     }
1817                 };
1818                 v.insert(r).clone()
1819             }
1820             Entry::Occupied(occ) => occ.get().clone(),
1821         };
1822         if let Some(commit) = commit {
1823             self.put_channel(commit)?;
1824         }
1825         Ok(result)
1826     }
1827 
fork( &mut self, channel: &ChannelRef<Self>, new_name: &str, ) -> Result<ChannelRef<Self>, ForkError<Self::GraphError>>1828     fn fork(
1829         &mut self,
1830         channel: &ChannelRef<Self>,
1831         new_name: &str,
1832     ) -> Result<ChannelRef<Self>, ForkError<Self::GraphError>> {
1833         let channel = channel.r.read();
1834         let name = SmallString::from_str(new_name);
1835         match btree::get(&self.txn, &self.channels, &name, None)
1836             .map_err(|e| ForkError::Txn(e.into()))?
1837         {
1838             Some((name_, _)) if name_ == name.as_ref() => {
1839                 Err(super::ForkError::ChannelNameExists(new_name.to_string()))
1840             }
1841             _ => {
1842                 let br = ChannelRef {
1843                     r: Arc::new(RwLock::new(Channel {
1844                         graph: btree::fork_db(&mut self.txn, &channel.graph)
1845                             .map_err(|e| ForkError::Txn(e.into()))?,
1846                         changes: btree::fork_db(&mut self.txn, &channel.changes)
1847                             .map_err(|e| ForkError::Txn(e.into()))?,
1848                         revchanges: btree::fork_db(&mut self.txn, &channel.revchanges)
1849                             .map_err(|e| ForkError::Txn(e.into()))?,
1850                         states: btree::fork_db(&mut self.txn, &channel.states)
1851                             .map_err(|e| ForkError::Txn(e.into()))?,
1852                         tags: btree::fork_db(&mut self.txn, &channel.tags)
1853                             .map_err(|e| ForkError::Txn(e.into()))?,
1854                         name: name.clone(),
1855                         apply_counter: channel.apply_counter,
1856                         last_modified: channel.last_modified,
1857                         id: {
1858                             let mut rng = rand::thread_rng();
1859                             use rand::Rng;
1860                             let mut x = RemoteId([0; 16]);
1861                             for x in x.0.iter_mut() {
1862                                 *x = rng.gen()
1863                             }
1864                             x
1865                         },
1866                     })),
1867                 };
1868                 self.open_channels.lock().insert(name, br.clone());
1869                 Ok(br)
1870             }
1871         }
1872     }
1873 
rename_channel( &mut self, channel: &mut ChannelRef<Self>, new_name: &str, ) -> Result<(), ForkError<Self::GraphError>>1874     fn rename_channel(
1875         &mut self,
1876         channel: &mut ChannelRef<Self>,
1877         new_name: &str,
1878     ) -> Result<(), ForkError<Self::GraphError>> {
1879         let name = SmallString::from_str(new_name);
1880         match btree::get(&self.txn, &self.channels, &name, None)
1881             .map_err(|e| ForkError::Txn(e.into()))?
1882         {
1883             Some((name_, _)) if name_ == name.as_ref() => {
1884                 Err(super::ForkError::ChannelNameExists(new_name.to_string()))
1885             }
1886             _ => {
1887                 btree::del(
1888                     &mut self.txn,
1889                     &mut self.channels,
1890                     &channel.r.read().name,
1891                     None,
1892                 )
1893                 .map_err(|e| ForkError::Txn(e.into()))?;
1894                 std::mem::drop(
1895                     self.open_channels
1896                         .lock()
1897                         .remove(&channel.r.read().name)
1898                         .unwrap(),
1899                 );
1900                 channel.r.write().name = name.clone();
1901                 self.open_channels.lock().insert(name, channel.clone());
1902                 Ok(())
1903             }
1904         }
1905     }
1906 
drop_channel(&mut self, name0: &str) -> Result<bool, Self::GraphError>1907     fn drop_channel(&mut self, name0: &str) -> Result<bool, Self::GraphError> {
1908         let name = SmallString::from_str(name0);
1909         let channel = if let Some(channel) = self.open_channels.lock().remove(&name) {
1910             let channel = Arc::try_unwrap(channel.r)
1911                 .map_err(|_| SanakirjaError::ChannelRc {
1912                     c: name0.to_string(),
1913                 })?
1914                 .into_inner();
1915             Some((
1916                 channel.graph,
1917                 channel.changes,
1918                 channel.revchanges,
1919                 channel.states,
1920                 channel.tags,
1921             ))
1922         } else if let Some((name_, chan)) = btree::get(&self.txn, &self.channels, &name, None)? {
1923             if name_ == name.as_ref() {
1924                 Some((
1925                     Db::from_page(chan.graph.into()),
1926                     Db::from_page(chan.changes.into()),
1927                     UDb::from_page(chan.revchanges.into()),
1928                     UDb::from_page(chan.states.into()),
1929                     UDb::from_page(chan.tags.into()),
1930                 ))
1931             } else {
1932                 None
1933             }
1934         } else {
1935             None
1936         };
1937         btree::del(&mut self.txn, &mut self.channels, &name, None)?;
1938         if let Some((a, b, c, d, e)) = channel {
1939             let mut unused_changes = Vec::new();
1940             'outer: for x in btree::rev_iter(&self.txn, &c, None)? {
1941                 let (_, p) = x?;
1942                 for chan in self.iter_channels("").map_err(|e| e.0)? {
1943                     let (name, chan) = chan.map_err(|e| e.0)?;
1944                     assert_ne!(name.as_str(), name0);
1945                     let chan = chan.read();
1946                     if self
1947                         .channel_has_state(&chan.states, &p.b)
1948                         .map_err(|e| e.0)?
1949                         .is_some()
1950                     {
1951                         break 'outer;
1952                     }
1953                     if self
1954                         .get_changeset(&chan.changes, &p.a)
1955                         .map_err(|e| e.0)?
1956                         .is_some()
1957                     {
1958                         continue 'outer;
1959                     }
1960                 }
1961                 unused_changes.push(p.a);
1962             }
1963             let mut deps = Vec::new();
1964             for ch in unused_changes.iter() {
1965                 for x in btree::iter(&self.txn, &self.dep, Some((ch, None)))? {
1966                     let (k, v) = x?;
1967                     if k > ch {
1968                         break;
1969                     }
1970                     deps.push((*k, *v));
1971                 }
1972                 for (k, v) in deps.drain(..) {
1973                     btree::del(&mut self.txn, &mut self.revdep, &k, Some(&v))?;
1974                     btree::del(&mut self.txn, &mut self.revdep, &v, Some(&k))?;
1975                 }
1976             }
1977             btree::drop(&mut self.txn, a)?;
1978             btree::drop(&mut self.txn, b)?;
1979             btree::drop(&mut self.txn, c)?;
1980             btree::drop(&mut self.txn, d)?;
1981             btree::drop(&mut self.txn, e)?;
1982             Ok(true)
1983         } else {
1984             Ok(false)
1985         }
1986     }
1987 
open_or_create_remote( &mut self, id: RemoteId, path: &str, ) -> Result<RemoteRef<Self>, Self::GraphError>1988     fn open_or_create_remote(
1989         &mut self,
1990         id: RemoteId,
1991         path: &str,
1992     ) -> Result<RemoteRef<Self>, Self::GraphError> {
1993         let mut commit = None;
1994         match self.open_remotes.lock().entry(id) {
1995             Entry::Vacant(v) => {
1996                 let r = match btree::get(&self.txn, &self.remotes, &id, None)? {
1997                     Some((name_, remote)) if *name_ == id => RemoteRef {
1998                         db: Arc::new(Mutex::new(Remote {
1999                             remote: UDb::from_page(remote.remote.into()),
2000                             rev: UDb::from_page(remote.rev.into()),
2001                             states: UDb::from_page(remote.states.into()),
2002                             id_rev: remote.id_rev.into(),
2003                             path: SmallString::from_str(path),
2004                         })),
2005                         id,
2006                     },
2007                     _ => {
2008                         let br = RemoteRef {
2009                             db: Arc::new(Mutex::new(Remote {
2010                                 remote: btree::create_db_(&mut self.txn)?,
2011                                 rev: btree::create_db_(&mut self.txn)?,
2012                                 states: btree::create_db_(&mut self.txn)?,
2013                                 id_rev: 0u64.into(),
2014                                 path: SmallString::from_str(path),
2015                             })),
2016                             id,
2017                         };
2018                         commit = Some(br.clone());
2019                         br
2020                     }
2021                 };
2022                 v.insert(r);
2023             }
2024             Entry::Occupied(_) => {}
2025         }
2026         if let Some(commit) = commit {
2027             self.put_remotes(commit)?;
2028         }
2029         Ok(self.open_remotes.lock().get(&id).unwrap().clone())
2030     }
2031 
drop_remote(&mut self, remote: RemoteRef<Self>) -> Result<bool, Self::GraphError>2032     fn drop_remote(&mut self, remote: RemoteRef<Self>) -> Result<bool, Self::GraphError> {
2033         let r = self.open_remotes.lock().remove(&remote.id).unwrap();
2034         std::mem::drop(remote);
2035         assert_eq!(Arc::strong_count(&r.db), 1);
2036         Ok(btree::del(&mut self.txn, &mut self.remotes, &r.id, None)?)
2037     }
2038 
drop_named_remote(&mut self, id: RemoteId) -> Result<bool, Self::GraphError>2039     fn drop_named_remote(&mut self, id: RemoteId) -> Result<bool, Self::GraphError> {
2040         if let Some(r) = self.open_remotes.lock().remove(&id) {
2041             assert_eq!(Arc::strong_count(&r.db), 1);
2042         }
2043         Ok(btree::del(&mut self.txn, &mut self.remotes, &id, None)?)
2044     }
2045 
commit(mut self) -> Result<(), Self::GraphError>2046     fn commit(mut self) -> Result<(), Self::GraphError> {
2047         use std::ops::DerefMut;
2048         {
2049             let open_channels =
2050                 std::mem::replace(self.open_channels.lock().deref_mut(), HashMap::default());
2051             for (name, channel) in open_channels {
2052                 debug!("commit_channel {:?}", name);
2053                 self.commit_channel(channel)?
2054             }
2055         }
2056         {
2057             let open_remotes =
2058                 std::mem::replace(self.open_remotes.lock().deref_mut(), HashMap::default());
2059             for (name, remote) in open_remotes {
2060                 debug!("commit remote {:?}", name);
2061                 self.commit_remote(remote)?
2062             }
2063         }
2064         if let Some(ref cur) = self.cur_channel {
2065             unsafe {
2066                 assert!(cur.len() < 256);
2067                 let b = self.txn.root_page_mut();
2068                 b[4096 - 256] = cur.len() as u8;
2069                 std::ptr::copy(cur.as_ptr(), b.as_mut_ptr().add(4096 - 255), cur.len())
2070             }
2071         }
2072         // No need to set `Root::Version`, it is set at init.
2073         self.txn.set_root(Root::Tree as usize, self.tree.db);
2074         self.txn.set_root(Root::RevTree as usize, self.revtree.db);
2075         self.txn.set_root(Root::Inodes as usize, self.inodes.db);
2076         self.txn
2077             .set_root(Root::RevInodes as usize, self.revinodes.db);
2078         self.txn.set_root(Root::Internal as usize, self.internal.db);
2079         self.txn.set_root(Root::External as usize, self.external.db);
2080         self.txn.set_root(Root::RevDep as usize, self.revdep.db);
2081         self.txn.set_root(Root::Channels as usize, self.channels.db);
2082         self.txn.set_root(Root::Remotes as usize, self.remotes.db);
2083         self.txn
2084             .set_root(Root::TouchedFiles as usize, self.touched_files.db);
2085         self.txn.set_root(Root::Dep as usize, self.dep.db);
2086         self.txn
2087             .set_root(Root::RevTouchedFiles as usize, self.rev_touched_files.db);
2088         self.txn.set_root(Root::Partials as usize, self.partials.db);
2089         self.txn.commit()?;
2090         Ok(())
2091     }
2092 
set_current_channel(&mut self, cur: &str) -> Result<(), Self::GraphError>2093     fn set_current_channel(&mut self, cur: &str) -> Result<(), Self::GraphError> {
2094         self.cur_channel = Some(cur.to_string());
2095         Ok(())
2096     }
2097 }
2098 
2099 impl Txn {
load_const_channel(&self, name: &str) -> Result<Option<Channel>, SanakirjaError>2100     pub fn load_const_channel(&self, name: &str) -> Result<Option<Channel>, SanakirjaError> {
2101         let name = SmallString::from_str(name);
2102         match btree::get(&self.txn, &self.channels, &name, None)? {
2103             Some((name_, c)) if name.as_ref() == name_ => {
2104                 debug!("load_const_channel = {:?} {:?}", name_, c);
2105                 Ok(Some(Channel {
2106                     graph: Db::from_page(c.graph.into()),
2107                     changes: Db::from_page(c.changes.into()),
2108                     revchanges: UDb::from_page(c.revchanges.into()),
2109                     states: UDb::from_page(c.states.into()),
2110                     tags: UDb::from_page(c.tags.into()),
2111                     apply_counter: c.apply_counter.into(),
2112                     last_modified: c.last_modified.into(),
2113                     id: c.id,
2114                     name,
2115                 }))
2116             }
2117             _ => Ok(None),
2118         }
2119     }
2120 }
2121 
2122 impl<T> MutTxn<T> {
put_channel(&mut self, channel: ChannelRef<Self>) -> Result<(), SanakirjaError>2123     fn put_channel(&mut self, channel: ChannelRef<Self>) -> Result<(), SanakirjaError> {
2124         debug!("Commit_channel.");
2125         let channel = channel.r.read();
2126         // Since we are replacing the value, we don't want to
2127         // decrement its reference counter (which del would do), hence
2128         // the transmute.
2129         //
2130         // This would normally be wrong. The only reason it works is
2131         // because we know that dbs_channels has never been forked
2132         // from another database, hence all the reference counts to
2133         // its elements are 1 (and therefore represented as "not
2134         // referenced" in Sanakirja).
2135         debug!("Commit_channel, dbs_channels = {:?}", self.channels);
2136         btree::del(&mut self.txn, &mut self.channels, &channel.name, None)?;
2137         let sc = SerializedChannel {
2138             graph: channel.graph.db.into(),
2139             changes: channel.changes.db.into(),
2140             revchanges: channel.revchanges.db.into(),
2141             states: channel.states.db.into(),
2142             tags: channel.tags.db.into(),
2143             apply_counter: channel.apply_counter.into(),
2144             last_modified: channel.last_modified.into(),
2145             id: channel.id,
2146         };
2147         btree::put(&mut self.txn, &mut self.channels, &channel.name, &sc)?;
2148         debug!("Commit_channel, self.channels = {:?}", self.channels);
2149         Ok(())
2150     }
2151 
commit_channel(&mut self, channel: ChannelRef<Self>) -> Result<(), SanakirjaError>2152     fn commit_channel(&mut self, channel: ChannelRef<Self>) -> Result<(), SanakirjaError> {
2153         std::mem::drop(self.open_channels.lock().remove(&channel.r.read().name));
2154         self.put_channel(channel)
2155     }
2156 
put_remotes(&mut self, remote: RemoteRef<Self>) -> Result<(), SanakirjaError>2157     fn put_remotes(&mut self, remote: RemoteRef<Self>) -> Result<(), SanakirjaError> {
2158         btree::del(&mut self.txn, &mut self.remotes, &remote.id, None)?;
2159         debug!("Commit_remote, dbs_remotes = {:?}", self.remotes);
2160         let r = remote.db.lock();
2161         let rr = OwnedSerializedRemote {
2162             _remote: r.remote.db.into(),
2163             _rev: r.rev.db.into(),
2164             _states: r.states.db.into(),
2165             _id_rev: r.id_rev.into(),
2166             _path: r.path.clone(),
2167         };
2168         debug!("put {:?}", rr);
2169         btree::put(&mut self.txn, &mut self.remotes, &remote.id, &rr)?;
2170         debug!("Commit_remote, self.dbs.remotes = {:?}", self.remotes);
2171         Ok(())
2172     }
2173 
commit_remote(&mut self, remote: RemoteRef<Self>) -> Result<(), SanakirjaError>2174     fn commit_remote(&mut self, remote: RemoteRef<Self>) -> Result<(), SanakirjaError> {
2175         std::mem::drop(self.open_remotes.lock().remove(&remote.id));
2176         // assert_eq!(Rc::strong_count(&remote.db), 1);
2177         self.put_remotes(remote)
2178     }
2179 }
2180 
2181 direct_repr!(L64);
2182 
2183 direct_repr!(ChangeId);
2184 
2185 direct_repr!(Vertex<ChangeId>);
2186 direct_repr!(Position<ChangeId>);
2187 
2188 direct_repr!(SerializedEdge);
2189 
2190 impl Storable for PathId {
compare<T>(&self, _: &T, x: &Self) -> std::cmp::Ordering2191     fn compare<T>(&self, _: &T, x: &Self) -> std::cmp::Ordering {
2192         self.cmp(x)
2193     }
2194     type PageReferences = std::iter::Empty<u64>;
page_references(&self) -> Self::PageReferences2195     fn page_references(&self) -> Self::PageReferences {
2196         std::iter::empty()
2197     }
2198 }
2199 impl UnsizedStorable for PathId {
2200     const ALIGN: usize = 8;
size(&self) -> usize2201     fn size(&self) -> usize {
2202         9 + self.basename.len()
2203     }
onpage_size(p: *const u8) -> usize2204     unsafe fn onpage_size(p: *const u8) -> usize {
2205         let len = *(p.add(8)) as usize;
2206         9 + len
2207     }
from_raw_ptr<'a, T>(_: &T, p: *const u8) -> &'a Self2208     unsafe fn from_raw_ptr<'a, T>(_: &T, p: *const u8) -> &'a Self {
2209         path_id_from_raw_ptr(p)
2210     }
write_to_page(&self, p: *mut u8)2211     unsafe fn write_to_page(&self, p: *mut u8) {
2212         *(p as *mut u64) = (self.parent_inode.0).0;
2213         self.basename.write_to_page(p.add(8))
2214     }
2215 }
2216 
path_id_from_raw_ptr<'a>(p: *const u8) -> &'a PathId2217 unsafe fn path_id_from_raw_ptr<'a>(p: *const u8) -> &'a PathId {
2218     let len = *(p.add(8)) as usize;
2219     std::mem::transmute(std::slice::from_raw_parts(p, 1 + len as usize))
2220 }
2221 
2222 #[test]
pathid_repr()2223 fn pathid_repr() {
2224     let o = OwnedPathId {
2225         parent_inode: Inode::ROOT,
2226         basename: SmallString::from_str("blablabla"),
2227     };
2228     let mut x = vec![0u8; 200];
2229 
2230     unsafe {
2231         o.write_to_page(x.as_mut_ptr());
2232         let p = path_id_from_raw_ptr(x.as_ptr());
2233         assert_eq!(p.basename.as_str(), "blablabla");
2234         assert_eq!(p.parent_inode, Inode::ROOT);
2235     }
2236 }
2237 
2238 direct_repr!(Inode);
2239 direct_repr!(SerializedMerkle);
2240 direct_repr!(SerializedHash);
2241 
2242 impl<A: Storable, B: Storable> Storable for Pair<A, B> {
2243     type PageReferences = core::iter::Chain<A::PageReferences, B::PageReferences>;
page_references(&self) -> Self::PageReferences2244     fn page_references(&self) -> Self::PageReferences {
2245         self.a.page_references().chain(self.b.page_references())
2246     }
compare<T: LoadPage>(&self, t: &T, b: &Self) -> core::cmp::Ordering2247     fn compare<T: LoadPage>(&self, t: &T, b: &Self) -> core::cmp::Ordering {
2248         match self.a.compare(t, &b.a) {
2249             core::cmp::Ordering::Equal => self.b.compare(t, &b.b),
2250             ord => ord,
2251         }
2252     }
2253 }
2254 
2255 impl<A: Ord + UnsizedStorable, B: Ord + UnsizedStorable> UnsizedStorable for Pair<A, B> {
2256     const ALIGN: usize = std::mem::align_of::<(A, B)>();
2257 
size(&self) -> usize2258     fn size(&self) -> usize {
2259         let a = self.a.size();
2260         let b_off = (a + (B::ALIGN - 1)) & !(B::ALIGN - 1);
2261         (b_off + self.b.size() + (Self::ALIGN - 1)) & !(Self::ALIGN - 1)
2262     }
onpage_size(p: *const u8) -> usize2263     unsafe fn onpage_size(p: *const u8) -> usize {
2264         let a = A::onpage_size(p);
2265         let b_off = (a + (B::ALIGN - 1)) & !(B::ALIGN - 1);
2266         let b_size = B::onpage_size(p.add(b_off));
2267         (b_off + b_size + (Self::ALIGN - 1)) & !(Self::ALIGN - 1)
2268     }
from_raw_ptr<'a, T>(_: &T, p: *const u8) -> &'a Self2269     unsafe fn from_raw_ptr<'a, T>(_: &T, p: *const u8) -> &'a Self {
2270         &*(p as *const Self)
2271     }
write_to_page(&self, p: *mut u8)2272     unsafe fn write_to_page(&self, p: *mut u8) {
2273         self.a.write_to_page(p);
2274         let off = (self.a.size() + (B::ALIGN - 1)) & !(B::ALIGN - 1);
2275         self.b.write_to_page(p.add(off));
2276     }
2277 }
2278 
2279 impl Storable for SerializedRemote {
2280     type PageReferences = std::iter::Empty<u64>;
page_references(&self) -> Self::PageReferences2281     fn page_references(&self) -> Self::PageReferences {
2282         std::iter::empty()
2283     }
compare<T: LoadPage>(&self, _t: &T, b: &Self) -> core::cmp::Ordering2284     fn compare<T: LoadPage>(&self, _t: &T, b: &Self) -> core::cmp::Ordering {
2285         self.cmp(b)
2286     }
2287 }
2288 
2289 impl UnsizedStorable for SerializedRemote {
2290     const ALIGN: usize = 8;
2291 
size(&self) -> usize2292     fn size(&self) -> usize {
2293         33 + self.path.len()
2294     }
onpage_size(p: *const u8) -> usize2295     unsafe fn onpage_size(p: *const u8) -> usize {
2296         33 + (*p.add(32)) as usize
2297     }
from_raw_ptr<'a, T>(_: &T, p: *const u8) -> &'a Self2298     unsafe fn from_raw_ptr<'a, T>(_: &T, p: *const u8) -> &'a Self {
2299         let len = *p.add(32) as usize;
2300         let m: &SerializedRemote =
2301             std::mem::transmute(std::slice::from_raw_parts(p, 1 + len as usize));
2302         m
2303     }
write_to_page(&self, p: *mut u8)2304     unsafe fn write_to_page(&self, p: *mut u8) {
2305         std::ptr::copy(
2306             &self.remote as *const L64 as *const u8,
2307             p,
2308             33 + self.path.len(),
2309         );
2310         debug!(
2311             "write_to_page: {:?}",
2312             std::slice::from_raw_parts(p, 33 + self.path.len())
2313         );
2314     }
2315 }
2316 
2317 #[derive(Debug)]
2318 struct OwnedSerializedRemote {
2319     _remote: L64,
2320     _rev: L64,
2321     _states: L64,
2322     _id_rev: L64,
2323     _path: SmallString,
2324 }
2325 
2326 impl std::ops::Deref for OwnedSerializedRemote {
2327     type Target = SerializedRemote;
deref(&self) -> &Self::Target2328     fn deref(&self) -> &Self::Target {
2329         let len = 33 + self._path.len() as usize;
2330         unsafe {
2331             std::mem::transmute(std::slice::from_raw_parts(
2332                 self as *const Self as *const u8,
2333                 len,
2334             ))
2335         }
2336     }
2337 }
2338 
2339 direct_repr!(SerializedChannel);
2340 direct_repr!(RemoteId);
2341