use crate::pack::{self, index}; use git_features::{ parallel, progress::{self, Progress}, }; use git_object::owned; /// mod indexed; mod lookup; mod reduce; pub(crate) use reduce::Reducer; mod error; pub use error::Error; mod types; pub use types::{Algorithm, Options, Outcome, SafetyCheck}; /// Traversal of pack data files using an index file impl index::File { /// Iterate through all _decoded objects_ in the given `pack` and handle them with a `Processor`. /// The return value is (pack-checksum, [`Outcome`], `progress`), thus the pack traversal will always verify /// the whole packs checksum to assure it was correct. In case of bit-rod, the operation will abort early without /// verifying all objects using the [interrupt mechanism][git_features::interrupt] mechanism. /// /// # Algorithms /// /// Using the [`Options::algorithm`] field one can chose between two algorithms providing different tradeoffs. Both invoke /// `new_processor()` to create functions receiving decoded objects, their object kind, index entry and a progress instance to provide /// progress information. /// /// * [`Algorithm::DeltaTreeLookup`] builds an index to avoid any unnecessary computation while resolving objects, avoiding /// the need for a cache entirely, rendering `new_cache()` unused. /// One could also call [`traverse_with_index()`][index::File::traverse_with_index()] directly. /// * [`Algorithm::Lookup`] uses a cache created by `new_cache()` to avoid having to re-compute all bases of a delta-chain while /// decoding objects. /// One could also call [`traverse_with_lookup()`][index::File::traverse_with_lookup()] directly. /// /// Use [`thread_limit`][Options::thread_limit] to further control parallelism and [`check`][SafetyCheck] to define how much the passed /// objects shall be verified beforehand. pub fn traverse
( &self, pack: &pack::data::File, progress: Option
, new_processor: impl Fn() -> Processor + Send + Sync, new_cache: impl Fn() -> C + Send + Sync, Options { algorithm, thread_limit, check, }: Options, ) -> Result<(owned::Id, Outcome, Option
), Error ::SubProgress as Progress>::SubProgress>,
) -> Result<(), E>,
{
let progress = progress::DoOrDiscard::from(progress);
match algorithm {
Algorithm::Lookup => {
self.traverse_with_lookup(check, thread_limit, new_processor, new_cache, progress, pack)
}
Algorithm::DeltaTreeLookup => self.traverse_with_index(check, thread_limit, new_processor, progress, pack),
}
.map(|(a, b, p)| (a, b, p.into_inner()))
}
pub(crate) fn possibly_verify (
check: SafetyCheck,
object_kind: git_object::Kind,
decompressed: &[u8],
progress: &mut P,
header_buf: &mut [u8; 64],
index_entry: &pack::index::Entry,
pack_entry_crc32: impl FnOnce() -> u32,
processor: &mut impl FnMut(git_object::Kind, &[u8], &index::Entry, &mut P) -> Result<(), E>,
) -> Result<(), Error