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