mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 16:22:43 +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',
|
'DifferentialActionEmailCommand' => 'applications/differential/command/DifferentialActionEmailCommand.php',
|
||||||
'DifferentialAdjustmentMapTestCase' => 'applications/differential/storage/__tests__/DifferentialAdjustmentMapTestCase.php',
|
'DifferentialAdjustmentMapTestCase' => 'applications/differential/storage/__tests__/DifferentialAdjustmentMapTestCase.php',
|
||||||
'DifferentialAffectedPath' => 'applications/differential/storage/DifferentialAffectedPath.php',
|
'DifferentialAffectedPath' => 'applications/differential/storage/DifferentialAffectedPath.php',
|
||||||
|
'DifferentialAffectedPathEngine' => 'applications/differential/engine/DifferentialAffectedPathEngine.php',
|
||||||
'DifferentialAsanaRepresentationField' => 'applications/differential/customfield/DifferentialAsanaRepresentationField.php',
|
'DifferentialAsanaRepresentationField' => 'applications/differential/customfield/DifferentialAsanaRepresentationField.php',
|
||||||
'DifferentialAuditorsCommitMessageField' => 'applications/differential/field/DifferentialAuditorsCommitMessageField.php',
|
'DifferentialAuditorsCommitMessageField' => 'applications/differential/field/DifferentialAuditorsCommitMessageField.php',
|
||||||
'DifferentialAuditorsField' => 'applications/differential/customfield/DifferentialAuditorsField.php',
|
'DifferentialAuditorsField' => 'applications/differential/customfield/DifferentialAuditorsField.php',
|
||||||
|
@ -6533,6 +6534,7 @@ phutil_register_library_map(array(
|
||||||
'DifferentialActionEmailCommand' => 'MetaMTAEmailTransactionCommand',
|
'DifferentialActionEmailCommand' => 'MetaMTAEmailTransactionCommand',
|
||||||
'DifferentialAdjustmentMapTestCase' => 'PhabricatorTestCase',
|
'DifferentialAdjustmentMapTestCase' => 'PhabricatorTestCase',
|
||||||
'DifferentialAffectedPath' => 'DifferentialDAO',
|
'DifferentialAffectedPath' => 'DifferentialDAO',
|
||||||
|
'DifferentialAffectedPathEngine' => 'Phobject',
|
||||||
'DifferentialAsanaRepresentationField' => 'DifferentialCustomField',
|
'DifferentialAsanaRepresentationField' => 'DifferentialCustomField',
|
||||||
'DifferentialAuditorsCommitMessageField' => 'DifferentialCommitMessageCustomField',
|
'DifferentialAuditorsCommitMessageField' => 'DifferentialCommitMessageCustomField',
|
||||||
'DifferentialAuditorsField' => 'DifferentialStoredCustomField',
|
'DifferentialAuditorsField' => 'DifferentialStoredCustomField',
|
||||||
|
|
|
@ -356,7 +356,12 @@ final class DifferentialTransactionEditor
|
||||||
// diff to a revision.
|
// diff to a revision.
|
||||||
|
|
||||||
$this->updateRevisionHashTable($object, $diff);
|
$this->updateRevisionHashTable($object, $diff);
|
||||||
$this->updateAffectedPathTable($object, $diff);
|
|
||||||
|
id(new DifferentialAffectedPathEngine())
|
||||||
|
->setRevision($object)
|
||||||
|
->setDiff($diff)
|
||||||
|
->updateAffectedPaths();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1258,92 +1263,6 @@ final class DifferentialTransactionEditor
|
||||||
return $adapter;
|
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
|
* Update the table connecting revisions to DVCS local hashes, so we can
|
||||||
* identify revisions by commit/tree hashes.
|
* 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);
|
$engine->destroyObject($diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
$conn_w = $this->establishConnection('w');
|
id(new DifferentialAffectedPathEngine())
|
||||||
|
->setRevision($this)
|
||||||
// we have to do paths a little differently as they do not have
|
->destroyAffectedPaths();
|
||||||
// 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());
|
|
||||||
|
|
||||||
$viewstate_query = id(new DifferentialViewStateQuery())
|
$viewstate_query = id(new DifferentialViewStateQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
|
|
Loading…
Reference in a new issue