/*
* Licensed to Crate.IO GmbH ("Crate") under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. Crate licenses
* this file to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* However, if you have executed another commercial license agreement
* with Crate these terms will supersede the license and you may use the
* software solely pursuant to the terms of the relevant commercial agreement.
*/
package io.crate.operation.merge;
import com.google.common.collect.ForwardingIterator;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import java.util.Collections;
import java.util.Iterator;
public class PassThroughPagingIterator<TKey, TRow> extends ForwardingIterator<TRow> implements PagingIterator<TKey, TRow> {
private Iterator<TRow> iterator = Collections.emptyIterator();
private final ImmutableList.Builder<KeyIterable<TKey, TRow>> iterables = ImmutableList.builder();
private final boolean repeatable;
private Iterable<TRow> storedForRepeat = null;
private PassThroughPagingIterator(boolean repeatable) {
this.repeatable = repeatable;
}
/**
* Create an iterator that is able to repeat over what has previously been iterated
*/
public static <TKey, TRow> PassThroughPagingIterator<TKey, TRow> repeatable() {
return new PassThroughPagingIterator<>(true);
}
/**
* Create an iterator that is not able to repeat.
* Calling {@link #repeat()} with instances created by this method is discouraged.
*/
public static <TKey, TRow> PassThroughPagingIterator<TKey, TRow> oneShot() {
return new PassThroughPagingIterator<>(false);
}
@Override
protected Iterator<TRow> delegate() {
return iterator;
}
@Override
public void merge(Iterable<? extends KeyIterable<TKey, TRow>> iterables) {
Iterable<TRow> concat = Iterables.concat(iterables);
if (repeatable) {
this.iterables.addAll(iterables);
this.storedForRepeat = null;
}
if (iterator.hasNext()) {
iterator = Iterators.concat(iterator, concat.iterator());
} else {
iterator = concat.iterator();
}
}
@Override
public void finish() {
}
@Override
public TKey exhaustedIterable() {
return null;
}
@Override
public Iterable<TRow> repeat() {
Iterable<TRow> repeatMe = storedForRepeat;
if (repeatMe == null) {
repeatMe = Iterables.concat(this.iterables.build());
this.storedForRepeat = repeatMe;
}
return repeatMe;
}
}