-
Notifications
You must be signed in to change notification settings - Fork 15.1k
KAFKA-13211: add support for infinite range query for WindowStore #11227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f270e18
5cb3685
55551f3
88cc410
688c422
db0c299
4dccb30
eb19d12
d3cee05
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -244,7 +244,7 @@ public KeyValueIterator<Windowed<Bytes>, byte[]> fetch(final Bytes keyFrom, | |
| final Bytes keyTo, | ||
| final long timeFrom, | ||
| final long timeTo) { | ||
| if (keyFrom.compareTo(keyTo) > 0) { | ||
| if (keyFrom != null && keyTo != null && keyFrom.compareTo(keyTo) > 0) { | ||
| LOG.warn("Returning empty iterator for fetch with invalid key range: from > to. " + | ||
| "This may be due to range arguments set in the wrong order, " + | ||
| "or serdes that don't preserve ordering when lexicographically comparing the serialized bytes. " + | ||
|
|
@@ -266,8 +266,8 @@ public KeyValueIterator<Windowed<Bytes>, byte[]> fetch(final Bytes keyFrom, | |
| new CacheIteratorWrapper(keyFrom, keyTo, timeFrom, timeTo, true) : | ||
| context.cache().range( | ||
| cacheName, | ||
| cacheFunction.cacheKey(keySchema.lowerRange(keyFrom, timeFrom)), | ||
| cacheFunction.cacheKey(keySchema.upperRange(keyTo, timeTo)) | ||
| keyFrom == null ? null : cacheFunction.cacheKey(keySchema.lowerRange(keyFrom, timeFrom)), | ||
| keyTo == null ? null : cacheFunction.cacheKey(keySchema.upperRange(keyTo, timeTo)) | ||
| ); | ||
|
|
||
| final HasNextCondition hasNextCondition = keySchema.hasNextCondition(keyFrom, keyTo, timeFrom, timeTo); | ||
|
|
@@ -289,7 +289,7 @@ public KeyValueIterator<Windowed<Bytes>, byte[]> backwardFetch(final Bytes keyFr | |
| final Bytes keyTo, | ||
| final long timeFrom, | ||
| final long timeTo) { | ||
| if (keyFrom.compareTo(keyTo) > 0) { | ||
| if (keyFrom != null && keyTo != null && keyFrom.compareTo(keyTo) > 0) { | ||
| LOG.warn("Returning empty iterator for fetch with invalid key range: from > to. " | ||
| + "This may be due to serdes that don't preserve ordering when lexicographically comparing the serialized bytes. " + | ||
| "Note that the built-in numerical serdes do not follow this for negative numbers"); | ||
|
|
@@ -310,8 +310,8 @@ public KeyValueIterator<Windowed<Bytes>, byte[]> backwardFetch(final Bytes keyFr | |
| new CacheIteratorWrapper(keyFrom, keyTo, timeFrom, timeTo, false) : | ||
| context.cache().reverseRange( | ||
| cacheName, | ||
| cacheFunction.cacheKey(keySchema.lowerRange(keyFrom, timeFrom)), | ||
| cacheFunction.cacheKey(keySchema.upperRange(keyTo, timeTo)) | ||
| keyFrom == null ? null : cacheFunction.cacheKey(keySchema.lowerRange(keyFrom, timeFrom)), | ||
| keyTo == null ? null : cacheFunction.cacheKey(keySchema.upperRange(keyTo, timeTo)) | ||
| ); | ||
|
|
||
| final HasNextCondition hasNextCondition = keySchema.hasNextCondition(keyFrom, keyTo, timeFrom, timeTo); | ||
|
|
@@ -573,12 +573,14 @@ private void setCacheKeyRange(final long lowerRangeEndTime, final long upperRang | |
| throw new IllegalStateException("Error iterating over segments: segment interval has changed"); | ||
| } | ||
|
|
||
| if (keyFrom.equals(keyTo)) { | ||
| if (keyFrom != null && keyTo != null && keyFrom.equals(keyTo)) { | ||
| cacheKeyFrom = cacheFunction.cacheKey(segmentLowerRangeFixedSize(keyFrom, lowerRangeEndTime)); | ||
| cacheKeyTo = cacheFunction.cacheKey(segmentUpperRangeFixedSize(keyTo, upperRangeEndTime)); | ||
| } else { | ||
| cacheKeyFrom = cacheFunction.cacheKey(keySchema.lowerRange(keyFrom, lowerRangeEndTime), currentSegmentId); | ||
| cacheKeyTo = cacheFunction.cacheKey(keySchema.upperRange(keyTo, timeTo), currentSegmentId); | ||
| cacheKeyFrom = keyFrom == null ? null : | ||
| cacheFunction.cacheKey(keySchema.lowerRange(keyFrom, lowerRangeEndTime), currentSegmentId); | ||
| cacheKeyTo = keyTo == null ? null : | ||
| cacheFunction.cacheKey(keySchema.upperRange(keyTo, timeTo), currentSegmentId); | ||
|
Comment on lines
580
to
583
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -213,12 +213,9 @@ KeyValueIterator<Windowed<Bytes>, byte[]> fetch(final Bytes from, | |
| final long timeFrom, | ||
| final long timeTo, | ||
| final boolean forward) { | ||
| Objects.requireNonNull(from, "from key cannot be null"); | ||
| Objects.requireNonNull(to, "to key cannot be null"); | ||
|
|
||
| removeExpiredSegments(); | ||
|
|
||
| if (from.compareTo(to) > 0) { | ||
| if (from != null && to != null && from.compareTo(to) > 0) { | ||
| LOG.warn("Returning empty iterator for fetch with invalid key range: from > to. " + | ||
| "This may be due to range arguments set in the wrong order, " + | ||
| "or serdes that don't preserve ordering when lexicographically comparing the serialized bytes. " + | ||
|
|
@@ -397,7 +394,8 @@ private WrappedWindowedKeyValueIterator registerNewWindowedKeyValueIterator(fina | |
| final Bytes to = (retainDuplicates && keyTo != null) ? wrapForDups(keyTo, Integer.MAX_VALUE) : keyTo; | ||
|
|
||
| final WrappedWindowedKeyValueIterator iterator = | ||
| new WrappedWindowedKeyValueIterator(from, | ||
| new WrappedWindowedKeyValueIterator( | ||
| from, | ||
| to, | ||
| segmentIterator, | ||
| openIterators::remove, | ||
|
|
@@ -462,14 +460,31 @@ public boolean hasNext() { | |
| } | ||
|
|
||
| final Bytes key = getKey(next.key); | ||
| if (key.compareTo(getKey(keyFrom)) >= 0 && key.compareTo(getKey(keyTo)) <= 0) { | ||
| if (isKeyWithinRange(key)) { | ||
| return true; | ||
| } else { | ||
| next = null; | ||
| return hasNext(); | ||
| } | ||
| } | ||
|
|
||
| private boolean isKeyWithinRange(final Bytes key) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per comment above, can you make this method more readable by splitting the statements? |
||
| // split all cases for readability and avoid BooleanExpressionComplexity checkstyle warning | ||
| if (keyFrom == null && keyTo == null) { | ||
| // fetch all | ||
| return true; | ||
| } else if (keyFrom == null) { | ||
| // start from the beginning | ||
| return key.compareTo(getKey(keyTo)) <= 0; | ||
| } else if (keyTo == null) { | ||
| // end to the last | ||
| return key.compareTo(getKey(keyFrom)) >= 0; | ||
| } else { | ||
| // key is within the range | ||
| return key.compareTo(getKey(keyFrom)) >= 0 && key.compareTo(getKey(keyTo)) <= 0; | ||
| } | ||
| } | ||
|
|
||
| public void close() { | ||
| next = null; | ||
| recordIterator = null; | ||
|
|
@@ -499,9 +514,16 @@ Iterator<Map.Entry<Bytes, byte[]>> setRecordIterator() { | |
| final Map.Entry<Long, ConcurrentNavigableMap<Bytes, byte[]>> currentSegment = segmentIterator.next(); | ||
| currentTime = currentSegment.getKey(); | ||
|
|
||
| final ConcurrentNavigableMap<Bytes, byte[]> subMap = allKeys ? | ||
| currentSegment.getValue() : | ||
| currentSegment.getValue().subMap(keyFrom, true, keyTo, true); | ||
| final ConcurrentNavigableMap<Bytes, byte[]> subMap; | ||
| if (allKeys) { // keyFrom == null && keyTo == null | ||
| subMap = currentSegment.getValue(); | ||
| } else if (keyFrom == null) { | ||
| subMap = currentSegment.getValue().headMap(keyTo, true); | ||
| } else if (keyTo == null) { | ||
| subMap = currentSegment.getValue().tailMap(keyFrom, true); | ||
| } else { | ||
| subMap = currentSegment.getValue().subMap(keyFrom, true, keyTo, true); | ||
| } | ||
|
|
||
| if (forward) { | ||
| return subMap.entrySet().iterator(); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.