History

[pack] also put counts in order for stable packs

Sebastian Thiel committed 5 years ago

Commit f2991601 parent e7ecdc16 files · +35 −28Browse files

Unified · Split

6 files
  1. git-pack/src/data/output/count/from_objects_iter.rs +14 −10
  2. git-pack/src/data/output/entry/from_counts_iter.rs +5 −5
  3. git-pack/src/data/output/in_order.rs +8 −6
  4. git-pack/src/data/output/mod.rs +1 −1
  5. git-pack/tests/pack/data/output.rs +2 −2
  6. gitoxide-core/src/pack/create.rs +5 −4
git-pack/src/data/output/count/from_objects_iter.rs+14−10
@@ -1,4 +1,7 @@
1use crate::{data::output, find, FindExt};1use crate::{
2 data::{output, output::ChunkId},
3 find, FindExt,
4};
2use dashmap::DashSet;5use dashmap::DashSet;
3use git_features::{parallel, progress::Progress};6use git_features::{parallel, progress::Progress};
4use git_hash::{oid, ObjectId};7use git_hash::{oid, ObjectId};
@@ -29,7 +32,7 @@ pub fn from_objects_iter<Find, Iter, Oid, Cache>( · 24 unmodified lines
29 input_object_expansion,32 input_object_expansion,
30 chunk_size,33 chunk_size,
31 }: Options,34 }: Options,
32) -> impl Iterator<Item = Result<Vec<output::Count>, Error<find::existing::Error<Find::Error>>>>35) -> impl Iterator<Item = Result<(ChunkId, Vec<output::Count>), Error<find::existing::Error<Find::Error>>>>
33 + parallel::reduce::Finalize<Reduce = reduce::Statistics<Error<find::existing::Error<Find::Error>>>>36 + parallel::reduce::Finalize<Reduce = reduce::Statistics<Error<find::existing::Error<Find::Error>>>>
34where37where
35 Find: crate::Find + Clone + Send + Sync + 'static,38 Find: crate::Find + Clone + Send + Sync + 'static,
@@ -48,7 +51,8 @@ where · 12 unmodified lines
48 let chunks = util::Chunks {51 let chunks = util::Chunks {
49 iter: objects,52 iter: objects,
50 size: chunk_size,53 size: chunk_size,
51 };54 }
55 .enumerate();
52 let seen_objs = Arc::new(dashmap::DashSet::<ObjectId>::new());56 let seen_objs = Arc::new(dashmap::DashSet::<ObjectId>::new());
53 let progress = Arc::new(parking_lot::Mutex::new(progress));57 let progress = Arc::new(parking_lot::Mutex::new(progress));
54 58
@@ -72,7 +76,7 @@ where · 17 unmodified lines
72 },76 },
73 {77 {
74 let seen_objs = Arc::clone(&seen_objs);78 let seen_objs = Arc::clone(&seen_objs);
75 move |oids: Vec<Oid>, (buf1, buf2, cache, progress)| {79 move |(chunk_id, oids): (ChunkId, Vec<Oid>), (buf1, buf2, cache, progress)| {
76 use ObjectExpansion::*;80 use ObjectExpansion::*;
77 let mut out = Vec::new();81 let mut out = Vec::new();
78 let mut tree_traversal_state = git_traverse::tree::breadthfirst::State::default();82 let mut tree_traversal_state = git_traverse::tree::breadthfirst::State::default();
@@ -243,7 +247,7 @@ where · 164 unmodified lines
243 AsIs => push_obj_count_unique(&mut out, seen_objs, id, &obj, progress, stats, false),247 AsIs => push_obj_count_unique(&mut out, seen_objs, id, &obj, progress, stats, false),
244 }248 }
245 }249 }
246 Ok((out, outcome))250 Ok((chunk_id, out, outcome))
247 }251 }
248 },252 },
249 reduce::Statistics::default(),253 reduce::Statistics::default(),
@@ -525,7 +529,7 @@ pub use types::{Error, ObjectExpansion, Options, Outcome}; · 275 unmodified lines
525 529
526mod reduce {530mod reduce {
527 use super::Outcome;531 use super::Outcome;
528 use crate::data::output;532 use crate::data::{output, output::ChunkId};
529 use git_features::parallel;533 use git_features::parallel;
530 use std::marker::PhantomData;534 use std::marker::PhantomData;
531 535
@@ -544,16 +548,16 @@ mod reduce { · 12 unmodified lines
544 }548 }
545 549
546 impl<Error> parallel::Reduce for Statistics<Error> {550 impl<Error> parallel::Reduce for Statistics<Error> {
547 type Input = Result<(Vec<output::Count>, Outcome), Error>;551 type Input = Result<(ChunkId, Vec<output::Count>, Outcome), Error>;
548 type FeedProduce = Vec<output::Count>;552 type FeedProduce = (ChunkId, Vec<output::Count>);
549 type Output = Outcome;553 type Output = Outcome;
550 type Error = Error;554 type Error = Error;
551 555
552 fn feed(&mut self, item: Self::Input) -> Result<Self::FeedProduce, Self::Error> {556 fn feed(&mut self, item: Self::Input) -> Result<Self::FeedProduce, Self::Error> {
553 item.map(|(counts, mut stats)| {557 item.map(|(chunk_id, counts, mut stats)| {
554 stats.total_objects = counts.len();558 stats.total_objects = counts.len();
555 self.total.aggregate(stats);559 self.total.aggregate(stats);
556 counts560 (chunk_id, counts)
557 })561 })
558 }562 }
559 563
git-pack/src/data/output/entry/from_counts_iter.rs+5−5
@@ -1,4 +1,7 @@
1use crate::{data::output, find, FindExt};1use crate::{
2 data::{output, output::ChunkId},
3 find, FindExt,
4};
2use git_features::{parallel, progress::Progress};5use git_features::{parallel, progress::Progress};
3use std::sync::Arc;6use std::sync::Arc;
4 7
@@ -185,9 +188,6 @@ mod reduce { · 180 unmodified lines
185mod types {188mod types {
186 use crate::data::output::entry;189 use crate::data::output::entry;
187 190
188 /// A counter for chunks to be able to put them back into original order later.
189 pub type ChunkId = usize;
190
191 /// Information gathered during the run of [`from_counts_iter()`][super::from_counts_iter()].191 /// Information gathered during the run of [`from_counts_iter()`][super::from_counts_iter()].
192 #[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]192 #[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
193 #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]193 #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
@@ -248,4 +248,4 @@ mod types { · 54 unmodified lines
248 NewEntry(#[from] entry::Error),248 NewEntry(#[from] entry::Error),
249 }249 }
250}250}
251pub use types::{ChunkId, Error, Options, Outcome};251pub use types::{Error, Options, Outcome};
git-pack/src/data/output/in_order.rs+8−6
@@ -1,5 +1,7 @@
1use std::cmp::Ordering;1use std::{cmp::Ordering, collections::BTreeMap};
2use std::collections::BTreeMap;2
3/// A counter for chunks to be able to put them back into original order later.
4pub type ChunkId = usize;
3 5
4/// An iterator which olds iterated items with a **sequential** ID starting at 0 long enough to dispense them in order.6/// An iterator which olds iterated items with a **sequential** ID starting at 0 long enough to dispense them in order.
5///7///
@@ -8,14 +10,14 @@ use std::collections::BTreeMap; · 2 unmodified lines
8pub struct InOrderIter<T, I> {10pub struct InOrderIter<T, I> {
9 /// The iterator yielding the out-of-order elements we are to yield in order.11 /// The iterator yielding the out-of-order elements we are to yield in order.
10 pub inner: I,12 pub inner: I,
11 store: BTreeMap<usize, T>,13 store: BTreeMap<ChunkId, T>,
12 next_chunk: usize,14 next_chunk: ChunkId,
13 is_done: bool,15 is_done: bool,
14}16}
15 17
16impl<T, E, I> From<I> for InOrderIter<T, I>18impl<T, E, I> From<I> for InOrderIter<T, I>
17where19where
18 I: Iterator<Item = Result<(usize, T), E>>,20 I: Iterator<Item = Result<(ChunkId, T), E>>,
19{21{
20 fn from(iter: I) -> Self {22 fn from(iter: I) -> Self {
21 InOrderIter {23 InOrderIter {
@@ -29,7 +31,7 @@ where · 7 unmodified lines
29 31
30impl<T, E, I> Iterator for InOrderIter<T, I>32impl<T, E, I> Iterator for InOrderIter<T, I>
31where33where
32 I: Iterator<Item = Result<(usize, T), E>>,34 I: Iterator<Item = Result<(ChunkId, T), E>>,
33{35{
34 type Item = Result<T, E>;36 type Item = Result<T, E>;
35 37
git-pack/src/data/output/mod.rs+1−1
@@ -12,4 +12,4 @@ pub use entry::Entry; · 11 unmodified lines
12pub mod bytes;12pub mod bytes;
13 13
14mod in_order;14mod in_order;
15pub use in_order::InOrderIter;15pub use in_order::{ChunkId, InOrderIter};
git-pack/tests/pack/data/output.rs+2−2
@@ -50,6 +50,7 @@ mod count_and_entries { · 49 unmodified lines
50 data::output::{db, DbKind},50 data::output::{db, DbKind},
51 hex_to_id,51 hex_to_id,
52 };52 };
53 use git_odb::data::output::InOrderIter;
53 54
54 #[test]55 #[test]
55 fn traversals() -> crate::Result {56 fn traversals() -> crate::Result {
@@ -153,8 +154,7 @@ mod count_and_entries { · 97 unmodified lines
153 ..Default::default()154 ..Default::default()
154 },155 },
155 );156 );
156 let counts: Vec<_> = counts_iter157 let counts: Vec<_> = InOrderIter::from(counts_iter.by_ref())
157 .by_ref()
158 .collect::<Result<Vec<_>, _>>()?158 .collect::<Result<Vec<_>, _>>()?
159 .into_iter()159 .into_iter()
160 .flatten()160 .flatten()
gitoxide-core/src/pack/create.rs+5−4
@@ -1,5 +1,6 @@
1use crate::OutputFormat;1use crate::OutputFormat;
2use anyhow::bail;2use anyhow::bail;
3use git_repository::odb::data::output::InOrderIter;
3use git_repository::{4use git_repository::{
4 hash,5 hash,
5 hash::ObjectId,6 hash::ObjectId,
@@ -117,7 +118,7 @@ where · 111 unmodified lines
117 let counts = {118 let counts = {
118 let mut progress = progress.add_child("counting");119 let mut progress = progress.add_child("counting");
119 progress.init(None, progress::count("objects"));120 progress.init(None, progress::count("objects"));
120 let mut counts_iter = pack::data::output::count::from_objects_iter(121 let mut in_order_counts_iter = InOrderIter::from(pack::data::output::count::from_objects_iter(
121 Arc::clone(&db),122 Arc::clone(&db),
122 pack::cache::lru::StaticLinkedList::<64>::default,123 pack::cache::lru::StaticLinkedList::<64>::default,
123 input,124 input,
@@ -127,9 +128,9 @@ where · 3 unmodified lines
127 chunk_size,128 chunk_size,
128 input_object_expansion: expansion.into(),129 input_object_expansion: expansion.into(),
129 },130 },
130 );131 ));
131 let mut counts = Vec::new();132 let mut counts = Vec::new();
132 for c in counts_iter.by_ref() {133 for c in in_order_counts_iter.by_ref() {
133 if interrupt::is_triggered() {134 if interrupt::is_triggered() {
134 bail!("Cancelled by user")135 bail!("Cancelled by user")
135 }136 }
@@ -137,7 +138,7 @@ where · 1 unmodified line
137 progress.inc_by(c.len());138 progress.inc_by(c.len());
138 counts.extend(c.into_iter());139 counts.extend(c.into_iter());
139 }140 }
140 stats.counts = counts_iter.finalize()?;141 stats.counts = in_order_counts_iter.inner.finalize()?;
141 progress.show_throughput(start);142 progress.show_throughput(start);
142 counts.shrink_to_fit();143 counts.shrink_to_fit();
143 counts144 counts