@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+148 -97
+2
src/__phutil_library_map__.php
··· 450 450 'DifferentialActionEmailCommand' => 'applications/differential/command/DifferentialActionEmailCommand.php', 451 451 'DifferentialAdjustmentMapTestCase' => 'applications/differential/storage/__tests__/DifferentialAdjustmentMapTestCase.php', 452 452 'DifferentialAffectedPath' => 'applications/differential/storage/DifferentialAffectedPath.php', 453 + 'DifferentialAffectedPathEngine' => 'applications/differential/engine/DifferentialAffectedPathEngine.php', 453 454 'DifferentialAsanaRepresentationField' => 'applications/differential/customfield/DifferentialAsanaRepresentationField.php', 454 455 'DifferentialAuditorsCommitMessageField' => 'applications/differential/field/DifferentialAuditorsCommitMessageField.php', 455 456 'DifferentialAuditorsField' => 'applications/differential/customfield/DifferentialAuditorsField.php', ··· 6533 6534 'DifferentialActionEmailCommand' => 'MetaMTAEmailTransactionCommand', 6534 6535 'DifferentialAdjustmentMapTestCase' => 'PhabricatorTestCase', 6535 6536 'DifferentialAffectedPath' => 'DifferentialDAO', 6537 + 'DifferentialAffectedPathEngine' => 'Phobject', 6536 6538 'DifferentialAsanaRepresentationField' => 'DifferentialCustomField', 6537 6539 'DifferentialAuditorsCommitMessageField' => 'DifferentialCommitMessageCustomField', 6538 6540 'DifferentialAuditorsField' => 'DifferentialStoredCustomField',
+6 -87
src/applications/differential/editor/DifferentialTransactionEditor.php
··· 356 356 // diff to a revision. 357 357 358 358 $this->updateRevisionHashTable($object, $diff); 359 - $this->updateAffectedPathTable($object, $diff); 359 + 360 + id(new DifferentialAffectedPathEngine()) 361 + ->setRevision($object) 362 + ->setDiff($diff) 363 + ->updateAffectedPaths(); 364 + 360 365 break; 361 366 } 362 367 } ··· 1256 1261 } 1257 1262 1258 1263 return $adapter; 1259 - } 1260 - 1261 - /** 1262 - * Update the table which links Differential revisions to paths they affect, 1263 - * so Diffusion can efficiently find pending revisions for a given file. 1264 - */ 1265 - private function updateAffectedPathTable( 1266 - DifferentialRevision $revision, 1267 - DifferentialDiff $diff) { 1268 - 1269 - $repository = $revision->getRepository(); 1270 - if (!$repository) { 1271 - // The repository where the code lives is untracked. 1272 - return; 1273 - } 1274 - 1275 - $path_prefix = null; 1276 - 1277 - $local_root = $diff->getSourceControlPath(); 1278 - if ($local_root) { 1279 - // We're in a working copy which supports subdirectory checkouts (e.g., 1280 - // SVN) so we need to figure out what prefix we should add to each path 1281 - // (e.g., trunk/projects/example/) to get the absolute path from the 1282 - // root of the repository. DVCS systems like Git and Mercurial are not 1283 - // affected. 1284 - 1285 - // Normalize both paths and check if the repository root is a prefix of 1286 - // the local root. If so, throw it away. Note that this correctly handles 1287 - // the case where the remote path is "/". 1288 - $local_root = id(new PhutilURI($local_root))->getPath(); 1289 - $local_root = rtrim($local_root, '/'); 1290 - 1291 - $repo_root = id(new PhutilURI($repository->getRemoteURI()))->getPath(); 1292 - $repo_root = rtrim($repo_root, '/'); 1293 - 1294 - if (!strncmp($repo_root, $local_root, strlen($repo_root))) { 1295 - $path_prefix = substr($local_root, strlen($repo_root)); 1296 - } 1297 - } 1298 - 1299 - $changesets = $diff->getChangesets(); 1300 - $paths = array(); 1301 - foreach ($changesets as $changeset) { 1302 - $paths[] = $path_prefix.'/'.$changeset->getFilename(); 1303 - } 1304 - 1305 - // Mark this as also touching all parent paths, so you can see all pending 1306 - // changes to any file within a directory. 1307 - $all_paths = array(); 1308 - foreach ($paths as $local) { 1309 - foreach (DiffusionPathIDQuery::expandPathToRoot($local) as $path) { 1310 - $all_paths[$path] = true; 1311 - } 1312 - } 1313 - $all_paths = array_keys($all_paths); 1314 - 1315 - $path_ids = 1316 - PhabricatorRepositoryCommitChangeParserWorker::lookupOrCreatePaths( 1317 - $all_paths); 1318 - 1319 - $table = new DifferentialAffectedPath(); 1320 - $conn_w = $table->establishConnection('w'); 1321 - 1322 - $sql = array(); 1323 - foreach ($path_ids as $path_id) { 1324 - $sql[] = qsprintf( 1325 - $conn_w, 1326 - '(%d, %d, %d, %d)', 1327 - $repository->getID(), 1328 - $path_id, 1329 - time(), 1330 - $revision->getID()); 1331 - } 1332 - 1333 - queryfx( 1334 - $conn_w, 1335 - 'DELETE FROM %T WHERE revisionID = %d', 1336 - $table->getTableName(), 1337 - $revision->getID()); 1338 - foreach (array_chunk($sql, 256) as $chunk) { 1339 - queryfx( 1340 - $conn_w, 1341 - 'INSERT INTO %T (repositoryID, pathID, epoch, revisionID) VALUES %LQ', 1342 - $table->getTableName(), 1343 - $chunk); 1344 - } 1345 1264 } 1346 1265 1347 1266 /**
+137
src/applications/differential/engine/DifferentialAffectedPathEngine.php
··· 1 + <?php 2 + 3 + final class DifferentialAffectedPathEngine 4 + extends Phobject { 5 + 6 + private $revision; 7 + private $diff; 8 + 9 + public function setRevision(DifferentialRevision $revision) { 10 + $this->revision = $revision; 11 + return $this; 12 + } 13 + 14 + public function getRevision() { 15 + return $this->revision; 16 + } 17 + 18 + public function setDiff(DifferentialDiff $diff) { 19 + $this->diff = $diff; 20 + return $this; 21 + } 22 + 23 + public function getDiff() { 24 + return $this->diff; 25 + } 26 + 27 + public function updateAffectedPaths() { 28 + $revision = $this->getRevision(); 29 + $diff = $this->getDiff(); 30 + $repository = $revision->getRepository(); 31 + 32 + if ($repository) { 33 + $repository_id = $repository->getID(); 34 + } else { 35 + return; 36 + } 37 + 38 + $paths = $this->getAffectedPaths(); 39 + 40 + $path_ids = 41 + PhabricatorRepositoryCommitChangeParserWorker::lookupOrCreatePaths( 42 + $paths); 43 + 44 + $table = new DifferentialAffectedPath(); 45 + $conn = $table->establishConnection('w'); 46 + 47 + $sql = array(); 48 + foreach ($path_ids as $path_id) { 49 + $sql[] = qsprintf( 50 + $conn, 51 + '(%d, %d, %d, %d)', 52 + $repository_id, 53 + $path_id, 54 + PhabricatorTime::getNow(), 55 + $revision->getID()); 56 + } 57 + 58 + queryfx( 59 + $conn, 60 + 'DELETE FROM %R WHERE revisionID = %d', 61 + $table, 62 + $revision->getID()); 63 + if ($sql) { 64 + foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) { 65 + queryfx( 66 + $conn, 67 + 'INSERT INTO %R (repositoryID, pathID, epoch, revisionID) VALUES %LQ', 68 + $table, 69 + $chunk); 70 + } 71 + } 72 + } 73 + 74 + public function destroyAffectedPaths() { 75 + $revision = $this->getRevision(); 76 + 77 + $table = new DifferentialAffectedPath(); 78 + $conn = $table->establishConnection('w'); 79 + 80 + queryfx( 81 + $conn, 82 + 'DELETE FROM %R WHERE revisionID = %d', 83 + $table, 84 + $revision->getID()); 85 + } 86 + 87 + public function getAffectedPaths() { 88 + $revision = $this->getRevision(); 89 + $diff = $this->getDiff(); 90 + $repository = $revision->getRepository(); 91 + 92 + $path_prefix = null; 93 + if ($repository) { 94 + $local_root = $diff->getSourceControlPath(); 95 + if ($local_root) { 96 + // We're in a working copy which supports subdirectory checkouts (e.g., 97 + // SVN) so we need to figure out what prefix we should add to each path 98 + // (e.g., trunk/projects/example/) to get the absolute path from the 99 + // root of the repository. DVCS systems like Git and Mercurial are not 100 + // affected. 101 + 102 + // Normalize both paths and check if the repository root is a prefix of 103 + // the local root. If so, throw it away. Note that this correctly 104 + // handles the case where the remote path is "/". 105 + $local_root = id(new PhutilURI($local_root))->getPath(); 106 + $local_root = rtrim($local_root, '/'); 107 + 108 + $repo_root = id(new PhutilURI($repository->getRemoteURI()))->getPath(); 109 + $repo_root = rtrim($repo_root, '/'); 110 + 111 + if (!strncmp($repo_root, $local_root, strlen($repo_root))) { 112 + $path_prefix = substr($local_root, strlen($repo_root)); 113 + } 114 + } 115 + } 116 + 117 + $changesets = $diff->getChangesets(); 118 + 119 + $paths = array(); 120 + foreach ($changesets as $changeset) { 121 + $paths[] = $path_prefix.'/'.$changeset->getFilename(); 122 + } 123 + 124 + // Mark this as also touching all parent paths, so you can see all pending 125 + // changes to any file within a directory. 126 + $all_paths = array(); 127 + foreach ($paths as $local) { 128 + foreach (DiffusionPathIDQuery::expandPathToRoot($local) as $path) { 129 + $all_paths[$path] = true; 130 + } 131 + } 132 + $all_paths = array_keys($all_paths); 133 + 134 + return $all_paths; 135 + } 136 + 137 + }
+3 -10
src/applications/differential/storage/DifferentialRevision.php
··· 1022 1022 $engine->destroyObject($diff); 1023 1023 } 1024 1024 1025 - $conn_w = $this->establishConnection('w'); 1026 - 1027 - // we have to do paths a little differently as they do not have 1028 - // an id or phid column for delete() to act on 1029 - $dummy_path = new DifferentialAffectedPath(); 1030 - queryfx( 1031 - $conn_w, 1032 - 'DELETE FROM %T WHERE revisionID = %d', 1033 - $dummy_path->getTableName(), 1034 - $this->getID()); 1025 + id(new DifferentialAffectedPathEngine()) 1026 + ->setRevision($this) 1027 + ->destroyAffectedPaths(); 1035 1028 1036 1029 $viewstate_query = id(new DifferentialViewStateQuery()) 1037 1030 ->setViewer($viewer)