mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Move "Affected Path" index updates to a separate class
Summary: Ref T13639. Move operations related to updating the "AffectedPath" index to a dedicated class. This change has no functional effect and only moves code. Test Plan: Used an external script to rebuild every revision index; destroyed a revision with `bin/remove destroy`. Maniphest Tasks: T13639 Differential Revision: https://secure.phabricator.com/D21616
This commit is contained in:
parent
e919b4c35a
commit
38ef910da8
4 changed files with 148 additions and 97 deletions
|
@ -450,6 +450,7 @@ phutil_register_library_map(array(
|
|||
'DifferentialActionEmailCommand' => 'applications/differential/command/DifferentialActionEmailCommand.php',
|
||||
'DifferentialAdjustmentMapTestCase' => 'applications/differential/storage/__tests__/DifferentialAdjustmentMapTestCase.php',
|
||||
'DifferentialAffectedPath' => 'applications/differential/storage/DifferentialAffectedPath.php',
|
||||
'DifferentialAffectedPathEngine' => 'applications/differential/engine/DifferentialAffectedPathEngine.php',
|
||||
'DifferentialAsanaRepresentationField' => 'applications/differential/customfield/DifferentialAsanaRepresentationField.php',
|
||||
'DifferentialAuditorsCommitMessageField' => 'applications/differential/field/DifferentialAuditorsCommitMessageField.php',
|
||||
'DifferentialAuditorsField' => 'applications/differential/customfield/DifferentialAuditorsField.php',
|
||||
|
@ -6533,6 +6534,7 @@ phutil_register_library_map(array(
|
|||
'DifferentialActionEmailCommand' => 'MetaMTAEmailTransactionCommand',
|
||||
'DifferentialAdjustmentMapTestCase' => 'PhabricatorTestCase',
|
||||
'DifferentialAffectedPath' => 'DifferentialDAO',
|
||||
'DifferentialAffectedPathEngine' => 'Phobject',
|
||||
'DifferentialAsanaRepresentationField' => 'DifferentialCustomField',
|
||||
'DifferentialAuditorsCommitMessageField' => 'DifferentialCommitMessageCustomField',
|
||||
'DifferentialAuditorsField' => 'DifferentialStoredCustomField',
|
||||
|
|
|
@ -356,7 +356,12 @@ final class DifferentialTransactionEditor
|
|||
// diff to a revision.
|
||||
|
||||
$this->updateRevisionHashTable($object, $diff);
|
||||
$this->updateAffectedPathTable($object, $diff);
|
||||
|
||||
id(new DifferentialAffectedPathEngine())
|
||||
->setRevision($object)
|
||||
->setDiff($diff)
|
||||
->updateAffectedPaths();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1258,92 +1263,6 @@ final class DifferentialTransactionEditor
|
|||
return $adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the table which links Differential revisions to paths they affect,
|
||||
* so Diffusion can efficiently find pending revisions for a given file.
|
||||
*/
|
||||
private function updateAffectedPathTable(
|
||||
DifferentialRevision $revision,
|
||||
DifferentialDiff $diff) {
|
||||
|
||||
$repository = $revision->getRepository();
|
||||
if (!$repository) {
|
||||
// The repository where the code lives is untracked.
|
||||
return;
|
||||
}
|
||||
|
||||
$path_prefix = null;
|
||||
|
||||
$local_root = $diff->getSourceControlPath();
|
||||
if ($local_root) {
|
||||
// We're in a working copy which supports subdirectory checkouts (e.g.,
|
||||
// SVN) so we need to figure out what prefix we should add to each path
|
||||
// (e.g., trunk/projects/example/) to get the absolute path from the
|
||||
// root of the repository. DVCS systems like Git and Mercurial are not
|
||||
// affected.
|
||||
|
||||
// Normalize both paths and check if the repository root is a prefix of
|
||||
// the local root. If so, throw it away. Note that this correctly handles
|
||||
// the case where the remote path is "/".
|
||||
$local_root = id(new PhutilURI($local_root))->getPath();
|
||||
$local_root = rtrim($local_root, '/');
|
||||
|
||||
$repo_root = id(new PhutilURI($repository->getRemoteURI()))->getPath();
|
||||
$repo_root = rtrim($repo_root, '/');
|
||||
|
||||
if (!strncmp($repo_root, $local_root, strlen($repo_root))) {
|
||||
$path_prefix = substr($local_root, strlen($repo_root));
|
||||
}
|
||||
}
|
||||
|
||||
$changesets = $diff->getChangesets();
|
||||
$paths = array();
|
||||
foreach ($changesets as $changeset) {
|
||||
$paths[] = $path_prefix.'/'.$changeset->getFilename();
|
||||
}
|
||||
|
||||
// Mark this as also touching all parent paths, so you can see all pending
|
||||
// changes to any file within a directory.
|
||||
$all_paths = array();
|
||||
foreach ($paths as $local) {
|
||||
foreach (DiffusionPathIDQuery::expandPathToRoot($local) as $path) {
|
||||
$all_paths[$path] = true;
|
||||
}
|
||||
}
|
||||
$all_paths = array_keys($all_paths);
|
||||
|
||||
$path_ids =
|
||||
PhabricatorRepositoryCommitChangeParserWorker::lookupOrCreatePaths(
|
||||
$all_paths);
|
||||
|
||||
$table = new DifferentialAffectedPath();
|
||||
$conn_w = $table->establishConnection('w');
|
||||
|
||||
$sql = array();
|
||||
foreach ($path_ids as $path_id) {
|
||||
$sql[] = qsprintf(
|
||||
$conn_w,
|
||||
'(%d, %d, %d, %d)',
|
||||
$repository->getID(),
|
||||
$path_id,
|
||||
time(),
|
||||
$revision->getID());
|
||||
}
|
||||
|
||||
queryfx(
|
||||
$conn_w,
|
||||
'DELETE FROM %T WHERE revisionID = %d',
|
||||
$table->getTableName(),
|
||||
$revision->getID());
|
||||
foreach (array_chunk($sql, 256) as $chunk) {
|
||||
queryfx(
|
||||
$conn_w,
|
||||
'INSERT INTO %T (repositoryID, pathID, epoch, revisionID) VALUES %LQ',
|
||||
$table->getTableName(),
|
||||
$chunk);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the table connecting revisions to DVCS local hashes, so we can
|
||||
* identify revisions by commit/tree hashes.
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
final class DifferentialAffectedPathEngine
|
||||
extends Phobject {
|
||||
|
||||
private $revision;
|
||||
private $diff;
|
||||
|
||||
public function setRevision(DifferentialRevision $revision) {
|
||||
$this->revision = $revision;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRevision() {
|
||||
return $this->revision;
|
||||
}
|
||||
|
||||
public function setDiff(DifferentialDiff $diff) {
|
||||
$this->diff = $diff;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDiff() {
|
||||
return $this->diff;
|
||||
}
|
||||
|
||||
public function updateAffectedPaths() {
|
||||
$revision = $this->getRevision();
|
||||
$diff = $this->getDiff();
|
||||
$repository = $revision->getRepository();
|
||||
|
||||
if ($repository) {
|
||||
$repository_id = $repository->getID();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$paths = $this->getAffectedPaths();
|
||||
|
||||
$path_ids =
|
||||
PhabricatorRepositoryCommitChangeParserWorker::lookupOrCreatePaths(
|
||||
$paths);
|
||||
|
||||
$table = new DifferentialAffectedPath();
|
||||
$conn = $table->establishConnection('w');
|
||||
|
||||
$sql = array();
|
||||
foreach ($path_ids as $path_id) {
|
||||
$sql[] = qsprintf(
|
||||
$conn,
|
||||
'(%d, %d, %d, %d)',
|
||||
$repository_id,
|
||||
$path_id,
|
||||
PhabricatorTime::getNow(),
|
||||
$revision->getID());
|
||||
}
|
||||
|
||||
queryfx(
|
||||
$conn,
|
||||
'DELETE FROM %R WHERE revisionID = %d',
|
||||
$table,
|
||||
$revision->getID());
|
||||
if ($sql) {
|
||||
foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) {
|
||||
queryfx(
|
||||
$conn,
|
||||
'INSERT INTO %R (repositoryID, pathID, epoch, revisionID) VALUES %LQ',
|
||||
$table,
|
||||
$chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function destroyAffectedPaths() {
|
||||
$revision = $this->getRevision();
|
||||
|
||||
$table = new DifferentialAffectedPath();
|
||||
$conn = $table->establishConnection('w');
|
||||
|
||||
queryfx(
|
||||
$conn,
|
||||
'DELETE FROM %R WHERE revisionID = %d',
|
||||
$table,
|
||||
$revision->getID());
|
||||
}
|
||||
|
||||
public function getAffectedPaths() {
|
||||
$revision = $this->getRevision();
|
||||
$diff = $this->getDiff();
|
||||
$repository = $revision->getRepository();
|
||||
|
||||
$path_prefix = null;
|
||||
if ($repository) {
|
||||
$local_root = $diff->getSourceControlPath();
|
||||
if ($local_root) {
|
||||
// We're in a working copy which supports subdirectory checkouts (e.g.,
|
||||
// SVN) so we need to figure out what prefix we should add to each path
|
||||
// (e.g., trunk/projects/example/) to get the absolute path from the
|
||||
// root of the repository. DVCS systems like Git and Mercurial are not
|
||||
// affected.
|
||||
|
||||
// Normalize both paths and check if the repository root is a prefix of
|
||||
// the local root. If so, throw it away. Note that this correctly
|
||||
// handles the case where the remote path is "/".
|
||||
$local_root = id(new PhutilURI($local_root))->getPath();
|
||||
$local_root = rtrim($local_root, '/');
|
||||
|
||||
$repo_root = id(new PhutilURI($repository->getRemoteURI()))->getPath();
|
||||
$repo_root = rtrim($repo_root, '/');
|
||||
|
||||
if (!strncmp($repo_root, $local_root, strlen($repo_root))) {
|
||||
$path_prefix = substr($local_root, strlen($repo_root));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$changesets = $diff->getChangesets();
|
||||
|
||||
$paths = array();
|
||||
foreach ($changesets as $changeset) {
|
||||
$paths[] = $path_prefix.'/'.$changeset->getFilename();
|
||||
}
|
||||
|
||||
// Mark this as also touching all parent paths, so you can see all pending
|
||||
// changes to any file within a directory.
|
||||
$all_paths = array();
|
||||
foreach ($paths as $local) {
|
||||
foreach (DiffusionPathIDQuery::expandPathToRoot($local) as $path) {
|
||||
$all_paths[$path] = true;
|
||||
}
|
||||
}
|
||||
$all_paths = array_keys($all_paths);
|
||||
|
||||
return $all_paths;
|
||||
}
|
||||
|
||||
}
|
|
@ -1022,16 +1022,9 @@ final class DifferentialRevision extends DifferentialDAO
|
|||
$engine->destroyObject($diff);
|
||||
}
|
||||
|
||||
$conn_w = $this->establishConnection('w');
|
||||
|
||||
// we have to do paths a little differently as they do not have
|
||||
// an id or phid column for delete() to act on
|
||||
$dummy_path = new DifferentialAffectedPath();
|
||||
queryfx(
|
||||
$conn_w,
|
||||
'DELETE FROM %T WHERE revisionID = %d',
|
||||
$dummy_path->getTableName(),
|
||||
$this->getID());
|
||||
id(new DifferentialAffectedPathEngine())
|
||||
->setRevision($this)
|
||||
->destroyAffectedPaths();
|
||||
|
||||
$viewstate_query = id(new DifferentialViewStateQuery())
|
||||
->setViewer($viewer)
|
||||
|
|
Loading…
Reference in a new issue