package org.archive.format.gzip.zipnum;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.archive.util.binsearch.SeekableLineReader;
import org.archive.util.binsearch.SeekableLineReaderIterator;
import org.archive.util.io.RuntimeIOException;
import org.archive.util.iterator.AbstractPeekableIterator;
import org.archive.util.iterator.CloseableIterator;
public class SummaryBlockIterator extends AbstractPeekableIterator<CloseableIterator<String>>
{
final static Logger LOGGER =
Logger.getLogger(SummaryBlockIterator.class.getName());
protected CloseableIterator<String> summaryIterator;
protected ZipNumIndex zipnumIndex;
//protected SeekableLineReader currReader = null;
protected SummaryLine nextLine, currLine;
protected boolean isFirst = true;
//protected String currPartId = null;
protected int totalBlocks = 0;
protected final ZipNumParams params;
public SummaryBlockIterator(CloseableIterator<String> summaryIterator, ZipNumIndex zipnumIndex, ZipNumParams params)
{
this.zipnumIndex = zipnumIndex;
this.summaryIterator = summaryIterator;
this.isFirst = true;
if (params != null) {
this.params = params;
} else {
this.params = new ZipNumParams();
}
}
@Override
public CloseableIterator<String> getNextInner() {
if (isFirst) {
if (summaryIterator.hasNext()) {
nextLine = new SummaryLine(summaryIterator.next());
}
isFirst = false;
}
if (nextLine == null) {
return null;
}
if ((params.getMaxBlocks() > 0) && (totalBlocks >= params.getMaxBlocks())) {
return null;
}
int numBlocks = 0;
int maxAggregateBlocks = params.getMaxAggregateBlocks();
long startOffset = nextLine.offset;
String currPartId = nextLine.partId;
int totalLength = 0;
do {
currLine = nextLine;
if (currLine == null) {
return null;
}
if (summaryIterator.hasNext()) {
nextLine = new SummaryLine(summaryIterator.next());
} else {
nextLine = null;
}
if (currLine.getNumFields() < 3) {
LOGGER.severe("Bad line(" + currLine.toString() +") ");
return null;
}
// if (currLine.sameTimestamp(nextLine)) {
// if (numBlocks == 0) {
// continue;
// } else {
// break;
// }
// }
// if ((currPartId == null) || !currPartId.equals(currLine.partId) || (numBlocks == 0)) {
// startOffset = currLine.offset;
// totalLength = 0;
// currPartId = currLine.partId;
// }
totalLength += currLine.length;
numBlocks++;
} while (((maxAggregateBlocks <= 0) || (numBlocks < maxAggregateBlocks)) &&
((params.getMaxBlocks() <= 0) || (totalBlocks + numBlocks) < params.getMaxBlocks())
&& currLine.isContinuous(nextLine));
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("Loading " + numBlocks + " blocks - " + startOffset + ":" + totalLength + " from " + currPartId);
}
//currReader = initReader(currPartId);
//currReader = zipnumIndex.createReader(currPartId);
//currReader.seekWithMaxRead(startOffset, true, totalLength);
SeekableLineReader currReader = zipnumIndex.doBlockLoad(currPartId, startOffset, totalLength);
if ((currReader == null) && zipnumIndex.isRequired()) {
throw new RuntimeIOException("Failed to load shards for: " + currPartId);
}
if (currReader != null) {
totalBlocks += numBlocks;
}
CloseableIterator<String> slrIter = new SeekableLineReaderIterator(currReader, zipnumIndex.isRequired());
if (params.isReverse()) {
slrIter = new LineBufferingIterator(slrIter, zipnumIndex.getCdxLinesPerBlock(), true);
}
return slrIter;
}
// protected SeekableLineReader initReader(String partId) throws IOException
// {
// //if ((currReader == null) || (currPartId == null) || !currPartId.equals(partId)) {
//
//// if (currReader != null) {
//// currReader.close();
//// currReader = null;
//// }
//
// SeekableLineReader currReader = null;
//
// if (cluster.locationUpdater != null) {
// currReader = initLocationReader(partId);
// }
//
// if (currReader == null) {
// String partUrl = cluster.getClusterPart(partId);
// currReader = cluster.blockLoader.createBlockReader(partUrl);
// }
//
// return currReader;
// }
//
// protected SeekableLineReader initLocationReader(String partId)
// {
// String[] locations = cluster.locationUpdater.getLocations(partId);
//
// if (locations == null) {
// LOGGER.severe("No locations for block(" + partId +")");
// } else if (locations != null && locations.length > 0) {
// for (String location : locations) {
// try {
// return cluster.blockLoader.createBlockReader(location);
// } catch (IOException io) {
// continue;
// }
// }
// }
//
// return null;
// }
@Override
public void close() throws IOException
{
if (summaryIterator != null) {
summaryIterator.close();
summaryIterator = null;
}
// if (currReader != null) {
// currReader.close();
// currReader = null;
// }
}
}