package com.appmetr.hercules.batch.iterator; import com.appmetr.hercules.profile.DataOperationsProfile; import com.appmetr.hercules.utils.Tuple2; import java.util.List; public abstract class TupleBatchIterator<E, K> extends AbstractBatchIterator<E, K> { private K prevKey = null; private K lastKey = null; public TupleBatchIterator() { } public TupleBatchIterator(int batchSize) { super(batchSize); } public TupleBatchIterator(K from, K to) { super(from, to); } public TupleBatchIterator(K from, K to, int batchSize) { super(from, to, batchSize); } protected abstract Tuple2<List<E>, K> getRangeTuple(K from, K to, int batchSize, DataOperationsProfile dataOperationsProfile); protected abstract K getKey(E item); @Override public List<E> next(DataOperationsProfile dataOperationsProfile) { Tuple2<List<E>, K> range = getRangeTuple(lowEnd, highEnd, batchSize + 1, dataOperationsProfile); List<E> batch = range.e1; K lastKeyInBatch = batch.size() > 0 ? getKey(batch.get(batch.size() - 1)) : null; List<E> result; //First condition for last batch case //Second condition is main case. If last element has not been deleted we cut it from result batch //Otherwise return result 'as is' if (range.e2 != null && range.e2.equals(lastKey)) { result = range.e1; } else if (batch.size() > 0 && range.e2 != null && range.e2.equals(lastKeyInBatch)) { result = batch.subList(0, batch.size() - 1); } else { result = range.e1; } prevKey = lastKey; lastKey = range.e2; lowEnd = lastKey; if (lastKey == null) { hasNext = false; } else if (lastKey.equals(prevKey)) { hasNext = false; } return result; } }