Skip to content

Commit

Permalink
Merge branch 'add-topo-walk'
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Apr 7, 2024
2 parents 45edd2e + 1cfeb11 commit b590a9d
Show file tree
Hide file tree
Showing 36 changed files with 1,643 additions and 653 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use clap::Parser;
use gix::{
bstr::{BString, ByteSlice},
date::time::format,
traverse::commit::Sorting,
traverse::commit::simple::Sorting,
};

fn main() {
Expand Down
2 changes: 1 addition & 1 deletion gitoxide-core/src/hours/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ where
}
commit_idx += 1;
}
Err(gix::traverse::commit::ancestors::Error::Find { .. }) => {
Err(gix::traverse::commit::simple::Error::Find { .. }) => {
is_shallow = true;
break;
}
Expand Down
4 changes: 2 additions & 2 deletions gitoxide-core/src/pack/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ where
.collect::<Result<Vec<_>, _>>()?;
let handle = repo.objects.into_shared_arc().to_cache_arc();
let iter = Box::new(
traverse::commit::Ancestors::new(tips, traverse::commit::ancestors::State::default(), handle.clone())
traverse::commit::Simple::new(tips, handle.clone())
.map(|res| res.map_err(|err| Box::new(err) as Box<_>).map(|c| c.id))
.inspect(move |_| progress.inc()),
);
Expand Down Expand Up @@ -361,7 +361,7 @@ pub mod input_iteration {
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("input objects couldn't be iterated completely")]
Iteration(#[from] traverse::commit::ancestors::Error),
Iteration(#[from] traverse::commit::simple::Error),
#[error("An error occurred while reading hashes from standard input")]
InputLinesIo(#[from] std::io::Error),
#[error("Could not decode hex hash provided on standard input")]
Expand Down
2 changes: 1 addition & 1 deletion gitoxide-core/src/query/engine/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ pub fn update(
break;
}
}
Err(gix::traverse::commit::ancestors::Error::Find { .. }) => {
Err(gix::traverse::commit::simple::Error::Find { .. }) => {
writeln!(err, "shallow repository - commit history is truncated").ok();
break;
}
Expand Down
2 changes: 1 addition & 1 deletion gitoxide-core/src/repository/commitgraph/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pub(crate) mod function {
use std::{borrow::Cow, ffi::OsString};

use anyhow::{bail, Context};
use gix::{prelude::ObjectIdExt, traverse::commit::Sorting};
use gix::{prelude::ObjectIdExt, traverse::commit::simple::Sorting};

use crate::OutputFormat;

Expand Down
2 changes: 1 addition & 1 deletion gitoxide-core/src/repository/revision/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 0..=2;

pub(crate) mod function {
use anyhow::{bail, Context};
use gix::{hashtable::HashMap, traverse::commit::Sorting, Progress};
use gix::{hashtable::HashMap, traverse::commit::simple::Sorting, Progress};
use layout::{
backends::svg::SVGWriter,
core::{base::Orientation, geometry::Point, style::StyleAttr},
Expand Down
2 changes: 1 addition & 1 deletion gix-config/src/file/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl<'a> TryFrom<&'a BStr> for File<'a> {

impl From<File<'_>> for BString {
fn from(c: File<'_>) -> Self {
c.into()
c.to_bstring()
}
}

Expand Down
2 changes: 1 addition & 1 deletion gix-config/src/parse/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl Display for Comment<'_> {

impl From<Comment<'_>> for BString {
fn from(c: Comment<'_>) -> Self {
c.into()
c.to_bstring()
}
}

Expand Down
2 changes: 1 addition & 1 deletion gix-config/src/parse/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl Display for Event<'_> {

impl From<Event<'_>> for BString {
fn from(event: Event<'_>) -> Self {
event.into()
event.to_bstring()
}
}

Expand Down
2 changes: 1 addition & 1 deletion gix-config/src/parse/section/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ impl Display for Header<'_> {

impl From<Header<'_>> for BString {
fn from(header: Header<'_>) -> Self {
header.into()
header.to_bstring()
}
}

Expand Down
3 changes: 1 addition & 2 deletions gix-diff/tests/tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,10 @@ mod changes {
}

fn all_commits(db: &gix_odb::Handle) -> HashMap<String, ObjectId> {
use gix_traverse::commit;
let mut buf = Vec::new();

let head = head_of(db);
commit::Ancestors::new(Some(head), commit::ancestors::State::default(), &db)
gix_traverse::commit::Simple::new(Some(head), &db)
.collect::<Result<Vec<_>, _>>()
.expect("valid iteration")
.into_iter()
Expand Down
14 changes: 8 additions & 6 deletions gix-pack/src/cache/delta/from_offsets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,14 @@ impl<T> Tree<T> {
})?,
);

let anticipated_num_objects = if let Some(num_objects) = data_sorted_by_offsets.size_hint().1 {
progress.init(Some(num_objects), progress::count("objects"));
num_objects
} else {
0
};
let anticipated_num_objects = data_sorted_by_offsets
.size_hint()
.1
.map(|num_objects| {
progress.init(Some(num_objects), progress::count("objects"));
num_objects
})
.unwrap_or_default();
let mut tree = Tree::with_capacity(anticipated_num_objects)?;

{
Expand Down
3 changes: 1 addition & 2 deletions gix-pack/tests/pack/data/output/count_and_entries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use gix_pack::data::{
output,
output::{count, entry},
};
use gix_traverse::commit;

use crate::pack::{
data::output::{db, DbKind},
Expand Down Expand Up @@ -241,7 +240,7 @@ fn traversals() -> crate::Result {
.copied()
{
let head = hex_to_id("dfcb5e39ac6eb30179808bbab721e8a28ce1b52e");
let mut commits = commit::Ancestors::new(Some(head), commit::ancestors::State::default(), db.clone())
let mut commits = gix_traverse::commit::Simple::new(Some(head), db.clone())
.map(Result::unwrap)
.map(|c| c.id)
.collect::<Vec<_>>();
Expand Down
1 change: 1 addition & 0 deletions gix-traverse/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ gix-revwalk = { version = "^0.13.0", path = "../gix-revwalk" }
gix-commitgraph = { version = "^0.24.2", path = "../gix-commitgraph" }
smallvec = "1.10.0"
thiserror = "1.0.32"
bitflags = "2"
88 changes: 88 additions & 0 deletions gix-traverse/src/commit/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//! Provide multiple traversal implementations with different performance envelopes.
//!
//! Use [`Simple`] for fast walks that maintain minimal state, or [`Topo`] for a more elaborate traversal.
use gix_hash::ObjectId;
use gix_object::FindExt;
use gix_revwalk::graph::IdMap;
use gix_revwalk::PriorityQueue;
use smallvec::SmallVec;

/// A fast iterator over the ancestors of one or more starting commits.
pub struct Simple<Find, Predicate> {
objects: Find,
cache: Option<gix_commitgraph::Graph>,
predicate: Predicate,
state: simple::State,
parents: Parents,
sorting: simple::Sorting,
}

/// Simple ancestors traversal, without the need to keep track of graph-state.
pub mod simple;

/// A commit walker that walks in topographical order, like `git rev-list
/// --topo-order` or `--date-order` depending on the chosen [`topo::Sorting`].
///
/// Instantiate with [`topo::Builder`].
pub struct Topo<Find, Predicate> {
commit_graph: Option<gix_commitgraph::Graph>,
find: Find,
predicate: Predicate,
indegrees: IdMap<i32>,
states: IdMap<topo::WalkFlags>,
explore_queue: PriorityQueue<topo::iter::GenAndCommitTime, ObjectId>,
indegree_queue: PriorityQueue<topo::iter::GenAndCommitTime, ObjectId>,
topo_queue: topo::iter::Queue,
parents: Parents,
min_gen: u32,
buf: Vec<u8>,
}

pub mod topo;

/// Specify how to handle commit parents during traversal.
#[derive(Default, Copy, Clone)]
pub enum Parents {
/// Traverse all parents, useful for traversing the entire ancestry.
#[default]
All,
/// Only traverse along the first parent, which commonly ignores all branches.
First,
}

/// The collection of parent ids we saw as part of the iteration.
///
/// Note that this list is truncated if [`Parents::First`] was used.
pub type ParentIds = SmallVec<[gix_hash::ObjectId; 1]>;

/// Information about a commit that we obtained naturally as part of the iteration.
#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub struct Info {
/// The id of the commit.
pub id: gix_hash::ObjectId,
/// All parent ids we have encountered. Note that these will be at most one if [`Parents::First`] is enabled.
pub parent_ids: ParentIds,
/// The time at which the commit was created. It will only be `Some(_)` if the chosen traversal was
/// taking dates into consideration.
pub commit_time: Option<gix_date::SecondsSinceUnixEpoch>,
}

enum Either<'buf, 'cache> {
CommitRefIter(gix_object::CommitRefIter<'buf>),
CachedCommit(gix_commitgraph::file::Commit<'cache>),
}

fn find<'cache, 'buf, Find>(
cache: Option<&'cache gix_commitgraph::Graph>,
objects: Find,
id: &gix_hash::oid,
buf: &'buf mut Vec<u8>,
) -> Result<Either<'buf, 'cache>, gix_object::find::existing_iter::Error>
where
Find: gix_object::Find,
{
match cache.and_then(|cache| cache.commit_by_id(id).map(Either::CachedCommit)) {
Some(c) => Ok(c),
None => objects.find_commit_iter(id, buf).map(Either::CommitRefIter),
}
}
Loading

0 comments on commit b590a9d

Please sign in to comment.