Skip to content

Commit 05d68a0

Browse files
committed
Consider KeysetScrollPosition direction in WindowIterator.
We now consider the scroll direction in the iterator to properly continue Keyset backward scrolling. Closes #2851
1 parent 487795d commit 05d68a0

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/main/java/org/springframework/data/support/WindowIterator.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.NoSuchElementException;
2020
import java.util.function.Function;
2121

22+
import org.springframework.data.domain.KeysetScrollPosition;
2223
import org.springframework.data.domain.ScrollPosition;
2324
import org.springframework.data.domain.Window;
2425
import org.springframework.lang.Nullable;
@@ -92,7 +93,7 @@ public boolean hasNext() {
9293

9394
if (currentWindow != null && currentWindow.hasNext()) {
9495

95-
currentPosition = currentWindow.positionAt(currentWindow.size() - 1);
96+
currentPosition = getNextPosition(currentPosition, currentWindow);
9697
currentIterator = null;
9798
currentWindow = null;
9899
continue;
@@ -113,6 +114,17 @@ public T next() {
113114
return currentIterator.next();
114115
}
115116

117+
private static ScrollPosition getNextPosition(ScrollPosition currentPosition, Window<?> window) {
118+
119+
if (currentPosition instanceof KeysetScrollPosition ksp) {
120+
if (ksp.scrollsBackward()) {
121+
return window.positionAt(0);
122+
}
123+
}
124+
125+
return window.positionAt(window.size() - 1);
126+
}
127+
116128
/**
117129
* Builder API to construct a {@link WindowIterator}.
118130
*

src/test/java/org/springframework/data/domain/WindowIteratorUnitTests.java

+27
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.ArrayList;
2323
import java.util.Collections;
2424
import java.util.List;
25+
import java.util.Map;
2526
import java.util.NoSuchElementException;
2627
import java.util.function.Function;
2728

@@ -30,7 +31,9 @@
3031
import org.mockito.junit.jupiter.MockitoExtension;
3132
import org.mockito.junit.jupiter.MockitoSettings;
3233
import org.mockito.quality.Strictness;
34+
import org.springframework.data.domain.ScrollPosition.Direction;
3335
import org.springframework.data.support.WindowIterator;
36+
import org.springframework.data.util.Streamable;
3437

3538
/**
3639
* Unit tests for {@link WindowIterator}.
@@ -127,4 +130,28 @@ void allowsToIterateAllWindows() {
127130

128131
assertThat(capturedResult).containsExactly("a", "b", "c", "d");
129132
}
133+
134+
@Test // GH-2151
135+
void considersBackwardKeysetScrolling() {
136+
137+
Window<String> initial = Window.from(List.of("c", "d"),
138+
value -> KeysetScrollPosition.of(Map.of("k", 10 + value), Direction.BACKWARD), true);
139+
Window<String> terminal = Window.from(List.of("a", "b"),
140+
value -> KeysetScrollPosition.of(Map.of("k", value), Direction.BACKWARD));
141+
142+
WindowIterator<String> iterator = WindowIterator.of(it -> {
143+
144+
if (it instanceof KeysetScrollPosition ksp) {
145+
if (Integer.valueOf(10).equals(ksp.getKeys().get("k"))) {
146+
return terminal;
147+
}
148+
}
149+
150+
return initial;
151+
152+
}).startingAt(ScrollPosition.keyset().backward());
153+
154+
List<String> items = Streamable.of(() -> iterator).toList();
155+
assertThat(items).containsExactly("c", "d", "a", "b");
156+
}
130157
}

0 commit comments

Comments
 (0)