package org.archive.util.iterator;
import java.io.IOException;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.PriorityQueue;
import java.util.logging.Logger;
public class SortedCompositeIterator<E> implements CloseableIterator<E> {
private final static Logger LOGGER = Logger.getLogger(SortedCompositeIterator.class.getName());
private static final int DEFAULT_CAPACITY = 10;
PriorityQueue<PeekableIterator<E>> q = null;
public SortedCompositeIterator(Comparator<E> comparator) {
this(DEFAULT_CAPACITY,comparator);
}
public SortedCompositeIterator(int capacity, Comparator<E> comparator) {
q = new PriorityQueue<PeekableIterator<E>>(capacity,
new PeekableIteratorComparator<E>(comparator));
}
public void addAll(Collection<Iterator<E>> toAdd) {
for(Iterator<E> e : toAdd) {
addIterator(e);
}
}
public void addIterator(Iterator<E> itr) {
PeekableIterator<E> i = null;
if(itr instanceof PeekableIterator) {
i = (PeekableIterator<E>) itr;
} else {
i = AbstractPeekableIterator.wrap(itr);
}
if(i.hasNext()) {
q.add(i);
}
}
public boolean hasNext() {
return (q.peek() != null);
}
public E next() {
PeekableIterator<E> i = q.poll();
if(i == null) {
throw new NoSuchElementException("Call hasNext!");
}
E tmp = i.next();
if(i.hasNext()) {
q.add(i);
} else {
try {
i.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tmp;
}
public void remove() {
throw new UnsupportedOperationException("No remove");
}
private class PeekableIteratorComparator<J> implements Comparator<PeekableIterator<J>> {
private Comparator<J> comparator = null;
public PeekableIteratorComparator(Comparator<J> comparator) {
this.comparator = comparator;
}
public int compare(PeekableIterator<J> o1, PeekableIterator<J> o2) {
return comparator.compare(o1.peek(), o2.peek());
}
}
public void close() throws IOException {
for(PeekableIterator<E> i : q) {
try {
i.close();
} catch (IOException io) {
LOGGER.warning(io.toString());
}
}
}
}