index = this.joinNode.getBufferManager().createSTree(reordered, this.joinNode.getConnectionID(), keyLength);
index.setPreferMemory(true);
if (!state.isDistinct()) {
index.getComparator().setDistinctIndex(keyLength-2);
}
IndexedTupleSource its = state.getTupleBuffer().createIndexedTupleSource(!joinNode.isDependent());
int rowId = 0;
List<?> lastTuple = null;
boolean sortedDistinct = sorted && !state.isDistinct();
int sizeHint = index.getExpectedHeight(state.getTupleBuffer().getRowCount());
outer: while (its.hasNext()) {
//detect if sorted and distinct
List<?> originalTuple = its.nextTuple();
//remove the tuple if it has null
for (int i : state.getExpressionIndexes()) {
if (originalTuple.get(i) == null) {
continue outer;
}
}
if (sortedDistinct && lastTuple != null && this.compare(lastTuple, originalTuple, state.getExpressionIndexes(), state.getExpressionIndexes()) == 0) {
sortedDistinct = false;
}
lastTuple = originalTuple;
List<Object> tuple = (List<Object>) RelationalNode.projectTuple(reorderedSortIndex, originalTuple);
if (!state.isDistinct()) {
tuple.add(keyLength - 1, rowId++);
}
index.insert(tuple, sorted?InsertMode.ORDERED:InsertMode.NEW, sizeHint);
}
if (!sorted) {
index.compact();
}
its.closeSource();
this.reverseIndexes = new int[elements.size()];
for (int i = 0; i < reverseIndexes.length; i++) {
int oldIndex = reorderedSortIndex[i];
this.reverseIndexes[oldIndex] = i + (!state.isDistinct()&&i>=keyLength-1?1:0);
}