|
21 | 21 | import java.util.function.Function;
|
22 | 22 |
|
23 | 23 | import org.springframework.data.util.CloseableIterator;
|
| 24 | +import org.springframework.util.Assert; |
24 | 25 |
|
25 | 26 | /**
|
26 | 27 | * Utility to support streaming queries.
|
27 | 28 | *
|
28 | 29 | * @author Mark Paluch
|
| 30 | + * @author Sascha Woo |
29 | 31 | * @since 3.2
|
30 | 32 | */
|
31 | 33 | abstract class StreamQueries {
|
32 | 34 |
|
33 | 35 | /**
|
34 | 36 | * Stream query results using {@link ScrolledPage}.
|
35 | 37 | *
|
36 |
| - * @param page the initial page. |
37 |
| - * @param continueFunction continuation function accepting the current scrollId. |
38 |
| - * @param clearScroll cleanup function accepting the current scrollId. |
| 38 | + * @param page the initial scrolled page. |
| 39 | + * @param continueScrollFunction function to continue scrolling applies to the current scrollId. |
| 40 | + * @param clearScrollConsumer consumer to clear the scroll context by accepting the current scrollId. |
39 | 41 | * @param <T>
|
40 | 42 | * @return the {@link CloseableIterator}.
|
41 | 43 | */
|
42 | 44 | static <T> CloseableIterator<T> streamResults(ScrolledPage<T> page,
|
43 |
| - Function<String, ScrolledPage<T>> continueFunction, Consumer<String> clearScroll) { |
| 45 | + Function<String, ScrolledPage<T>> continueScrollFunction, Consumer<String> clearScrollConsumer) { |
44 | 46 |
|
45 |
| - return new CloseableIterator<T>() { |
| 47 | + Assert.notNull(page, "page must not be null."); |
| 48 | + Assert.notNull(page.getScrollId(), "scrollId must not be null."); |
| 49 | + Assert.notNull(continueScrollFunction, "continueScrollFunction must not be null."); |
| 50 | + Assert.notNull(clearScrollConsumer, "clearScrollConsumer must not be null."); |
46 | 51 |
|
47 |
| - /** As we couldn't retrieve single result with scroll, store current hits. */ |
48 |
| - private volatile Iterator<T> currentHits = page.iterator(); |
| 52 | + return new CloseableIterator<T>() { |
49 | 53 |
|
50 |
| - /** The scroll id. */ |
| 54 | + // As we couldn't retrieve single result with scroll, store current hits. |
| 55 | + private volatile Iterator<T> scrollHits = page.iterator(); |
51 | 56 | private volatile String scrollId = page.getScrollId();
|
52 |
| - |
53 |
| - /** If stream is finished (ie: cluster returns no results. */ |
54 |
| - private volatile boolean finished = !currentHits.hasNext(); |
| 57 | + private volatile boolean continueScroll = scrollHits.hasNext(); |
55 | 58 |
|
56 | 59 | @Override
|
57 | 60 | public void close() {
|
| 61 | + |
58 | 62 | try {
|
59 |
| - // Clear scroll on cluster only in case of error (cause elasticsearch auto clear scroll when it's done) |
60 |
| - if (!finished && scrollId != null && currentHits != null && currentHits.hasNext()) { |
61 |
| - clearScroll.accept(scrollId); |
62 |
| - } |
| 63 | + clearScrollConsumer.accept(scrollId); |
63 | 64 | } finally {
|
64 |
| - currentHits = null; |
| 65 | + scrollHits = null; |
65 | 66 | scrollId = null;
|
66 | 67 | }
|
67 | 68 | }
|
68 | 69 |
|
69 | 70 | @Override
|
70 | 71 | public boolean hasNext() {
|
71 |
| - // Test if stream is finished |
72 |
| - if (finished) { |
| 72 | + |
| 73 | + if (!continueScroll) { |
73 | 74 | return false;
|
74 | 75 | }
|
75 |
| - // Test if it remains hits |
76 |
| - if (currentHits == null || !currentHits.hasNext()) { |
77 |
| - // Do a new request |
78 |
| - ScrolledPage<T> scroll = continueFunction.apply(scrollId); |
79 |
| - // Save hits and scroll id |
80 |
| - currentHits = scroll.iterator(); |
81 |
| - finished = !currentHits.hasNext(); |
82 |
| - scrollId = scroll.getScrollId(); |
| 76 | + |
| 77 | + if (!scrollHits.hasNext()) { |
| 78 | + ScrolledPage<T> nextPage = continueScrollFunction.apply(scrollId); |
| 79 | + scrollHits = nextPage.iterator(); |
| 80 | + scrollId = nextPage.getScrollId(); |
| 81 | + continueScroll = scrollHits.hasNext(); |
83 | 82 | }
|
84 |
| - return currentHits.hasNext(); |
| 83 | + |
| 84 | + return scrollHits.hasNext(); |
85 | 85 | }
|
86 | 86 |
|
87 | 87 | @Override
|
88 | 88 | public T next() {
|
89 | 89 | if (hasNext()) {
|
90 |
| - return currentHits.next(); |
| 90 | + return scrollHits.next(); |
91 | 91 | }
|
92 | 92 | throw new NoSuchElementException();
|
93 | 93 | }
|
94 | 94 |
|
95 | 95 | @Override
|
96 | 96 | public void remove() {
|
97 |
| - throw new UnsupportedOperationException("remove"); |
| 97 | + throw new UnsupportedOperationException(); |
98 | 98 | }
|
99 | 99 | };
|
100 | 100 | }
|
101 | 101 |
|
102 | 102 | // utility constructor
|
103 |
| - private StreamQueries() {} |
| 103 | + private StreamQueries() { |
| 104 | + } |
104 | 105 | }
|
0 commit comments