History

Move some utilities to super module to make them sharable

Makes it easier to use these types for different kinds of commit walking. No matter how the history graph is traversed some concepts remain identical.

Øystein Walle committed 3 years ago

Commit 5b3dfbb1 parent ecc049c2 files · +58 −53Browse files

Unified · Split

2 files
  1. gix-traverse/src/commit/ancestors.rs +7 −52
  2. gix-traverse/src/commit/mod.rs +51 −1
gix-traverse/src/commit/ancestors.rs+7−52
@@ -1,4 +1,3 @@
1use gix_object::FindExt;
2use smallvec::SmallVec;1use smallvec::SmallVec;
3 2
4/// An iterator over the ancestors one or more starting commits3/// An iterator over the ancestors one or more starting commits
@@ -7,20 +6,10 @@ pub struct Ancestors<Find, Predicate, StateMut> { · 2 unmodified lines
7 cache: Option<gix_commitgraph::Graph>,6 cache: Option<gix_commitgraph::Graph>,
8 predicate: Predicate,7 predicate: Predicate,
9 state: StateMut,8 state: StateMut,
10 parents: Parents,9 parents: super::Parents,
11 sorting: Sorting,10 sorting: Sorting,
12}11}
13 12
14/// Specify how to handle commit parents during traversal.
15#[derive(Default, Copy, Clone)]
16pub enum Parents {
17 /// Traverse all parents, useful for traversing the entire ancestry.
18 #[default]
19 All,
20 /// Only traverse along the first parent, which commonly ignores all branches.
21 First,
22}
23
24/// Specify how to sort commits during traversal.13/// Specify how to sort commits during traversal.
25///14///
26/// ### Sample History15/// ### Sample History
@@ -69,23 +58,6 @@ pub enum Sorting { · 42 unmodified lines
69 },58 },
70}59}
71 60
72/// The collection of parent ids we saw as part of the iteration.
73///
74/// Note that this list is truncated if [`Parents::First`] was used.
75pub type ParentIds = SmallVec<[gix_hash::ObjectId; 1]>;
76
77/// Information about a commit that we obtained naturally as part of the iteration.
78#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
79pub struct Info {
80 /// The id of the commit.
81 pub id: gix_hash::ObjectId,
82 /// All parent ids we have encountered. Note that these will be at most one if [`Parents::First`] is enabled.
83 pub parent_ids: ParentIds,
84 /// The time at which the commit was created. It's only `Some(_)` if sorting is not [`Sorting::BreadthFirst`], as the walk
85 /// needs to require the commit-date.
86 pub commit_time: Option<gix_date::SecondsSinceUnixEpoch>,
87}
88
89///61///
90#[allow(clippy::empty_docs)]62#[allow(clippy::empty_docs)]
91pub mod ancestors {63pub mod ancestors {
@@ -100,7 +72,10 @@ pub mod ancestors { · 8 unmodified lines
100 use gix_object::{CommitRefIter, FindExt};72 use gix_object::{CommitRefIter, FindExt};
101 use smallvec::SmallVec;73 use smallvec::SmallVec;
102 74
103 use super::{collect_parents, Ancestors, Either, Info, ParentIds, Parents, Sorting};75 use super::{
76 super::{Either, Info, ParentIds, Parents},
77 collect_parents, Ancestors, Sorting,
78 };
104 79
105 /// The error is part of the item returned by the [Ancestors] iterator.80 /// The error is part of the item returned by the [Ancestors] iterator.
106 #[derive(Debug, thiserror::Error)]81 #[derive(Debug, thiserror::Error)]
@@ -339,7 +314,7 @@ pub mod ancestors { · 232 unmodified lines
339 314
340 let (commit_time, oid) = state.queue.pop()?;315 let (commit_time, oid) = state.queue.pop()?;
341 let mut parents: ParentIds = Default::default();316 let mut parents: ParentIds = Default::default();
342 match super::find(self.cache.as_ref(), &self.objects, &oid, &mut state.buf) {317 match super::super::find(self.cache.as_ref(), &self.objects, &oid, &mut state.buf) {
343 Ok(Either::CachedCommit(commit)) => {318 Ok(Either::CachedCommit(commit)) => {
344 if !collect_parents(&mut state.parent_ids, self.cache.as_ref(), commit.iter_parents()) {319 if !collect_parents(&mut state.parent_ids, self.cache.as_ref(), commit.iter_parents()) {
345 // drop corrupt caches and try again with ODB320 // drop corrupt caches and try again with ODB
@@ -406,7 +381,7 @@ pub mod ancestors { · 60 unmodified lines
406 let state = self.state.borrow_mut();381 let state = self.state.borrow_mut();
407 let oid = state.next.pop_front()?;382 let oid = state.next.pop_front()?;
408 let mut parents: ParentIds = Default::default();383 let mut parents: ParentIds = Default::default();
409 match super::find(self.cache.as_ref(), &self.objects, &oid, &mut state.buf) {384 match super::super::find(self.cache.as_ref(), &self.objects, &oid, &mut state.buf) {
410 Ok(Either::CachedCommit(commit)) => {385 Ok(Either::CachedCommit(commit)) => {
411 if !collect_parents(&mut state.parent_ids, self.cache.as_ref(), commit.iter_parents()) {386 if !collect_parents(&mut state.parent_ids, self.cache.as_ref(), commit.iter_parents()) {
412 // drop corrupt caches and try again with ODB387 // drop corrupt caches and try again with ODB
@@ -457,11 +432,6 @@ pub mod ancestors { · 44 unmodified lines
457 432
458pub use ancestors::{Error, State};433pub use ancestors::{Error, State};
459 434
460enum Either<'buf, 'cache> {
461 CommitRefIter(gix_object::CommitRefIter<'buf>),
462 CachedCommit(gix_commitgraph::file::Commit<'cache>),
463}
464
465fn collect_parents(435fn collect_parents(
466 dest: &mut SmallVec<[(gix_hash::ObjectId, gix_date::SecondsSinceUnixEpoch); 2]>,436 dest: &mut SmallVec<[(gix_hash::ObjectId, gix_date::SecondsSinceUnixEpoch); 2]>,
467 cache: Option<&gix_commitgraph::Graph>,437 cache: Option<&gix_commitgraph::Graph>,
@@ -483,18 +453,3 @@ fn collect_parents( · 15 unmodified lines
483 }453 }
484 true454 true
485}455}
486
487fn find<'cache, 'buf, Find>(
488 cache: Option<&'cache gix_commitgraph::Graph>,
489 objects: Find,
490 id: &gix_hash::oid,
491 buf: &'buf mut Vec<u8>,
492) -> Result<Either<'buf, 'cache>, gix_object::find::existing_iter::Error>
493where
494 Find: gix_object::Find,
495{
496 match cache.and_then(|cache| cache.commit_by_id(id).map(Either::CachedCommit)) {
497 Some(c) => Ok(c),
498 None => objects.find_commit_iter(id, buf).map(Either::CommitRefIter),
499 }
500}
gix-traverse/src/commit/mod.rs+51−1
@@ -1,3 +1,53 @@
1use gix_object::FindExt;
2use smallvec::SmallVec;
3
1/// Simple ancestors traversal4/// Simple ancestors traversal
2pub mod ancestors;5pub mod ancestors;
3pub use ancestors::{Ancestors, Info, ParentIds, Parents, Sorting};6pub use ancestors::{Ancestors, Sorting};
7
8/// Specify how to handle commit parents during traversal.
9#[derive(Default, Copy, Clone)]
10pub enum Parents {
11 /// Traverse all parents, useful for traversing the entire ancestry.
12 #[default]
13 All,
14 /// Only traverse along the first parent, which commonly ignores all branches.
15 First,
16}
17
18/// The collection of parent ids we saw as part of the iteration.
19///
20/// Note that this list is truncated if [`Parents::First`] was used.
21pub type ParentIds = SmallVec<[gix_hash::ObjectId; 1]>;
22
23/// Information about a commit that we obtained naturally as part of the iteration.
24#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
25pub struct Info {
26 /// The id of the commit.
27 pub id: gix_hash::ObjectId,
28 /// All parent ids we have encountered. Note that these will be at most one if [`Parents::First`] is enabled.
29 pub parent_ids: ParentIds,
30 /// The time at which the commit was created. It's only `Some(_)` if sorting is not [`Sorting::BreadthFirst`], as the walk
31 /// needs to require the commit-date.
32 pub commit_time: Option<gix_date::SecondsSinceUnixEpoch>,
33}
34
35enum Either<'buf, 'cache> {
36 CommitRefIter(gix_object::CommitRefIter<'buf>),
37 CachedCommit(gix_commitgraph::file::Commit<'cache>),
38}
39
40fn find<'cache, 'buf, Find>(
41 cache: Option<&'cache gix_commitgraph::Graph>,
42 objects: Find,
43 id: &gix_hash::oid,
44 buf: &'buf mut Vec<u8>,
45) -> Result<Either<'buf, 'cache>, gix_object::find::existing_iter::Error>
46where
47 Find: gix_object::Find,
48{
49 match cache.and_then(|cache| cache.commit_by_id(id).map(Either::CachedCommit)) {
50 Some(c) => Ok(c),
51 None => objects.find_commit_iter(id, buf).map(Either::CommitRefIter),
52 }
53}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t