1use std::sync::Arc;
11
12use futures::StreamExt;
13use futures::TryStreamExt;
14
15use crate::clone::CloneData;
16use crate::default_impl;
17use crate::errors::NotFoundError;
18use crate::id::Group;
19use crate::id::Id;
20use crate::id::VertexName;
21pub use crate::iddag::IdDagAlgorithm;
22use crate::namedag::MemNameDag;
23use crate::nameset::id_lazy::IdLazySet;
24use crate::nameset::id_static::IdStaticSet;
25use crate::nameset::NameSet;
26use crate::IdSet;
27use crate::Result;
28use crate::VerLink;
29use crate::VertexListWithOptions;
30
31#[async_trait::async_trait]
33pub trait DagAlgorithm: Send + Sync {
34 async fn sort(&self, set: &NameSet) -> Result<NameSet>;
43
44 async fn beautify(&self, main_branch: Option<NameSet>) -> Result<MemNameDag> {
46 default_impl::beautify(self, main_branch).await
47 }
48
49 async fn subdag(&self, set: NameSet) -> Result<MemNameDag> {
51 default_impl::subdag(self, set).await
52 }
53
54 async fn parent_names(&self, name: VertexName) -> Result<Vec<VertexName>>;
56
57 async fn all(&self) -> Result<NameSet>;
59
60 async fn master_group(&self) -> Result<NameSet>;
62
63 async fn ancestors(&self, set: NameSet) -> Result<NameSet>;
65
66 async fn parents(&self, set: NameSet) -> Result<NameSet> {
71 default_impl::parents(self, set).await
72 }
73
74 async fn first_ancestor_nth(&self, name: VertexName, n: u64) -> Result<Option<VertexName>> {
76 default_impl::first_ancestor_nth(self, name, n).await
77 }
78
79 async fn first_ancestors(&self, set: NameSet) -> Result<NameSet> {
81 default_impl::first_ancestors(self, set).await
82 }
83
84 async fn heads(&self, set: NameSet) -> Result<NameSet> {
86 default_impl::heads(self, set).await
87 }
88
89 async fn children(&self, set: NameSet) -> Result<NameSet>;
91
92 async fn roots(&self, set: NameSet) -> Result<NameSet> {
94 default_impl::roots(self, set).await
95 }
96
97 async fn merges(&self, set: NameSet) -> Result<NameSet> {
99 default_impl::merges(self, set).await
100 }
101
102 async fn gca_one(&self, set: NameSet) -> Result<Option<VertexName>> {
108 default_impl::gca_one(self, set).await
109 }
110
111 async fn gca_all(&self, set: NameSet) -> Result<NameSet> {
114 default_impl::gca_all(self, set).await
115 }
116
117 async fn common_ancestors(&self, set: NameSet) -> Result<NameSet> {
119 default_impl::common_ancestors(self, set).await
120 }
121
122 async fn is_ancestor(&self, ancestor: VertexName, descendant: VertexName) -> Result<bool> {
124 default_impl::is_ancestor(self, ancestor, descendant).await
125 }
126
127 async fn heads_ancestors(&self, set: NameSet) -> Result<NameSet> {
138 default_impl::heads_ancestors(self, set).await
139 }
140
141 async fn range(&self, roots: NameSet, heads: NameSet) -> Result<NameSet>;
143
144 async fn only(&self, reachable: NameSet, unreachable: NameSet) -> Result<NameSet> {
146 default_impl::only(self, reachable, unreachable).await
147 }
148
149 async fn only_both(
154 &self,
155 reachable: NameSet,
156 unreachable: NameSet,
157 ) -> Result<(NameSet, NameSet)> {
158 default_impl::only_both(self, reachable, unreachable).await
159 }
160
161 async fn descendants(&self, set: NameSet) -> Result<NameSet>;
163
164 async fn reachable_roots(&self, roots: NameSet, heads: NameSet) -> Result<NameSet> {
191 default_impl::reachable_roots(self, roots, heads).await
192 }
193
194 async fn dirty(&self) -> Result<NameSet>;
196
197 fn is_vertex_lazy(&self) -> bool;
199
200 fn dag_snapshot(&self) -> Result<Arc<dyn DagAlgorithm + Send + Sync>>;
204
205 fn id_dag_snapshot(&self) -> Result<Arc<dyn IdDagAlgorithm + Send + Sync>> {
211 Err(crate::errors::BackendError::Generic(format!(
212 "id_dag_snapshot() is not supported for {}",
213 std::any::type_name::<Self>()
214 ))
215 .into())
216 }
217
218 fn dag_id(&self) -> &str;
220
221 fn dag_version(&self) -> &VerLink;
223}
224
225#[async_trait::async_trait]
226pub trait Parents: Send + Sync {
227 async fn parent_names(&self, name: VertexName) -> Result<Vec<VertexName>>;
228
229 async fn hint_subdag_for_insertion(&self, _heads: &[VertexName]) -> Result<MemNameDag>;
240}
241
242#[async_trait::async_trait]
243impl Parents for Arc<dyn DagAlgorithm + Send + Sync> {
244 async fn parent_names(&self, name: VertexName) -> Result<Vec<VertexName>> {
245 DagAlgorithm::parent_names(self, name).await
246 }
247
248 async fn hint_subdag_for_insertion(&self, heads: &[VertexName]) -> Result<MemNameDag> {
249 let scope = self.dirty().await?;
250 default_impl::hint_subdag_for_insertion(self, &scope, heads).await
251 }
252}
253
254#[async_trait::async_trait]
255impl Parents for &(dyn DagAlgorithm + Send + Sync) {
256 async fn parent_names(&self, name: VertexName) -> Result<Vec<VertexName>> {
257 DagAlgorithm::parent_names(*self, name).await
258 }
259
260 async fn hint_subdag_for_insertion(&self, heads: &[VertexName]) -> Result<MemNameDag> {
261 let scope = self.dirty().await?;
262 default_impl::hint_subdag_for_insertion(self, &scope, heads).await
263 }
264}
265
266#[async_trait::async_trait]
267impl<'a> Parents for Box<dyn Fn(VertexName) -> Result<Vec<VertexName>> + Send + Sync + 'a> {
268 async fn parent_names(&self, name: VertexName) -> Result<Vec<VertexName>> {
269 (self)(name)
270 }
271
272 async fn hint_subdag_for_insertion(&self, _heads: &[VertexName]) -> Result<MemNameDag> {
273 Ok(MemNameDag::new())
275 }
276}
277
278#[async_trait::async_trait]
279impl Parents for std::collections::HashMap<VertexName, Vec<VertexName>> {
280 async fn parent_names(&self, name: VertexName) -> Result<Vec<VertexName>> {
281 match self.get(&name) {
282 Some(v) => Ok(v.clone()),
283 None => name.not_found(),
284 }
285 }
286
287 async fn hint_subdag_for_insertion(&self, heads: &[VertexName]) -> Result<MemNameDag> {
288 let mut keys: Vec<VertexName> = self.keys().cloned().collect();
289 keys.sort_unstable();
290 let scope = NameSet::from_static_names(keys);
291 default_impl::hint_subdag_for_insertion(self, &scope, heads).await
292 }
293}
294
295#[async_trait::async_trait]
297pub trait DagAddHeads {
298 async fn add_heads(
301 &mut self,
302 parents: &dyn Parents,
303 heads: &VertexListWithOptions,
304 ) -> Result<bool>;
305}
306
307#[async_trait::async_trait]
309pub trait DagStrip {
310 async fn strip(&mut self, set: &NameSet) -> Result<()>;
319}
320
321#[async_trait::async_trait]
323pub trait DagImportCloneData {
324 async fn import_clone_data(&mut self, clone_data: CloneData<VertexName>) -> Result<()>;
326}
327
328#[async_trait::async_trait]
331pub trait DagImportPullData {
332 async fn import_pull_data(
336 &mut self,
337 clone_data: CloneData<VertexName>,
338 heads: &VertexListWithOptions,
339 ) -> Result<()>;
340}
341
342#[async_trait::async_trait]
343pub trait DagExportCloneData {
344 async fn export_clone_data(&self) -> Result<CloneData<VertexName>>;
346}
347
348#[async_trait::async_trait]
349pub trait DagExportPullData {
350 async fn export_pull_data(&self, set: &NameSet) -> Result<CloneData<VertexName>>;
353}
354
355#[async_trait::async_trait]
357pub trait DagPersistent {
358 async fn flush(&mut self, master_heads: &VertexListWithOptions) -> Result<()>;
361
362 async fn flush_cached_idmap(&self) -> Result<()>;
365
366 async fn add_heads_and_flush(
368 &mut self,
369 parent_names_func: &dyn Parents,
370 heads: &VertexListWithOptions,
371 ) -> Result<()>;
372
373 async fn import_and_flush(
375 &mut self,
376 dag: &dyn DagAlgorithm,
377 master_heads: NameSet,
378 ) -> Result<()> {
379 let heads = dag.heads(dag.all().await?).await?;
380 let non_master_heads = heads - master_heads.clone();
381 let master_heads: Vec<VertexName> =
382 master_heads.iter().await?.try_collect::<Vec<_>>().await?;
383 let non_master_heads: Vec<VertexName> = non_master_heads
384 .iter()
385 .await?
386 .try_collect::<Vec<_>>()
387 .await?;
388 let heads = VertexListWithOptions::from(master_heads)
389 .with_highest_group(Group::MASTER)
390 .chain(non_master_heads);
391 self.add_heads_and_flush(&dag.dag_snapshot()?, &heads).await
392 }
393}
394
395pub trait ImportAscii {
397 fn import_ascii_with_heads(
401 &mut self,
402 text: &str,
403 heads: Option<&[impl AsRef<str>]>,
404 ) -> Result<()>;
405
406 fn import_ascii(&mut self, text: &str) -> Result<()> {
408 self.import_ascii_with_heads(text, <Option<&[&str]>>::None)
409 }
410}
411
412#[async_trait::async_trait]
414pub trait PrefixLookup {
415 async fn vertexes_by_hex_prefix(
417 &self,
418 hex_prefix: &[u8],
419 limit: usize,
420 ) -> Result<Vec<VertexName>>;
421}
422
423#[async_trait::async_trait]
425pub trait IdConvert: PrefixLookup + Sync {
426 async fn vertex_id(&self, name: VertexName) -> Result<Id>;
427 async fn vertex_id_with_max_group(
428 &self,
429 name: &VertexName,
430 max_group: Group,
431 ) -> Result<Option<Id>>;
432 async fn vertex_name(&self, id: Id) -> Result<VertexName>;
433 async fn contains_vertex_name(&self, name: &VertexName) -> Result<bool>;
434
435 async fn contains_vertex_id_locally(&self, id: &[Id]) -> Result<Vec<bool>>;
437
438 async fn contains_vertex_name_locally(&self, name: &[VertexName]) -> Result<Vec<bool>>;
440
441 async fn vertex_id_optional(&self, name: &VertexName) -> Result<Option<Id>> {
442 self.vertex_id_with_max_group(name, Group::NON_MASTER).await
443 }
444
445 async fn vertex_name_batch(&self, ids: &[Id]) -> Result<Vec<Result<VertexName>>> {
447 let mut names = Vec::with_capacity(ids.len());
449 for &id in ids {
450 names.push(self.vertex_name(id).await);
451 }
452 Ok(names)
453 }
454
455 async fn vertex_id_batch(&self, names: &[VertexName]) -> Result<Vec<Result<Id>>> {
457 let mut ids = Vec::with_capacity(names.len());
459 for name in names {
460 ids.push(self.vertex_id(name.clone()).await);
461 }
462 Ok(ids)
463 }
464
465 fn map_id(&self) -> &str;
467
468 fn map_version(&self) -> &VerLink;
470}
471
472#[async_trait::async_trait]
474pub trait CheckIntegrity {
475 async fn check_universal_ids(&self) -> Result<Vec<Id>>;
484
485 async fn check_segments(&self) -> Result<Vec<String>>;
491
492 async fn check_isomorphic_graph(
502 &self,
503 other: &dyn DagAlgorithm,
504 heads: NameSet,
505 ) -> Result<Vec<String>>;
506}
507
508impl<T> ImportAscii for T
509where
510 T: DagAddHeads,
511{
512 fn import_ascii_with_heads(
513 &mut self,
514 text: &str,
515 heads: Option<&[impl AsRef<str>]>,
516 ) -> Result<()> {
517 let parents = drawdag::parse(&text);
518 let heads: Vec<_> = match heads {
519 Some(heads) => heads
520 .iter()
521 .map(|s| VertexName::copy_from(s.as_ref().as_bytes()))
522 .collect(),
523 None => {
524 let mut heads: Vec<_> = parents
525 .keys()
526 .map(|s| VertexName::copy_from(s.as_bytes()))
527 .collect();
528 heads.sort();
529 heads
530 }
531 };
532
533 let v = |s: String| VertexName::copy_from(s.as_bytes());
534 let parents: std::collections::HashMap<VertexName, Vec<VertexName>> = parents
535 .into_iter()
536 .map(|(k, vs)| (v(k), vs.into_iter().map(v).collect()))
537 .collect();
538 nonblocking::non_blocking_result(self.add_heads(&parents, &heads[..].into()))?;
539 Ok(())
540 }
541}
542
543#[async_trait::async_trait]
544pub trait ToIdSet {
545 async fn to_id_set(&self, set: &NameSet) -> Result<IdSet>;
547}
548
549pub trait ToSet {
550 fn to_set(&self, set: &IdSet) -> Result<NameSet>;
552}
553
554pub trait IdMapSnapshot {
555 fn id_map_snapshot(&self) -> Result<Arc<dyn IdConvert + Send + Sync>>;
557}
558
559pub trait Persist {
561 type Lock: Send + Sync;
563
564 fn lock(&mut self) -> Result<Self::Lock>;
567
568 fn reload(&mut self, _lock: &Self::Lock) -> Result<()>;
572
573 fn persist(&mut self, _lock: &Self::Lock) -> Result<()>;
577}
578
579pub trait Open: Clone {
583 type OpenTarget;
584
585 fn open(&self) -> Result<Self::OpenTarget>;
586}
587
588pub trait IntVersion {
592 fn int_version(&self) -> (u64, u64);
593}
594
595pub trait TryClone {
597 fn try_clone(&self) -> Result<Self>
598 where
599 Self: Sized;
600}
601
602impl<T: Clone> TryClone for T {
603 fn try_clone(&self) -> Result<Self> {
604 Ok(self.clone())
605 }
606}
607
608#[async_trait::async_trait]
609impl<T: IdConvert + IdMapSnapshot> ToIdSet for T {
610 async fn to_id_set(&self, set: &NameSet) -> Result<IdSet> {
612 let version = set.hints().id_map_version();
613
614 if let Some(set) = set.as_any().downcast_ref::<IdStaticSet>() {
616 if None < version && version <= Some(self.map_version()) {
617 return Ok(set.spans.clone());
618 }
619 }
620
621 if let Some(set) = set.as_any().downcast_ref::<IdLazySet>() {
623 if None < version && version <= Some(self.map_version()) {
624 let set: IdStaticSet = set.to_static()?;
625 return Ok(set.spans);
626 }
627 }
628
629 let mut spans = IdSet::empty();
632 let mut iter = set.iter().await?.chunks(1 << 17);
633 while let Some(names) = iter.next().await {
634 let names = names.into_iter().collect::<Result<Vec<_>>>()?;
635 let ids = self.vertex_id_batch(&names).await?;
636 for id in ids {
637 spans.push(id?);
638 }
639 }
640 Ok(spans)
641 }
642}
643
644impl IdMapSnapshot for Arc<dyn IdConvert + Send + Sync> {
645 fn id_map_snapshot(&self) -> Result<Arc<dyn IdConvert + Send + Sync>> {
646 Ok(self.clone())
647 }
648}
649
650impl<T: IdMapSnapshot + DagAlgorithm> ToSet for T {
651 fn to_set(&self, set: &IdSet) -> Result<NameSet> {
653 NameSet::from_spans_dag(set.clone(), self)
654 }
655}