package org.gbif.checklistbank.neo.traverse;
import org.gbif.checklistbank.neo.NeoProperties;
import java.util.Iterator;
import java.util.List;
import com.google.common.collect.Ordering;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.ResourceIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Path iterator that traverses multiple start nodes in a given traversal description.
*/
public abstract class MultiRooIterator<T> implements AutoCloseable, ResourceIterator<T> {
private static final Logger LOG = LoggerFactory.getLogger(MultiRooIterator.class);
private final Iterator<Node> roots;
private ResourceIterator<T> rootPaths;
private T next;
MultiRooIterator(List<Node> roots) {
this.roots = Ordering.from(new TaxonomicOrder()).sortedCopy(roots).iterator();
LOG.debug("Found {} root nodes to iterate over", roots.size());
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public T next() {
T p = next;
prefetch();
return p;
}
abstract ResourceIterator<T> iterateRoot(Node root);
public void prefetch() {
while ((rootPaths == null || !rootPaths.hasNext()) && roots.hasNext()) {
// close as quickly as we can
if (rootPaths != null) {
rootPaths.close();
}
Node root = roots.next();
LOG.debug("Traverse a new root taxon: {}", NeoProperties.getCanonicalName(root));
rootPaths = iterateRoot(root);
}
if (rootPaths != null && rootPaths.hasNext()) {
next = rootPaths.next();
} else {
next = null;
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public void close() {
if (rootPaths != null) {
rootPaths.close();
}
}
}