blob: 4b9ecea20a1034b082dbee97f2156a0d27b8dadc [file] [log] [blame]
/// Information gathered during the run of [`iter_from_objects()`][super::objects()].
#[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Outcome {
/// The amount of objects provided to start the iteration.
pub input_objects: usize,
/// The amount of objects that have been expanded from the input source.
/// It's desirable to do that as expansion happens on multiple threads, allowing the amount of input objects to be small.
/// `expanded_objects - decoded_objects` is the 'cheap' object we found without decoding the object itself.
pub expanded_objects: usize,
/// The amount of fully decoded objects. These are the most expensive as they are fully decoded
pub decoded_objects: usize,
/// The total amount of encountered objects. Should be `expanded_objects + input_objects`.
pub total_objects: usize,
}
impl Outcome {
pub(in crate::data::output::count) fn aggregate(
&mut self,
Outcome {
input_objects,
decoded_objects,
expanded_objects,
total_objects,
}: Self,
) {
self.input_objects += input_objects;
self.decoded_objects += decoded_objects;
self.expanded_objects += expanded_objects;
self.total_objects += total_objects;
}
}
/// The way input objects are handled
#[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ObjectExpansion {
/// Don't do anything with the input objects except for transforming them into pack entries
#[default]
AsIs,
/// If the input object is a Commit then turn it into a pack entry. Additionally obtain its tree, turn it into a pack entry
/// along with all of its contents, that is nested trees, and any other objects reachable from it.
/// Otherwise, the same as [`AsIs`][ObjectExpansion::AsIs].
///
/// This mode is useful if all reachable objects should be added, as in cloning a repository.
TreeContents,
/// If the input is a commit, obtain its ancestors and turn them into pack entries. Obtain the ancestor trees along with the commits
/// tree and turn them into pack entries. Finally obtain the added/changed objects when comparing the ancestor trees with the
/// current tree and turn them into entries as well.
/// Otherwise, the same as [`AsIs`][ObjectExpansion::AsIs].
///
/// This mode is useful to build a pack containing only new objects compared to a previous state.
TreeAdditionsComparedToAncestor,
}
/// Configuration options for the pack generation functions provided in [this module][crate::data::output].
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Options {
/// The amount of threads to use at most when resolving the pack. If `None`, all logical cores are used.
/// If more than one thread is used, the order of returned [counts][crate::data::output::Count] is not deterministic anymore
/// especially when tree traversal is involved. Thus deterministic ordering requires `Some(1)` to be set.
pub thread_limit: Option<usize>,
/// The amount of objects per chunk or unit of work to be sent to threads for processing
pub chunk_size: usize,
/// The way input objects are handled
pub input_object_expansion: ObjectExpansion,
}
impl Default for Options {
fn default() -> Self {
Options {
thread_limit: None,
chunk_size: 10,
input_object_expansion: Default::default(),
}
}
}
/// The error returned by the pack generation iterator [`bytes::FromEntriesIter`][crate::data::output::bytes::FromEntriesIter].
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error(transparent)]
CommitDecode(gix_object::decode::Error),
#[error(transparent)]
FindExisting(#[from] crate::find::existing::Error),
#[error(transparent)]
InputIteration(Box<dyn std::error::Error + Send + Sync + 'static>),
#[error(transparent)]
TreeTraverse(gix_traverse::tree::breadthfirst::Error),
#[error(transparent)]
TreeChanges(gix_diff::tree::changes::Error),
#[error("Operation interrupted")]
Interrupted,
}