use gix_hash::ObjectId;
use gix_object::FindExt;
use gix_revwalk::{graph::IdMap, PriorityQueue};
use smallvec::SmallVec;
pub struct Simple<Find, Predicate> {
objects: Find,
cache: Option<gix_commitgraph::Graph>,
predicate: Predicate,
state: simple::State,
parents: Parents,
sorting: simple::Sorting,
}
pub mod simple;
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;
#[derive(Default, Copy, Clone)]
pub enum Parents {
#[default]
All,
First,
}
pub type ParentIds = SmallVec<[gix_hash::ObjectId; 1]>;
#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub struct Info {
pub id: gix_hash::ObjectId,
pub parent_ids: ParentIds,
pub commit_time: Option<gix_date::SecondsSinceUnixEpoch>,
}
#[derive(Clone, Copy)]
pub enum Either<'buf, 'cache> {
CommitRefIter(gix_object::CommitRefIter<'buf>),
CachedCommit(gix_commitgraph::file::Commit<'cache>),
}
impl Either<'_, '_> {
pub fn tree_id(self) -> Result<ObjectId, gix_object::decode::Error> {
match self {
Self::CommitRefIter(mut commit_ref_iter) => commit_ref_iter.tree_id(),
Self::CachedCommit(commit) => Ok(commit.root_tree_id().into()),
}
}
pub fn commit_time(self) -> Result<gix_date::SecondsSinceUnixEpoch, gix_object::decode::Error> {
match self {
Self::CommitRefIter(commit_ref_iter) => commit_ref_iter.committer().map(|c| c.seconds()),
Self::CachedCommit(commit) => Ok(commit.committer_timestamp() as gix_date::SecondsSinceUnixEpoch),
}
}
}
pub 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),
}
}