mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-22 21:40:55 +01:00
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
This commit is contained in:
parent
d2d7e7f5ff
commit
5d0ae283a9
5 changed files with 125 additions and 12 deletions
|
@ -67,17 +67,26 @@ final class DifferentialDiffInlineCommentQuery
|
|||
return $id_map;
|
||||
}
|
||||
|
||||
protected function newInlineContextFromCacheData(array $map) {
|
||||
return PhabricatorDiffInlineCommentContext::newFromCacheData($map);
|
||||
}
|
||||
|
||||
protected function newInlineContextMap(array $inlines) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$map = array();
|
||||
|
||||
$changeset_ids = mpull($inlines, 'getChangesetID');
|
||||
|
||||
$changesets = id(new DifferentialChangesetQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs($changeset_ids)
|
||||
->needHunks(true)
|
||||
->execute();
|
||||
$changesets = mpull($changesets, null, 'getID');
|
||||
|
||||
foreach ($inlines as $key => $inline) {
|
||||
$changeset = id(new DifferentialChangesetQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($inline->getChangesetID()))
|
||||
->needHunks(true)
|
||||
->executeOne();
|
||||
$changeset = idx($changesets, $inline->getChangesetID());
|
||||
|
||||
if (!$changeset) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -70,4 +70,8 @@ final class DiffusionDiffInlineCommentQuery
|
|||
return array();
|
||||
}
|
||||
|
||||
protected function newInlineContextFromCacheData(array $map) {
|
||||
return PhabricatorDiffInlineCommentContext::newFromCacheData($map);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,26 @@ final class PhabricatorDiffInlineCommentContext
|
|||
private $bodyLines;
|
||||
private $tailLines;
|
||||
|
||||
public static function newFromCacheData(array $map) {
|
||||
$context = new self();
|
||||
|
||||
$context->setFilename(idx($map, 'filename'));
|
||||
$context->setHeadLines(idx($map, 'headLines'));
|
||||
$context->setBodyLines(idx($map, 'bodyLines'));
|
||||
$context->setTailLines(idx($map, 'tailLines'));
|
||||
|
||||
return $context;
|
||||
}
|
||||
|
||||
public function newCacheDataMap() {
|
||||
return array(
|
||||
'filename' => $this->getFilename(),
|
||||
'headLines' => $this->getHeadLines(),
|
||||
'bodyLines' => $this->getBodyLines(),
|
||||
'tailLines' => $this->getTailLines(),
|
||||
);
|
||||
}
|
||||
|
||||
public function setFilename($filename) {
|
||||
$this->filename = $filename;
|
||||
return $this;
|
||||
|
|
|
@ -82,6 +82,16 @@ abstract class PhabricatorInlineComment
|
|||
return $this->storageObject;
|
||||
}
|
||||
|
||||
public function getInlineCommentCacheFragment() {
|
||||
$phid = $this->getPHID();
|
||||
|
||||
if ($phid === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return sprintf('inline(%s)', $phid);
|
||||
}
|
||||
|
||||
abstract protected function newStorageObject();
|
||||
abstract public function getControllerURI();
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
abstract class PhabricatorDiffInlineCommentQuery
|
||||
extends PhabricatorApplicationTransactionCommentQuery {
|
||||
|
||||
const INLINE_CONTEXT_CACHE_VERSION = 1;
|
||||
|
||||
private $fixedStates;
|
||||
private $needReplyToComments;
|
||||
private $publishedComments;
|
||||
|
@ -19,6 +21,7 @@ abstract class PhabricatorDiffInlineCommentQuery
|
|||
array $comments);
|
||||
|
||||
abstract protected function newInlineContextMap(array $inlines);
|
||||
abstract protected function newInlineContextFromCacheData(array $map);
|
||||
|
||||
final public function withFixedStates(array $states) {
|
||||
$this->fixedStates = $states;
|
||||
|
@ -268,18 +271,85 @@ abstract class PhabricatorDiffInlineCommentQuery
|
|||
}
|
||||
|
||||
if ($need_context) {
|
||||
$context_map = $this->newInlineContextMap($need_context);
|
||||
|
||||
foreach ($need_context as $key => $inline) {
|
||||
$inline->attachInlineContext(idx($context_map, $key));
|
||||
}
|
||||
$this->loadInlineCommentContext($need_context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $inlines;
|
||||
}
|
||||
|
||||
private function loadInlineCommentContext(array $inlines) {
|
||||
$cache_keys = array();
|
||||
foreach ($inlines as $key => $inline) {
|
||||
$object = $inline->newInlineCommentObject();
|
||||
$fragment = $object->getInlineCommentCacheFragment();
|
||||
|
||||
if ($fragment === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cache_keys[$key] = sprintf(
|
||||
'%s.context(v%d)',
|
||||
$fragment,
|
||||
self::INLINE_CONTEXT_CACHE_VERSION);
|
||||
}
|
||||
|
||||
$cache = PhabricatorCaches::getMutableStructureCache();
|
||||
|
||||
$cache_map = $cache->getKeys($cache_keys);
|
||||
|
||||
$context_map = array();
|
||||
$need_construct = array();
|
||||
|
||||
foreach ($inlines as $key => $inline) {
|
||||
$cache_key = idx($cache_keys, $key);
|
||||
|
||||
if ($cache_key !== null) {
|
||||
if (array_key_exists($cache_key, $cache_map)) {
|
||||
$cache_data = $cache_map[$cache_key];
|
||||
$context_map[$key] = $this->newInlineContextFromCacheData(
|
||||
$cache_data);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$need_construct[$key] = $inline;
|
||||
}
|
||||
|
||||
if ($need_construct) {
|
||||
$construct_map = $this->newInlineContextMap($need_construct);
|
||||
|
||||
$write_map = array();
|
||||
foreach ($construct_map as $key => $context) {
|
||||
if ($context === null) {
|
||||
$cache_data = $context;
|
||||
} else {
|
||||
$cache_data = $this->newCacheDataFromInlineContext($context);
|
||||
}
|
||||
|
||||
$cache_key = idx($cache_keys, $key);
|
||||
if ($cache_key !== null) {
|
||||
$write_map[$cache_key] = $cache_data;
|
||||
}
|
||||
}
|
||||
|
||||
if ($write_map) {
|
||||
$cache->setKeys($write_map);
|
||||
}
|
||||
|
||||
$context_map += $construct_map;
|
||||
}
|
||||
|
||||
foreach ($inlines as $key => $inline) {
|
||||
$inline->attachInlineContext(idx($context_map, $key));
|
||||
}
|
||||
}
|
||||
|
||||
protected function newCacheDataFromInlineContext(
|
||||
PhabricatorInlineCommentContext $context) {
|
||||
return $context->newCacheDataMap();
|
||||
}
|
||||
|
||||
final protected function simplifyContext(array $lines, $is_head) {
|
||||
// We want to provide the smallest amount of context we can while still
|
||||
// being useful, since the actual code is visible nearby and showing a
|
||||
|
|
Loading…
Reference in a new issue