Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/differential/query/DifferentialDiffInlineCommentQuery.php b/src/applications/differential/query/DifferentialDiffInlineCommentQuery.php
index b8392c474d..7e2f7127b1 100644
--- a/src/applications/differential/query/DifferentialDiffInlineCommentQuery.php
+++ b/src/applications/differential/query/DifferentialDiffInlineCommentQuery.php
@@ -1,144 +1,153 @@
<?php
final class DifferentialDiffInlineCommentQuery
extends PhabricatorDiffInlineCommentQuery {
private $revisionPHIDs;
protected function newApplicationTransactionCommentTemplate() {
return new DifferentialTransactionComment();
}
public function withRevisionPHIDs(array $phids) {
$this->revisionPHIDs = $phids;
return $this;
}
public function withObjectPHIDs(array $phids) {
return $this->withRevisionPHIDs($phids);
}
protected function buildInlineCommentWhereClauseParts(
AphrontDatabaseConnection $conn) {
$where = array();
$alias = $this->getPrimaryTableAlias();
$where[] = qsprintf(
$conn,
'changesetID IS NOT NULL');
return $where;
}
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = parent::buildWhereClauseParts($conn);
$alias = $this->getPrimaryTableAlias();
if ($this->revisionPHIDs !== null) {
$where[] = qsprintf(
$conn,
'%T.revisionPHID IN (%Ls)',
$alias,
$this->revisionPHIDs);
}
return $where;
}
protected function loadHiddenCommentIDs(
$viewer_phid,
array $comments) {
$table = new DifferentialHiddenComment();
$conn = $table->establishConnection('r');
$rows = queryfx_all(
$conn,
'SELECT commentID FROM %R
WHERE userPHID = %s
AND commentID IN (%Ld)',
$table,
$viewer_phid,
mpull($comments, 'getID'));
$id_map = ipull($rows, 'commentID');
$id_map = array_fuse($id_map);
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;
}
$hunks = $changeset->getHunks();
$is_simple =
(count($hunks) === 1) &&
((int)head($hunks)->getOldOffset() <= 1) &&
((int)head($hunks)->getNewOffset() <= 1);
if (!$is_simple) {
continue;
}
if ($inline->getIsNewFile()) {
$vector = $changeset->getNewStatePathVector();
$filename = last($vector);
$corpus = $changeset->makeNewFile();
} else {
$vector = $changeset->getOldStatePathVector();
$filename = last($vector);
$corpus = $changeset->makeOldFile();
}
$corpus = phutil_split_lines($corpus);
// Adjust the line number into a 0-based offset.
$offset = $inline->getLineNumber();
$offset = $offset - 1;
// Adjust the inclusive range length into a row count.
$length = $inline->getLineLength();
$length = $length + 1;
$head_min = max(0, $offset - 3);
$head_max = $offset;
$head_len = $head_max - $head_min;
if ($head_len) {
$head = array_slice($corpus, $head_min, $head_len, true);
$head = $this->simplifyContext($head, true);
} else {
$head = array();
}
$body = array_slice($corpus, $offset, $length, true);
$tail = array_slice($corpus, $offset + $length, 3, true);
$tail = $this->simplifyContext($tail, false);
$context = id(new PhabricatorDiffInlineCommentContext())
->setFilename($filename)
->setHeadLines($head)
->setBodyLines($body)
->setTailLines($tail);
$map[$key] = $context;
}
return $map;
}
}
diff --git a/src/applications/diffusion/query/DiffusionDiffInlineCommentQuery.php b/src/applications/diffusion/query/DiffusionDiffInlineCommentQuery.php
index c395231808..01dc49a91e 100644
--- a/src/applications/diffusion/query/DiffusionDiffInlineCommentQuery.php
+++ b/src/applications/diffusion/query/DiffusionDiffInlineCommentQuery.php
@@ -1,73 +1,77 @@
<?php
final class DiffusionDiffInlineCommentQuery
extends PhabricatorDiffInlineCommentQuery {
private $commitPHIDs;
private $pathIDs;
protected function newApplicationTransactionCommentTemplate() {
return new PhabricatorAuditTransactionComment();
}
public function withCommitPHIDs(array $phids) {
$this->commitPHIDs = $phids;
return $this;
}
public function withObjectPHIDs(array $phids) {
return $this->withCommitPHIDs($phids);
}
public function withPathIDs(array $path_ids) {
$this->pathIDs = $path_ids;
return $this;
}
protected function buildInlineCommentWhereClauseParts(
AphrontDatabaseConnection $conn) {
$where = array();
$alias = $this->getPrimaryTableAlias();
$where[] = qsprintf(
$conn,
'%T.pathID IS NOT NULL',
$alias);
return $where;
}
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = parent::buildWhereClauseParts($conn);
$alias = $this->getPrimaryTableAlias();
if ($this->commitPHIDs !== null) {
$where[] = qsprintf(
$conn,
'%T.commitPHID IN (%Ls)',
$alias,
$this->commitPHIDs);
}
if ($this->pathIDs !== null) {
$where[] = qsprintf(
$conn,
'%T.pathID IN (%Ld)',
$alias,
$this->pathIDs);
}
return $where;
}
protected function loadHiddenCommentIDs(
$viewer_phid,
array $comments) {
return array();
}
protected function newInlineContextMap(array $inlines) {
return array();
}
+ protected function newInlineContextFromCacheData(array $map) {
+ return PhabricatorDiffInlineCommentContext::newFromCacheData($map);
+ }
+
}
diff --git a/src/infrastructure/diff/inline/PhabricatorDiffInlineCommentContext.php b/src/infrastructure/diff/inline/PhabricatorDiffInlineCommentContext.php
index 95f8473caf..f09d53092d 100644
--- a/src/infrastructure/diff/inline/PhabricatorDiffInlineCommentContext.php
+++ b/src/infrastructure/diff/inline/PhabricatorDiffInlineCommentContext.php
@@ -1,47 +1,67 @@
<?php
final class PhabricatorDiffInlineCommentContext
extends PhabricatorInlineCommentContext {
private $filename;
private $headLines;
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;
}
public function getFilename() {
return $this->filename;
}
public function setHeadLines(array $head_lines) {
$this->headLines = $head_lines;
return $this;
}
public function getHeadLines() {
return $this->headLines;
}
public function setBodyLines(array $body_lines) {
$this->bodyLines = $body_lines;
return $this;
}
public function getBodyLines() {
return $this->bodyLines;
}
public function setTailLines(array $tail_lines) {
$this->tailLines = $tail_lines;
return $this;
}
public function getTailLines() {
return $this->tailLines;
}
}
diff --git a/src/infrastructure/diff/interface/PhabricatorInlineComment.php b/src/infrastructure/diff/interface/PhabricatorInlineComment.php
index 3d3bb6e106..76976b5929 100644
--- a/src/infrastructure/diff/interface/PhabricatorInlineComment.php
+++ b/src/infrastructure/diff/interface/PhabricatorInlineComment.php
@@ -1,382 +1,392 @@
<?php
abstract class PhabricatorInlineComment
extends Phobject
implements
PhabricatorMarkupInterface {
const MARKUP_FIELD_BODY = 'markup:body';
const STATE_UNDONE = 'undone';
const STATE_DRAFT = 'draft';
const STATE_UNDRAFT = 'undraft';
const STATE_DONE = 'done';
private $storageObject;
private $syntheticAuthor;
private $isGhost;
private $versionedDrafts = array();
public function __clone() {
$this->storageObject = clone $this->storageObject;
}
final public static function loadAndAttachVersionedDrafts(
PhabricatorUser $viewer,
array $inlines) {
$viewer_phid = $viewer->getPHID();
if (!$viewer_phid) {
return;
}
$inlines = mpull($inlines, null, 'getPHID');
$load = array();
foreach ($inlines as $key => $inline) {
if (!$inline->getIsEditing()) {
continue;
}
if ($inline->getAuthorPHID() !== $viewer_phid) {
continue;
}
$load[$key] = $inline;
}
if (!$load) {
return;
}
$drafts = PhabricatorVersionedDraft::loadDrafts(
array_keys($load),
$viewer_phid);
$drafts = mpull($drafts, null, 'getObjectPHID');
foreach ($inlines as $inline) {
$draft = idx($drafts, $inline->getPHID());
$inline->attachVersionedDraftForViewer($viewer, $draft);
}
}
public function setSyntheticAuthor($synthetic_author) {
$this->syntheticAuthor = $synthetic_author;
return $this;
}
public function getSyntheticAuthor() {
return $this->syntheticAuthor;
}
public function setStorageObject($storage_object) {
$this->storageObject = $storage_object;
return $this;
}
public function getStorageObject() {
if (!$this->storageObject) {
$this->storageObject = $this->newStorageObject();
}
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();
abstract public function setChangesetID($id);
abstract public function getChangesetID();
abstract public function supportsHiding();
abstract public function isHidden();
public function isDraft() {
return !$this->getTransactionPHID();
}
public function getTransactionPHID() {
return $this->getStorageObject()->getTransactionPHID();
}
public function isCompatible(PhabricatorInlineComment $comment) {
return
($this->getAuthorPHID() === $comment->getAuthorPHID()) &&
($this->getSyntheticAuthor() === $comment->getSyntheticAuthor()) &&
($this->getContent() === $comment->getContent());
}
public function setIsGhost($is_ghost) {
$this->isGhost = $is_ghost;
return $this;
}
public function getIsGhost() {
return $this->isGhost;
}
public function setContent($content) {
$this->getStorageObject()->setContent($content);
return $this;
}
public function getContent() {
return $this->getStorageObject()->getContent();
}
public function getID() {
return $this->getStorageObject()->getID();
}
public function getPHID() {
return $this->getStorageObject()->getPHID();
}
public function setIsNewFile($is_new) {
$this->getStorageObject()->setIsNewFile($is_new);
return $this;
}
public function getIsNewFile() {
return $this->getStorageObject()->getIsNewFile();
}
public function setFixedState($state) {
$this->getStorageObject()->setFixedState($state);
return $this;
}
public function setHasReplies($has_replies) {
$this->getStorageObject()->setHasReplies($has_replies);
return $this;
}
public function getHasReplies() {
return $this->getStorageObject()->getHasReplies();
}
public function getFixedState() {
return $this->getStorageObject()->getFixedState();
}
public function setLineNumber($number) {
$this->getStorageObject()->setLineNumber($number);
return $this;
}
public function getLineNumber() {
return $this->getStorageObject()->getLineNumber();
}
public function setLineLength($length) {
$this->getStorageObject()->setLineLength($length);
return $this;
}
public function getLineLength() {
return $this->getStorageObject()->getLineLength();
}
public function setAuthorPHID($phid) {
$this->getStorageObject()->setAuthorPHID($phid);
return $this;
}
public function getAuthorPHID() {
return $this->getStorageObject()->getAuthorPHID();
}
public function setReplyToCommentPHID($phid) {
$this->getStorageObject()->setReplyToCommentPHID($phid);
return $this;
}
public function getReplyToCommentPHID() {
return $this->getStorageObject()->getReplyToCommentPHID();
}
public function setIsDeleted($is_deleted) {
$this->getStorageObject()->setIsDeleted($is_deleted);
return $this;
}
public function getIsDeleted() {
return $this->getStorageObject()->getIsDeleted();
}
public function setIsEditing($is_editing) {
$this->getStorageObject()->setAttribute('editing', (bool)$is_editing);
return $this;
}
public function getIsEditing() {
return (bool)$this->getStorageObject()->getAttribute('editing', false);
}
public function setDocumentEngineKey($engine_key) {
$this->getStorageObject()->setAttribute('documentEngineKey', $engine_key);
return $this;
}
public function getDocumentEngineKey() {
return $this->getStorageObject()->getAttribute('documentEngineKey');
}
public function setStartOffset($offset) {
$this->getStorageObject()->setAttribute('startOffset', $offset);
return $this;
}
public function getStartOffset() {
return $this->getStorageObject()->getAttribute('startOffset');
}
public function setEndOffset($offset) {
$this->getStorageObject()->setAttribute('endOffset', $offset);
return $this;
}
public function getEndOffset() {
return $this->getStorageObject()->getAttribute('endOffset');
}
public function getDateModified() {
return $this->getStorageObject()->getDateModified();
}
public function getDateCreated() {
return $this->getStorageObject()->getDateCreated();
}
public function openTransaction() {
$this->getStorageObject()->openTransaction();
}
public function saveTransaction() {
$this->getStorageObject()->saveTransaction();
}
public function save() {
$this->getTransactionCommentForSave()->save();
return $this;
}
public function delete() {
$this->getStorageObject()->delete();
return $this;
}
public function makeEphemeral() {
$this->getStorageObject()->makeEphemeral();
return $this;
}
public function attachVersionedDraftForViewer(
PhabricatorUser $viewer,
PhabricatorVersionedDraft $draft = null) {
$key = $viewer->getCacheFragment();
$this->versionedDrafts[$key] = $draft;
return $this;
}
public function hasVersionedDraftForViewer(PhabricatorUser $viewer) {
$key = $viewer->getCacheFragment();
return array_key_exists($key, $this->versionedDrafts);
}
public function getVersionedDraftForViewer(PhabricatorUser $viewer) {
$key = $viewer->getCacheFragment();
if (!array_key_exists($key, $this->versionedDrafts)) {
throw new Exception(
pht(
'Versioned draft is not attached for user with fragment "%s".',
$key));
}
return $this->versionedDrafts[$key];
}
public function isVoidComment(PhabricatorUser $viewer) {
return $this->getContentStateForEdit($viewer)->isEmptyContentState();
}
public function getContentStateForEdit(PhabricatorUser $viewer) {
$state = $this->getContentState();
if ($this->hasVersionedDraftForViewer($viewer)) {
$versioned_draft = $this->getVersionedDraftForViewer($viewer);
if ($versioned_draft) {
$storage_map = $versioned_draft->getProperty('inline.state');
if (is_array($storage_map)) {
$state->readStorageMap($storage_map);
}
}
}
return $state;
}
protected function newContentState() {
return new PhabricatorDiffInlineCommentContentState();
}
public function newContentStateFromRequest(AphrontRequest $request) {
return $this->newContentState()->readFromRequest($request);
}
public function getContentState() {
$state = $this->newContentState();
$storage = $this->getStorageObject();
$storage_map = $storage->getAttribute('inline.state');
if (is_array($storage_map)) {
$state->readStorageMap($storage_map);
}
$state->setContentText($this->getContent());
return $state;
}
public function setContentState(PhabricatorInlineCommentContentState $state) {
$storage = $this->getStorageObject();
$storage_map = $state->newStorageMap();
$storage->setAttribute('inline.state', $storage_map);
$this->setContent($state->getContentText());
return $this;
}
public function getInlineContext() {
return $this->getStorageObject()->getInlineContext();
}
/* -( PhabricatorMarkupInterface Implementation )-------------------------- */
public function getMarkupFieldKey($field) {
$content = $this->getMarkupText($field);
return PhabricatorMarkupEngine::digestRemarkupContent($this, $content);
}
public function newMarkupEngine($field) {
return PhabricatorMarkupEngine::newDifferentialMarkupEngine();
}
public function getMarkupText($field) {
return $this->getContent();
}
public function didMarkupText($field, $output, PhutilMarkupEngine $engine) {
return $output;
}
public function shouldUseMarkupCache($field) {
return !$this->isDraft();
}
}
diff --git a/src/infrastructure/diff/query/PhabricatorDiffInlineCommentQuery.php b/src/infrastructure/diff/query/PhabricatorDiffInlineCommentQuery.php
index 85987c89a5..275a9a5aea 100644
--- a/src/infrastructure/diff/query/PhabricatorDiffInlineCommentQuery.php
+++ b/src/infrastructure/diff/query/PhabricatorDiffInlineCommentQuery.php
@@ -1,312 +1,382 @@
<?php
abstract class PhabricatorDiffInlineCommentQuery
extends PhabricatorApplicationTransactionCommentQuery {
+ const INLINE_CONTEXT_CACHE_VERSION = 1;
+
private $fixedStates;
private $needReplyToComments;
private $publishedComments;
private $publishableComments;
private $needHidden;
private $needAppliedDrafts;
private $needInlineContext;
abstract protected function buildInlineCommentWhereClauseParts(
AphrontDatabaseConnection $conn);
abstract public function withObjectPHIDs(array $phids);
abstract protected function loadHiddenCommentIDs(
$viewer_phid,
array $comments);
abstract protected function newInlineContextMap(array $inlines);
+ abstract protected function newInlineContextFromCacheData(array $map);
final public function withFixedStates(array $states) {
$this->fixedStates = $states;
return $this;
}
final public function needReplyToComments($need_reply_to) {
$this->needReplyToComments = $need_reply_to;
return $this;
}
final public function withPublishableComments($with_publishable) {
$this->publishableComments = $with_publishable;
return $this;
}
final public function withPublishedComments($with_published) {
$this->publishedComments = $with_published;
return $this;
}
final public function needHidden($need_hidden) {
$this->needHidden = $need_hidden;
return $this;
}
final public function needInlineContext($need_context) {
$this->needInlineContext = $need_context;
return $this;
}
final public function needAppliedDrafts($need_applied) {
$this->needAppliedDrafts = $need_applied;
return $this;
}
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = parent::buildWhereClauseParts($conn);
$alias = $this->getPrimaryTableAlias();
foreach ($this->buildInlineCommentWhereClauseParts($conn) as $part) {
$where[] = $part;
}
if ($this->fixedStates !== null) {
$where[] = qsprintf(
$conn,
'%T.fixedState IN (%Ls)',
$alias,
$this->fixedStates);
}
$show_published = false;
$show_publishable = false;
if ($this->publishableComments !== null) {
if (!$this->publishableComments) {
throw new Exception(
pht(
'Querying for comments that are "not publishable" is '.
'not supported.'));
}
$show_publishable = true;
}
if ($this->publishedComments !== null) {
if (!$this->publishedComments) {
throw new Exception(
pht(
'Querying for comments that are "not published" is '.
'not supported.'));
}
$show_published = true;
}
if ($show_publishable || $show_published) {
$clauses = array();
if ($show_published) {
$clauses[] = qsprintf(
$conn,
'%T.transactionPHID IS NOT NULL',
$alias);
}
if ($show_publishable) {
$viewer = $this->getViewer();
$viewer_phid = $viewer->getPHID();
// If the viewer has a PHID, unpublished comments they authored and
// have not deleted are visible.
if ($viewer_phid) {
$clauses[] = qsprintf(
$conn,
'%T.authorPHID = %s
AND %T.isDeleted = 0
AND %T.transactionPHID IS NULL ',
$alias,
$viewer_phid,
$alias,
$alias);
}
}
// We can end up with a known-empty query if we (for example) query for
// publishable comments and the viewer is logged-out.
if (!$clauses) {
throw new PhabricatorEmptyQueryException();
}
$where[] = qsprintf(
$conn,
'%LO',
$clauses);
}
return $where;
}
protected function willFilterPage(array $inlines) {
$viewer = $this->getViewer();
if ($this->needReplyToComments) {
$reply_phids = array();
foreach ($inlines as $inline) {
$reply_phid = $inline->getReplyToCommentPHID();
if ($reply_phid) {
$reply_phids[] = $reply_phid;
}
}
if ($reply_phids) {
$reply_inlines = newv(get_class($this), array())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($reply_phids)
->execute();
$reply_inlines = mpull($reply_inlines, null, 'getPHID');
} else {
$reply_inlines = array();
}
foreach ($inlines as $key => $inline) {
$reply_phid = $inline->getReplyToCommentPHID();
if (!$reply_phid) {
$inline->attachReplyToComment(null);
continue;
}
$reply = idx($reply_inlines, $reply_phid);
if (!$reply) {
$this->didRejectResult($inline);
unset($inlines[$key]);
continue;
}
$inline->attachReplyToComment($reply);
}
}
if (!$inlines) {
return $inlines;
}
$need_drafts = $this->needAppliedDrafts;
$drop_void = $this->publishableComments;
$convert_objects = ($need_drafts || $drop_void);
if ($convert_objects) {
$inlines = mpull($inlines, 'newInlineCommentObject');
PhabricatorInlineComment::loadAndAttachVersionedDrafts(
$viewer,
$inlines);
if ($need_drafts) {
// Don't count void inlines when considering draft state.
foreach ($inlines as $key => $inline) {
if ($inline->isVoidComment($viewer)) {
$this->didRejectResult($inline->getStorageObject());
unset($inlines[$key]);
continue;
}
// For other inlines: if they have a nonempty draft state, set their
// content to the draft state content. We want to submit the comment
// as it is currently shown to the user, not as it was stored the last
// time they clicked "Save".
$draft_state = $inline->getContentStateForEdit($viewer);
if (!$draft_state->isEmptyContentState()) {
$inline->setContentState($draft_state);
}
}
}
// If we're loading publishable comments, discard any comments that are
// empty.
if ($drop_void) {
foreach ($inlines as $key => $inline) {
if ($inline->getTransactionPHID()) {
continue;
}
if ($inline->isVoidComment($viewer)) {
$this->didRejectResult($inline->getStorageObject());
unset($inlines[$key]);
continue;
}
}
}
$inlines = mpull($inlines, 'getStorageObject');
}
return $inlines;
}
protected function didFilterPage(array $inlines) {
$viewer = $this->getViewer();
if ($this->needHidden) {
$viewer_phid = $viewer->getPHID();
if ($viewer_phid) {
$hidden = $this->loadHiddenCommentIDs(
$viewer_phid,
$inlines);
} else {
$hidden = array();
}
foreach ($inlines as $inline) {
$inline->attachIsHidden(isset($hidden[$inline->getID()]));
}
}
if ($this->needInlineContext) {
$need_context = array();
foreach ($inlines as $inline) {
$object = $inline->newInlineCommentObject();
if ($object->getDocumentEngineKey() !== null) {
$inline->attachInlineContext(null);
continue;
}
$need_context[] = $inline;
}
if ($need_context) {
- $context_map = $this->newInlineContextMap($need_context);
+ $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);
- foreach ($need_context as $key => $inline) {
- $inline->attachInlineContext(idx($context_map, $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;
}
- return $inlines;
+ 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
// ton of context is silly.
// Examine each line until we find one that looks "useful" (not just
// whitespace or a single bracket). Once we find a useful piece of context
// to anchor the text, discard the rest of the lines beyond it.
if ($is_head) {
$lines = array_reverse($lines, true);
}
$saw_context = false;
foreach ($lines as $key => $line) {
if ($saw_context) {
unset($lines[$key]);
continue;
}
$saw_context = (strlen(trim($line)) > 3);
}
if ($is_head) {
$lines = array_reverse($lines, true);
}
return $lines;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jun 10, 3:55 PM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
140045
Default Alt Text
(29 KB)

Event Timeline