blob: 66c2735c7d18b68904e648e06dcf0a54b75216c9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.
*/
package org.apache.ignite.internal.processors.query.h2.opt.join;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree;
import org.apache.ignite.internal.processors.query.h2.H2Utils;
import org.apache.ignite.internal.processors.query.h2.database.H2TreeIndex;
import org.apache.ignite.internal.processors.query.h2.opt.H2Row;
import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2RowMessage;
import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2RowRange;
import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2RowRangeBounds;
import static java.util.Collections.emptyIterator;
/**
* Bounds iterator.
*/
public class RangeSource {
/** Index. */
private final H2TreeIndex idx;
/** */
private Iterator<GridH2RowRangeBounds> boundsIter;
/** */
private int curRangeId = -1;
/** */
private final int segment;
/** */
private final BPlusTree.TreeRowClosure<H2Row, H2Row> filter;
/** Iterator. */
private Iterator<H2Row> iter = emptyIterator();
/**
* @param bounds Bounds.
* @param segment Segment.
* @param filter Filter.
*/
public RangeSource(
H2TreeIndex idx,
Iterable<GridH2RowRangeBounds> bounds,
int segment,
BPlusTree.TreeRowClosure<H2Row, H2Row> filter
) {
this.idx = idx;
this.segment = segment;
this.filter = filter;
boundsIter = bounds.iterator();
}
/**
* @return {@code true} If there are more rows in this source.
*/
public boolean hasMoreRows() {
return boundsIter.hasNext() || iter.hasNext();
}
/**
* @param maxRows Max allowed rows.
* @return Range.
*/
public GridH2RowRange next(int maxRows) {
assert maxRows > 0 : maxRows;
for (; ; ) {
if (iter.hasNext()) {
// Here we are getting last rows from previously partially fetched range.
List<GridH2RowMessage> rows = new ArrayList<>();
GridH2RowRange nextRange = new GridH2RowRange();
nextRange.rangeId(curRangeId);
nextRange.rows(rows);
do {
rows.add(H2Utils.toRowMessage(iter.next()));
}
while (rows.size() < maxRows && iter.hasNext());
if (iter.hasNext())
nextRange.setPartial();
else
iter = emptyIterator();
return nextRange;
}
iter = emptyIterator();
if (!boundsIter.hasNext()) {
boundsIter = emptyIterator();
return null;
}
GridH2RowRangeBounds bounds = boundsIter.next();
curRangeId = bounds.rangeId();
iter = idx.findForSegment(bounds, segment, filter);
if (!iter.hasNext()) {
// We have to return empty range here.
GridH2RowRange emptyRange = new GridH2RowRange();
emptyRange.rangeId(curRangeId);
return emptyRange;
}
}
}
}