@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.

Put a readthrough cache in front of inline context construction

Summary: Ref T13513. Inline comment context information is somewhat expensive to construct and can be cached. Add a readthrough cache on top of it.

Test Plan: Loaded a source code changeset with many inline comments, used Darkconsole to inspect query activity. Saw caches get populated. Updated cache key, saw caches regenerate. Browsed Diffusion, nothing looked broken.

Maniphest Tasks: T13513

Differential Revision: https://secure.phabricator.com/D21279

+123 -10
+15 -6
src/applications/differential/query/DifferentialDiffInlineCommentQuery.php
··· 67 67 return $id_map; 68 68 } 69 69 70 + protected function newInlineContextFromCacheData(array $map) { 71 + return PhabricatorDiffInlineCommentContext::newFromCacheData($map); 72 + } 73 + 70 74 protected function newInlineContextMap(array $inlines) { 71 75 $viewer = $this->getViewer(); 76 + $map = array(); 72 77 73 - $map = array(); 78 + $changeset_ids = mpull($inlines, 'getChangesetID'); 79 + 80 + $changesets = id(new DifferentialChangesetQuery()) 81 + ->setViewer($viewer) 82 + ->withIDs($changeset_ids) 83 + ->needHunks(true) 84 + ->execute(); 85 + $changesets = mpull($changesets, null, 'getID'); 74 86 75 87 foreach ($inlines as $key => $inline) { 76 - $changeset = id(new DifferentialChangesetQuery()) 77 - ->setViewer($viewer) 78 - ->withIDs(array($inline->getChangesetID())) 79 - ->needHunks(true) 80 - ->executeOne(); 88 + $changeset = idx($changesets, $inline->getChangesetID()); 89 + 81 90 if (!$changeset) { 82 91 continue; 83 92 }
+4
src/applications/diffusion/query/DiffusionDiffInlineCommentQuery.php
··· 70 70 return array(); 71 71 } 72 72 73 + protected function newInlineContextFromCacheData(array $map) { 74 + return PhabricatorDiffInlineCommentContext::newFromCacheData($map); 75 + } 76 + 73 77 }
+20
src/infrastructure/diff/inline/PhabricatorDiffInlineCommentContext.php
··· 8 8 private $bodyLines; 9 9 private $tailLines; 10 10 11 + public static function newFromCacheData(array $map) { 12 + $context = new self(); 13 + 14 + $context->setFilename(idx($map, 'filename')); 15 + $context->setHeadLines(idx($map, 'headLines')); 16 + $context->setBodyLines(idx($map, 'bodyLines')); 17 + $context->setTailLines(idx($map, 'tailLines')); 18 + 19 + return $context; 20 + } 21 + 22 + public function newCacheDataMap() { 23 + return array( 24 + 'filename' => $this->getFilename(), 25 + 'headLines' => $this->getHeadLines(), 26 + 'bodyLines' => $this->getBodyLines(), 27 + 'tailLines' => $this->getTailLines(), 28 + ); 29 + } 30 + 11 31 public function setFilename($filename) { 12 32 $this->filename = $filename; 13 33 return $this;
+10
src/infrastructure/diff/interface/PhabricatorInlineComment.php
··· 82 82 return $this->storageObject; 83 83 } 84 84 85 + public function getInlineCommentCacheFragment() { 86 + $phid = $this->getPHID(); 87 + 88 + if ($phid === null) { 89 + return null; 90 + } 91 + 92 + return sprintf('inline(%s)', $phid); 93 + } 94 + 85 95 abstract protected function newStorageObject(); 86 96 abstract public function getControllerURI(); 87 97
+74 -4
src/infrastructure/diff/query/PhabricatorDiffInlineCommentQuery.php
··· 3 3 abstract class PhabricatorDiffInlineCommentQuery 4 4 extends PhabricatorApplicationTransactionCommentQuery { 5 5 6 + const INLINE_CONTEXT_CACHE_VERSION = 1; 7 + 6 8 private $fixedStates; 7 9 private $needReplyToComments; 8 10 private $publishedComments; ··· 19 21 array $comments); 20 22 21 23 abstract protected function newInlineContextMap(array $inlines); 24 + abstract protected function newInlineContextFromCacheData(array $map); 22 25 23 26 final public function withFixedStates(array $states) { 24 27 $this->fixedStates = $states; ··· 268 271 } 269 272 270 273 if ($need_context) { 271 - $context_map = $this->newInlineContextMap($need_context); 274 + $this->loadInlineCommentContext($need_context); 275 + } 276 + } 277 + 278 + return $inlines; 279 + } 280 + 281 + private function loadInlineCommentContext(array $inlines) { 282 + $cache_keys = array(); 283 + foreach ($inlines as $key => $inline) { 284 + $object = $inline->newInlineCommentObject(); 285 + $fragment = $object->getInlineCommentCacheFragment(); 286 + 287 + if ($fragment === null) { 288 + continue; 289 + } 290 + 291 + $cache_keys[$key] = sprintf( 292 + '%s.context(v%d)', 293 + $fragment, 294 + self::INLINE_CONTEXT_CACHE_VERSION); 295 + } 296 + 297 + $cache = PhabricatorCaches::getMutableStructureCache(); 298 + 299 + $cache_map = $cache->getKeys($cache_keys); 300 + 301 + $context_map = array(); 302 + $need_construct = array(); 303 + 304 + foreach ($inlines as $key => $inline) { 305 + $cache_key = idx($cache_keys, $key); 306 + 307 + if ($cache_key !== null) { 308 + if (array_key_exists($cache_key, $cache_map)) { 309 + $cache_data = $cache_map[$cache_key]; 310 + $context_map[$key] = $this->newInlineContextFromCacheData( 311 + $cache_data); 312 + continue; 313 + } 314 + } 315 + 316 + $need_construct[$key] = $inline; 317 + } 318 + 319 + if ($need_construct) { 320 + $construct_map = $this->newInlineContextMap($need_construct); 321 + 322 + $write_map = array(); 323 + foreach ($construct_map as $key => $context) { 324 + if ($context === null) { 325 + $cache_data = $context; 326 + } else { 327 + $cache_data = $this->newCacheDataFromInlineContext($context); 328 + } 272 329 273 - foreach ($need_context as $key => $inline) { 274 - $inline->attachInlineContext(idx($context_map, $key)); 330 + $cache_key = idx($cache_keys, $key); 331 + if ($cache_key !== null) { 332 + $write_map[$cache_key] = $cache_data; 275 333 } 276 334 } 277 335 336 + if ($write_map) { 337 + $cache->setKeys($write_map); 338 + } 339 + 340 + $context_map += $construct_map; 278 341 } 279 342 280 - return $inlines; 343 + foreach ($inlines as $key => $inline) { 344 + $inline->attachInlineContext(idx($context_map, $key)); 345 + } 346 + } 347 + 348 + protected function newCacheDataFromInlineContext( 349 + PhabricatorInlineCommentContext $context) { 350 + return $context->newCacheDataMap(); 281 351 } 282 352 283 353 final protected function simplifyContext(array $lines, $is_head) {