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:
parent
9debf779d6
commit
3460da5f34
2 changed files with 37 additions and 25 deletions
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue