diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
commit | 9918693037dce8aa4bb6f08741b6812923486c18 (patch) | |
tree | 21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/gix-pack/src | |
parent | Releasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff) | |
download | rustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip |
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-pack/src')
19 files changed, 279 insertions, 268 deletions
diff --git a/vendor/gix-pack/src/bundle/write/mod.rs b/vendor/gix-pack/src/bundle/write/mod.rs index 8983cb92f..9ddd1b9d3 100644 --- a/vendor/gix-pack/src/bundle/write/mod.rs +++ b/vendor/gix-pack/src/bundle/write/mod.rs @@ -21,10 +21,6 @@ pub use types::{Options, Outcome}; use crate::bundle::write::types::SharedTempFile; -type ThinPackLookupFn = Box<dyn for<'a> FnMut(gix_hash::ObjectId, &'a mut Vec<u8>) -> Option<gix_object::Data<'a>>>; -type ThinPackLookupFnSend = - Box<dyn for<'a> FnMut(gix_hash::ObjectId, &'a mut Vec<u8>) -> Option<gix_object::Data<'a>> + Send + 'static>; - /// The progress ids used in [`write_to_directory()`][crate::Bundle::write_to_directory()]. /// /// Use this information to selectively extract the progress of interest in case the parent application has custom visualization. @@ -54,7 +50,7 @@ impl crate::Bundle { /// /// * `progress` provides detailed progress information which can be discarded with [`gix_features::progress::Discard`]. /// * `should_interrupt` is checked regularly and when true, the whole operation will stop. - /// * `thin_pack_base_object_lookup_fn` If set, we expect to see a thin-pack with objects that reference their base object by object id which is + /// * `thin_pack_base_object_lookup` If set, we expect to see a thin-pack with objects that reference their base object by object id which is /// expected to exist in the object database the bundle is contained within. /// `options` further configure how the task is performed. /// @@ -68,7 +64,7 @@ impl crate::Bundle { directory: Option<&Path>, progress: &mut dyn DynNestedProgress, should_interrupt: &AtomicBool, - thin_pack_base_object_lookup_fn: Option<ThinPackLookupFn>, + thin_pack_base_object_lookup: Option<impl gix_object::Find>, options: Options, ) -> Result<Outcome, Error> { let _span = gix_features::trace::coarse!("gix_pack::Bundle::write_to_directory()"); @@ -90,8 +86,8 @@ impl crate::Bundle { let (pack_entries_iter, pack_version): ( Box<dyn Iterator<Item = Result<data::input::Entry, data::input::Error>>>, _, - ) = match thin_pack_base_object_lookup_fn { - Some(thin_pack_lookup_fn) => { + ) = match thin_pack_base_object_lookup { + Some(thin_pack_lookup) => { let pack = interrupt::Read { inner: pack, should_interrupt, @@ -104,7 +100,7 @@ impl crate::Bundle { data::input::EntryDataMode::KeepAndCrc32, object_hash, )?, - thin_pack_lookup_fn, + thin_pack_lookup, ); let pack_version = pack_entries_iter.inner.version(); let pack_entries_iter = data::input::EntriesToBytesIter::new( @@ -178,7 +174,7 @@ impl crate::Bundle { directory: Option<impl AsRef<Path>>, progress: &mut dyn DynNestedProgress, should_interrupt: &'static AtomicBool, - thin_pack_base_object_lookup_fn: Option<ThinPackLookupFnSend>, + thin_pack_base_object_lookup: Option<impl gix_object::Find + Send + 'static>, options: Options, ) -> Result<Outcome, Error> { let _span = gix_features::trace::coarse!("gix_pack::Bundle::write_to_directory_eagerly()"); @@ -198,8 +194,8 @@ impl crate::Bundle { let (pack_entries_iter, pack_version): ( Box<dyn Iterator<Item = Result<data::input::Entry, data::input::Error>> + Send + 'static>, _, - ) = match thin_pack_base_object_lookup_fn { - Some(thin_pack_lookup_fn) => { + ) = match thin_pack_base_object_lookup { + Some(thin_pack_lookup) => { let pack = interrupt::Read { inner: pack, should_interrupt, @@ -212,7 +208,7 @@ impl crate::Bundle { data::input::EntryDataMode::KeepAndCrc32, object_hash, )?, - thin_pack_lookup_fn, + thin_pack_lookup, ); let pack_kind = pack_entries_iter.inner.version(); (Box::new(pack_entries_iter), pack_kind) diff --git a/vendor/gix-pack/src/cache/delta/traverse/mod.rs b/vendor/gix-pack/src/cache/delta/traverse/mod.rs index 0598cf92e..ee3481627 100644 --- a/vendor/gix-pack/src/cache/delta/traverse/mod.rs +++ b/vendor/gix-pack/src/cache/delta/traverse/mod.rs @@ -1,15 +1,14 @@ use std::sync::atomic::{AtomicBool, Ordering}; -use gix_features::progress::DynNestedProgress; use gix_features::{ parallel::in_parallel_with_slice, - progress::{self, Progress}, + progress::{self, DynNestedProgress, Progress}, threading, threading::{Mutable, OwnShared}, }; use crate::{ - cache::delta::{traverse::util::ItemSliceSend, Item, Tree}, + cache::delta::{traverse::util::ItemSliceSync, Item, Tree}, data::EntryRange, }; @@ -130,32 +129,26 @@ where }; size_progress.init(None, progress::bytes()); let size_counter = size_progress.counter(); - let child_items = self.child_items.as_mut_slice(); let object_progress = OwnShared::new(Mutable::new(object_progress)); let start = std::time::Instant::now(); + let child_items = ItemSliceSync::new(&mut self.child_items); + let child_items = &child_items; in_parallel_with_slice( &mut self.root_items, thread_limit, { - let child_items = ItemSliceSend(std::ptr::slice_from_raw_parts_mut( - child_items.as_mut_ptr(), - child_items.len(), - )); { let object_progress = object_progress.clone(); - move |thread_index| { - let _ = &child_items; - resolve::State { - delta_bytes: Vec::<u8>::with_capacity(4096), - fully_resolved_delta_bytes: Vec::<u8>::with_capacity(4096), - progress: Box::new( - threading::lock(&object_progress).add_child(format!("thread {thread_index}")), - ), - resolve: resolve.clone(), - modify_base: inspect_object.clone(), - child_items: child_items.clone(), - } + move |thread_index| resolve::State { + delta_bytes: Vec::<u8>::with_capacity(4096), + fully_resolved_delta_bytes: Vec::<u8>::with_capacity(4096), + progress: Box::new( + threading::lock(&object_progress).add_child(format!("thread {thread_index}")), + ), + resolve: resolve.clone(), + modify_base: inspect_object.clone(), + child_items, } } }, diff --git a/vendor/gix-pack/src/cache/delta/traverse/resolve.rs b/vendor/gix-pack/src/cache/delta/traverse/resolve.rs index daf6f273e..26a182485 100644 --- a/vendor/gix-pack/src/cache/delta/traverse/resolve.rs +++ b/vendor/gix-pack/src/cache/delta/traverse/resolve.rs @@ -7,30 +7,81 @@ use gix_features::{progress::Progress, threading, zlib}; use crate::{ cache::delta::{ - traverse::{ - util::{ItemSliceSend, Node}, - Context, Error, - }, + traverse::{util::ItemSliceSync, Context, Error}, Item, }, data, data::EntryRange, }; -pub(crate) struct State<F, MBFN, T: Send> { +mod node { + use crate::cache::delta::{traverse::util::ItemSliceSync, Item}; + + /// An item returned by `iter_root_chunks`, allowing access to the `data` stored alongside nodes in a [`Tree`]. + pub(crate) struct Node<'a, T: Send> { + item: &'a mut Item<T>, + child_items: &'a ItemSliceSync<'a, Item<T>>, + } + + impl<'a, T: Send> Node<'a, T> { + /// SAFETY: The child_items must be unique among between users of the `ItemSliceSync`. + #[allow(unsafe_code)] + pub(crate) unsafe fn new(item: &'a mut Item<T>, child_items: &'a ItemSliceSync<'a, Item<T>>) -> Self { + Node { item, child_items } + } + } + + impl<'a, T: Send> Node<'a, T> { + /// Returns the offset into the pack at which the `Node`s data is located. + pub fn offset(&self) -> u64 { + self.item.offset + } + + /// Returns the slice into the data pack at which the pack entry is located. + pub fn entry_slice(&self) -> crate::data::EntryRange { + self.item.offset..self.item.next_offset + } + + /// Returns the node data associated with this node. + pub fn data(&mut self) -> &mut T { + &mut self.item.data + } + + /// Returns true if this node has children, e.g. is not a leaf in the tree. + pub fn has_children(&self) -> bool { + !self.item.children.is_empty() + } + + /// Transform this `Node` into an iterator over its children. + /// + /// Children are `Node`s referring to pack entries whose base object is this pack entry. + pub fn into_child_iter(self) -> impl Iterator<Item = Node<'a, T>> + 'a { + let children = self.child_items; + // SAFETY: The index is a valid index into the children array. + // SAFETY: The resulting mutable pointer cannot be yielded by any other node. + #[allow(unsafe_code)] + self.item.children.iter().map(move |&index| Node { + item: unsafe { children.get_mut(index as usize) }, + child_items: children, + }) + } + } +} + +pub(crate) struct State<'items, F, MBFN, T: Send> { pub delta_bytes: Vec<u8>, pub fully_resolved_delta_bytes: Vec<u8>, pub progress: Box<dyn Progress>, pub resolve: F, pub modify_base: MBFN, - pub child_items: ItemSliceSend<Item<T>>, + pub child_items: &'items ItemSliceSync<'items, Item<T>>, } #[allow(clippy::too_many_arguments)] pub(crate) fn deltas<T, F, MBFN, E, R>( objects: gix_features::progress::StepShared, size: gix_features::progress::StepShared, - node: &mut Item<T>, + item: &mut Item<T>, State { delta_bytes, fully_resolved_delta_bytes, @@ -38,7 +89,7 @@ pub(crate) fn deltas<T, F, MBFN, E, R>( resolve, modify_base, child_items, - }: &mut State<F, MBFN, T>, + }: &mut State<'_, F, MBFN, T>, resolve_data: &R, hash_len: usize, threads_left: &AtomicIsize, @@ -67,13 +118,10 @@ where // each node is a base, and its children always start out as deltas which become a base after applying them. // These will be pushed onto our stack until all are processed let root_level = 0; - let mut nodes: Vec<_> = vec![( - root_level, - Node { - item: node, - child_items: child_items.clone(), - }, - )]; + // SAFETY: The child items are unique + #[allow(unsafe_code)] + let root_node = unsafe { node::Node::new(item, child_items) }; + let mut nodes: Vec<_> = vec![(root_level, root_node)]; while let Some((level, mut base)) = nodes.pop() { if should_interrupt.load(Ordering::Relaxed) { return Err(Error::Interrupted); @@ -186,13 +234,13 @@ where /// system. Since this thread will take a controlling function, we may spawn one more than that. In threaded mode, we will finish /// all remaining work. #[allow(clippy::too_many_arguments)] -pub(crate) fn deltas_mt<T, F, MBFN, E, R>( +fn deltas_mt<T, F, MBFN, E, R>( mut threads_to_create: isize, decompressed_bytes_by_pack_offset: BTreeMap<u64, (data::Entry, u64, Vec<u8>)>, objects: gix_features::progress::StepShared, size: gix_features::progress::StepShared, progress: &dyn Progress, - nodes: Vec<(u16, Node<'_, T>)>, + nodes: Vec<(u16, node::Node<'_, T>)>, resolve: F, resolve_data: &R, modify_base: MBFN, diff --git a/vendor/gix-pack/src/cache/delta/traverse/util.rs b/vendor/gix-pack/src/cache/delta/traverse/util.rs index 1b7015351..5f09b918d 100644 --- a/vendor/gix-pack/src/cache/delta/traverse/util.rs +++ b/vendor/gix-pack/src/cache/delta/traverse/util.rs @@ -1,65 +1,36 @@ -use crate::cache::delta::Item; +use std::marker::PhantomData; -pub struct ItemSliceSend<T>(pub *mut [T]) -where - T: Send; - -/// SAFETY: This would be unsafe if this would ever be abused, but it's used internally and only in a way that assure that the pointers -/// don't violate aliasing rules. -impl<T> Clone for ItemSliceSend<T> +pub(crate) struct ItemSliceSync<'a, T> where T: Send, { - fn clone(&self) -> Self { - ItemSliceSend(self.0) - } -} - -// SAFETY: T is `Send`, and we only ever access one T at a time. And, ptrs need that assurance, I wonder if it's always right. -#[allow(unsafe_code)] -unsafe impl<T> Send for ItemSliceSend<T> where T: Send {} - -/// An item returned by `iter_root_chunks`, allowing access to the `data` stored alongside nodes in a [`Tree`]. -pub struct Node<'a, T: Send> { - pub item: &'a mut Item<T>, - pub child_items: ItemSliceSend<Item<T>>, + items: *mut T, + phantom: PhantomData<&'a T>, } -impl<'a, T: Send> Node<'a, T> { - /// Returns the offset into the pack at which the `Node`s data is located. - pub fn offset(&self) -> u64 { - self.item.offset - } - - /// Returns the slice into the data pack at which the pack entry is located. - pub fn entry_slice(&self) -> crate::data::EntryRange { - self.item.offset..self.item.next_offset - } - - /// Returns the node data associated with this node. - pub fn data(&mut self) -> &mut T { - &mut self.item.data - } - - /// Returns true if this node has children, e.g. is not a leaf in the tree. - pub fn has_children(&self) -> bool { - !self.item.children.is_empty() +impl<'a, T> ItemSliceSync<'a, T> +where + T: Send, +{ + pub fn new(items: &'a mut [T]) -> Self { + ItemSliceSync { + items: items.as_mut_ptr(), + phantom: PhantomData, + } } - /// Transform this `Node` into an iterator over its children. - /// - /// Children are `Node`s referring to pack entries whose base object is this pack entry. - pub fn into_child_iter(self) -> impl Iterator<Item = Node<'a, T>> + 'a { - let children = self.child_items; - self.item.children.iter().map(move |&index| { - // SAFETY: The children array is alive by the 'a lifetime. - // SAFETY: The index is a valid index into the children array. - // SAFETY: The resulting mutable pointer cannot be yielded by any other node. - #[allow(unsafe_code)] - Node { - item: &mut unsafe { &mut *children.0 }[index as usize], - child_items: children.clone(), - } - }) + /// SAFETY: The index must point into the slice and must not be reused concurrently. + #[allow(unsafe_code)] + pub unsafe fn get_mut(&self, index: usize) -> &'a mut T { + // SAFETY: The children array is alive by the 'a lifetime. + unsafe { &mut *self.items.add(index) } } } + +// SAFETY: T is `Send`, and we only use the pointer for creating new pointers. +#[allow(unsafe_code)] +unsafe impl<T> Send for ItemSliceSync<'_, T> where T: Send {} +// SAFETY: T is `Send`, and as long as the user follows the contract of +// `get_mut()`, we only ever access one T at a time. +#[allow(unsafe_code)] +unsafe impl<T> Sync for ItemSliceSync<'_, T> where T: Send {} diff --git a/vendor/gix-pack/src/data/file/decode/header.rs b/vendor/gix-pack/src/data/file/decode/header.rs index 3a6e40f8a..fb23f482d 100644 --- a/vendor/gix-pack/src/data/file/decode/header.rs +++ b/vendor/gix-pack/src/data/file/decode/header.rs @@ -1,8 +1,9 @@ +use gix_features::zlib; + use crate::{ data, data::{delta, file::decode::Error, File}, }; -use gix_features::zlib; /// A return value of a resolve function, which given an [`ObjectId`][gix_hash::ObjectId] determines where an object can be found. #[derive(Debug, PartialEq, Eq, Hash, Ord, PartialOrd, Clone)] diff --git a/vendor/gix-pack/src/data/file/verify.rs b/vendor/gix-pack/src/data/file/verify.rs index 11cec041d..76d47de0b 100644 --- a/vendor/gix-pack/src/data/file/verify.rs +++ b/vendor/gix-pack/src/data/file/verify.rs @@ -1,6 +1,7 @@ -use gix_features::progress::Progress; use std::sync::atomic::AtomicBool; +use gix_features::progress::Progress; + use crate::data::File; /// diff --git a/vendor/gix-pack/src/data/input/lookup_ref_delta_objects.rs b/vendor/gix-pack/src/data/input/lookup_ref_delta_objects.rs index 60f686d3a..f6036e20f 100644 --- a/vendor/gix-pack/src/data/input/lookup_ref_delta_objects.rs +++ b/vendor/gix-pack/src/data/input/lookup_ref_delta_objects.rs @@ -5,10 +5,10 @@ use gix_hash::ObjectId; use crate::data::{entry::Header, input}; /// An iterator to resolve thin packs on the fly. -pub struct LookupRefDeltaObjectsIter<I, LFn> { +pub struct LookupRefDeltaObjectsIter<I, Find> { /// The inner iterator whose entries we will resolve. pub inner: I, - lookup: LFn, + lookup: Find, /// The cached delta to provide next time we are called, it's the delta to go with the base we just resolved in its place. next_delta: Option<input::Entry>, /// Fuse to stop iteration after first missing object. @@ -21,14 +21,14 @@ pub struct LookupRefDeltaObjectsIter<I, LFn> { buf: Vec<u8>, } -impl<I, LFn> LookupRefDeltaObjectsIter<I, LFn> +impl<I, Find> LookupRefDeltaObjectsIter<I, Find> where I: Iterator<Item = Result<input::Entry, input::Error>>, - LFn: for<'a> FnMut(ObjectId, &'a mut Vec<u8>) -> Option<gix_object::Data<'a>>, + Find: gix_object::Find, { /// Create a new instance wrapping `iter` and using `lookup` as function to retrieve objects that will serve as bases /// for ref deltas seen while traversing `iter`. - pub fn new(iter: I, lookup: LFn) -> Self { + pub fn new(iter: I, lookup: Find) -> Self { LookupRefDeltaObjectsIter { inner: iter, lookup, @@ -75,10 +75,10 @@ where } } -impl<I, LFn> Iterator for LookupRefDeltaObjectsIter<I, LFn> +impl<I, Find> Iterator for LookupRefDeltaObjectsIter<I, Find> where I: Iterator<Item = Result<input::Entry, input::Error>>, - LFn: for<'a> FnMut(ObjectId, &'a mut Vec<u8>) -> Option<gix_object::Data<'a>>, + Find: gix_object::Find, { type Item = Result<input::Entry, input::Error>; @@ -94,7 +94,7 @@ where Header::RefDelta { base_id } => { match self.inserted_entry_length_at_offset.iter().rfind(|e| e.oid == base_id) { None => { - let base_entry = match (self.lookup)(base_id, &mut self.buf) { + let base_entry = match self.lookup.try_find(&base_id, &mut self.buf).ok()? { Some(obj) => { let current_pack_offset = entry.pack_offset; let mut entry = match input::Entry::from_data_obj(&obj, 0) { diff --git a/vendor/gix-pack/src/data/output/count/objects/mod.rs b/vendor/gix-pack/src/data/output/count/objects/mod.rs index 24810577c..34e922e9b 100644 --- a/vendor/gix-pack/src/data/output/count/objects/mod.rs +++ b/vendor/gix-pack/src/data/output/count/objects/mod.rs @@ -114,10 +114,13 @@ pub fn objects_unthreaded( } mod expand { - use std::sync::atomic::{AtomicBool, Ordering}; + use std::{ + cell::RefCell, + sync::atomic::{AtomicBool, Ordering}, + }; use gix_hash::{oid, ObjectId}; - use gix_object::{CommitRefIter, TagRefIter}; + use gix_object::{CommitRefIter, Data, TagRefIter}; use super::{ tree, @@ -206,24 +209,15 @@ mod expand { let objects_ref = if parent_commit_ids.is_empty() { traverse_delegate.clear(); + let objects = ExpandedCountingObjects::new(db, out, objects); gix_traverse::tree::breadthfirst( current_tree_iter, &mut tree_traversal_state, - |oid, buf| { - stats.decoded_objects += 1; - match db.find(oid, buf).ok() { - Some((obj, location)) => { - objects.fetch_add(1, Ordering::Relaxed); - stats.expanded_objects += 1; - out.push(output::Count::from_data(oid, location)); - obj.try_into_tree_iter() - } - None => None, - } - }, + &objects, &mut traverse_delegate, ) .map_err(Error::TreeTraverse)?; + out = objects.dissolve(stats); &traverse_delegate.non_trees } else { for commit_id in &parent_commit_ids { @@ -252,17 +246,16 @@ mod expand { }; changes_delegate.clear(); + let objects = CountingObjects::new(db); gix_diff::tree::Changes::from(Some(parent_tree)) .needed_to_obtain( - current_tree_iter.clone(), + current_tree_iter, &mut tree_diff_state, - |oid, buf| { - stats.decoded_objects += 1; - db.find_tree_iter(oid, buf).map(|t| t.0) - }, + &objects, &mut changes_delegate, ) .map_err(Error::TreeChanges)?; + stats.decoded_objects += objects.into_count(); } &changes_delegate.objects }; @@ -283,24 +276,17 @@ mod expand { match obj.0.kind { Tree => { traverse_delegate.clear(); - gix_traverse::tree::breadthfirst( - gix_object::TreeRefIter::from_bytes(obj.0.data), - &mut tree_traversal_state, - |oid, buf| { - stats.decoded_objects += 1; - match db.find(oid, buf).ok() { - Some((obj, location)) => { - objects.fetch_add(1, Ordering::Relaxed); - stats.expanded_objects += 1; - out.push(output::Count::from_data(oid, location)); - obj.try_into_tree_iter() - } - None => None, - } - }, - &mut traverse_delegate, - ) - .map_err(Error::TreeTraverse)?; + { + let objects = ExpandedCountingObjects::new(db, out, objects); + gix_traverse::tree::breadthfirst( + gix_object::TreeRefIter::from_bytes(obj.0.data), + &mut tree_traversal_state, + &objects, + &mut traverse_delegate, + ) + .map_err(Error::TreeTraverse)?; + out = objects.dissolve(stats); + } for id in &traverse_delegate.non_trees { out.push(id_to_count(db, buf1, id, objects, stats, allow_pack_lookups)); } @@ -374,4 +360,76 @@ mod expand { }, } } + + struct CountingObjects<'a> { + decoded_objects: std::cell::RefCell<usize>, + objects: &'a dyn crate::Find, + } + + impl<'a> CountingObjects<'a> { + fn new(objects: &'a dyn crate::Find) -> Self { + Self { + decoded_objects: Default::default(), + objects, + } + } + + fn into_count(self) -> usize { + self.decoded_objects.into_inner() + } + } + + impl gix_object::Find for CountingObjects<'_> { + fn try_find<'a>(&self, id: &oid, buffer: &'a mut Vec<u8>) -> Result<Option<Data<'a>>, gix_object::find::Error> { + let res = Ok(self.objects.try_find(id, buffer)?.map(|t| t.0)); + *self.decoded_objects.borrow_mut() += 1; + res + } + } + + struct ExpandedCountingObjects<'a> { + decoded_objects: std::cell::RefCell<usize>, + expanded_objects: std::cell::RefCell<usize>, + out: std::cell::RefCell<Vec<output::Count>>, + objects_count: &'a gix_features::progress::AtomicStep, + objects: &'a dyn crate::Find, + } + + impl<'a> ExpandedCountingObjects<'a> { + fn new( + objects: &'a dyn crate::Find, + out: Vec<output::Count>, + objects_count: &'a gix_features::progress::AtomicStep, + ) -> Self { + Self { + decoded_objects: Default::default(), + expanded_objects: Default::default(), + out: RefCell::new(out), + objects_count, + objects, + } + } + + fn dissolve(self, stats: &mut Outcome) -> Vec<output::Count> { + stats.decoded_objects += self.decoded_objects.into_inner(); + stats.expanded_objects += self.expanded_objects.into_inner(); + self.out.into_inner() + } + } + + impl gix_object::Find for ExpandedCountingObjects<'_> { + fn try_find<'a>(&self, id: &oid, buffer: &'a mut Vec<u8>) -> Result<Option<Data<'a>>, gix_object::find::Error> { + let maybe_obj = self.objects.try_find(id, buffer)?; + *self.decoded_objects.borrow_mut() += 1; + match maybe_obj { + None => Ok(None), + Some((obj, location)) => { + self.objects_count.fetch_add(1, Ordering::Relaxed); + *self.expanded_objects.borrow_mut() += 1; + self.out.borrow_mut().push(output::Count::from_data(id, location)); + Ok(Some(obj)) + } + } + } + } } diff --git a/vendor/gix-pack/src/data/output/count/objects/tree.rs b/vendor/gix-pack/src/data/output/count/objects/tree.rs index d3f4f6b9a..824b48062 100644 --- a/vendor/gix-pack/src/data/output/count/objects/tree.rs +++ b/vendor/gix-pack/src/data/output/count/objects/tree.rs @@ -4,7 +4,7 @@ pub mod changes { Visit, }; use gix_hash::ObjectId; - use gix_object::{bstr::BStr, tree::EntryMode}; + use gix_object::bstr::BStr; use crate::data::output::count::objects_impl::util::InsertImmutable; @@ -43,7 +43,7 @@ pub mod changes { fn visit(&mut self, change: Change) -> Action { match change { Change::Addition { oid, entry_mode } | Change::Modification { oid, entry_mode, .. } => { - if entry_mode == EntryMode::Commit { + if entry_mode.is_commit() { return Action::Continue; } let inserted = self.all_seen.insert(oid); @@ -60,10 +60,7 @@ pub mod changes { pub mod traverse { use gix_hash::ObjectId; - use gix_object::{ - bstr::BStr, - tree::{EntryMode, EntryRef}, - }; + use gix_object::{bstr::BStr, tree::EntryRef}; use gix_traverse::tree::{visit::Action, Visit}; use crate::data::output::count::objects_impl::util::InsertImmutable; @@ -110,8 +107,7 @@ pub mod traverse { } fn visit_nontree(&mut self, entry: &EntryRef<'_>) -> Action { - if entry.mode == EntryMode::Commit { - // links don't have a representation + if entry.mode.is_commit() { return Action::Continue; } let inserted = self.all_seen.insert(entry.oid.to_owned()); diff --git a/vendor/gix-pack/src/data/output/count/objects/types.rs b/vendor/gix-pack/src/data/output/count/objects/types.rs index 4b9ecea20..15e395018 100644 --- a/vendor/gix-pack/src/data/output/count/objects/types.rs +++ b/vendor/gix-pack/src/data/output/count/objects/types.rs @@ -84,7 +84,7 @@ pub enum Error { #[error(transparent)] CommitDecode(gix_object::decode::Error), #[error(transparent)] - FindExisting(#[from] crate::find::existing::Error), + FindExisting(#[from] gix_object::find::existing::Error), #[error(transparent)] InputIteration(Box<dyn std::error::Error + Send + Sync + 'static>), #[error(transparent)] diff --git a/vendor/gix-pack/src/data/output/entry/iter_from_counts.rs b/vendor/gix-pack/src/data/output/entry/iter_from_counts.rs index 2bebf5b20..87caf039c 100644 --- a/vendor/gix-pack/src/data/output/entry/iter_from_counts.rs +++ b/vendor/gix-pack/src/data/output/entry/iter_from_counts.rs @@ -1,8 +1,14 @@ pub(crate) mod function { use std::{cmp::Ordering, sync::Arc}; - use gix_features::progress::prodash::{Count, DynNestedProgress}; - use gix_features::{parallel, parallel::SequenceId, progress::Progress}; + use gix_features::{ + parallel, + parallel::SequenceId, + progress::{ + prodash::{Count, DynNestedProgress}, + Progress, + }, + }; use super::{reduce, util, Error, Mode, Options, Outcome, ProgressId}; use crate::data::output; @@ -204,7 +210,7 @@ pub(crate) mod function { stats.objects_copied_from_pack += 1; entry } - None => match db.try_find(&count.id, buf).map_err(Error::FindExisting)? { + None => match db.try_find(&count.id, buf).map_err(Error::Find)? { Some((obj, _location)) => { stats.decoded_and_recompressed_objects += 1; output::Entry::from_data(count, &obj) @@ -216,7 +222,7 @@ pub(crate) mod function { }, } } - None => match db.try_find(&count.id, buf).map_err(Error::FindExisting)? { + None => match db.try_find(&count.id, buf).map_err(Error::Find)? { Some((obj, _location)) => { stats.decoded_and_recompressed_objects += 1; output::Entry::from_data(count, &obj) @@ -397,7 +403,7 @@ mod types { #[allow(missing_docs)] pub enum Error { #[error(transparent)] - FindExisting(crate::find::Error), + Find(gix_object::find::Error), #[error(transparent)] NewEntry(#[from] entry::Error), } diff --git a/vendor/gix-pack/src/find.rs b/vendor/gix-pack/src/find.rs index b049d4d78..efc9513ed 100644 --- a/vendor/gix-pack/src/find.rs +++ b/vendor/gix-pack/src/find.rs @@ -1,57 +1,3 @@ -/// The error returned by methods of the [Find](crate::Find) trait. -pub type Error = Box<dyn std::error::Error + Send + Sync + 'static>; - -/// -pub mod existing { - use gix_hash::ObjectId; - - /// The error returned by the [`find(…)`](crate::FindExt::find()) trait methods. - #[derive(Debug, thiserror::Error)] - #[allow(missing_docs)] - pub enum Error { - #[error(transparent)] - Find(crate::find::Error), - #[error("An object with id {} could not be found", .oid)] - NotFound { oid: ObjectId }, - } -} - -/// -pub mod existing_object { - use gix_hash::ObjectId; - - /// The error returned by the various [`find_*`](crate::FindExt::find_commit()) trait methods. - #[derive(Debug, thiserror::Error)] - #[allow(missing_docs)] - pub enum Error { - #[error(transparent)] - Find(crate::find::Error), - #[error(transparent)] - Decode(gix_object::decode::Error), - #[error("An object with id {} could not be found", .oid)] - NotFound { oid: ObjectId }, - #[error("Expected object of kind {} something else", .expected)] - ObjectKind { expected: gix_object::Kind }, - } -} - -/// -pub mod existing_iter { - use gix_hash::ObjectId; - - /// The error returned by the various [`find_*`](crate::FindExt::find_commit()) trait methods. - #[derive(Debug, thiserror::Error)] - #[allow(missing_docs)] - pub enum Error { - #[error(transparent)] - Find(crate::find::Error), - #[error("An object with id {} could not be found", .oid)] - NotFound { oid: ObjectId }, - #[error("Expected object of kind {} something else", .expected)] - ObjectKind { expected: gix_object::Kind }, - } -} - /// An Entry in a pack providing access to its data. /// /// Its commonly retrieved by reading from a pack index file followed by a read from a pack data file. diff --git a/vendor/gix-pack/src/find_traits.rs b/vendor/gix-pack/src/find_traits.rs index 7c4821d81..787ed5b63 100644 --- a/vendor/gix-pack/src/find_traits.rs +++ b/vendor/gix-pack/src/find_traits.rs @@ -25,7 +25,7 @@ pub trait Find { &self, id: &gix_hash::oid, buffer: &'a mut Vec<u8>, - ) -> Result<Option<(gix_object::Data<'a>, Option<data::entry::Location>)>, find::Error> { + ) -> Result<Option<(gix_object::Data<'a>, Option<data::entry::Location>)>, gix_object::find::Error> { self.try_find_cached(id, buffer, &mut crate::cache::Never) } @@ -40,7 +40,7 @@ pub trait Find { id: &gix_hash::oid, buffer: &'a mut Vec<u8>, pack_cache: &mut dyn crate::cache::DecodeEntry, - ) -> Result<Option<(gix_object::Data<'a>, Option<data::entry::Location>)>, find::Error>; + ) -> Result<Option<(gix_object::Data<'a>, Option<data::entry::Location>)>, gix_object::find::Error>; /// Find the packs location where an object with `id` can be found in the database, or `None` if there is no pack /// holding the object. @@ -66,8 +66,6 @@ pub trait Find { mod ext { use gix_object::{BlobRef, CommitRef, CommitRefIter, Kind, ObjectRef, TagRef, TagRefIter, TreeRef, TreeRefIter}; - use crate::find; - macro_rules! make_obj_lookup { ($method:ident, $object_variant:path, $object_kind:path, $object_type:ty) => { /// Like [`find(…)`][Self::find()], but flattens the `Result<Option<_>>` into a single `Result` making a non-existing object an error @@ -76,21 +74,27 @@ mod ext { &self, id: &gix_hash::oid, buffer: &'a mut Vec<u8>, - ) -> Result<($object_type, Option<crate::data::entry::Location>), find::existing_object::Error> { + ) -> Result<($object_type, Option<crate::data::entry::Location>), gix_object::find::existing_object::Error> + { let id = id.as_ref(); self.try_find(id, buffer) - .map_err(find::existing_object::Error::Find)? - .ok_or_else(|| find::existing_object::Error::NotFound { + .map_err(gix_object::find::existing_object::Error::Find)? + .ok_or_else(|| gix_object::find::existing_object::Error::NotFound { oid: id.as_ref().to_owned(), }) .and_then(|(o, l)| { o.decode() - .map_err(find::existing_object::Error::Decode) + .map_err(|err| gix_object::find::existing_object::Error::Decode { + source: err, + oid: id.to_owned(), + }) .map(|o| (o, l)) }) .and_then(|(o, l)| match o { $object_variant(o) => return Ok((o, l)), - _other => Err(find::existing_object::Error::ObjectKind { + o => Err(gix_object::find::existing_object::Error::ObjectKind { + oid: id.to_owned(), + actual: o.kind(), expected: $object_kind, }), }) @@ -106,16 +110,18 @@ mod ext { &self, id: &gix_hash::oid, buffer: &'a mut Vec<u8>, - ) -> Result<($object_type, Option<crate::data::entry::Location>), find::existing_iter::Error> { + ) -> Result<($object_type, Option<crate::data::entry::Location>), gix_object::find::existing_iter::Error> { let id = id.as_ref(); self.try_find(id, buffer) - .map_err(find::existing_iter::Error::Find)? - .ok_or_else(|| find::existing_iter::Error::NotFound { + .map_err(gix_object::find::existing_iter::Error::Find)? + .ok_or_else(|| gix_object::find::existing_iter::Error::NotFound { oid: id.as_ref().to_owned(), }) .and_then(|(o, l)| { o.$into_iter() - .ok_or_else(|| find::existing_iter::Error::ObjectKind { + .ok_or_else(|| gix_object::find::existing_iter::Error::ObjectKind { + oid: id.to_owned(), + actual: o.kind, expected: $object_kind, }) .map(|i| (i, l)) @@ -131,10 +137,11 @@ mod ext { &self, id: &gix_hash::oid, buffer: &'a mut Vec<u8>, - ) -> Result<(gix_object::Data<'a>, Option<crate::data::entry::Location>), find::existing::Error> { + ) -> Result<(gix_object::Data<'a>, Option<crate::data::entry::Location>), gix_object::find::existing::Error> + { self.try_find(id, buffer) - .map_err(find::existing::Error::Find)? - .ok_or_else(|| find::existing::Error::NotFound { + .map_err(gix_object::find::existing::Error::Find)? + .ok_or_else(|| gix_object::find::existing::Error::NotFound { oid: id.as_ref().to_owned(), }) } @@ -172,7 +179,7 @@ mod find_impls { id: &oid, buffer: &'a mut Vec<u8>, pack_cache: &mut dyn crate::cache::DecodeEntry, - ) -> Result<Option<(gix_object::Data<'a>, Option<data::entry::Location>)>, crate::find::Error> { + ) -> Result<Option<(gix_object::Data<'a>, Option<data::entry::Location>)>, gix_object::find::Error> { (*self).try_find_cached(id, buffer, pack_cache) } @@ -202,7 +209,7 @@ mod find_impls { id: &oid, buffer: &'a mut Vec<u8>, pack_cache: &mut dyn crate::cache::DecodeEntry, - ) -> Result<Option<(gix_object::Data<'a>, Option<data::entry::Location>)>, find::Error> { + ) -> Result<Option<(gix_object::Data<'a>, Option<data::entry::Location>)>, gix_object::find::Error> { self.deref().try_find_cached(id, buffer, pack_cache) } @@ -232,7 +239,7 @@ mod find_impls { id: &oid, buffer: &'a mut Vec<u8>, pack_cache: &mut dyn crate::cache::DecodeEntry, - ) -> Result<Option<(gix_object::Data<'a>, Option<data::entry::Location>)>, find::Error> { + ) -> Result<Option<(gix_object::Data<'a>, Option<data::entry::Location>)>, gix_object::find::Error> { self.deref().try_find_cached(id, buffer, pack_cache) } @@ -262,7 +269,7 @@ mod find_impls { id: &oid, buffer: &'a mut Vec<u8>, pack_cache: &mut dyn crate::cache::DecodeEntry, - ) -> Result<Option<(gix_object::Data<'a>, Option<data::entry::Location>)>, find::Error> { + ) -> Result<Option<(gix_object::Data<'a>, Option<data::entry::Location>)>, gix_object::find::Error> { self.deref().try_find_cached(id, buffer, pack_cache) } diff --git a/vendor/gix-pack/src/index/encode.rs b/vendor/gix-pack/src/index/encode.rs index d9dad68ce..61c6f6de7 100644 --- a/vendor/gix-pack/src/index/encode.rs +++ b/vendor/gix-pack/src/index/encode.rs @@ -34,14 +34,14 @@ pub(crate) fn fanout(iter: &mut dyn ExactSizeIterator<Item = u8>) -> [u32; 256] #[cfg(feature = "streaming-input")] mod function { + use std::io; + use gix_features::{ hash, progress::{self, DynNestedProgress}, }; - use std::io; use super::{fanout, HIGH_BIT, LARGE_OFFSET_THRESHOLD}; - use crate::index::V2_SIGNATURE; struct Count<W> { diff --git a/vendor/gix-pack/src/index/traverse/with_index.rs b/vendor/gix-pack/src/index/traverse/with_index.rs index 91382034c..88b3dea96 100644 --- a/vendor/gix-pack/src/index/traverse/with_index.rs +++ b/vendor/gix-pack/src/index/traverse/with_index.rs @@ -1,7 +1,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; -use gix_features::parallel; -use gix_features::progress::DynNestedProgress; +use gix_features::{parallel, progress::DynNestedProgress}; use super::Error; use crate::{ diff --git a/vendor/gix-pack/src/index/traverse/with_lookup.rs b/vendor/gix-pack/src/index/traverse/with_lookup.rs index 3759dae5e..9f1db3d05 100644 --- a/vendor/gix-pack/src/index/traverse/with_lookup.rs +++ b/vendor/gix-pack/src/index/traverse/with_lookup.rs @@ -1,9 +1,8 @@ use std::sync::atomic::{AtomicBool, Ordering}; -use gix_features::progress::{Count, DynNestedProgress}; use gix_features::{ parallel::{self, in_parallel_if}, - progress::{self, Progress}, + progress::{self, Count, DynNestedProgress, Progress}, threading::{lock, Mutable, OwnShared}, zlib, }; diff --git a/vendor/gix-pack/src/index/verify.rs b/vendor/gix-pack/src/index/verify.rs index d259a6a38..343a647b4 100644 --- a/vendor/gix-pack/src/index/verify.rs +++ b/vendor/gix-pack/src/index/verify.rs @@ -1,7 +1,7 @@ use std::sync::atomic::AtomicBool; use gix_features::progress::{DynNestedProgress, Progress}; -use gix_object::{bstr::ByteSlice, WriteTo}; +use gix_object::WriteTo; use crate::index; @@ -235,7 +235,7 @@ impl index::File { object_kind: gix_object::Kind, buf: &[u8], index_entry: &index::Entry, - progress: &dyn gix_features::progress::Progress, + _progress: &dyn gix_features::progress::Progress, ) -> Result<(), integrity::Error> { if let Mode::HashCrc32Decode | Mode::HashCrc32DecodeEncode = verify_mode { use gix_object::Kind::*; @@ -252,21 +252,12 @@ impl index::File { encode_buf.clear(); object.write_to(&mut *encode_buf)?; if encode_buf.as_slice() != buf { - let mut should_return_error = true; - if let Tree = object_kind { - if buf.as_bstr().find(b"100664").is_some() || buf.as_bstr().find(b"100640").is_some() { - progress.info(format!("Tree object {} would be cleaned up during re-serialization, replacing mode '100664|100640' with '100644'", index_entry.oid)); - should_return_error = false - } - } - if should_return_error { - return Err(integrity::Error::ObjectEncodeMismatch { - kind: object_kind, - id: index_entry.oid, - expected: buf.into(), - actual: encode_buf.clone().into(), - }); - } + return Err(integrity::Error::ObjectEncodeMismatch { + kind: object_kind, + id: index_entry.oid, + expected: buf.into(), + actual: encode_buf.clone().into(), + }); } } } diff --git a/vendor/gix-pack/src/index/write/mod.rs b/vendor/gix-pack/src/index/write/mod.rs index d1402fa86..3ecb7347b 100644 --- a/vendor/gix-pack/src/index/write/mod.rs +++ b/vendor/gix-pack/src/index/write/mod.rs @@ -1,8 +1,7 @@ use std::{convert::TryInto, io, sync::atomic::AtomicBool}; pub use error::Error; -use gix_features::progress::prodash::DynNestedProgress; -use gix_features::progress::{self, Count, Progress}; +use gix_features::progress::{self, prodash::DynNestedProgress, Count, Progress}; use crate::cache::delta::{traverse, Tree}; diff --git a/vendor/gix-pack/src/lib.rs b/vendor/gix-pack/src/lib.rs index 200b87019..b56d1fe98 100755 --- a/vendor/gix-pack/src/lib.rs +++ b/vendor/gix-pack/src/lib.rs @@ -12,10 +12,10 @@ //! in order to decompress packs in parallel and without any waste. //! ## Feature Flags #![cfg_attr( - feature = "document-features", - cfg_attr(doc, doc = ::document_features::document_features!()) + all(doc, feature = "document-features"), + doc = ::document_features::document_features!() )] -#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(all(doc, feature = "document-features"), feature(doc_cfg, doc_auto_cfg))] #![deny(missing_docs, rust_2018_idioms, unsafe_code)] /// |