1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-18 12:52:42 +01:00

Optimize filtering private threads when querying Conpherence

Summary:
Because most threads are private, this query can overheat the policy filter (today, probably only on this install).

Improve the common case by skipping "Visible To: Room Participants" threads if the viewer isn't a participant. This means they don't hit the application and don't count toward overheating the filter.

Test Plan: Viewed Conpherence threads.

Reviewers: chad

Reviewed By: chad

Differential Revision: https://secure.phabricator.com/D16740
This commit is contained in:
epriestley 2016-10-20 13:28:24 -07:00
parent 7678f412be
commit 4058726b3a

View file

@ -151,61 +151,100 @@ final class ConpherenceThreadQuery
} }
} }
protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {
$joins = array(); $joins = parent::buildJoinClauseParts($conn);
if ($this->participantPHIDs !== null) { if ($this->participantPHIDs !== null) {
$joins[] = qsprintf( $joins[] = qsprintf(
$conn_r, $conn,
'JOIN %T p ON p.conpherencePHID = thread.phid', 'JOIN %T p ON p.conpherencePHID = thread.phid',
id(new ConpherenceParticipant())->getTableName()); id(new ConpherenceParticipant())->getTableName());
} }
if (strlen($this->fulltext)) { if (strlen($this->fulltext)) {
$joins[] = qsprintf( $joins[] = qsprintf(
$conn_r, $conn,
'JOIN %T idx ON idx.threadPHID = thread.phid', 'JOIN %T idx ON idx.threadPHID = thread.phid',
id(new ConpherenceIndex())->getTableName()); id(new ConpherenceIndex())->getTableName());
} }
$joins[] = $this->buildApplicationSearchJoinClause($conn_r); // See note in buildWhereClauseParts() about this optimization.
return implode(' ', $joins); $viewer = $this->getViewer();
if (!$viewer->isOmnipotent() && $viewer->isLoggedIn()) {
$joins[] = qsprintf(
$conn,
'LEFT JOIN %T vp ON vp.conpherencePHID = thread.phid
AND vp.participantPHID = %s',
id(new ConpherenceParticipant())->getTableName(),
$viewer->getPHID());
}
return $joins;
} }
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = array(); $where = parent::buildWhereClauseParts($conn);
$where[] = $this->buildPagingClause($conn_r); // Optimize policy filtering of private rooms. If we are not looking for
// particular rooms by ID or PHID, we can just skip over any rooms with
// "View Policy: Room Participants" if the viewer isn't a participant: we
// know they won't be able to see the room.
// This avoids overheating browse/search queries, since it's common for
// a large number of rooms to be private and have this view policy.
$viewer = $this->getViewer();
$can_optimize =
!$viewer->isOmnipotent() &&
($this->ids === null) &&
($this->phids === null);
if ($can_optimize) {
$members_policy = id(new ConpherenceThreadMembersPolicyRule())
->getObjectPolicyFullKey();
if ($viewer->isLoggedIn()) {
$where[] = qsprintf(
$conn,
'thread.viewPolicy != %s OR vp.participantPHID = %s',
$members_policy,
$viewer->getPHID());
} else {
$where[] = qsprintf(
$conn,
'thread.viewPolicy != %s',
$members_policy);
}
}
if ($this->ids !== null) { if ($this->ids !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn,
'thread.id IN (%Ld)', 'thread.id IN (%Ld)',
$this->ids); $this->ids);
} }
if ($this->phids !== null) { if ($this->phids !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn,
'thread.phid IN (%Ls)', 'thread.phid IN (%Ls)',
$this->phids); $this->phids);
} }
if ($this->participantPHIDs !== null) { if ($this->participantPHIDs !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn,
'p.participantPHID IN (%Ls)', 'p.participantPHID IN (%Ls)',
$this->participantPHIDs); $this->participantPHIDs);
} }
if (strlen($this->fulltext)) { if (strlen($this->fulltext)) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn,
'MATCH(idx.corpus) AGAINST (%s IN BOOLEAN MODE)', 'MATCH(idx.corpus) AGAINST (%s IN BOOLEAN MODE)',
$this->fulltext); $this->fulltext);
} }
return $this->formatWhereClause($where); return $where;
} }
private function loadParticipantsAndInitHandles(array $conpherences) { private function loadParticipantsAndInitHandles(array $conpherences) {