Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8cbe85d

Browse files
committed
add thread-count and chunk-size computation; interrupt capability (#301)
1 parent 8945d95 commit 8cbe85d

6 files changed

Lines changed: 25 additions & 4 deletions

File tree

git-features/src/parallel/reduce.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ mod stepped {
1010
receive_result: std::sync::mpsc::Receiver<Reduce::Input>,
1111
/// `join()` will be called on these guards to assure every thread tries to send through a closed channel. When
1212
/// that happens, they break out of their loops.
13-
_threads: Vec<std::thread::JoinHandle<()>>,
13+
threads: Vec<std::thread::JoinHandle<()>>,
1414
/// The reducer is called only in the thread using the iterator, dropping it has no side effects.
1515
reducer: Option<Reduce>,
1616
}
@@ -21,7 +21,7 @@ mod stepped {
2121
drop(std::mem::replace(&mut self.receive_result, sink));
2222

2323
let mut last_err = None;
24-
for handle in std::mem::take(&mut self._threads) {
24+
for handle in std::mem::take(&mut self.threads) {
2525
if let Err(err) = handle.join() {
2626
last_err = Some(err);
2727
};
@@ -82,7 +82,7 @@ mod stepped {
8282
receive_result
8383
};
8484
Stepwise {
85-
_threads: threads,
85+
threads,
8686
receive_result,
8787
reducer: Some(reducer),
8888
}

git-worktree/src/index/checkout.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ pub struct Outcome {
164164
pub struct Options {
165165
/// capabilities of the file system
166166
pub fs: crate::fs::Capabilities,
167+
/// If set, don't use more than this amount of threads.
168+
/// Otherwise, usually use as many threads as there are logical cores.
169+
/// A value of 0 is interpreted as no-limit
170+
pub thread_limit: Option<usize>,
167171
/// If true, we assume no file to exist in the target directory, and want exclusive access to it.
168172
/// This should be enabled when cloning to avoid checks for freshness of files. This also enables
169173
/// detection of collisions based on whether or not exclusive file creation succeeds or fails.
@@ -194,6 +198,7 @@ impl Default for Options {
194198
fn default() -> Self {
195199
Options {
196200
fs: Default::default(),
201+
thread_limit: None,
197202
destination_is_initially_empty: false,
198203
keep_going: false,
199204
trust_ctime: true,

git-worktree/src/index/mod.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use bstr::BStr;
2+
use git_features::interrupt;
23
use git_features::progress::Progress;
34
use git_hash::oid;
5+
use std::sync::atomic::AtomicBool;
46

57
use crate::index::checkout::{ErrorRecord, PathCache};
68
use crate::{index, os};
@@ -14,6 +16,7 @@ pub fn checkout<Find, E>(
1416
find: Find,
1517
files: &mut impl Progress,
1618
bytes: &mut impl Progress,
19+
should_interrupt: &AtomicBool,
1720
options: checkout::Options,
1821
) -> Result<checkout::Outcome, checkout::Error<E>>
1922
where
@@ -35,8 +38,14 @@ where
3538
find,
3639
options,
3740
};
41+
let (chunk_size, _, num_threads) = git_features::parallel::optimize_chunk_size_and_thread_limit(
42+
100,
43+
index.entries().len().into(),
44+
options.thread_limit,
45+
None,
46+
);
3847

39-
for (entry, entry_path) in index.entries_mut_with_paths() {
48+
for (entry, entry_path) in interrupt::Iter::new(index.entries_mut_with_paths(), should_interrupt) {
4049
// TODO: write test for that
4150
if entry.flags.contains(git_index::entry::Flags::SKIP_WORKTREE) {
4251
ctx.files.inc();

git-worktree/tests/index/checkout.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ use git_object::bstr::ByteSlice;
109109
use git_odb::FindExt;
110110
use git_worktree::{fs::Capabilities, index, index::checkout::Collision};
111111
use std::io::ErrorKind::AlreadyExists;
112+
use std::sync::atomic::AtomicBool;
112113
use tempfile::TempDir;
113114

114115
use crate::fixture_path;
@@ -468,6 +469,7 @@ fn checkout_index_in_tmp_dir_opts(
468469
},
469470
&mut progress::Discard,
470471
&mut progress::Discard,
472+
&AtomicBool::default(),
471473
opts,
472474
)?;
473475
Ok((source_tree, destination, index, outcome))

gitoxide-core/src/index/checkout.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ use anyhow::bail;
44
use git::{odb::FindExt, worktree::index::checkout, Progress};
55
use git_repository as git;
66
use std::path::{Path, PathBuf};
7+
use std::sync::atomic::AtomicBool;
78

89
pub fn checkout_exclusive(
910
index_path: impl AsRef<Path>,
1011
dest_directory: impl AsRef<Path>,
1112
repo: Option<PathBuf>,
1213
mut err: impl std::io::Write,
1314
mut progress: impl Progress,
15+
should_interrupt: &AtomicBool,
1416
index::checkout_exclusive::Options {
1517
index: Options { object_hash, .. },
1618
empty_files,
@@ -84,6 +86,7 @@ pub fn checkout_exclusive(
8486
},
8587
&mut files,
8688
&mut bytes,
89+
should_interrupt,
8790
opts,
8891
),
8992
None => git::worktree::index::checkout(
@@ -95,6 +98,7 @@ pub fn checkout_exclusive(
9598
},
9699
&mut files,
97100
&mut bytes,
101+
should_interrupt,
98102
opts,
99103
),
100104
}?;

src/plumbing/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ pub fn main() -> Result<()> {
9797
repository,
9898
err,
9999
progress,
100+
&should_interrupt,
100101
core::index::checkout_exclusive::Options {
101102
index: core::index::Options { object_hash, format },
102103
empty_files,

0 commit comments

Comments
 (0)