use of org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2RowRangeBounds in project ignite by apache.
the class DistributedLookupBatch method addSearchRows.
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "ForLoopReplaceableByForEach", "IfMayBeConditional" })
@Override
public boolean addSearchRows(SearchRow firstRow, SearchRow lastRow) {
if (joinCtx == null || findCalled) {
if (joinCtx == null) {
// It is the first call after query begin (may be after reuse),
// reinitialize query context and result.
QueryContext qctx = QueryContext.threadLocal();
res = new ArrayList<>();
assert qctx != null;
assert !findCalled;
joinCtx = qctx.distributedJoinContext();
} else {
// Cleanup after the previous lookup phase.
assert batchLookupId != 0;
findCalled = false;
joinCtx.putStreams(batchLookupId, null);
res.clear();
}
// Reinitialize for the next lookup phase.
batchLookupId = joinCtx.nextBatchLookupId();
rangeStreams = new HashMap<>();
}
Object affKey = getAffinityKey(firstRow, lastRow);
List<SegmentKey> segmentKeys;
if (affKey != null) {
// Affinity key is provided.
if (// Affinity key is explicit null, we will not find anything.
affKey == EXPLICIT_NULL)
return false;
segmentKeys = F.asList(rangeSegment(affKey));
} else {
// Affinity key is not provided or is not the same in upper and lower bounds, we have to broadcast.
if (broadcastSegments == null)
broadcastSegments = broadcastSegments();
segmentKeys = broadcastSegments;
}
assert !F.isEmpty(segmentKeys) : segmentKeys;
final int rangeId = res.size();
// Create messages.
GridH2RowMessage first = idx.toSearchRowMessage(firstRow);
GridH2RowMessage last = idx.toSearchRowMessage(lastRow);
// Range containing upper and lower bounds.
GridH2RowRangeBounds rangeBounds = rangeBounds(rangeId, first, last);
// Add range to every message of every participating node.
for (int i = 0; i < segmentKeys.size(); i++) {
SegmentKey segmentKey = segmentKeys.get(i);
assert segmentKey != null;
RangeStream stream = rangeStreams.get(segmentKey);
List<GridH2RowRangeBounds> bounds;
if (stream == null) {
stream = new RangeStream(cctx.kernalContext(), idx, joinCtx, segmentKey.node());
stream.request(createRequest(joinCtx, batchLookupId, segmentKey.segmentId()));
stream.request().bounds(bounds = new ArrayList<>());
rangeStreams.put(segmentKey, stream);
} else
bounds = stream.request().bounds();
bounds.add(rangeBounds);
// If at least one node will have a full batch then we are ok.
if (bounds.size() >= joinCtx.pageSize())
batchFull = true;
}
Cursor cur;
if (segmentKeys.size() == 1)
cur = new UnicastCursor(rangeId, rangeStreams.get(F.first(segmentKeys)));
else
cur = new BroadcastCursor(idx, rangeId, segmentKeys, rangeStreams);
res.add(new DoneFuture<>(cur));
return true;
}
use of org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2RowRangeBounds in project ignite by apache.
the class RangeSource method next.
/**
* @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, qryCtx);
if (!iter.hasNext()) {
// We have to return empty range here.
GridH2RowRange emptyRange = new GridH2RowRange();
emptyRange.rangeId(curRangeId);
return emptyRange;
}
}
}
use of org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2RowRangeBounds in project ignite by apache.
the class H2TreeIndex method findForSegment.
/**
* Find rows for the segments (distributed joins).
*
* @param bounds Bounds.
* @param segment Segment.
* @param qryCtx Index query context.
* @return Iterator.
*/
public Iterator<H2Row> findForSegment(GridH2RowRangeBounds bounds, int segment, IndexQueryContext qryCtx) {
SearchRow lower = toSearchRow(bounds.first());
SearchRow upper = toSearchRow(bounds.last());
T2<IndexRow, IndexRow> key = prepareIndexKeys(lower, upper);
try {
GridCursor<IndexRow> range = queryIndex.find(key.get1(), key.get2(), true, true, segment, qryCtx);
if (range == null)
range = IndexValueCursor.EMPTY;
GridCursor<H2Row> h2cursor = new IndexValueCursor<>(range, this::mapIndexRow);
H2Cursor cur = new H2Cursor(h2cursor);
return new CursorIteratorWrapper(cur);
} catch (IgniteCheckedException e) {
throw DbException.convert(e);
}
}
Aggregations