use of org.teiid.common.buffer.TupleBuffer in project teiid by teiid.
the class SortNode method sortPhase.
private void sortPhase() throws BlockedException, TeiidComponentException, TeiidProcessingException {
if (this.sortUtility == null) {
TupleSource ts = null;
TupleBuffer working = null;
if (!getChildren()[0].hasBuffer()) {
ts = new BatchIterator(getChildren()[0]);
} else {
working = getChildren()[0].getBuffer(-1);
}
this.sortUtility = new SortUtility(ts, items, this.mode, getBufferManager(), getConnectionID(), getChildren()[0].getElements());
if (ts == null) {
this.sortUtility.setWorkingBuffer(working);
}
}
this.output = this.sortUtility.sort(rowLimit);
if (this.outputTs == null) {
this.outputTs = this.output.createIndexedTupleSource();
}
this.phase = OUTPUT;
}
use of org.teiid.common.buffer.TupleBuffer in project teiid by teiid.
the class SortUtility method onePassSort.
public List<TupleBuffer> onePassSort(boolean lowLatency) throws TeiidComponentException, TeiidProcessingException {
boolean success = false;
try {
if (this.phase == INITIAL_SORT) {
initialSort(true, lowLatency, -1);
if (!isDoneReading()) {
this.phase = INITIAL_SORT;
}
}
for (TupleBuffer tb : activeTupleBuffers) {
tb.close();
// it is up to the caller to set the flag now
tb.setForwardOnly(false);
}
success = true;
return activeTupleBuffers;
} catch (BlockedException e) {
success = true;
throw e;
} finally {
if (!success) {
remove();
}
}
}
use of org.teiid.common.buffer.TupleBuffer in project teiid by teiid.
the class SortUtility method remove.
public synchronized void remove() {
if (workingBuffer != null && source != null) {
workingBuffer.remove();
workingBuffer = null;
}
if (!this.activeTupleBuffers.isEmpty()) {
// they should not be reused whole
for (int i = 0; i < this.activeTupleBuffers.size(); i++) {
TupleBuffer tb = this.activeTupleBuffers.get(i);
if (i == 0 && phase == DONE) {
continue;
}
tb.remove();
}
this.activeTupleBuffers.clear();
}
}
use of org.teiid.common.buffer.TupleBuffer in project teiid by teiid.
the class SortingFilter method getResult.
/**
* @throws TeiidProcessingException
* @see org.teiid.query.function.aggregate.AggregateFunction#getResult(CommandContext)
*/
public Object getResult(CommandContext commandContext) throws TeiidComponentException, TeiidProcessingException {
if (collectionBuffer != null) {
this.collectionBuffer.close();
// Sort
if (sortUtility == null) {
sortUtility = new SortUtility(null, sortItems, removeDuplicates ? Mode.DUP_REMOVE_SORT : Mode.SORT, mgr, groupName, collectionBuffer.getSchema());
collectionBuffer.setForwardOnly(true);
this.sortUtility.setWorkingBuffer(collectionBuffer);
}
TupleBuffer sorted = sortUtility.sort();
sorted.setForwardOnly(true);
try {
// Add all input to proxy
TupleSource sortedSource = sorted.createIndexedTupleSource();
while (true) {
List<?> tuple = sortedSource.nextTuple();
if (tuple == null) {
break;
}
// TODO should possibly remove the order by columns from this tuple
this.proxy.addInputDirect(tuple, commandContext);
}
} finally {
sorted.remove();
}
close();
}
// Return
return this.proxy.getResult(commandContext);
}
use of org.teiid.common.buffer.TupleBuffer in project teiid by teiid.
the class SubqueryAwareEvaluator method evaluateSubquery.
@Override
protected ValueIterator evaluateSubquery(SubqueryContainer<?> container, List<?> tuple) throws TeiidProcessingException, BlockedException, TeiidComponentException {
ContextReference ref = (ContextReference) container;
String key = ref.getContextSymbol();
SubqueryState state = this.subqueries.get(key);
if (state == null) {
String otherKey = commands.get(container.getCommand());
if (otherKey != null) {
state = this.subqueries.get(otherKey);
if (state != null) {
key = otherKey;
}
}
}
if (state == null) {
state = new SubqueryState();
state.plan = container.getCommand().getProcessorPlan().clone();
if (container.getCommand().getCorrelatedReferences() != null) {
for (ElementSymbol es : container.getCommand().getCorrelatedReferences().getKeys()) {
if (DataTypeManager.isNonComparable(DataTypeManager.getDataTypeName(es.getType()))) {
state.comparable = false;
break;
}
}
}
this.subqueries.put(key, state);
this.commands.put(container.getCommand(), key);
}
SymbolMap correlatedRefs = container.getCommand().getCorrelatedReferences();
VariableContext currentContext = null;
boolean shouldClose = false;
boolean deterministic = true;
if (state.processor != null && correlatedRefs != null) {
Determinism determinism = state.processor.getContext().getDeterminismLevel();
deterministic = Determinism.COMMAND_DETERMINISTIC.compareTo(determinism) <= 0;
}
boolean removeBuffer = true;
if (correlatedRefs != null) {
currentContext = new VariableContext();
for (Map.Entry<ElementSymbol, Expression> entry : container.getCommand().getCorrelatedReferences().asMap().entrySet()) {
currentContext.setValue(entry.getKey(), evaluate(entry.getValue(), tuple));
}
List<Object> refValues = currentContext.getLocalValues();
if (!refValues.equals(state.refValues)) {
if (state.comparable && deterministic) {
if (state.processor != null) {
// cache the old value
TupleBuffer tb = state.collector.collectTuples();
// recheck determinism as the plan may not have been fully processed by the initial check
Determinism determinism = state.processor.getContext().getDeterminismLevel();
deterministic = Determinism.COMMAND_DETERMINISTIC.compareTo(determinism) <= 0;
if (deterministic) {
// allowed to track up to 4x the maximum results size
maxTuples = Math.max((int) Math.min(Integer.MAX_VALUE, tb.getRowCount() << 2), maxTuples);
ArrayList<Object> cacheKey = new ArrayList<Object>(state.refValues);
cacheKey.add(key);
// ensure that we aren't leaving large last batches in memory
tb.saveBatch();
this.cache.put(cacheKey, tb);
removeBuffer = false;
this.currentTuples += tb.getRowCount();
while (this.currentTuples > maxTuples && !cache.isEmpty()) {
Iterator<Map.Entry<List<?>, TupleBuffer>> i = this.cache.entrySet().iterator();
Map.Entry<List<?>, TupleBuffer> entry = i.next();
TupleBuffer buffer = entry.getValue();
if (buffer.getRowCount() <= 2) {
this.smallCache.put(entry.getKey(), buffer);
} else {
buffer.remove();
}
this.currentTuples -= buffer.getRowCount();
i.remove();
}
}
}
// find if we have cached values
List<Object> cacheKey = new ArrayList<Object>(refValues);
cacheKey.add(key);
TupleBuffer cachedResult = cache.get(cacheKey);
if (cachedResult == null) {
cachedResult = smallCache.get(cacheKey);
}
if (cachedResult != null) {
state.close(false);
return new TupleSourceValueIterator(cachedResult.createIndexedTupleSource(), 0);
}
}
state.refValues = refValues;
shouldClose = true;
}
}
if (shouldClose || (!deterministic && !state.blocked)) {
state.close(removeBuffer);
}
state.blocked = true;
if (state.processor == null) {
CommandContext subContext = context.clone();
state.plan.reset();
state.processor = new QueryProcessor(state.plan, subContext, manager, this.dataMgr);
if (currentContext != null) {
state.processor.getContext().pushVariableContext(currentContext);
}
state.collector = state.processor.createBatchCollector();
}
TupleSourceValueIterator iter = new TupleSourceValueIterator(state.collector.collectTuples().createIndexedTupleSource(), 0);
state.blocked = false;
return iter;
}
Aggregations