From 63ff050e4d48f8b997905e9e0a11d944ea6038a6 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Mon, 14 Apr 2008 03:18:32 +0000 Subject: Support query fetch limits. --- .../com/amazon/carbonado/qe/AbstractQuery.java | 22 +++++++++++++++++++++ .../amazon/carbonado/qe/AbstractQueryExecutor.java | 23 +++++++++++++++++++++- .../carbonado/qe/DelegatedQueryExecutor.java | 4 ++++ .../java/com/amazon/carbonado/qe/EmptyQuery.java | 16 +++++++++++++++ .../com/amazon/carbonado/qe/QueryExecutor.java | 7 +++++++ .../com/amazon/carbonado/qe/StandardQuery.java | 23 ++++++++++++++++++++++ 6 files changed, 94 insertions(+), 1 deletion(-) (limited to 'src/main/java/com/amazon/carbonado/qe') diff --git a/src/main/java/com/amazon/carbonado/qe/AbstractQuery.java b/src/main/java/com/amazon/carbonado/qe/AbstractQuery.java index 7639348..767b039 100644 --- a/src/main/java/com/amazon/carbonado/qe/AbstractQuery.java +++ b/src/main/java/com/amazon/carbonado/qe/AbstractQuery.java @@ -129,4 +129,26 @@ public abstract class AbstractQuery implements Query, App @Override public abstract boolean equals(Object obj); + + /** + * Called by sliced fetch to ensure that arguments are valid. + * + * @return false if from is 0 and to is null + * @throws IllegalArgumentException if arguments are invalid + * @since 1.2 + */ + protected boolean checkSliceArguments(long from, Long to) { + if (from < 0) { + throw new IllegalArgumentException("Slice from is negative: " + from); + } + if (to == null) { + if (from == 0) { + return false; + } + } else if (from > to) { + throw new IllegalArgumentException + ("Slice from is more than to: " + from + " > " + to); + } + return true; + } } diff --git a/src/main/java/com/amazon/carbonado/qe/AbstractQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/AbstractQueryExecutor.java index dc67fc1..8a8a127 100644 --- a/src/main/java/com/amazon/carbonado/qe/AbstractQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/AbstractQueryExecutor.java @@ -24,6 +24,9 @@ import com.amazon.carbonado.Cursor; import com.amazon.carbonado.FetchException; import com.amazon.carbonado.Storable; +import com.amazon.carbonado.cursor.LimitCursor; +import com.amazon.carbonado.cursor.SkipCursor; + import com.amazon.carbonado.filter.FilterValues; /** @@ -37,7 +40,25 @@ public abstract class AbstractQueryExecutor implements Query } /** - * Counts results by opening a cursor and skipping entries. + * Produces a slice via skip and limit cursors. Subclasses are encouraged + * to override with a more efficient implementation. + * + * @since 1.2 + */ + public Cursor fetch(FilterValues values, long from, Long to) throws FetchException { + Cursor cursor = fetch(values); + if (from > 0) { + cursor = new SkipCursor(cursor, from); + } + if (to != null) { + cursor = new LimitCursor(cursor, to - from); + } + return cursor; + } + + /** + * Counts results by opening a cursor and skipping entries. Subclasses are + * encouraged to override with a more efficient implementation. */ public long count(FilterValues values) throws FetchException { Cursor cursor = fetch(values); diff --git a/src/main/java/com/amazon/carbonado/qe/DelegatedQueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/DelegatedQueryExecutor.java index b4bc0a3..3ec209d 100644 --- a/src/main/java/com/amazon/carbonado/qe/DelegatedQueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/DelegatedQueryExecutor.java @@ -95,6 +95,10 @@ public class DelegatedQueryExecutor implements QueryExecutor return applyFilterValues(values).fetch(); } + public Cursor fetch(FilterValues values, long from, Long to) throws FetchException { + return applyFilterValues(values).fetch(from, to); + } + public long count(FilterValues values) throws FetchException { return applyFilterValues(values).count(); } diff --git a/src/main/java/com/amazon/carbonado/qe/EmptyQuery.java b/src/main/java/com/amazon/carbonado/qe/EmptyQuery.java index f3d54f5..9754019 100644 --- a/src/main/java/com/amazon/carbonado/qe/EmptyQuery.java +++ b/src/main/java/com/amazon/carbonado/qe/EmptyQuery.java @@ -212,6 +212,14 @@ public final class EmptyQuery extends AbstractQuery { return EmptyCursor.the(); } + /** + * Always returns an {@link EmptyCursor}. + */ + public Cursor fetch(long from, Long to) { + checkSliceArguments(from, to); + return EmptyCursor.the(); + } + /** * Always returns an {@link EmptyCursor}. */ @@ -219,6 +227,14 @@ public final class EmptyQuery extends AbstractQuery { return EmptyCursor.the(); } + /** + * Always returns an {@link EmptyCursor}. + */ + public Cursor fetchAfter(S start, long from, Long to) { + checkSliceArguments(from, to); + return EmptyCursor.the(); + } + /** * Always throws {@link PersistNoneException}. */ diff --git a/src/main/java/com/amazon/carbonado/qe/QueryExecutor.java b/src/main/java/com/amazon/carbonado/qe/QueryExecutor.java index b0ab801..6b5a864 100644 --- a/src/main/java/com/amazon/carbonado/qe/QueryExecutor.java +++ b/src/main/java/com/amazon/carbonado/qe/QueryExecutor.java @@ -45,6 +45,13 @@ public interface QueryExecutor { */ Cursor fetch(FilterValues values) throws FetchException; + /** + * Returns a new cursor using the given filter values and slice. + * + * @since 1.2 + */ + Cursor fetch(FilterValues values, long from, Long to) throws FetchException; + /** * Counts the query results using the given filter values. */ diff --git a/src/main/java/com/amazon/carbonado/qe/StandardQuery.java b/src/main/java/com/amazon/carbonado/qe/StandardQuery.java index 5596c32..10fdf43 100644 --- a/src/main/java/com/amazon/carbonado/qe/StandardQuery.java +++ b/src/main/java/com/amazon/carbonado/qe/StandardQuery.java @@ -217,6 +217,18 @@ public abstract class StandardQuery extends AbstractQuery } } + public Cursor fetch(long from, Long to) throws FetchException { + if (!checkSliceArguments(from, to)) { + return fetch(); + } + try { + QueryHints hints = QueryHints.emptyHints().with(QueryHint.CONSUME_SLICE); + return executorFactory().executor(mFilter, mOrdering, hints).fetch(mValues, from, to); + } catch (RepositoryException e) { + throw e.toFetchException(); + } + } + public Cursor fetchAfter(S start) throws FetchException { OrderingList orderings; if (start == null || (orderings = mOrdering).size() == 0) { @@ -225,6 +237,17 @@ public abstract class StandardQuery extends AbstractQuery return buildAfter(start, orderings).fetch(); } + public Cursor fetchAfter(S start, long from, Long to) throws FetchException { + if (!checkSliceArguments(from, to)) { + return fetchAfter(start); + } + OrderingList orderings; + if (start == null || (orderings = mOrdering).size() == 0) { + return fetch(from, to); + } + return buildAfter(start, orderings).fetch(from, to); + } + private Query buildAfter(S start, OrderingList orderings) throws FetchException { Class storableType = getStorableType(); Filter orderFilter = Filter.getClosedFilter(storableType); -- cgit v1.2.3