Fix paginationType NONE to run further queries only if needed

If the first query to the index did not fill the full limit the caller
wants, we paginate to obtain more results. However, subsequent queries
are not needed if the previous query returned less results
than the limit.

This is a follow up of the change 413358 [1], that has reintroduced the
issue fixed in change 344695.

[1]: https://gerrit-review.googlesource.com/c/gerrit/+/413358/comment/85bca522_2b3552b2/

Bug: Issue 330195358
Release-Notes: Fix pagination to stop querying when there are no more results
Change-Id: Ie326f3628f5312a83bf83177a3fa5134f042b59a
diff --git a/java/com/google/gerrit/index/query/PaginatingSource.java b/java/com/google/gerrit/index/query/PaginatingSource.java
index 9ec64e6..d89fe66 100644
--- a/java/com/google/gerrit/index/query/PaginatingSource.java
+++ b/java/com/google/gerrit/index/query/PaginatingSource.java
@@ -55,12 +55,9 @@
           List<T> r = new ArrayList<>();
           T last = null;
           int pageResultSize = 0;
-          boolean skipped = false;
           for (T data : buffer(resultSet)) {
             if (!isMatchable() || match(data)) {
               r.add(data);
-            } else {
-              skipped = true;
             }
             last = data;
             pageResultSize++;
@@ -69,16 +66,16 @@
           if (last != null && source instanceof Paginated) {
             // Restart source and continue if we have not filled the
             // full limit the caller wants.
-            //
+            @SuppressWarnings("unchecked")
+            Paginated<T> p = (Paginated<T>) source;
+            QueryOptions opts = p.getOptions();
+            final int limit = opts.limit();
+
             // TODO: this fix is only for the stable branches and the real refactoring would be to
             // restore the logic
             // for the filtering in AndSource (L58 - 64) as per
             // https://gerrit-review.googlesource.com/c/gerrit/+/345634/9
             if (!indexConfig.paginationType().equals(PaginationType.NONE)) {
-              @SuppressWarnings("unchecked")
-              Paginated<T> p = (Paginated<T>) source;
-              QueryOptions opts = p.getOptions();
-              final int limit = opts.limit();
               int pageSize = opts.pageSize();
               int pageSizeMultiplier = opts.pageSizeMultiplier();
               Object searchAfter = resultSet.searchAfter();
@@ -100,20 +97,16 @@
                 searchAfter = next.searchAfter();
               }
             } else {
-              @SuppressWarnings("unchecked")
-              Paginated<T> p = (Paginated<T>) source;
-              while (skipped && r.size() < p.getOptions().limit() + start) {
-                skipped = false;
-                ResultSet<T> next = p.restart(pageResultSize);
-
+              int nextStart = pageResultSize;
+              while (pageResultSize == limit && r.size() < limit) {
+                ResultSet<T> next = p.restart(nextStart);
                 for (T data : buffer(next)) {
                   if (match(data)) {
                     r.add(data);
-                  } else {
-                    skipped = true;
                   }
                   pageResultSize++;
                 }
+                nextStart += pageResultSize;
               }
             }
           }