1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-22 14:52:40 +01:00

Parallelize calls for ArcanistGitAPI::getWorkingCopyStatus

Summary:
executes the calls to git in parallel to improve startup performance of
arc lint and possibly other commands

Gets about a 2~3x speedup when repo is in buffer cache, with 4 cores.

Test Plan:
arc linted a repo with unstaged, untracked, staged, and committed
changes, see that the same files were linted.

Reviewed By: jungejason
Reviewers: jungejason, epriestley
Commenters: epriestley
CC: aran, jungejason, epriestley
Differential Revision: 594
This commit is contained in:
Yiding Jia 2011-07-05 11:06:46 -07:00
parent 2aa853f85c
commit 88c4e69802
2 changed files with 36 additions and 14 deletions

View file

@ -183,17 +183,47 @@ class ArcanistGitAPI extends ArcanistRepositoryAPI {
$options = $this->getDiffBaseOptions(); $options = $this->getDiffBaseOptions();
// -- parallelize these slow cpu bound git calls.
// Find committed changes. // Find committed changes.
list($stdout) = execx( $committed_future = new ExecFuture(
"(cd %s; git diff {$options} --raw %s --)", "(cd %s; git diff {$options} --raw %s --)",
$this->getPath(), $this->getPath(),
$this->getRelativeCommit()); $this->getRelativeCommit());
$files = $this->parseGitStatus($stdout);
// Find uncommitted changes. // Find uncommitted changes.
list($stdout) = execx( $uncommitted_future = new ExecFuture(
"(cd %s; git diff {$options} --raw HEAD --)", "(cd %s; git diff {$options} --raw HEAD --)",
$this->getPath()); $this->getPath());
// Untracked files
$untracked_future = new ExecFuture(
'(cd %s; git ls-files --others --exclude-standard)',
$this->getPath());
// TODO: This doesn't list unstaged adds. It's not clear how to get that
// list other than "git status --porcelain" and then parsing it. :/
// Unstaged changes
$unstaged_future = new ExecFuture(
'(cd %s; git ls-files -m)',
$this->getPath());
$futures = array(
$committed_future,
$uncommitted_future,
$untracked_future,
$unstaged_future
);
Futures($futures)->resolveAll();
// -- read back and process the results
list($stdout, $stderr) = $committed_future->resolvex();
$files = $this->parseGitStatus($stdout);
list($stdout, $stderr) = $uncommitted_future->resolvex();
$uncommitted_files = $this->parseGitStatus($stdout); $uncommitted_files = $this->parseGitStatus($stdout);
foreach ($uncommitted_files as $path => $mask) { foreach ($uncommitted_files as $path => $mask) {
$mask |= self::FLAG_UNCOMMITTED; $mask |= self::FLAG_UNCOMMITTED;
@ -203,10 +233,7 @@ class ArcanistGitAPI extends ArcanistRepositoryAPI {
$files[$path] |= $mask; $files[$path] |= $mask;
} }
// Find untracked files. list($stdout, $stderr) = $untracked_future->resolvex();
list($stdout) = execx(
'(cd %s; git ls-files --others --exclude-standard)',
$this->getPath());
$stdout = rtrim($stdout, "\n"); $stdout = rtrim($stdout, "\n");
if (strlen($stdout)) { if (strlen($stdout)) {
$stdout = explode("\n", $stdout); $stdout = explode("\n", $stdout);
@ -215,13 +242,7 @@ class ArcanistGitAPI extends ArcanistRepositoryAPI {
} }
} }
// TODO: This doesn't list unstaged adds. It's not clear how to get that list($stdout, $stderr) = $unstaged_future->resolvex();
// list other than "git status --porcelain" and then parsing it. :/
// Find unstaged changes.
list($stdout) = execx(
'(cd %s; git ls-files -m)',
$this->getPath());
$stdout = rtrim($stdout, "\n"); $stdout = rtrim($stdout, "\n");
if (strlen($stdout)) { if (strlen($stdout)) {
$stdout = explode("\n", $stdout); $stdout = explode("\n", $stdout);

View file

@ -8,6 +8,7 @@
phutil_require_module('arcanist', 'repository/api/base'); phutil_require_module('arcanist', 'repository/api/base');
phutil_require_module('phutil', 'future');
phutil_require_module('phutil', 'future/exec'); phutil_require_module('phutil', 'future/exec');
phutil_require_module('phutil', 'utils'); phutil_require_module('phutil', 'utils');