Skip to content

Commit 2a9c178

Browse files
committed
fix!: Make topo more similar to Ancestors, but also rename Ancestors to Simple
1 parent 3f938fa commit 2a9c178

File tree

16 files changed

+130
-130
lines changed

16 files changed

+130
-130
lines changed

gitoxide-core/src/hours/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ where
175175
}
176176
commit_idx += 1;
177177
}
178-
Err(gix::traverse::commit::ancestors::Error::Find { .. }) => {
178+
Err(gix::traverse::commit::simple::Error::Find { .. }) => {
179179
is_shallow = true;
180180
break;
181181
}

gitoxide-core/src/pack/create.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ where
130130
.collect::<Result<Vec<_>, _>>()?;
131131
let handle = repo.objects.into_shared_arc().to_cache_arc();
132132
let iter = Box::new(
133-
traverse::commit::Ancestors::new(tips, handle.clone())
133+
traverse::commit::Simple::new(tips, handle.clone())
134134
.map(|res| res.map_err(|err| Box::new(err) as Box<_>).map(|c| c.id))
135135
.inspect(move |_| progress.inc()),
136136
);
@@ -361,7 +361,7 @@ pub mod input_iteration {
361361
#[derive(Debug, thiserror::Error)]
362362
pub enum Error {
363363
#[error("input objects couldn't be iterated completely")]
364-
Iteration(#[from] traverse::commit::ancestors::Error),
364+
Iteration(#[from] traverse::commit::simple::Error),
365365
#[error("An error occurred while reading hashes from standard input")]
366366
InputLinesIo(#[from] std::io::Error),
367367
#[error("Could not decode hex hash provided on standard input")]

gitoxide-core/src/query/engine/update.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ pub fn update(
429429
break;
430430
}
431431
}
432-
Err(gix::traverse::commit::ancestors::Error::Find { .. }) => {
432+
Err(gix::traverse::commit::simple::Error::Find { .. }) => {
433433
writeln!(err, "shallow repository - commit history is truncated").ok();
434434
break;
435435
}

gix-diff/tests/tree/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ mod changes {
133133
let mut buf = Vec::new();
134134

135135
let head = head_of(db);
136-
commit::Ancestors::new(Some(head), &db)
136+
commit::Simple::new(Some(head), &db)
137137
.collect::<Result<Vec<_>, _>>()
138138
.expect("valid iteration")
139139
.into_iter()

gix-pack/tests/pack/data/output/count_and_entries.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ fn traversals() -> crate::Result {
241241
.copied()
242242
{
243243
let head = hex_to_id("dfcb5e39ac6eb30179808bbab721e8a28ce1b52e");
244-
let mut commits = commit::Ancestors::new(Some(head), db.clone())
244+
let mut commits = commit::Simple::new(Some(head), db.clone())
245245
.map(Result::unwrap)
246246
.map(|c| c.id)
247247
.collect::<Vec<_>>();

gix-traverse/src/commit/mod.rs

+29-53
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,43 @@
1+
//! Provide multiple traversal implementations with different performance envelopes.
2+
//!
3+
//! Use [`Simple`] for fast walks that maintain minimal state, or [`Topo`] for a more elaborate traversal.
4+
use gix_hash::ObjectId;
15
use gix_object::FindExt;
6+
use gix_revwalk::graph::IdMap;
7+
use gix_revwalk::PriorityQueue;
28
use smallvec::SmallVec;
39

410
/// A fast iterator over the ancestors of one or more starting commits.
5-
pub struct Ancestors<Find, Predicate> {
11+
pub struct Simple<Find, Predicate> {
612
objects: Find,
713
cache: Option<gix_commitgraph::Graph>,
814
predicate: Predicate,
9-
state: ancestors::State,
15+
state: simple::State,
1016
parents: Parents,
11-
sorting: Sorting,
17+
sorting: simple::Sorting,
1218
}
1319

14-
/// Specify how to sort commits during the [ancestor](Ancestors) traversal.
15-
///
16-
/// ### Sample History
17-
///
18-
/// The following history will be referred to for explaining how the sort order works, with the number denoting the commit timestamp
19-
/// (*their X-alignment doesn't matter*).
20+
/// Simple ancestors traversal, without the need to keep track of graph-state.
21+
pub mod simple;
22+
23+
/// A commit walker that walks in topographical order, like `git rev-list
24+
/// --topo-order` or `--date-order` depending on the chosen [`topo::Sorting`].
2025
///
21-
/// ```text
22-
/// ---1----2----4----7 <- second parent of 8
23-
/// \ \
24-
/// 3----5----6----8---
25-
/// ```
26-
#[derive(Default, Debug, Copy, Clone)]
27-
pub enum Sorting {
28-
/// Commits are sorted as they are mentioned in the commit graph.
29-
///
30-
/// In the *sample history* the order would be `8, 6, 7, 5, 4, 3, 2, 1`
31-
///
32-
/// ### Note
33-
///
34-
/// This is not to be confused with `git log/rev-list --topo-order`, which is notably different from
35-
/// as it avoids overlapping branches.
36-
#[default]
37-
BreadthFirst,
38-
/// Commits are sorted by their commit time in descending order, that is newest first.
39-
///
40-
/// The sorting applies to all currently queued commit ids and thus is full.
41-
///
42-
/// In the *sample history* the order would be `8, 7, 6, 5, 4, 3, 2, 1`
43-
///
44-
/// # Performance
45-
///
46-
/// This mode benefits greatly from having an object_cache in `find()`
47-
/// to avoid having to lookup each commit twice.
48-
ByCommitTimeNewestFirst,
49-
/// This sorting is similar to `ByCommitTimeNewestFirst`, but adds a cutoff to not return commits older than
50-
/// a given time, stopping the iteration once no younger commits is queued to be traversed.
51-
///
52-
/// As the query is usually repeated with different cutoff dates, this search mode benefits greatly from an object cache.
53-
///
54-
/// In the *sample history* and a cut-off date of 4, the returned list of commits would be `8, 7, 6, 4`
55-
ByCommitTimeNewestFirstCutoffOlderThan {
56-
/// The amount of seconds since unix epoch, the same value obtained by any `gix_date::Time` structure and the way git counts time.
57-
seconds: gix_date::SecondsSinceUnixEpoch,
58-
},
26+
/// Instantiate with [`topo::Builder`].
27+
pub struct Topo<Find, Predicate> {
28+
commit_graph: Option<gix_commitgraph::Graph>,
29+
find: Find,
30+
predicate: Predicate,
31+
indegrees: IdMap<i32>,
32+
states: IdMap<topo::WalkFlags>,
33+
explore_queue: PriorityQueue<topo::iter::GenAndCommitTime, ObjectId>,
34+
indegree_queue: PriorityQueue<topo::iter::GenAndCommitTime, ObjectId>,
35+
topo_queue: topo::iter::Queue,
36+
parents: Parents,
37+
min_gen: u32,
38+
buf: Vec<u8>,
5939
}
6040

61-
/// Simple ancestors traversal
62-
pub mod ancestors;
63-
64-
// Topological traversal
6541
pub mod topo;
6642

6743
/// Specify how to handle commit parents during traversal.
@@ -86,8 +62,8 @@ pub struct Info {
8662
pub id: gix_hash::ObjectId,
8763
/// All parent ids we have encountered. Note that these will be at most one if [`Parents::First`] is enabled.
8864
pub parent_ids: ParentIds,
89-
/// The time at which the commit was created. It's only `Some(_)` if sorting is not [`Sorting::BreadthFirst`], as the walk
90-
/// needs to require the commit-date.
65+
/// The time at which the commit was created. It will only be `Some(_)` if the chosen traversal was
66+
/// taking dates into consideration.
9167
pub commit_time: Option<gix_date::SecondsSinceUnixEpoch>,
9268
}
9369

gix-traverse/src/commit/ancestors.rs gix-traverse/src/commit/simple.rs

+56-9
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,54 @@ use gix_hashtable::HashSet;
44
use smallvec::SmallVec;
55
use std::collections::VecDeque;
66

7-
/// The error is part of the item returned by the [Ancestors](super::Ancestors) iterator.
7+
/// Specify how to sort commits during a [simple](super::Simple) traversal.
8+
///
9+
/// ### Sample History
10+
///
11+
/// The following history will be referred to for explaining how the sort order works, with the number denoting the commit timestamp
12+
/// (*their X-alignment doesn't matter*).
13+
///
14+
/// ```text
15+
/// ---1----2----4----7 <- second parent of 8
16+
/// \ \
17+
/// 3----5----6----8---
18+
/// ```
19+
#[derive(Default, Debug, Copy, Clone)]
20+
pub enum Sorting {
21+
/// Commits are sorted as they are mentioned in the commit graph.
22+
///
23+
/// In the *sample history* the order would be `8, 6, 7, 5, 4, 3, 2, 1`
24+
///
25+
/// ### Note
26+
///
27+
/// This is not to be confused with `git log/rev-list --topo-order`, which is notably different from
28+
/// as it avoids overlapping branches.
29+
#[default]
30+
BreadthFirst,
31+
/// Commits are sorted by their commit time in descending order, that is newest first.
32+
///
33+
/// The sorting applies to all currently queued commit ids and thus is full.
34+
///
35+
/// In the *sample history* the order would be `8, 7, 6, 5, 4, 3, 2, 1`
36+
///
37+
/// # Performance
38+
///
39+
/// This mode benefits greatly from having an object_cache in `find()`
40+
/// to avoid having to lookup each commit twice.
41+
ByCommitTimeNewestFirst,
42+
/// This sorting is similar to `ByCommitTimeNewestFirst`, but adds a cutoff to not return commits older than
43+
/// a given time, stopping the iteration once no younger commits is queued to be traversed.
44+
///
45+
/// As the query is usually repeated with different cutoff dates, this search mode benefits greatly from an object cache.
46+
///
47+
/// In the *sample history* and a cut-off date of 4, the returned list of commits would be `8, 7, 6, 4`
48+
ByCommitTimeNewestFirstCutoffOlderThan {
49+
/// The amount of seconds since unix epoch, the same value obtained by any `gix_date::Time` structure and the way git counts time.
50+
seconds: gix_date::SecondsSinceUnixEpoch,
51+
},
52+
}
53+
54+
/// The error is part of the item returned by the [Ancestors](super::Simple) iterator.
855
#[derive(Debug, thiserror::Error)]
956
#[allow(missing_docs)]
1057
pub enum Error {
@@ -33,7 +80,7 @@ mod init {
3380
use gix_object::{CommitRefIter, FindExt};
3481

3582
use super::{
36-
super::{Ancestors, Either, Info, ParentIds, Parents, Sorting},
83+
super::{simple::Sorting, Either, Info, ParentIds, Parents, Simple},
3784
collect_parents, Error, State,
3885
};
3986

@@ -60,7 +107,7 @@ mod init {
60107
}
61108

62109
/// Builder
63-
impl<Find, Predicate> Ancestors<Find, Predicate>
110+
impl<Find, Predicate> Simple<Find, Predicate>
64111
where
65112
Find: gix_object::Find,
66113
{
@@ -121,7 +168,7 @@ mod init {
121168
}
122169

123170
/// Lifecyle
124-
impl<Find> Ancestors<Find, fn(&oid) -> bool>
171+
impl<Find> Simple<Find, fn(&oid) -> bool>
125172
where
126173
Find: gix_object::Find,
127174
{
@@ -139,7 +186,7 @@ mod init {
139186
}
140187

141188
/// Lifecyle
142-
impl<Find, Predicate> Ancestors<Find, Predicate>
189+
impl<Find, Predicate> Simple<Find, Predicate>
143190
where
144191
Find: gix_object::Find,
145192
Predicate: FnMut(&oid) -> bool,
@@ -183,7 +230,7 @@ mod init {
183230
}
184231

185232
/// Access
186-
impl<Find, Predicate> Ancestors<Find, Predicate> {
233+
impl<Find, Predicate> Simple<Find, Predicate> {
187234
/// Return an iterator for accessing data of the current commit, parsed lazily.
188235
pub fn commit_iter(&self) -> CommitRefIter<'_> {
189236
CommitRefIter::from_bytes(&self.state.buf)
@@ -195,7 +242,7 @@ mod init {
195242
}
196243
}
197244

198-
impl<Find, Predicate> Iterator for Ancestors<Find, Predicate>
245+
impl<Find, Predicate> Iterator for Simple<Find, Predicate>
199246
where
200247
Find: gix_object::Find,
201248
Predicate: FnMut(&oid) -> bool,
@@ -228,7 +275,7 @@ mod init {
228275
}
229276

230277
/// Utilities
231-
impl<Find, Predicate> Ancestors<Find, Predicate>
278+
impl<Find, Predicate> Simple<Find, Predicate>
232279
where
233280
Find: gix_object::Find,
234281
Predicate: FnMut(&oid) -> bool,
@@ -298,7 +345,7 @@ mod init {
298345
}
299346

300347
/// Utilities
301-
impl<Find, Predicate> Ancestors<Find, Predicate>
348+
impl<Find, Predicate> Simple<Find, Predicate>
302349
where
303350
Find: gix_object::Find,
304351
Predicate: FnMut(&oid) -> bool,

gix-traverse/src/commit/topo/init.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use crate::commit::topo::iter::gen_and_commit_time;
2-
use crate::commit::topo::{Error, Sorting, Walk, WalkFlags};
3-
use crate::commit::{find, Info, Parents};
2+
use crate::commit::topo::{Error, Sorting, WalkFlags};
3+
use crate::commit::{find, Info, Parents, Topo};
44
use gix_hash::{oid, ObjectId};
55
use gix_revwalk::graph::IdMap;
66
use gix_revwalk::PriorityQueue;
77

8-
/// Builder for [`Walk`].
8+
/// Builder for [`Topo`].
99
pub struct Builder<Find, Predicate> {
1010
commit_graph: Option<gix_commitgraph::Graph>,
1111
find: Find,
@@ -20,7 +20,7 @@ impl<Find> Builder<Find, fn(&oid) -> bool>
2020
where
2121
Find: gix_object::Find,
2222
{
23-
/// Create a new `Builder` for a [`Walk`] that reads commits from a repository with `find`.
23+
/// Create a new `Builder` for a [`Topo`] that reads commits from a repository with `find`.
2424
/// starting at the `tips` and ending at the `ends`. Like `git rev-list
2525
/// --topo-order ^ends... tips...`.
2626
pub fn from_iters(
@@ -87,11 +87,11 @@ where
8787
self
8888
}
8989

90-
/// Build a new [`Walk`] instance.
90+
/// Build a new [`Topo`] instance.
9191
///
9292
/// Note that merely building an instance is currently expensive.
93-
pub fn build(self) -> Result<Walk<Find, Predicate>, Error> {
94-
let mut w = Walk {
93+
pub fn build(self) -> Result<Topo<Find, Predicate>, Error> {
94+
let mut w = Topo {
9595
commit_graph: self.commit_graph,
9696
find: self.find,
9797
predicate: self.predicate,

gix-traverse/src/commit/topo/iter.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
use crate::commit::topo::{Error, Sorting, Walk, WalkFlags};
2-
use crate::commit::{find, Either, Info, Parents};
1+
use crate::commit::topo::{Error, Sorting, WalkFlags};
2+
use crate::commit::{find, Either, Info, Parents, Topo};
33
use gix_hash::{oid, ObjectId};
44
use gix_revwalk::PriorityQueue;
55
use smallvec::SmallVec;
66

7-
pub(super) type GenAndCommitTime = (u32, i64);
7+
pub(in crate::commit) type GenAndCommitTime = (u32, i64);
88

99
// Git's priority queue works as a LIFO stack if no compare function is set,
1010
// which is the case for `--topo-order.` However, even in that case the initial
1111
// items of the queue are sorted according to the commit time before beginning
1212
// the walk.
1313
#[derive(Debug)]
14-
pub(super) enum Queue {
14+
pub(in crate::commit) enum Queue {
1515
Date(PriorityQueue<i64, Info>),
1616
Topo(Vec<(i64, Info)>),
1717
}
@@ -45,7 +45,7 @@ impl Queue {
4545
}
4646
}
4747

48-
impl<Find, Predicate> Walk<Find, Predicate>
48+
impl<Find, Predicate> Topo<Find, Predicate>
4949
where
5050
Find: gix_object::Find,
5151
{
@@ -214,7 +214,7 @@ where
214214
}
215215
}
216216

217-
impl<Find, Predicate> Iterator for Walk<Find, Predicate>
217+
impl<Find, Predicate> Iterator for Topo<Find, Predicate>
218218
where
219219
Find: gix_object::Find,
220220
Predicate: FnMut(&oid) -> bool,

0 commit comments

Comments
 (0)