Skip to content

Commit 60d5e51

Browse files
committed
Optimize paginated getChildren: return children names instead of PathWithStat
1 parent 4ee53c4 commit 60d5e51

File tree

6 files changed

+177
-332
lines changed

6 files changed

+177
-332
lines changed

zookeeper-server/src/main/java/org/apache/zookeeper/ChildrenBatchIterator.java

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,18 @@
2121
import java.util.LinkedList;
2222
import java.util.List;
2323
import java.util.NoSuchElementException;
24+
import org.apache.zookeeper.data.PathWithStat;
2425

2526
/**
2627
* Iterator over children nodes of a given path.
27-
* <p>
28-
* Note: the final collection of children may not be strongly consistent with the server.
29-
* If there are concurrent writes to the children during iteration, the final collection could
30-
* miss some children or contain some duplicate children.
31-
*
32-
* @see ZooKeeper#getAllChildrenPaginated(String, boolean)
3328
*/
34-
class ChildrenBatchIterator implements RemoteIterator<String> {
29+
class ChildrenBatchIterator implements RemoteIterator<PathWithStat> {
3530

3631
private final ZooKeeper zooKeeper;
3732
private final String path;
3833
private final Watcher watcher;
3934
private final int batchSize;
40-
private final LinkedList<String> childrenQueue;
41-
private final PaginationNextPage nextPage;
35+
private final LinkedList<PathWithStat> childrenQueue;
4236
private long nextBatchMinZxid;
4337
private int nextBatchZxidOffset;
4438

@@ -53,44 +47,55 @@ class ChildrenBatchIterator implements RemoteIterator<String> {
5347
this.nextBatchMinZxid = minZxid;
5448

5549
this.childrenQueue = new LinkedList<>();
56-
this.nextPage = new PaginationNextPage();
5750

58-
batchGetChildren();
51+
List<PathWithStat> firstChildrenBatch = zooKeeper.getChildren(path, watcher, batchSize, nextBatchMinZxid, nextBatchZxidOffset);
52+
childrenQueue.addAll(firstChildrenBatch);
53+
54+
updateOffsetsForNextBatch(firstChildrenBatch);
5955
}
6056

6157
@Override
6258
public boolean hasNext() {
59+
6360
// next() never lets childrenQueue empty unless we iterated over all children
6461
return !childrenQueue.isEmpty();
6562
}
6663

6764
@Override
68-
public String next() throws KeeperException, InterruptedException {
65+
public PathWithStat next() throws KeeperException, InterruptedException, NoSuchElementException {
66+
6967
if (!hasNext()) {
7068
throw new NoSuchElementException("No more children");
7169
}
7270

7371
// If we're down to the last element, backfill before returning it
74-
if (childrenQueue.size() == 1 && nextBatchMinZxid != ZooDefs.GetChildrenPaginated.lastPageMinCzxid
75-
&& nextBatchZxidOffset != ZooDefs.GetChildrenPaginated.lastPageMinCzxidOffset) {
76-
batchGetChildren();
72+
if (childrenQueue.size() == 1) {
73+
74+
List<PathWithStat> childrenBatch = zooKeeper.getChildren(path, watcher, batchSize, nextBatchMinZxid, nextBatchZxidOffset);
75+
childrenQueue.addAll(childrenBatch);
76+
77+
updateOffsetsForNextBatch(childrenBatch);
7778
}
7879

79-
return childrenQueue.pop();
80+
PathWithStat returnChildren = childrenQueue.pop();
81+
82+
return returnChildren;
8083
}
8184

8285
/**
83-
* Prepare minZxid and zxidOffset for the next batch request
86+
* Prepare minZxid and zkidOffset for the next batch request based on the children returned in the current
8487
*/
85-
private void updateOffsetsForNextBatch() {
86-
nextBatchMinZxid = nextPage.getMinCzxid();
87-
nextBatchZxidOffset = nextPage.getMinCzxidOffset();
88-
}
88+
private void updateOffsetsForNextBatch(List<PathWithStat> children) {
8989

90-
private void batchGetChildren() throws KeeperException, InterruptedException {
91-
List<String> childrenBatch =
92-
zooKeeper.getChildren(path, watcher, batchSize, nextBatchMinZxid, nextBatchZxidOffset, nextPage);
93-
childrenQueue.addAll(childrenBatch);
94-
updateOffsetsForNextBatch();
90+
for (PathWithStat child : children) {
91+
long childZxid = child.getStat().getCzxid();
92+
93+
if (nextBatchMinZxid == childZxid) {
94+
++nextBatchZxidOffset;
95+
} else {
96+
nextBatchZxidOffset = 1;
97+
nextBatchMinZxid = childZxid;
98+
}
99+
}
95100
}
96101
}

zookeeper-server/src/main/java/org/apache/zookeeper/RemoteIterator.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,16 @@ public interface RemoteIterator<E> {
2727

2828
/**
2929
* Returns true if the iterator has more elements.
30-
*
3130
* @return true if the iterator has more elements, false otherwise.
3231
*/
3332
boolean hasNext();
3433

3534
/**
3635
* Returns the next element in the iteration.
37-
*
3836
* @return the next element in the iteration.
3937
* @throws InterruptedException if the thread is interrupted
4038
* @throws KeeperException if an error is encountered server-side
4139
* @throws NoSuchElementException if the iteration has no more elements
4240
*/
43-
E next() throws InterruptedException, KeeperException;
41+
E next() throws InterruptedException, KeeperException, NoSuchElementException;
4442
}

0 commit comments

Comments
 (0)