|
4 | 4 | import java.util.Collection; |
5 | 5 | import java.util.Collections; |
6 | 6 | import java.util.Iterator; |
| 7 | +import java.util.List; |
7 | 8 |
|
8 | 9 | /** Provides a collection interface that provides efficient range queries via iterators. |
9 | 10 | * Does not allow insertion of null objects. |
@@ -232,24 +233,31 @@ public Iterator<T> iterator() { |
232 | 233 | return iterator(Long.MIN_VALUE, Long.MAX_VALUE); |
233 | 234 | } |
234 | 235 |
|
235 | | - public Iterator iterator(long lb, long ub) { |
236 | | -// System.out.println("Creating iterator for node " + nodeID + " data=" + data); |
| 236 | + public Iterator<T> iterator(long lb, long ub) { |
| 237 | + ArrayList<Iterator<T>> accumulator = new ArrayList<>(); |
| 238 | + iteratorHelper(lb, ub, accumulator); |
| 239 | + |
| 240 | + if(accumulator.isEmpty()) |
| 241 | + accumulator.add(new NullIterator<>()); |
| 242 | + |
| 243 | + // Copying to a zero length array is a bit faster since the JVM avoids zeroing the array |
| 244 | + // (see https://shipilev.net/blog/2016/arrays-wisdom-ancients/ for more detail) |
| 245 | + return new MergedIterator<T>(accumulator.toArray(new Iterator[0])); |
| 246 | + } |
| 247 | + |
| 248 | + // Recursively create a flat tree of iterators in accumulator by walking the range query tree |
| 249 | + private void iteratorHelper(long lb, long ub, List<Iterator<T>> accumulator) { |
237 | 250 | if(data == null){ |
238 | 251 | boolean useLeft = leftChild.lowerBound <= ub && leftChild.upperBound >= lb; |
239 | 252 | boolean useRight = rightChild.lowerBound <= ub && rightChild.upperBound >= lb; |
240 | 253 |
|
241 | | - if(useLeft && useRight) |
242 | | - return new MergedIterator(leftChild.iterator(lb, ub), rightChild.iterator(lb, ub)); |
243 | | - else if(useLeft) |
244 | | - return leftChild.iterator(lb, ub); |
245 | | - else if(useRight) |
246 | | - return rightChild.iterator(lb, ub); |
247 | | - else |
248 | | - return new NullIterator(); |
249 | | - |
| 254 | + if(useLeft) |
| 255 | + leftChild.iteratorHelper(lb, ub, accumulator); |
| 256 | + if(useRight) |
| 257 | + rightChild.iteratorHelper(lb, ub, accumulator); |
250 | 258 | } else { |
251 | 259 | // A local range iterator: |
252 | | - return new RangeIterator(data.iterator(), lb, ub); |
| 260 | + accumulator.add(new RangeIterator(data.iterator(), lb, ub)); |
253 | 261 | } |
254 | 262 | } |
255 | 263 |
|
|
0 commit comments