summaryrefslogtreecommitdiffstats
path: root/vendor/gix-odb/src/store_impls
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix-odb/src/store_impls')
-rw-r--r--vendor/gix-odb/src/store_impls/dynamic/find.rs54
-rw-r--r--vendor/gix-odb/src/store_impls/dynamic/handle.rs7
-rw-r--r--vendor/gix-odb/src/store_impls/dynamic/header.rs18
-rw-r--r--vendor/gix-odb/src/store_impls/dynamic/init.rs10
-rw-r--r--vendor/gix-odb/src/store_impls/dynamic/iter.rs2
-rw-r--r--vendor/gix-odb/src/store_impls/dynamic/load_index.rs10
-rw-r--r--vendor/gix-odb/src/store_impls/dynamic/mod.rs2
-rw-r--r--vendor/gix-odb/src/store_impls/dynamic/prefix.rs5
-rw-r--r--vendor/gix-odb/src/store_impls/dynamic/structure.rs1
-rw-r--r--vendor/gix-odb/src/store_impls/dynamic/types.rs2
-rw-r--r--vendor/gix-odb/src/store_impls/dynamic/verify.rs225
-rw-r--r--vendor/gix-odb/src/store_impls/dynamic/write.rs7
-rw-r--r--vendor/gix-odb/src/store_impls/loose/find.rs18
-rw-r--r--vendor/gix-odb/src/store_impls/loose/verify.rs8
-rw-r--r--vendor/gix-odb/src/store_impls/loose/write.rs36
15 files changed, 209 insertions, 196 deletions
diff --git a/vendor/gix-odb/src/store_impls/dynamic/find.rs b/vendor/gix-odb/src/store_impls/dynamic/find.rs
index 88f95db51..b4cd25aeb 100644
--- a/vendor/gix-odb/src/store_impls/dynamic/find.rs
+++ b/vendor/gix-odb/src/store_impls/dynamic/find.rs
@@ -75,6 +75,7 @@ pub(crate) mod error {
}
}
pub use error::Error;
+use gix_features::zlib;
use crate::{store::types::PackId, Find};
@@ -86,7 +87,8 @@ where
&'b self,
mut id: &'b gix_hash::oid,
buffer: &'a mut Vec<u8>,
- pack_cache: &mut impl DecodeEntry,
+ inflate: &mut zlib::Inflate,
+ pack_cache: &mut dyn DecodeEntry,
snapshot: &mut load_index::Snapshot,
recursion: Option<error::DeltaBaseRecursion<'_>>,
) -> Result<Option<(gix_object::Data<'a>, Option<gix_pack::data::entry::Location>)>, Error> {
@@ -147,7 +149,8 @@ where
let res = match pack.decode_entry(
entry,
buffer,
- |id, _out| {
+ inflate,
+ &|id, _out| {
index_file.pack_offset_by_id(id).map(|pack_offset| {
gix_pack::data::decode::entry::ResolvedBase::InPack(pack.entry(pack_offset))
})
@@ -182,10 +185,11 @@ where
.try_find_cached_inner(
&base_id,
&mut buf,
+ inflate,
pack_cache,
snapshot,
recursion
- .map(|r| r.inc_depth())
+ .map(error::DeltaBaseRecursion::inc_depth)
.or_else(|| error::DeltaBaseRecursion::new(id).into()),
)
.map_err(|err| Error::DeltaBaseLookup {
@@ -231,7 +235,8 @@ where
pack.decode_entry(
entry,
buffer,
- |id, out| {
+ inflate,
+ &|id, out| {
index_file
.pack_offset_by_id(id)
.map(|pack_offset| {
@@ -306,11 +311,8 @@ impl<S> gix_pack::Find for super::Handle<S>
where
S: Deref<Target = super::Store> + Clone,
{
- type Error = Error;
-
// TODO: probably make this method fallible, but that would mean its own error type.
- fn contains(&self, id: impl AsRef<gix_hash::oid>) -> bool {
- let id = id.as_ref();
+ fn contains(&self, id: &gix_hash::oid) -> bool {
let mut snapshot = self.snapshot.borrow_mut();
loop {
for (idx, index) in snapshot.indices.iter().enumerate() {
@@ -341,20 +343,17 @@ where
fn try_find_cached<'a>(
&self,
- id: impl AsRef<gix_hash::oid>,
+ id: &gix_hash::oid,
buffer: &'a mut Vec<u8>,
- pack_cache: &mut impl DecodeEntry,
- ) -> Result<Option<(gix_object::Data<'a>, Option<gix_pack::data::entry::Location>)>, Self::Error> {
- let id = id.as_ref();
+ pack_cache: &mut dyn DecodeEntry,
+ ) -> Result<Option<(gix_object::Data<'a>, Option<gix_pack::data::entry::Location>)>, gix_pack::find::Error> {
let mut snapshot = self.snapshot.borrow_mut();
- self.try_find_cached_inner(id, buffer, pack_cache, &mut snapshot, None)
+ let mut inflate = self.inflate.borrow_mut();
+ self.try_find_cached_inner(id, buffer, &mut inflate, pack_cache, &mut snapshot, None)
+ .map_err(|err| Box::new(err) as _)
}
- fn location_by_oid(
- &self,
- id: impl AsRef<gix_hash::oid>,
- buf: &mut Vec<u8>,
- ) -> Option<gix_pack::data::entry::Location> {
+ fn location_by_oid(&self, id: &gix_hash::oid, buf: &mut Vec<u8>) -> Option<gix_pack::data::entry::Location> {
assert!(
matches!(self.token.as_ref(), Some(handle::Mode::KeepDeletedPacksAvailable)),
"BUG: handle must be configured to `prevent_pack_unload()` before using this method"
@@ -362,8 +361,8 @@ where
assert!(self.store_ref().replacements.is_empty() || self.ignore_replacements, "Everything related to packing must not use replacements. These are not used here, but it should be turned off for good measure.");
- let id = id.as_ref();
let mut snapshot = self.snapshot.borrow_mut();
+ let mut inflate = self.inflate.borrow_mut();
'outer: loop {
{
let marker = snapshot.marker;
@@ -404,13 +403,14 @@ where
buf.resize(entry.decompressed_size.try_into().expect("representable size"), 0);
assert_eq!(pack.id, pack_id.to_intrinsic_pack_id(), "both ids must always match");
- let res = pack.decompress_entry(&entry, buf).ok().map(|entry_size_past_header| {
- gix_pack::data::entry::Location {
+ let res = pack
+ .decompress_entry(&entry, &mut inflate, buf)
+ .ok()
+ .map(|entry_size_past_header| gix_pack::data::entry::Location {
pack_id: pack.id,
pack_offset,
entry_size: entry.header_size() + entry_size_past_header,
- }
- });
+ });
if idx != 0 {
snapshot.indices.swap(0, idx);
@@ -503,17 +503,15 @@ where
S: Deref<Target = super::Store> + Clone,
Self: gix_pack::Find,
{
- type Error = <Self as gix_pack::Find>::Error;
-
- fn contains(&self, id: impl AsRef<gix_hash::oid>) -> bool {
+ fn contains(&self, id: &gix_hash::oid) -> bool {
gix_pack::Find::contains(self, id)
}
fn try_find<'a>(
&self,
- id: impl AsRef<gix_hash::oid>,
+ id: &gix_hash::oid,
buffer: &'a mut Vec<u8>,
- ) -> Result<Option<gix_object::Data<'a>>, Self::Error> {
+ ) -> Result<Option<gix_object::Data<'a>>, crate::find::Error> {
gix_pack::Find::try_find(self, id, buffer).map(|t| t.map(|t| t.0))
}
}
diff --git a/vendor/gix-odb/src/store_impls/dynamic/handle.rs b/vendor/gix-odb/src/store_impls/dynamic/handle.rs
index 78efd4451..655bdfa43 100644
--- a/vendor/gix-odb/src/store_impls/dynamic/handle.rs
+++ b/vendor/gix-odb/src/store_impls/dynamic/handle.rs
@@ -257,6 +257,7 @@ impl super::Store {
refresh: RefreshMode::default(),
ignore_replacements: false,
token: Some(token),
+ inflate: RefCell::new(Default::default()),
snapshot: RefCell::new(self.collect_snapshot()),
max_recursion_depth: Self::INITIAL_MAX_RECURSION_DEPTH,
packed_object_count: Default::default(),
@@ -273,6 +274,7 @@ impl super::Store {
refresh: Default::default(),
ignore_replacements: false,
token: Some(token),
+ inflate: RefCell::new(Default::default()),
snapshot: RefCell::new(self.collect_snapshot()),
max_recursion_depth: Self::INITIAL_MAX_RECURSION_DEPTH,
packed_object_count: Default::default(),
@@ -344,8 +346,8 @@ impl TryFrom<&super::Store> for super::Store {
fn try_from(s: &super::Store) -> Result<Self, Self::Error> {
super::Store::at_opts(
- s.path(),
- s.replacements(),
+ s.path().into(),
+ &mut s.replacements(),
crate::store::init::Options {
slots: crate::store::init::Slots::Given(s.files.len().try_into().expect("BUG: too many slots")),
object_hash: Default::default(),
@@ -391,6 +393,7 @@ where
}
.into()
},
+ inflate: RefCell::new(Default::default()),
snapshot: RefCell::new(self.store.collect_snapshot()),
max_recursion_depth: self.max_recursion_depth,
packed_object_count: Default::default(),
diff --git a/vendor/gix-odb/src/store_impls/dynamic/header.rs b/vendor/gix-odb/src/store_impls/dynamic/header.rs
index d29a911f1..05ff7cf64 100644
--- a/vendor/gix-odb/src/store_impls/dynamic/header.rs
+++ b/vendor/gix-odb/src/store_impls/dynamic/header.rs
@@ -1,3 +1,4 @@
+use gix_features::zlib;
use std::ops::Deref;
use gix_hash::oid;
@@ -15,6 +16,7 @@ where
fn try_header_inner<'b>(
&'b self,
mut id: &'b gix_hash::oid,
+ inflate: &mut zlib::Inflate,
snapshot: &mut load_index::Snapshot,
recursion: Option<DeltaBaseRecursion<'_>>,
) -> Result<Option<Header>, Error> {
@@ -71,7 +73,7 @@ where
},
};
let entry = pack.entry(pack_offset);
- let res = match pack.decode_header(entry, |id| {
+ let res = match pack.decode_header(entry, inflate, &|id| {
index_file.pack_offset_by_id(id).map(|pack_offset| {
gix_pack::data::decode::header::ResolvedBase::InPack(pack.entry(pack_offset))
})
@@ -85,9 +87,10 @@ where
let hdr = self
.try_header_inner(
&base_id,
+ inflate,
snapshot,
recursion
- .map(|r| r.inc_depth())
+ .map(DeltaBaseRecursion::inc_depth)
.or_else(|| DeltaBaseRecursion::new(id).into()),
)
.map_err(|err| Error::DeltaBaseLookup {
@@ -127,7 +130,7 @@ where
.as_ref()
.expect("pack to still be available like just now");
let entry = pack.entry(pack_offset);
- pack.decode_header(entry, |id| {
+ pack.decode_header(entry, inflate, &|id| {
index_file
.pack_offset_by_id(id)
.map(|pack_offset| {
@@ -179,11 +182,10 @@ impl<S> crate::Header for super::Handle<S>
where
S: Deref<Target = super::Store> + Clone,
{
- type Error = Error;
-
- fn try_header(&self, id: impl AsRef<oid>) -> Result<Option<Header>, Self::Error> {
- let id = id.as_ref();
+ fn try_header(&self, id: &oid) -> Result<Option<Header>, crate::find::Error> {
let mut snapshot = self.snapshot.borrow_mut();
- self.try_header_inner(id, &mut snapshot, None)
+ let mut inflate = self.inflate.borrow_mut();
+ self.try_header_inner(id, &mut inflate, &mut snapshot, None)
+ .map_err(|err| Box::new(err) as _)
}
}
diff --git a/vendor/gix-odb/src/store_impls/dynamic/init.rs b/vendor/gix-odb/src/store_impls/dynamic/init.rs
index 5e272dcff..d7e1d9d99 100644
--- a/vendor/gix-odb/src/store_impls/dynamic/init.rs
+++ b/vendor/gix-odb/src/store_impls/dynamic/init.rs
@@ -70,8 +70,8 @@ impl Store {
/// `replacements` is an iterator over pairs of old and new object ids for replacement support.
/// This means that when asking for object `X`, one will receive object `X-replaced` given an iterator like `Some((X, X-replaced))`.
pub fn at_opts(
- objects_dir: impl Into<PathBuf>,
- replacements: impl IntoIterator<Item = (gix_hash::ObjectId, gix_hash::ObjectId)>,
+ objects_dir: PathBuf,
+ replacements: &mut dyn Iterator<Item = (gix_hash::ObjectId, gix_hash::ObjectId)>,
Options {
slots,
object_hash,
@@ -79,7 +79,7 @@ impl Store {
current_dir,
}: Options,
) -> std::io::Result<Self> {
- let objects_dir = objects_dir.into();
+ let _span = gix_features::trace::detail!("gix_odb::Store::at()");
let current_dir = current_dir.map_or_else(std::env::current_dir, Ok)?;
if !objects_dir.is_dir() {
return Err(std::io::Error::new(
@@ -90,7 +90,7 @@ impl Store {
let slot_count = match slots {
Slots::Given(n) => n as usize,
Slots::AsNeededByDiskState { multiplier, minimum } => {
- let mut db_paths = crate::alternate::resolve(&objects_dir, &current_dir)
+ let mut db_paths = crate::alternate::resolve(objects_dir.clone(), &current_dir)
.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))?;
db_paths.insert(0, objects_dir.clone());
let num_slots = super::Store::collect_indices_and_mtime_sorted_by_size(db_paths, None, None)
@@ -106,7 +106,7 @@ impl Store {
"Cannot use more than 1^15 slots",
));
}
- let mut replacements: Vec<_> = replacements.into_iter().collect();
+ let mut replacements: Vec<_> = replacements.collect();
replacements.sort_by(|a, b| a.0.cmp(&b.0));
Ok(Store {
diff --git a/vendor/gix-odb/src/store_impls/dynamic/iter.rs b/vendor/gix-odb/src/store_impls/dynamic/iter.rs
index 2152dff71..2a7253aec 100644
--- a/vendor/gix-odb/src/store_impls/dynamic/iter.rs
+++ b/vendor/gix-odb/src/store_impls/dynamic/iter.rs
@@ -192,7 +192,7 @@ impl Iterator for AllObjects {
Some(id) => Some(id),
None => {
*index += 1;
- match self.loose_dbs.get(*index).map(|ldb| ldb.iter()) {
+ match self.loose_dbs.get(*index).map(loose::Store::iter) {
Some(new_iter) => {
*iter = new_iter;
self.next()
diff --git a/vendor/gix-odb/src/store_impls/dynamic/load_index.rs b/vendor/gix-odb/src/store_impls/dynamic/load_index.rs
index 84224dff1..4716a5806 100644
--- a/vendor/gix-odb/src/store_impls/dynamic/load_index.rs
+++ b/vendor/gix-odb/src/store_impls/dynamic/load_index.rs
@@ -206,7 +206,7 @@ impl super::Store {
self.num_disk_state_consolidation.fetch_add(1, Ordering::Relaxed);
let db_paths: Vec<_> = std::iter::once(objects_directory.to_owned())
- .chain(crate::alternate::resolve(objects_directory, &self.current_dir)?)
+ .chain(crate::alternate::resolve(objects_directory.clone(), &self.current_dir)?)
.collect();
// turn db paths into loose object databases. Reuse what's there, but only if it is in the right order.
@@ -470,8 +470,7 @@ impl super::Store {
})
.transpose()?;
if let Some((multi_index, mtime, flen)) = multi_index_info {
- let index_names_in_multi_index: Vec<_> =
- multi_index.index_names().iter().map(|p| p.as_path()).collect();
+ let index_names_in_multi_index: Vec<_> = multi_index.index_names().iter().map(AsRef::as_ref).collect();
let mut indices_not_in_multi_index: Vec<(Either, _, _)> = indices
.into_iter()
.filter_map(|(path, a, b)| {
@@ -494,6 +493,11 @@ impl super::Store {
// Unlike libgit2, do not sort by modification date, but by size and put the biggest indices first. That way
// the chance to hit an object should be higher. We leave it to the handle to sort by LRU.
// Git itself doesn't change the order which may safe time, but we want it to be stable which also helps some tests.
+ // NOTE: this will work well for well-packed repos or those using geometric repacking, but force us to open a lot
+ // of files when dealing with new objects, as there is no notion of recency here as would be with unmaintained
+ // repositories. Different algorithms should be provided, like newest packs first, and possibly a mix of both
+ // with big packs first, then sorting by recency for smaller packs.
+ // We also want to implement `fetch.unpackLimit` to alleviate this issue a little.
indices_by_modification_time.sort_by(|l, r| l.2.cmp(&r.2).reverse());
Ok(indices_by_modification_time)
}
diff --git a/vendor/gix-odb/src/store_impls/dynamic/mod.rs b/vendor/gix-odb/src/store_impls/dynamic/mod.rs
index e992fada6..35d4f7ca6 100644
--- a/vendor/gix-odb/src/store_impls/dynamic/mod.rs
+++ b/vendor/gix-odb/src/store_impls/dynamic/mod.rs
@@ -1,4 +1,5 @@
//! The standard object store which should fit all needs.
+use gix_features::zlib;
use std::{cell::RefCell, ops::Deref};
use crate::Store;
@@ -24,6 +25,7 @@ where
pub(crate) token: Option<handle::Mode>,
snapshot: RefCell<load_index::Snapshot>,
+ inflate: RefCell<zlib::Inflate>,
packed_object_count: RefCell<Option<u64>>,
}
diff --git a/vendor/gix-odb/src/store_impls/dynamic/prefix.rs b/vendor/gix-odb/src/store_impls/dynamic/prefix.rs
index c0edeba3f..58a49416b 100644
--- a/vendor/gix-odb/src/store_impls/dynamic/prefix.rs
+++ b/vendor/gix-odb/src/store_impls/dynamic/prefix.rs
@@ -40,13 +40,13 @@ pub mod disambiguate {
/// matching this prefix.
pub fn new(id: impl Into<gix_hash::ObjectId>, hex_len: usize) -> Result<Self, gix_hash::prefix::Error> {
let id = id.into();
- gix_hash::Prefix::new(id, hex_len)?;
+ gix_hash::Prefix::new(&id, hex_len)?;
Ok(Candidate { id, hex_len })
}
/// Transform ourselves into a `Prefix` with our current hex lengths.
pub fn to_prefix(&self) -> gix_hash::Prefix {
- gix_hash::Prefix::new(self.id, self.hex_len).expect("our hex-len to always be in bounds")
+ gix_hash::Prefix::new(&self.id, self.hex_len).expect("our hex-len to always be in bounds")
}
pub(crate) fn inc_hex_len(&mut self) {
@@ -85,6 +85,7 @@ where
match *count {
Some(count) => Ok(count),
None => {
+ let _span = gix_features::trace::detail!("gix_odb::Handle::packed_object_count()");
let mut snapshot = self.snapshot.borrow_mut();
*snapshot = self.store.load_all_indices()?;
let mut obj_count = 0;
diff --git a/vendor/gix-odb/src/store_impls/dynamic/structure.rs b/vendor/gix-odb/src/store_impls/dynamic/structure.rs
index 687e74d6a..8e5adc23c 100644
--- a/vendor/gix-odb/src/store_impls/dynamic/structure.rs
+++ b/vendor/gix-odb/src/store_impls/dynamic/structure.rs
@@ -52,6 +52,7 @@ impl Store {
/// implementation. The likelihood of actual changes is low though as these still depend on something
/// changing on disk and somebody reading at the same time.
pub fn structure(&self) -> Result<Vec<Record>, load_index::Error> {
+ let _span = gix_features::trace::detail!("gix_odb::Store::structure()");
let index = self.index.load();
if !index.is_initialized() {
self.consolidate_with_disk_state(true, false /*load one new index*/)?;
diff --git a/vendor/gix-odb/src/store_impls/dynamic/types.rs b/vendor/gix-odb/src/store_impls/dynamic/types.rs
index c77cf2109..473c587bb 100644
--- a/vendor/gix-odb/src/store_impls/dynamic/types.rs
+++ b/vendor/gix-odb/src/store_impls/dynamic/types.rs
@@ -305,7 +305,7 @@ impl IndexAndPacks {
match self {
Self::Index(bundle) => bundle.index.is_disposable() || bundle.data.is_disposable(),
Self::MultiIndex(bundle) => {
- bundle.multi_index.is_disposable() || bundle.data.iter().any(|odf| odf.is_disposable())
+ bundle.multi_index.is_disposable() || bundle.data.iter().any(OnDiskFile::is_disposable)
}
}
}
diff --git a/vendor/gix-odb/src/store_impls/dynamic/verify.rs b/vendor/gix-odb/src/store_impls/dynamic/verify.rs
index 5156074ac..94a916b98 100644
--- a/vendor/gix-odb/src/store_impls/dynamic/verify.rs
+++ b/vendor/gix-odb/src/store_impls/dynamic/verify.rs
@@ -4,7 +4,7 @@ use std::{
time::Instant,
};
-use gix_features::progress::{MessageLevel, Progress};
+use gix_features::progress::{DynNestedProgress, MessageLevel, Progress};
use crate::{
pack,
@@ -73,13 +73,11 @@ pub mod integrity {
}
/// Returned by [`Store::verify_integrity()`][crate::Store::verify_integrity()].
- pub struct Outcome<P> {
+ pub struct Outcome {
/// Statistics for validated loose object stores.
pub loose_object_stores: Vec<LooseObjectStatistics>,
/// Pack traversal statistics for each index and their pack(s)
pub index_statistics: Vec<IndexStatistics>,
- /// The provided progress instance.
- pub progress: P,
}
/// The progress ids used in [`Store::verify_integrity()`][crate::Store::verify_integrity()].
@@ -111,17 +109,17 @@ impl super::Store {
///
/// Note that this will not force loading all indices or packs permanently, as we will only use the momentarily loaded disk state.
/// This does, however, include all alternates.
- pub fn verify_integrity<C, P, F>(
+ pub fn verify_integrity<C, F>(
&self,
- mut progress: P,
+ progress: &mut dyn DynNestedProgress,
should_interrupt: &AtomicBool,
options: integrity::Options<F>,
- ) -> Result<integrity::Outcome<P>, integrity::Error>
+ ) -> Result<integrity::Outcome, integrity::Error>
where
- P: Progress,
C: pack::cache::DecodeEntry,
F: Fn() -> C + Send + Clone,
{
+ let _span = gix_features::trace::coarse!("gix_odb:Store::verify_integrity()");
let mut index = self.index.load();
if !index.is_initialized() {
self.consolidate_with_disk_state(true, false)?;
@@ -141,126 +139,131 @@ impl super::Store {
format!(
"Checking integrity: {}",
path.file_name()
- .map_or_else(std::borrow::Cow::default, |f| f.to_string_lossy())
+ .map_or_else(Default::default, std::ffi::OsStr::to_string_lossy)
)
};
- for slot_index in &index.slot_indices {
- let slot = &self.files[*slot_index];
- if slot.generation.load(Ordering::SeqCst) != index.generation {
- return Err(integrity::Error::NeedsRetryDueToChangeOnDisk);
- }
- let files = slot.files.load();
- let files = Option::as_ref(&files).ok_or(integrity::Error::NeedsRetryDueToChangeOnDisk)?;
+ gix_features::trace::detail!("verify indices").into_scope(|| {
+ for slot_index in &index.slot_indices {
+ let slot = &self.files[*slot_index];
+ if slot.generation.load(Ordering::SeqCst) != index.generation {
+ return Err(integrity::Error::NeedsRetryDueToChangeOnDisk);
+ }
+ let files = slot.files.load();
+ let files = Option::as_ref(&files).ok_or(integrity::Error::NeedsRetryDueToChangeOnDisk)?;
- let start = Instant::now();
- let (mut child_progress, num_objects, index_path) = match files {
- IndexAndPacks::Index(bundle) => {
- let index;
- let index = match bundle.index.loaded() {
- Some(index) => index.deref(),
- None => {
- index = pack::index::File::at(bundle.index.path(), self.object_hash)?;
- &index
- }
- };
- let pack;
- let data = match bundle.data.loaded() {
- Some(pack) => pack.deref(),
- None => {
- pack = pack::data::File::at(bundle.data.path(), self.object_hash)?;
- &pack
- }
- };
- let outcome = index.verify_integrity(
- Some(pack::index::verify::PackContext {
- data,
- options: options.clone(),
- }),
- progress.add_child_with_id(
- "verify index",
+ let start = Instant::now();
+ let (mut child_progress, num_objects, index_path) = match files {
+ IndexAndPacks::Index(bundle) => {
+ let index;
+ let index = match bundle.index.loaded() {
+ Some(index) => index.deref(),
+ None => {
+ index = pack::index::File::at(bundle.index.path(), self.object_hash)?;
+ &index
+ }
+ };
+ let pack;
+ let data = match bundle.data.loaded() {
+ Some(pack) => pack.deref(),
+ None => {
+ pack = pack::data::File::at(bundle.data.path(), self.object_hash)?;
+ &pack
+ }
+ };
+ let mut child_progress = progress.add_child_with_id(
+ "verify index".into(),
integrity::ProgressId::VerifyIndex(Default::default()).into(),
- ),
- should_interrupt,
- )?;
- statistics.push(IndexStatistics {
- path: bundle.index.path().to_owned(),
- statistics: SingleOrMultiStatistics::Single(
- outcome
- .pack_traverse_statistics
- .expect("pack provided so there are stats"),
- ),
- });
- (outcome.progress, index.num_objects(), index.path().to_owned())
- }
- IndexAndPacks::MultiIndex(bundle) => {
- let index;
- let index = match bundle.multi_index.loaded() {
- Some(index) => index.deref(),
- None => {
- index = pack::multi_index::File::at(bundle.multi_index.path())?;
- &index
- }
- };
- let outcome = index.verify_integrity(
- progress.add_child_with_id(
- "verify multi-index",
+ );
+ let outcome = index.verify_integrity(
+ Some(pack::index::verify::PackContext {
+ data,
+ options: options.clone(),
+ }),
+ &mut child_progress,
+ should_interrupt,
+ )?;
+ statistics.push(IndexStatistics {
+ path: bundle.index.path().to_owned(),
+ statistics: SingleOrMultiStatistics::Single(
+ outcome
+ .pack_traverse_statistics
+ .expect("pack provided so there are stats"),
+ ),
+ });
+ (child_progress, index.num_objects(), index.path().to_owned())
+ }
+ IndexAndPacks::MultiIndex(bundle) => {
+ let index;
+ let index = match bundle.multi_index.loaded() {
+ Some(index) => index.deref(),
+ None => {
+ index = pack::multi_index::File::at(bundle.multi_index.path())?;
+ &index
+ }
+ };
+ let mut child_progress = progress.add_child_with_id(
+ "verify multi-index".into(),
integrity::ProgressId::VerifyMultiIndex(Default::default()).into(),
- ),
- should_interrupt,
- options.clone(),
- )?;
+ );
+ let outcome = index.verify_integrity(&mut child_progress, should_interrupt, options.clone())?;
- let index_dir = bundle.multi_index.path().parent().expect("file in a directory");
- statistics.push(IndexStatistics {
- path: Default::default(),
- statistics: SingleOrMultiStatistics::Multi(
- outcome
- .pack_traverse_statistics
- .into_iter()
- .zip(index.index_names())
- .map(|(statistics, index_name)| (index_dir.join(index_name), statistics))
- .collect(),
- ),
- });
- (outcome.progress, index.num_objects(), index.path().to_owned())
- }
- };
+ let index_dir = bundle.multi_index.path().parent().expect("file in a directory");
+ statistics.push(IndexStatistics {
+ path: Default::default(),
+ statistics: SingleOrMultiStatistics::Multi(
+ outcome
+ .pack_traverse_statistics
+ .into_iter()
+ .zip(index.index_names())
+ .map(|(statistics, index_name)| (index_dir.join(index_name), statistics))
+ .collect(),
+ ),
+ });
+ (child_progress, index.num_objects(), index.path().to_owned())
+ }
+ };
- child_progress.set_name(index_check_message(&index_path));
- child_progress.show_throughput_with(
- start,
- num_objects as usize,
- gix_features::progress::count("objects").expect("set"),
- MessageLevel::Success,
- );
- progress.inc();
- }
+ child_progress.set_name(index_check_message(&index_path));
+ child_progress.show_throughput_with(
+ start,
+ num_objects as usize,
+ gix_features::progress::count("objects").expect("set"),
+ MessageLevel::Success,
+ );
+ progress.inc();
+ }
+ Ok(())
+ })?;
progress.init(
Some(index.loose_dbs.len()),
gix_features::progress::count("loose object stores"),
);
let mut loose_object_stores = Vec::new();
- for loose_db in &*index.loose_dbs {
- let out = loose_db
- .verify_integrity(
- progress.add_child_with_id(
- loose_db.path().display().to_string(),
- integrity::ProgressId::VerifyLooseObjectDbPath.into(),
- ),
- should_interrupt,
- )
- .map(|statistics| integrity::LooseObjectStatistics {
- path: loose_db.path().to_owned(),
- statistics,
- })?;
- loose_object_stores.push(out);
- }
+ gix_features::trace::detail!("verify loose ODBs").into_scope(
+ || -> Result<_, crate::loose::verify::integrity::Error> {
+ for loose_db in &*index.loose_dbs {
+ let out = loose_db
+ .verify_integrity(
+ &mut progress.add_child_with_id(
+ loose_db.path().display().to_string(),
+ integrity::ProgressId::VerifyLooseObjectDbPath.into(),
+ ),
+ should_interrupt,
+ )
+ .map(|statistics| integrity::LooseObjectStatistics {
+ path: loose_db.path().to_owned(),
+ statistics,
+ })?;
+ loose_object_stores.push(out);
+ }
+ Ok(())
+ },
+ )?;
Ok(integrity::Outcome {
loose_object_stores,
index_statistics: statistics,
- progress,
})
}
}
diff --git a/vendor/gix-odb/src/store_impls/dynamic/write.rs b/vendor/gix-odb/src/store_impls/dynamic/write.rs
index a2e40eec4..ba615f351 100644
--- a/vendor/gix-odb/src/store_impls/dynamic/write.rs
+++ b/vendor/gix-odb/src/store_impls/dynamic/write.rs
@@ -28,16 +28,15 @@ impl<S> crate::Write for store::Handle<S>
where
S: Deref<Target = dynamic::Store> + Clone,
{
- type Error = Error;
-
- fn write_stream(&self, kind: Kind, size: u64, from: impl Read) -> Result<ObjectId, Self::Error> {
+ fn write_stream(&self, kind: Kind, size: u64, from: &mut dyn Read) -> Result<ObjectId, crate::write::Error> {
let mut snapshot = self.snapshot.borrow_mut();
Ok(match snapshot.loose_dbs.first() {
Some(ldb) => ldb.write_stream(kind, size, from)?,
None => {
let new_snapshot = self
.store
- .load_one_index(self.refresh, snapshot.marker)?
+ .load_one_index(self.refresh, snapshot.marker)
+ .map_err(Box::new)?
.expect("there is always at least one ODB, and this code runs only once for initialization");
*snapshot = new_snapshot;
snapshot.loose_dbs[0].write_stream(kind, size, from)?
diff --git a/vendor/gix-odb/src/store_impls/loose/find.rs b/vendor/gix-odb/src/store_impls/loose/find.rs
index 04fabe61b..91bf0ba87 100644
--- a/vendor/gix-odb/src/store_impls/loose/find.rs
+++ b/vendor/gix-odb/src/store_impls/loose/find.rs
@@ -34,9 +34,9 @@ impl Store {
const OPEN_ACTION: &'static str = "open";
/// Returns true if the given id is contained in our repository.
- pub fn contains(&self, id: impl AsRef<gix_hash::oid>) -> bool {
- debug_assert_eq!(self.object_hash, id.as_ref().kind());
- hash_path(id.as_ref(), self.path.clone()).is_file()
+ pub fn contains(&self, id: &gix_hash::oid) -> bool {
+ debug_assert_eq!(self.object_hash, id.kind());
+ hash_path(id, self.path.clone()).is_file()
}
/// Given a `prefix`, find an object that matches it uniquely within this loose object
@@ -56,7 +56,7 @@ impl Store {
) -> Result<Option<crate::store::prefix::lookup::Outcome>, crate::loose::iter::Error> {
let single_directory_iter = crate::loose::Iter {
inner: gix_features::fs::walkdir_new(
- self.path.join(prefix.as_oid().to_hex_with_len(2).to_string()),
+ &self.path.join(prefix.as_oid().to_hex_with_len(2).to_string()),
gix_features::fs::walkdir::Parallelism::Serial,
)
.min_depth(1)
@@ -108,11 +108,11 @@ impl Store {
/// there was no such object.
pub fn try_find<'a>(
&self,
- id: impl AsRef<gix_hash::oid>,
+ id: &gix_hash::oid,
out: &'a mut Vec<u8>,
) -> Result<Option<gix_object::Data<'a>>, Error> {
- debug_assert_eq!(self.object_hash, id.as_ref().kind());
- match self.find_inner(id.as_ref(), out) {
+ debug_assert_eq!(self.object_hash, id.kind());
+ match self.find_inner(id, out) {
Ok(obj) => Ok(Some(obj)),
Err(err) => match err {
Error::Io {
@@ -137,10 +137,10 @@ impl Store {
/// Return only the decompressed size of the object and its kind without fully reading it into memory as tuple of `(size, kind)`.
/// Returns `None` if `id` does not exist in the database.
- pub fn try_header(&self, id: impl AsRef<gix_hash::oid>) -> Result<Option<(usize, gix_object::Kind)>, Error> {
+ pub fn try_header(&self, id: &gix_hash::oid) -> Result<Option<(usize, gix_object::Kind)>, Error> {
const BUF_SIZE: usize = 256;
let mut buf = [0_u8; BUF_SIZE];
- let path = hash_path(id.as_ref(), self.path.clone());
+ let path = hash_path(id, self.path.clone());
let mut inflate = zlib::Inflate::default();
let mut istream = match fs::File::open(&path) {
diff --git a/vendor/gix-odb/src/store_impls/loose/verify.rs b/vendor/gix-odb/src/store_impls/loose/verify.rs
index 8ffbb7105..ae83c1d01 100644
--- a/vendor/gix-odb/src/store_impls/loose/verify.rs
+++ b/vendor/gix-odb/src/store_impls/loose/verify.rs
@@ -3,7 +3,7 @@ use std::{
time::Instant,
};
-use gix_features::progress::Progress;
+use gix_features::progress::{Count, DynNestedProgress, Progress};
use crate::{loose::Store, Write};
@@ -61,7 +61,7 @@ impl Store {
/// Check all loose objects for their integrity checking their hash matches the actual data and by decoding them fully.
pub fn verify_integrity(
&self,
- mut progress: impl Progress,
+ progress: &mut dyn DynNestedProgress,
should_interrupt: &AtomicBool,
) -> Result<integrity::Statistics, integrity::Error> {
let mut buf = Vec::new();
@@ -69,11 +69,11 @@ impl Store {
let mut num_objects = 0;
let start = Instant::now();
- let mut progress = progress.add_child_with_id("Validating", integrity::ProgressId::LooseObjects.into());
+ let mut progress = progress.add_child_with_id("Validating".into(), integrity::ProgressId::LooseObjects.into());
progress.init(None, gix_features::progress::count("loose objects"));
for id in self.iter().filter_map(Result::ok) {
let object = self
- .try_find(id, &mut buf)
+ .try_find(&id, &mut buf)
.map_err(|_| integrity::Error::Retry)?
.ok_or(integrity::Error::Retry)?;
let actual_id = sink.write_buf(object.kind, object.data).expect("sink never fails");
diff --git a/vendor/gix-odb/src/store_impls/loose/write.rs b/vendor/gix-odb/src/store_impls/loose/write.rs
index 912426bba..e537eda92 100644
--- a/vendor/gix-odb/src/store_impls/loose/write.rs
+++ b/vendor/gix-odb/src/store_impls/loose/write.rs
@@ -27,9 +27,7 @@ pub enum Error {
}
impl crate::traits::Write for Store {
- type Error = Error;
-
- fn write(&self, object: impl WriteTo) -> Result<gix_hash::ObjectId, Self::Error> {
+ fn write(&self, object: &dyn WriteTo) -> Result<gix_hash::ObjectId, crate::write::Error> {
let mut to = self.dest()?;
to.write_all(&object.loose_header()).map_err(|err| Error::Io {
source: err,
@@ -41,15 +39,15 @@ impl crate::traits::Write for Store {
message: "stream all data into tempfile in",
path: self.path.to_owned(),
})?;
- to.flush()?;
- self.finalize_object(to)
+ to.flush().map_err(Box::new)?;
+ Ok(self.finalize_object(to).map_err(Box::new)?)
}
/// Write the given buffer in `from` to disk in one syscall at best.
///
/// This will cost at least 4 IO operations.
- fn write_buf(&self, kind: gix_object::Kind, from: &[u8]) -> Result<gix_hash::ObjectId, Self::Error> {
- let mut to = self.dest()?;
+ fn write_buf(&self, kind: gix_object::Kind, from: &[u8]) -> Result<gix_hash::ObjectId, crate::write::Error> {
+ let mut to = self.dest().map_err(Box::new)?;
to.write_all(&gix_object::encode::loose_header(kind, from.len()))
.map_err(|err| Error::Io {
source: err,
@@ -63,7 +61,7 @@ impl crate::traits::Write for Store {
path: self.path.to_owned(),
})?;
to.flush()?;
- self.finalize_object(to)
+ Ok(self.finalize_object(to)?)
}
/// Write the given stream in `from` to disk with at least one syscall.
@@ -73,9 +71,9 @@ impl crate::traits::Write for Store {
&self,
kind: gix_object::Kind,
size: u64,
- mut from: impl io::Read,
- ) -> Result<gix_hash::ObjectId, Self::Error> {
- let mut to = self.dest()?;
+ mut from: &mut dyn io::Read,
+ ) -> Result<gix_hash::ObjectId, crate::write::Error> {
+ let mut to = self.dest().map_err(Box::new)?;
to.write_all(&gix_object::encode::loose_header(
kind,
size.try_into().expect("object size to fit into usize"),
@@ -86,13 +84,15 @@ impl crate::traits::Write for Store {
path: self.path.to_owned(),
})?;
- io::copy(&mut from, &mut to).map_err(|err| Error::Io {
- source: err,
- message: "stream all data into tempfile in",
- path: self.path.to_owned(),
- })?;
- to.flush()?;
- self.finalize_object(to)
+ io::copy(&mut from, &mut to)
+ .map_err(|err| Error::Io {
+ source: err,
+ message: "stream all data into tempfile in",
+ path: self.path.to_owned(),
+ })
+ .map_err(Box::new)?;
+ to.flush().map_err(Box::new)?;
+ Ok(self.finalize_object(to)?)
}
}