
com.github.phantomthief.util.CursorIterator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cursor-iterator Show documentation
Show all versions of cursor-iterator Show documentation
A cursor iterator implements for batch build cursor data
The newest version!
/**
*
*/
package com.github.phantomthief.util;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Function;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
*
* @author w.vela
*/
public class CursorIterator implements Iterable {
private static final int DEFAULT_BUFFER_SIZE = 30;
private final GetByCursorDAO dao;
private final int bufferSize;
private final Function function;
private Id initCursor;
private boolean firstTime;
private boolean end;
/**
* @param dao 游标方式取的DAO
* @param initCursor 第一次的游标位置(包含)
* @param bufferSize 每次游标迭代的条数
* @param extractor 游标和实体数据的转换器
*
* better use {@code #newBuilder()}
*/
@Deprecated
public CursorIterator(GetByCursorDAO dao, Id initCursor, int bufferSize,
Function extractor) {
checkArgument(bufferSize > 0);
checkNotNull(dao);
checkNotNull(extractor);
this.dao = dao;
this.initCursor = initCursor;
this.bufferSize = bufferSize;
this.firstTime = true;
this.function = extractor;
this.end = false;
}
private List innerData;
private List innerData() {
if (end) {
return Collections.emptyList();
}
if (innerData == null) {
innerData = dao.getByCursor(initCursor, firstTime ? bufferSize : bufferSize + 1);
if ((innerData.size() > 0) && !firstTime) {
innerData = innerData.subList(1, innerData.size());
}
}
return innerData;
}
/**
* 取到内部迭代器
*
* @return
*/
private Iterator innerIterator() {
return innerData().iterator();
}
/**
* 下一个迭代时拿上一次游标的位置
*
* @return
*/
private Id getLastCursor() {
List byCursor = innerData();
if (byCursor == null || byCursor.isEmpty()) {
return null;
}
Id result = function.apply(byCursor.get(byCursor.size() - 1));
return result;
}
/**
* 判断是否到结尾的标记
*
* @return
*/
private boolean hasMore() {
List byCurosr = innerData();
if (byCurosr.size() < bufferSize) {
return false;
} else {
return true;
}
}
/* (non-Javadoc)
* @see java.lang.Iterable#iterator()
*/
@Override
public Iterator iterator() {
/**
* 这个匿名类主要做lazy的用途,可以在迭代的过程中,不会把所有的数据和迭代器都生成,只生成最近两个的
*/
return new Iterator() {
private Iterator itr;
private Iterator itr() {
if (itr == null) {
itr = innerIterator();
}
return itr;
}
@Override
public boolean hasNext() {
boolean hasNext = itr().hasNext();
if (!hasNext) {
if (end) {
return hasNext;
} else {
initCursor = getLastCursor();
firstTime = false;
end = !hasMore();
innerData = null;
itr = null;
return itr().hasNext();
}
}
return hasNext;
}
@Override
public Entity next() {
return itr().next();
}
@Override
public void remove() {
itr().remove();
}
};
}
public Stream stream() {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(iterator(),
(Spliterator.NONNULL | Spliterator.IMMUTABLE | Spliterator.ORDERED)),
false);
}
@SuppressWarnings("unchecked")
public static final class Builder {
private GetByCursorDAO dao;
private int bufferSize;
private Function function;
private Id init;
public CursorIterator build(GetByCursorDAO super I, ? extends E> dao) {
Builder thisBuilder = (Builder) this;
thisBuilder.dao = (GetByCursorDAO) dao;
return thisBuilder.build();
}
public Builder bufferSize(int bufferSize) {
this.bufferSize = bufferSize;
return this;
}
public Builder cursorExtractor(Function super E, ? extends I> function) {
Builder thisBuilder = (Builder) this;
thisBuilder.function = (Function) function;
return thisBuilder;
}
public Builder start(I init) {
Builder thisBuilder = (Builder) this;
thisBuilder.init = init;
return thisBuilder;
}
private CursorIterator build() {
ensure();
return new CursorIterator<>(dao, init, bufferSize, function);
}
private void ensure() {
checkNotNull(dao);
checkNotNull(function);
if (bufferSize <= 0) {
bufferSize = DEFAULT_BUFFER_SIZE;
}
}
}
public static Builder
© 2015 - 2025 Weber Informatics LLC | Privacy Policy