Skip to content

Commit 3a1fbe1

Browse files
Remove limit(long) from Cursor and hint users to stream().limit(...)
Original Pull Request: #2014
1 parent b0dd3cd commit 3a1fbe1

File tree

5 files changed

+16
-155
lines changed

5 files changed

+16
-155
lines changed

src/main/java/org/springframework/data/redis/core/ConvertingCursor.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,4 @@ public Cursor<T> open() {
119119
public long getPosition() {
120120
return delegate.getPosition();
121121
}
122-
123-
/*
124-
* (non-Javadoc)
125-
* @see org.springframework.data.redis.core.Cursor#limit(long)
126-
*/
127-
@Override
128-
public Cursor<T> limit(long count) {
129-
return new ConvertingCursor<>(delegate.limit(count), converter);
130-
}
131122
}

src/main/java/org/springframework/data/redis/core/Cursor.java

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,25 @@
1515
*/
1616
package org.springframework.data.redis.core;
1717

18-
import org.springframework.data.redis.util.BoundedIterator;
1918
import org.springframework.data.util.CloseableIterator;
2019

2120
/**
2221
* Cursor abstraction to scan over the keyspace or elements within a data structure using a variant of a {@code SCAN}
2322
* command.
23+
* <p />
24+
* Using a Java 8 {@link #stream() java.util.stream.Stream} allows to apply additional
25+
* {@link java.util.stream.Stream#filter(java.util.function.Predicate) filters} and {@link java.util.stream.Stream#limit(long) limits} to
26+
* the underlying {@link Cursor}.
27+
* <p />
28+
* Make sure to {@link CloseableIterator#close() close} the cursor when done as this allows implementations to clean up
29+
* any resources they need to keep open to iterate over elements (eg. by using a try-with-resource statement).
2430
*
2531
* @author Christoph Strobl
2632
* @author Mark Paluch
2733
* @param <T>
2834
* @since 1.4
2935
*/
30-
public interface Cursor<T> extends BoundedIterator<T>, CloseableIterator<T> {
36+
public interface Cursor<T> extends CloseableIterator<T> {
3137

3238
/**
3339
* Get the reference cursor. <br>
@@ -56,15 +62,4 @@ public interface Cursor<T> extends BoundedIterator<T>, CloseableIterator<T> {
5662
* @return the current position of the cursor.
5763
*/
5864
long getPosition();
59-
60-
/**
61-
* Limit the maximum number of elements to be returned from this cursor. The returned cursor object can be used to
62-
* iterate over the remaining items and to {@link #close() release} associated resources. The returned cursor is not
63-
* attached to the state of {@code this} cursor and this object should be no longer used.
64-
*
65-
* @return a new {@link Cursor} with detached iteration state.
66-
* @since 2.5
67-
*/
68-
@Override
69-
Cursor<T> limit(long count);
7065
}

src/main/java/org/springframework/data/redis/core/ScanCursor.java

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ public abstract class ScanCursor<T> implements Cursor<T> {
4343
private Iterator<T> delegate;
4444
private final ScanOptions scanOptions;
4545
private long position;
46-
private final long limit;
4746

4847
/**
4948
* Crates new {@link ScanCursor} with {@code id=0} and {@link ScanOptions#NONE}
@@ -82,23 +81,6 @@ public ScanCursor(long cursorId, @Nullable ScanOptions options) {
8281
this.cursorId = cursorId;
8382
this.state = CursorState.READY;
8483
this.delegate = Collections.emptyIterator();
85-
this.limit = -1;
86-
}
87-
88-
/**
89-
* Crates a new {@link ScanCursor}.
90-
*
91-
* @param source source cursor.
92-
* @param limit
93-
* @since 2.5
94-
*/
95-
private ScanCursor(ScanCursor<T> source, long limit) {
96-
97-
this.scanOptions = source.scanOptions;
98-
this.cursorId = source.cursorId;
99-
this.state = source.state;
100-
this.delegate = source.delegate;
101-
this.limit = limit;
10284
}
10385

10486
private void scan(long cursorId) {
@@ -189,10 +171,6 @@ public boolean hasNext() {
189171

190172
assertCursorIsOpen();
191173

192-
if (limit != -1 && getPosition() > limit - 1) {
193-
return false;
194-
}
195-
196174
while (!delegate.hasNext() && !CursorState.FINISHED.equals(state)) {
197175
scan(cursorId);
198176
}
@@ -294,54 +272,10 @@ public long getPosition() {
294272
return position;
295273
}
296274

297-
/*
298-
* (non-Javadoc)
299-
* @see org.springframework.data.redis.core.Cursor#limit(long)
300-
*/
301-
@Override
302-
public ScanCursor<T> limit(long count) {
303-
304-
Assert.isTrue(count >= 0, "Count must be greater or equal to zero");
305-
306-
return new ScanCursorWrapper<>(this, count);
307-
}
308-
309275
/**
310276
* @author Thomas Darimont
311277
*/
312278
enum CursorState {
313279
READY, OPEN, FINISHED, CLOSED;
314280
}
315-
316-
/**
317-
* Wrapper for a concrete {@link ScanCursor} forwarding {@link #doScan(long, ScanOptions)}, {@link #doClose()} and
318-
* {@link #isClosed()}.
319-
*
320-
* @param <T>
321-
* @since 2.5
322-
*/
323-
private static class ScanCursorWrapper<T> extends ScanCursor<T> {
324-
325-
private final ScanCursor<T> delegate;
326-
327-
public ScanCursorWrapper(ScanCursor<T> delegate, long limit) {
328-
super(delegate, limit);
329-
this.delegate = delegate;
330-
}
331-
332-
@Override
333-
protected ScanIteration<T> doScan(long cursorId, ScanOptions options) {
334-
return delegate.doScan(cursorId, options);
335-
}
336-
337-
@Override
338-
protected void doClose() {
339-
delegate.close();
340-
}
341-
342-
@Override
343-
public boolean isClosed() {
344-
return delegate.isClosed();
345-
}
346-
}
347281
}

src/main/java/org/springframework/data/redis/util/BoundedIterator.java

Lines changed: 0 additions & 36 deletions
This file was deleted.

src/test/java/org/springframework/data/redis/core/ScanCursorUnitTests.java

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@
2424
import java.util.List;
2525
import java.util.NoSuchElementException;
2626
import java.util.Queue;
27+
import java.util.stream.Collectors;
28+
import java.util.stream.Stream;
2729

2830
import org.junit.jupiter.api.Test;
29-
3031
import org.springframework.dao.InvalidDataAccessApiUsageException;
3132

3233
/**
@@ -200,60 +201,36 @@ void hasNextShouldStopCorrectlyWhenWholeScanIterationDoesNotReturnResultsAndStat
200201
}
201202

202203
@Test // GH-1575
203-
void limitShouldApplyLimitation() {
204+
void streamLimitShouldApplyLimitation() {
204205

205206
LinkedList<ScanIteration<String>> values = new LinkedList<>();
206207
values.add(createIteration(1, "spring"));
207208
values.add(createIteration(2, "data"));
208209
values.add(createIteration(3, "redis"));
209210
values.add(createIteration(0));
210-
Cursor<String> cursor = initCursor(values).limit(2);
211-
212-
List<String> result = new ArrayList<>();
213-
while (cursor.hasNext()) {
214-
result.add(cursor.next());
215-
}
216-
217-
assertThat(result).hasSize(2).contains("spring", "data");
218-
}
219-
220-
@Test // GH-1575
221-
void limitShouldNotLimitOriginalCursor() {
222211

223-
LinkedList<ScanIteration<String>> values = new LinkedList<>();
224-
values.add(createIteration(1, "spring"));
225-
values.add(createIteration(2, "data"));
226-
values.add(createIteration(3, "redis"));
227-
values.add(createIteration(0));
228212
Cursor<String> cursor = initCursor(values);
229-
cursor.limit(1);
230-
231-
List<String> result = new ArrayList<>();
232-
while (cursor.hasNext()) {
233-
result.add(cursor.next());
234-
}
235213

236-
assertThat(result).hasSize(3);
214+
assertThat(cursor.stream().limit(2).collect(Collectors.toList())).hasSize(2).contains("spring", "data");
237215
}
238216

239217
@Test // GH-1575
240-
void decoratedCursorShouldForwardClose() {
218+
void streamingCursorShouldForwardClose() {
241219

242220
LinkedList<ScanIteration<String>> values = new LinkedList<>();
243221
values.add(createIteration(1, "spring"));
244222
values.add(createIteration(2, "data"));
245223
values.add(createIteration(3, "redis"));
246224
values.add(createIteration(0));
247225
Cursor<String> cursor = initCursor(values);
248-
Cursor<String> limited = cursor.limit(1);
249226

250227
assertThat(cursor.isClosed()).isFalse();
251-
assertThat(limited.isClosed()).isFalse();
252228

253-
limited.close();
229+
Stream<String> stream = cursor.stream();
230+
stream.collect(Collectors.toList());
231+
stream.close();
254232

255233
assertThat(cursor.isClosed()).isTrue();
256-
assertThat(limited.isClosed()).isTrue();
257234
}
258235

259236
private CapturingCursorDummy initCursor(Queue<ScanIteration<String>> values) {

0 commit comments

Comments
 (0)