1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 16:52:41 +01:00

Fix limits in queries

Summary: I think this is simpler? Includes test cases.

Test Plan: Ran tests. Loaded /paste/.

Reviewers: vrana, nh

Reviewed By: vrana

CC: aran

Differential Revision: https://secure.phabricator.com/D3209
This commit is contained in:
epriestley 2012-08-08 18:55:07 -07:00
parent 9debf779d6
commit 3460da5f34
2 changed files with 37 additions and 25 deletions

View file

@ -136,6 +136,36 @@ final class PhabricatorPolicyTestCase extends PhabricatorTestCase {
}
/**
* Test limits.
*/
public function testLimits() {
$results = array(
$this->buildObject(PhabricatorPolicies::POLICY_USER),
$this->buildObject(PhabricatorPolicies::POLICY_USER),
$this->buildObject(PhabricatorPolicies::POLICY_USER),
$this->buildObject(PhabricatorPolicies::POLICY_USER),
$this->buildObject(PhabricatorPolicies::POLICY_USER),
$this->buildObject(PhabricatorPolicies::POLICY_USER),
);
$query = new PhabricatorPolicyTestQuery();
$query->setResults($results);
$query->setViewer($this->buildUser('user'));
$this->assertEqual(
3,
count($query->setLimit(3)->setOffset(0)->execute()),
'Limits work.');
$this->assertEqual(
2,
count($query->setLimit(3)->setOffset(4)->execute()),
'Limit + offset work.');
}
/**
* Test an object for visibility across multiple user specifications.
*/

View file

@ -153,34 +153,16 @@ abstract class PhabricatorPolicyQuery extends PhabricatorOffsetPagedQuery {
$limit = (int)$this->getLimit();
$count = 0;
$need = null;
if ($offset) {
$need = $offset + $limit;
}
$need = $offset + $limit;
$this->willExecute();
do {
// Figure out how many results to load. "0" means "all results".
$load = 0;
if ($need && ($count < $offset)) {
// This cap is just an arbitrary limit to keep memory usage from going
// crazy for large offsets; we can't execute them efficiently, but
// it should be possible to execute them without crashing.
$load = min($need, 1024);
} else if ($limit) {
// Otherwise, just load the number of rows we're after. Note that it
// might be more efficient to load more rows than this (if we expect
// about 5% of objects to be filtered, loading 105% of the limit might
// be better) or fewer rows than this (if we already have 95 rows and
// only need 100, loading only 5 rows might be better), but we currently
// just use the simplest heuristic since we don't have enough data
// about policy queries in the real world to tweak it.
$load = $limit;
if ($need) {
$this->rawResultLimit = min($need - $count, 1024);
} else {
$this->rawResultLimit = 0;
}
$this->rawResultLimit = $load;
$page = $this->loadPage();
@ -202,13 +184,13 @@ abstract class PhabricatorPolicyQuery extends PhabricatorOffsetPagedQuery {
}
}
if (!$load) {
if (!$this->rawResultLimit) {
// If we don't have a load count, we loaded all the results. We do
// not need to load another page.
break;
}
if (count($page) < $load) {
if (count($page) < $this->rawResultLimit) {
// If we have a load count but the unfiltered results contained fewer
// objects, we know this was the last page of objects; we do not need
// to load another page because we can deduce it would be empty.