You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by th...@apache.org on 2012/10/24 13:50:54 UTC
svn commit: r1401633 -
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
Author: thomasm
Date: Wed Oct 24 11:50:54 2012
New Revision: 1401633
URL: http://svn.apache.org/viewvc?rev=1401633&view=rev
Log:
OAK-308 NodeIterator limit and offset don't work as expected
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java?rev=1401633&r1=1401632&r2=1401633&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java Wed Oct 24 11:50:54 2012
@@ -308,7 +308,13 @@ public class Query {
null);
it = Arrays.asList(r).iterator();
} else {
- it = new RowIterator(root, limit, offset);
+ if (orderings == null) {
+ // can apply limit and offset directly
+ it = new RowIterator(root, limit, offset);
+ } else {
+ // read and order first; skip and limit afterwards
+ it = new RowIterator(root, Long.MAX_VALUE, 0);
+ }
long resultCount = 0;
if (orderings != null) {
// TODO "order by" is not necessary if the used index returns
@@ -318,9 +324,25 @@ public class Query {
ResultRowImpl r = it.next();
list.add(r);
}
- resultCount = size = list.size();
Collections.sort(list);
+ // if limit is set, possibly remove the tailing entries
+ // for list size 10, offset 2, limit 5: remove 3
+ resultCount = list.size();
+ // avoid overflow (both offset and limit could be Long.MAX_VALUE)
+ long keep = Math.min(list.size(), offset) + Math.min(list.size(), limit);
+ while (list.size() > keep) {
+ // remove tail entries right now, to save memory (don't copy)
+ // remove the entries starting at the end,
+ // to avoid n^2 performance
+ list.remove(list.size() - 1);
+ }
it = list.iterator();
+ // skip the head (this is more efficient than removing
+ // if there are many entries)
+ for (int i = 0; i < offset && it.hasNext(); i++) {
+ it.next();
+ }
+ size = list.size() - offset;
} else if (measure) {
while (it.hasNext()) {
resultCount++;