1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-18 21:02:41 +01:00

Batch execution of LastModified query

Summary:
Ref T2683. Further reduces query count of last modified loads; we're now at 11 instead of 200+.

(This works in SVN but could be further optimized.)

Test Plan:
Loaded SVN, Mercurial, Git:

{F34864}
{F34865}
{F34866}

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley, vrana, aran

Maniphest Tasks: T2683

Differential Revision: https://secure.phabricator.com/D5256
This commit is contained in:
epriestley 2014-05-10 16:46:32 -07:00
parent e03deb7d4a
commit e34ee684e1
4 changed files with 91 additions and 122 deletions

View file

@ -30,7 +30,8 @@ final class ConduitAPI_diffusion_diffquery_Method
return array( return array(
'changes' => mpull($result, 'toDictionary'), 'changes' => mpull($result, 'toDictionary'),
'effectiveCommit' => $this->getEffectiveCommit($request)); 'effectiveCommit' => $this->getEffectiveCommit($request),
);
} }
protected function getGitResult(ConduitAPIRequest $request) { protected function getGitResult(ConduitAPIRequest $request) {
@ -160,26 +161,19 @@ final class ConduitAPI_diffusion_diffquery_Method
private function getEffectiveCommit(ConduitAPIRequest $request) { private function getEffectiveCommit(ConduitAPIRequest $request) {
if ($this->effectiveCommit === null) { if ($this->effectiveCommit === null) {
$drequest = $this->getDiffusionRequest(); $drequest = $this->getDiffusionRequest();
$user = $request->getUser();
$commit = null;
$conduit_result = DiffusionQuery::callConduitWithDiffusionRequest( $path = $drequest->getPath();
$user, $result = DiffusionQuery::callConduitWithDiffusionRequest(
$request->getUser(),
$drequest, $drequest,
'diffusion.lastmodifiedquery', 'diffusion.lastmodifiedquery',
array( array(
'commit' => $drequest->getCommit(), 'paths' => array($path => $drequest->getCommit()),
'path' => $drequest->getPath())); ));
$c_dict = $conduit_result['commit'];
if ($c_dict) { $this->effectiveCommit = idx($result, $path);
$commit = PhabricatorRepositoryCommit::newFromDictionary($c_dict);
}
if (!$commit) {
// TODO: Improve error messages here.
return null;
}
$this->effectiveCommit = $commit->getCommitIdentifier();
} }
return $this->effectiveCommit; return $this->effectiveCommit;
} }

View file

@ -1,115 +1,84 @@
<?php <?php
/**
* @group conduit
*/
final class ConduitAPI_diffusion_lastmodifiedquery_Method final class ConduitAPI_diffusion_lastmodifiedquery_Method
extends ConduitAPI_diffusion_abstractquery_Method { extends ConduitAPI_diffusion_abstractquery_Method {
public function getMethodDescription() { public function getMethodDescription() {
return return pht('Get the commits at which paths were last modified.');
'Get last modified information from a repository for a specific commit '.
'at a specific path.';
} }
public function defineReturnType() { public function defineReturnType() {
return 'array'; return 'map<string, string>';
} }
protected function defineCustomParamTypes() { protected function defineCustomParamTypes() {
return array( return array(
'commit' => 'required string', 'paths' => 'required map<string, string>',
'path' => 'required string',
); );
} }
protected function getResult(ConduitAPIRequest $request) {
list($commit, $commit_data) = parent::getResult($request);
if ($commit) {
$commit = $commit->toDictionary();
}
if ($commit_data) {
$commit_data = $commit_data->toDictionary();
}
return array(
'commit' => $commit,
'commitData' => $commit_data);
}
protected function getGitResult(ConduitAPIRequest $request) { protected function getGitResult(ConduitAPIRequest $request) {
$drequest = $this->getDiffusionRequest(); $drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository(); $repository = $drequest->getRepository();
list($hash) = $repository->execxLocalCommand( $result = array();
'log -n1 --format=%%H %s -- %s', foreach ($request->getValue('paths') as $path => $commit) {
$drequest->getCommit(), list($hash) = $repository->execxLocalCommand(
$drequest->getPath()); 'log -n1 --format=%%H %s -- %s',
$hash = trim($hash); $commit,
$path);
$result[$path] = trim($hash);
}
return $this->loadDataFromHash($hash); return $result;
} }
protected function getSVNResult(ConduitAPIRequest $request) { protected function getSVNResult(ConduitAPIRequest $request) {
$drequest = $this->getDiffusionRequest(); $drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository(); $repository = $drequest->getRepository();
$path = $drequest->getPath(); $result = array();
foreach ($request->getValue('paths') as $path => $commit) {
$history_result = DiffusionQuery::callConduitWithDiffusionRequest(
$request->getUser(),
$drequest,
'diffusion.historyquery',
array(
'commit' => $commit,
'path' => $path,
'limit' => 1,
'offset' => 0,
'needDirectChanges' => true,
'needChildChanges' => true,
));
$history_result = DiffusionQuery::callConduitWithDiffusionRequest( $history_array = DiffusionPathChange::newFromConduit(
$request->getUser(), $history_result['pathChanges']);
$drequest, if ($history_array) {
'diffusion.historyquery', $result[$path] = head($history_array)
array( ->getCommit()
'commit' => $drequest->getCommit(), ->getCommitIdentifier();
'path' => $path, }
'limit' => 1,
'offset' => 0,
'needDirectChanges' => true,
'needChildChanges' => true));
$history_array = DiffusionPathChange::newFromConduit(
$history_result['pathChanges']);
if (!$history_array) {
return array(array(), array());
} }
$history = reset($history_array); return $result;
return array($history->getCommit(), $history->getCommitData());
} }
protected function getMercurialResult(ConduitAPIRequest $request) { protected function getMercurialResult(ConduitAPIRequest $request) {
$drequest = $this->getDiffusionRequest(); $drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository(); $repository = $drequest->getRepository();
$path = $drequest->getPath(); $result = array();
foreach ($request->getValue('paths') as $path => $commit) {
list($hash) = $repository->execxLocalCommand( list($hash) = $repository->execxLocalCommand(
'log --template %s --limit 1 --removed --rev %s -- %s', 'log --template %s --limit 1 --removed --rev %s -- %s',
'{node}', '{node}',
hgsprintf('reverse(ancestors(%s))', $drequest->getCommit()), hgsprintf('reverse(ancestors(%s))', $commit),
nonempty(ltrim($path, '/'), '.')); nonempty(ltrim($path, '/'), '.'));
$result[$path] = trim($hash);
return $this->loadDataFromHash($hash);
}
private function loadDataFromHash($hash) {
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
$commit = id(new PhabricatorRepositoryCommit())->loadOneWhere(
'repositoryID = %d AND commitIdentifier = %s',
$repository->getID(),
$hash);
if ($commit) {
$commit_data = $commit->loadCommitData();
} else {
$commit = array();
$commit_data = array();
} }
return array($commit, $commit_data); return $result;
} }
} }

View file

@ -9,6 +9,7 @@ final class DiffusionLastModifiedController extends DiffusionController {
public function processRequest() { public function processRequest() {
$drequest = $this->getDiffusionRequest(); $drequest = $this->getDiffusionRequest();
$request = $this->getRequest(); $request = $this->getRequest();
$viewer = $request->getUser();
$paths = $request->getStr('paths'); $paths = $request->getStr('paths');
$paths = json_decode($paths, true); $paths = json_decode($paths, true);
@ -16,44 +17,46 @@ final class DiffusionLastModifiedController extends DiffusionController {
return new Aphront400Response(); return new Aphront400Response();
} }
$commits = array(); $modified_map = $this->callConduitWithDiffusionRequest(
foreach ($paths as $path) { 'diffusion.lastmodifiedquery',
$prequest = clone $drequest; array(
$prequest->setPath($path); 'paths' => array_fill_keys($paths, $drequest->getCommit()),
));
$conduit_result = $this->callConduitWithDiffusionRequest( if ($modified_map) {
'diffusion.lastmodifiedquery', $commit_map = id(new DiffusionCommitQuery())
array( ->setViewer($viewer)
'commit' => $prequest->getCommit(), ->withRepository($drequest->getRepository())
'path' => $prequest->getPath(), ->withIdentifiers(array_values($modified_map))
)); ->needCommitData(true)
->execute();
$commit = PhabricatorRepositoryCommit::newFromDictionary( $commit_map = mpull($commit_map, null, 'getCommitIdentifier');
$conduit_result['commit']); } else {
$commit_map = array();
$commit_data = PhabricatorRepositoryCommitData::newFromDictionary(
$conduit_result['commitData']);
$commit->attachCommitData($commit_data);
$phids = array();
if ($commit_data) {
if ($commit_data->getCommitDetail('authorPHID')) {
$phids[$commit_data->getCommitDetail('authorPHID')] = true;
}
if ($commit_data->getCommitDetail('committerPHID')) {
$phids[$commit_data->getCommitDetail('committerPHID')] = true;
}
}
$commits[$path] = $commit;
} }
$phids = array_keys($phids); $commits = array();
foreach ($paths as $path) {
$modified_at = idx($modified_map, $path);
if ($modified_at) {
$commit = idx($commit_map, $modified_at);
if ($commit) {
$commits[$path] = $commit;
}
}
}
$phids = array();
foreach ($commits as $commit) {
$data = $commit->getCommitData();
$phids[] = $data->getCommitDetail('authorPHID');
$phids[] = $data->getCommitDetail('committerPHID');
}
$phids = array_filter($phids);
$handles = $this->loadViewerHandles($phids); $handles = $this->loadViewerHandles($phids);
$branch = $drequest->loadBranch(); $branch = $drequest->loadBranch();
if ($branch) { if ($branch && $commits) {
$lint_query = id(new DiffusionLintCountQuery()) $lint_query = id(new DiffusionLintCountQuery())
->withBranchIDs(array($branch->getID())) ->withBranchIDs(array($branch->getID()))
->withPaths(array_keys($commits)); ->withPaths(array_keys($commits));

View file

@ -250,6 +250,9 @@ final class DiffusionCommitQuery
$data = mpull($data, null, 'getCommitID'); $data = mpull($data, null, 'getCommitID');
foreach ($commits as $commit) { foreach ($commits as $commit) {
$commit_data = idx($data, $commit->getID()); $commit_data = idx($data, $commit->getID());
if (!$commit_data) {
$commit_data = new PhabricatorRepositoryCommitData();
}
$commit->attachCommitData($commit_data); $commit->attachCommitData($commit_data);
} }
} }