...
To achieve reverseRange and reverseAll, we can generate a new class like below in Rejected Alternatives part, we can also reuse lots of code from RangeQuery
, to simplify the code we choose reuse the RangeQuery
code.
We add a variable reverse
in RangeQuery
, the default value is false, we want do reverseRange or reverseAll, we can set it to true.
Then we generate two public methods:
The first one is isReverse()
, if this method return true, do reverseQuery otherwise do rangeQuery
the second method is setReverse()
, if we want the query do reverseQuery, we can use this method to set the reverse
to true, so this time, rangeQuery Stand for reverseQuery.
Use bounded reverseQuery to achieve reverseRange and use unbounded reverseQuery to achieve reverseAll.
Code Block | ||||
---|---|---|---|---|
| ||||
/**
* Interactive query for issuing range queries and scans over KeyValue stores.
* <p>
* A range query retrieves a set of records, specified using an upper and/or lower bound on the keys.
* <p>
* A scan query retrieves all records contained | ||||
Code Block | ||||
| ||||
@Evolving public final class ReverseRangeQuery<K, V> implements Query<KeyValueIterator<K, V>> { private final Optional<K> lower; private final Optional<K> upper; private ReverseRangeQuery(final Optional<K> lower, final Optional<K> upper) { this.lower = lower; this.upper = upper; } /** * Interactive range query using a lower and upper bound to filter the keys returned. * @param lower The key that specifies the lower bound of the range * @param upper The key that specifies the upper bound of the range * @param <K> The key type * @param <V> The value type */ public static <K, V> ReverseRangeQuery<K, V> withRange(final K lower, final K upper) { return new ReverseRangeQuery<>(Optional.ofNullable(lower), Optional.ofNullable(upper)); } /** * Interactive range query using an upper bound to filter the keys returned. * If both <K,V> are null, RangQuery returns a full range scan. * @param upper The key that specifies the upper bound of the range * @param <K> The key type * @param <V> The value type */ public static <K, V> ReverseRangeQuery<K, V> withUpperBound(final K upper) { return new ReverseRangeQuery<>(Optional.empty(), Optional.of(upper)); } /** * Interactive range query using a lower bound to filter the keys returned. * @param lower The key that specifies the lower bound of the range * @param <K> The key type * @param <V> The value type */ public static <K, V> ReverseRangeQuery<K, V> withLowerBound(final K lower) { return new ReverseRangeQuery<>(Optional.of(lower), Optional.empty()); } /** * Interactive scan query that returns all records in the store. * <p> * @paramIf <K>the Thereverse keyis type false, do rangeQuery. If the *reverse @paramis <V>true Thedo value typereverseQuery */ @Evolving public final public static <Kclass RangeQuery<K, V> implements ReverseRangeQuery<KQuery<KeyValueIterator<K, V>V>> withNoBounds() {{ ... private return new ReverseRangeQuery<>(Optional.empty(), Optional.empty()); }boolean reverse; /** * TheCheck lowerwhether bound of the query,Query ifis specifiedreverseQuery. */ public Optional<K>boolean getLowerBoundisReverse() { return lowerreverse; } /** * The upper bound of Set the query,Query ifto specifiedreverseQuery. */ public Optional<K>void getUpperBoundsetReverse() { this.reverse return= uppertrue; } } |
We add a variable reverse
in RangeQuery
, the default value is false, we want do reverseRange or reverseAll, we can set it to true.
Then we generate two public methods:
The first one is isReverse()
, if this method return true, do reverseQuery otherwise do rangeQuery
the second method is setReverse()
, if we want the query do reverseQuery, we can use this method to set the reverse
to true, so this time, rangeQuery Stand for reverseQuery.
...
} |
Test Plan
This time, we aim to implement reverseRange and reverseAll. To ensure the accuracy of the results for both, modifications to IQv2StoreIntegrationTest
are necessary. Previously, we stored query results in a set, which doesn't retain order. I've since switched to using a list to store the query results. This allows us to discern the differences between rangeQuery and reverseQuery.
Compatibility, Deprecation, and Migration Plan
- Because we have already have
RangeQuery
class, so we can update some code to achieve reverseRange and reverseAll. - Since nothing is deprecated in this KIP, users have no need to migrate unless they want to.
Rejected Alternatives
At first, we planned to implement ReverseRangeQuery
from scratch. However, after discussions, we decided to reuse some of the RangeQuery
code, allowing RangeQuery
to possess the reverseQuery functionality. Therefore, in the end, we chose not to add a new ReverseRangeQuery
class but instead to enhance the RangeQuery
with new featuresUse bounded reverseQuery to achieve reverseRange and use unbounded reverseQuery to achieve reverseAll.
Code Block | |||||
---|---|---|---|---|---|
| |||||
/** * Interactive query for issuing range queries and scans over KeyValue stores. * <p> * A range query retrieves a set of records, specified using an upper and/or lower bound on the keys. * <p> * A scan query retrieves all records contained in the store. * <p> * If the reverse is false, do rangeQuery. If the reverse is true do reverseQuery */ @Evolving public final class RangeQuery<KReverseRangeQuery<K, V> implements Query<KeyValueIterator<K, V>> { private final Optional<K> lower; private final Optional<K> upper; private boolean reverse; private RangeQueryReverseRangeQuery(final Optional<K> lower, final Optional<K> upper) { this.lower = lower; this.upper = upper; } /** * Interactive range query using a lower and upper bound to filter the keys returned. * @param lower The key that specifies the lower bound of the range * @param upper The key that specifies the upper bound of the range * @param <K> The key type * @param <V> The value type */ public static <K, V> RangeQuery<KReverseRangeQuery<K, V> withRange(final K lower, final K upper) { return new RangeQuery<>ReverseRangeQuery<>(Optional.ofNullable(lower), Optional.ofNullable(upper)); } /** * Check whether the Query is reverseQuery. */ public boolean isReverse() { return reverse; } /** * Set the Query to reverseQuery. */ public void setReverse() { this.reverse = true; } /** * Interactive range query using an upper bound to filter the keys returned. * If both <K,V> are null, RangQuery returns a full range scan. * @param upper The key that specifies the upper bound of the range * @param <K> The key type * @param <V> The value type */ public static <K, V> RangeQuery<KReverseRangeQuery<K, V> withUpperBound(final K upper) { return new RangeQuery<>ReverseRangeQuery<>(Optional.empty(), Optional.of(upper)); } /** * Interactive range query using a lower bound to filter the keys returned. * @param lower The key that specifies the lower bound of the range * @param <K> The key type * @param <V> The value type */ public static <K, V> RangeQuery<KReverseRangeQuery<K, V> withLowerBound(final K lower) { return new RangeQuery<>ReverseRangeQuery<>(Optional.of(lower), Optional.empty()); } /** * Interactive scan query that returns all records in the store. * @param <K> The key type * @param <V> The value type */ public static <K, V> RangeQuery<KReverseRangeQuery<K, V> withNoBounds() { return new RangeQuery<>ReverseRangeQuery<>(Optional.empty(), Optional.empty()); } /** * The lower bound of the query, if specified. */ public Optional<K> getLowerBound() { return lower; } /** * The upper bound of the query, if specified */ public Optional<K> getUpperBound() { return upper; } } |
Test Plan
This time, we aim to implement reverseRange and reverseAll. To ensure the accuracy of the results for both, modifications to IQv2StoreIntegrationTest
are necessary. Previously, we stored query results in a set, which doesn't retain order. I've since switched to using a list to store the query results. This allows us to discern the differences between rangeQuery and reverseQuery.
Compatibility, Deprecation, and Migration Plan
- Because we have already have
RangeQuery
class, so we can update some code to achieve reverseRange and reverseAll. - Since nothing is deprecated in this KIP, users have no need to migrate unless they want to.
Rejected Alternatives
...
|