21
21
import java .util .LinkedList ;
22
22
import java .util .List ;
23
23
import java .util .NoSuchElementException ;
24
+ import org .apache .zookeeper .data .PathWithStat ;
24
25
25
26
/**
26
27
* 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)
33
28
*/
34
- class ChildrenBatchIterator implements RemoteIterator <String > {
29
+ class ChildrenBatchIterator implements RemoteIterator <PathWithStat > {
35
30
36
31
private final ZooKeeper zooKeeper ;
37
32
private final String path ;
38
33
private final Watcher watcher ;
39
34
private final int batchSize ;
40
- private final LinkedList <String > childrenQueue ;
41
- private final PaginationNextPage nextPage ;
35
+ private final LinkedList <PathWithStat > childrenQueue ;
42
36
private long nextBatchMinZxid ;
43
37
private int nextBatchZxidOffset ;
44
38
@@ -53,44 +47,55 @@ class ChildrenBatchIterator implements RemoteIterator<String> {
53
47
this .nextBatchMinZxid = minZxid ;
54
48
55
49
this .childrenQueue = new LinkedList <>();
56
- this .nextPage = new PaginationNextPage ();
57
50
58
- batchGetChildren ();
51
+ List <PathWithStat > firstChildrenBatch = zooKeeper .getChildren (path , watcher , batchSize , nextBatchMinZxid , nextBatchZxidOffset );
52
+ childrenQueue .addAll (firstChildrenBatch );
53
+
54
+ updateOffsetsForNextBatch (firstChildrenBatch );
59
55
}
60
56
61
57
@ Override
62
58
public boolean hasNext () {
59
+
63
60
// next() never lets childrenQueue empty unless we iterated over all children
64
61
return !childrenQueue .isEmpty ();
65
62
}
66
63
67
64
@ Override
68
- public String next () throws KeeperException , InterruptedException {
65
+ public PathWithStat next () throws KeeperException , InterruptedException , NoSuchElementException {
66
+
69
67
if (!hasNext ()) {
70
68
throw new NoSuchElementException ("No more children" );
71
69
}
72
70
73
71
// 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 );
77
78
}
78
79
79
- return childrenQueue .pop ();
80
+ PathWithStat returnChildren = childrenQueue .pop ();
81
+
82
+ return returnChildren ;
80
83
}
81
84
82
85
/**
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
84
87
*/
85
- private void updateOffsetsForNextBatch () {
86
- nextBatchMinZxid = nextPage .getMinCzxid ();
87
- nextBatchZxidOffset = nextPage .getMinCzxidOffset ();
88
- }
88
+ private void updateOffsetsForNextBatch (List <PathWithStat > children ) {
89
89
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
+ }
95
100
}
96
101
}
0 commit comments