/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
***************************************************************************************
*/
package com.espertech.esper.epl.core;
import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.EventType;
import com.espertech.esper.collection.ArrayEventIterator;
import com.espertech.esper.collection.MultiKey;
import com.espertech.esper.collection.UniformPair;
import com.espertech.esper.core.context.util.AgentInstanceContext;
import com.espertech.esper.epl.agg.service.AggregationService;
import com.espertech.esper.epl.expression.core.ExprEvaluator;
import com.espertech.esper.epl.expression.core.ExprEvaluatorContext;
import com.espertech.esper.epl.spec.OutputLimitLimitType;
import com.espertech.esper.metrics.instrumentation.InstrumentationHelper;
import com.espertech.esper.view.Viewable;
import java.util.*;
/**
* Result set processor for the case: aggregation functions used in the select clause, and no group-by,
* and not all of the properties in the select clause are under an aggregation function.
* <p>
* This processor does not perform grouping, every event entering and leaving is in the same group.
* The processor generates one row for each event entering (new event) and one row for each event leaving (old event).
* Aggregation state is simply one row holding all the state.
*/
public class ResultSetProcessorAggregateAll implements ResultSetProcessor {
private final ResultSetProcessorAggregateAllFactory prototype;
private final SelectExprProcessor selectExprProcessor;
private final OrderByProcessor orderByProcessor;
private final AggregationService aggregationService;
private ExprEvaluatorContext exprEvaluatorContext;
private ResultSetProcessorAggregateAllOutputLastHelper outputLastUnordHelper;
private ResultSetProcessorAggregateAllOutputAllHelper outputAllUnordHelper;
public ResultSetProcessorAggregateAll(ResultSetProcessorAggregateAllFactory prototype, SelectExprProcessor selectExprProcessor, OrderByProcessor orderByProcessor, AggregationService aggregationService, AgentInstanceContext agentInstanceContext) {
this.prototype = prototype;
this.selectExprProcessor = selectExprProcessor;
this.orderByProcessor = orderByProcessor;
this.aggregationService = aggregationService;
this.exprEvaluatorContext = agentInstanceContext;
this.outputLastUnordHelper = prototype.isEnableOutputLimitOpt() && prototype.isOutputLast() ? prototype.getResultSetProcessorHelperFactory().makeRSAggregateAllOutputLast(this, agentInstanceContext) : null;
this.outputAllUnordHelper = prototype.isEnableOutputLimitOpt() && prototype.isOutputAll() ? prototype.getResultSetProcessorHelperFactory().makeRSAggregateAllOutputAll(this, agentInstanceContext) : null;
}
public void setAgentInstanceContext(AgentInstanceContext context) {
this.exprEvaluatorContext = context;
}
public EventType getResultEventType() {
return prototype.getResultEventType();
}
public void applyViewResult(EventBean[] newData, EventBean[] oldData) {
EventBean[] eventsPerStream = new EventBean[1];
ResultSetProcessorUtil.applyAggViewResult(aggregationService, exprEvaluatorContext, newData, oldData, eventsPerStream);
}
public void applyJoinResult(Set<MultiKey<EventBean>> newEvents, Set<MultiKey<EventBean>> oldEvents) {
ResultSetProcessorUtil.applyAggJoinResult(aggregationService, exprEvaluatorContext, newEvents, oldEvents);
}
public UniformPair<EventBean[]> processJoinResult(Set<MultiKey<EventBean>> newEvents, Set<MultiKey<EventBean>> oldEvents, boolean isSynthesize) {
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().qResultSetProcessUngroupedNonfullyAgg();
}
EventBean[] selectOldEvents = null;
EventBean[] selectNewEvents;
if (prototype.isUnidirectional()) {
this.clear();
}
ResultSetProcessorUtil.applyAggJoinResult(aggregationService, exprEvaluatorContext, newEvents, oldEvents);
if (prototype.getOptionalHavingNode() == null) {
if (prototype.isSelectRStream()) {
if (orderByProcessor == null) {
selectOldEvents = ResultSetProcessorUtil.getSelectJoinEventsNoHaving(selectExprProcessor, oldEvents, false, isSynthesize, exprEvaluatorContext);
} else {
selectOldEvents = ResultSetProcessorUtil.getSelectJoinEventsNoHavingWithOrderBy(selectExprProcessor, orderByProcessor, oldEvents, false, isSynthesize, exprEvaluatorContext);
}
}
if (orderByProcessor == null) {
selectNewEvents = ResultSetProcessorUtil.getSelectJoinEventsNoHaving(selectExprProcessor, newEvents, true, isSynthesize, exprEvaluatorContext);
} else {
selectNewEvents = ResultSetProcessorUtil.getSelectJoinEventsNoHavingWithOrderBy(selectExprProcessor, orderByProcessor, newEvents, true, isSynthesize, exprEvaluatorContext);
}
} else {
if (prototype.isSelectRStream()) {
if (orderByProcessor == null) {
selectOldEvents = ResultSetProcessorUtil.getSelectJoinEventsHaving(selectExprProcessor, oldEvents, prototype.getOptionalHavingNode(), false, isSynthesize, exprEvaluatorContext);
} else {
selectOldEvents = ResultSetProcessorUtil.getSelectJoinEventsHavingWithOrderBy(selectExprProcessor, orderByProcessor, oldEvents, prototype.getOptionalHavingNode(), false, isSynthesize, exprEvaluatorContext);
}
}
if (orderByProcessor == null) {
selectNewEvents = ResultSetProcessorUtil.getSelectJoinEventsHaving(selectExprProcessor, newEvents, prototype.getOptionalHavingNode(), true, isSynthesize, exprEvaluatorContext);
} else {
selectNewEvents = ResultSetProcessorUtil.getSelectJoinEventsHavingWithOrderBy(selectExprProcessor, orderByProcessor, newEvents, prototype.getOptionalHavingNode(), true, isSynthesize, exprEvaluatorContext);
}
}
if ((selectNewEvents == null) && (selectOldEvents == null)) {
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().aResultSetProcessUngroupedNonfullyAgg(null, null);
}
return null;
}
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().aResultSetProcessUngroupedNonfullyAgg(selectNewEvents, selectOldEvents);
}
return new UniformPair<EventBean[]>(selectNewEvents, selectOldEvents);
}
public UniformPair<EventBean[]> processViewResult(EventBean[] newData, EventBean[] oldData, boolean isSynthesize) {
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().qResultSetProcessUngroupedNonfullyAgg();
}
EventBean[] selectOldEvents = null;
EventBean[] selectNewEvents;
EventBean[] eventsPerStream = new EventBean[1];
ResultSetProcessorUtil.applyAggViewResult(aggregationService, exprEvaluatorContext, newData, oldData, eventsPerStream);
// generate new events using select expressions
if (prototype.getOptionalHavingNode() == null) {
if (prototype.isSelectRStream()) {
if (orderByProcessor == null) {
selectOldEvents = ResultSetProcessorUtil.getSelectEventsNoHaving(selectExprProcessor, oldData, false, isSynthesize, exprEvaluatorContext);
} else {
selectOldEvents = ResultSetProcessorUtil.getSelectEventsNoHavingWithOrderBy(selectExprProcessor, orderByProcessor, oldData, false, isSynthesize, exprEvaluatorContext);
}
}
if (orderByProcessor == null) {
selectNewEvents = ResultSetProcessorUtil.getSelectEventsNoHaving(selectExprProcessor, newData, true, isSynthesize, exprEvaluatorContext);
} else {
selectNewEvents = ResultSetProcessorUtil.getSelectEventsNoHavingWithOrderBy(selectExprProcessor, orderByProcessor, newData, true, isSynthesize, exprEvaluatorContext);
}
} else {
if (prototype.isSelectRStream()) {
if (orderByProcessor == null) {
selectOldEvents = ResultSetProcessorUtil.getSelectEventsHaving(selectExprProcessor, oldData, prototype.getOptionalHavingNode(), false, isSynthesize, exprEvaluatorContext);
} else {
selectOldEvents = ResultSetProcessorUtil.getSelectEventsHavingWithOrderBy(selectExprProcessor, orderByProcessor, oldData, prototype.getOptionalHavingNode(), false, isSynthesize, exprEvaluatorContext);
}
}
if (orderByProcessor == null) {
selectNewEvents = ResultSetProcessorUtil.getSelectEventsHaving(selectExprProcessor, newData, prototype.getOptionalHavingNode(), true, isSynthesize, exprEvaluatorContext);
} else {
selectNewEvents = ResultSetProcessorUtil.getSelectEventsHavingWithOrderBy(selectExprProcessor, orderByProcessor, newData, prototype.getOptionalHavingNode(), true, isSynthesize, exprEvaluatorContext);
}
}
if ((selectNewEvents == null) && (selectOldEvents == null)) {
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().aResultSetProcessUngroupedNonfullyAgg(null, null);
}
return null;
}
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().aResultSetProcessUngroupedNonfullyAgg(selectNewEvents, selectOldEvents);
}
return new UniformPair<EventBean[]>(selectNewEvents, selectOldEvents);
}
public Iterator<EventBean> getIterator(Viewable parent) {
if (!prototype.isHistoricalOnly()) {
return obtainIterator(parent);
}
ResultSetProcessorUtil.clearAndAggregateUngrouped(exprEvaluatorContext, aggregationService, parent);
ArrayDeque<EventBean> deque = ResultSetProcessorUtil.iteratorToDeque(obtainIterator(parent));
aggregationService.clearResults(exprEvaluatorContext);
return deque.iterator();
}
public Iterator<EventBean> obtainIterator(Viewable parent) {
if (orderByProcessor == null) {
return new ResultSetAggregateAllIterator(parent.iterator(), this, exprEvaluatorContext);
}
// Pull all parent events, generate order keys
EventBean[] eventsPerStream = new EventBean[1];
List<EventBean> outgoingEvents = new ArrayList<EventBean>();
List<Object> orderKeys = new ArrayList<Object>();
for (EventBean candidate : parent) {
eventsPerStream[0] = candidate;
Boolean pass = true;
if (prototype.getOptionalHavingNode() != null) {
pass = (Boolean) prototype.getOptionalHavingNode().evaluate(eventsPerStream, true, exprEvaluatorContext);
}
if ((pass == null) || (!pass)) {
continue;
}
outgoingEvents.add(selectExprProcessor.process(eventsPerStream, true, true, exprEvaluatorContext));
Object orderKey = orderByProcessor.getSortKey(eventsPerStream, true, exprEvaluatorContext);
orderKeys.add(orderKey);
}
// sort
EventBean[] outgoingEventsArr = outgoingEvents.toArray(new EventBean[outgoingEvents.size()]);
Object[] orderKeysArr = orderKeys.toArray(new Object[orderKeys.size()]);
EventBean[] orderedEvents = orderByProcessor.sort(outgoingEventsArr, orderKeysArr, exprEvaluatorContext);
return new ArrayEventIterator(orderedEvents);
}
/**
* Returns the select expression processor
*
* @return select processor.
*/
public SelectExprProcessor getSelectExprProcessor() {
return selectExprProcessor;
}
/**
* Returns the optional having expression.
*
* @return having expression node
*/
public ExprEvaluator getOptionalHavingNode() {
return prototype.getOptionalHavingNode();
}
public Iterator<EventBean> getIterator(Set<MultiKey<EventBean>> joinSet) {
EventBean[] result;
if (prototype.getOptionalHavingNode() == null) {
if (orderByProcessor == null) {
result = ResultSetProcessorUtil.getSelectJoinEventsNoHaving(selectExprProcessor, joinSet, true, true, exprEvaluatorContext);
} else {
result = ResultSetProcessorUtil.getSelectJoinEventsNoHavingWithOrderBy(selectExprProcessor, orderByProcessor, joinSet, true, true, exprEvaluatorContext);
}
} else {
if (orderByProcessor == null) {
result = ResultSetProcessorUtil.getSelectJoinEventsHaving(selectExprProcessor, joinSet, prototype.getOptionalHavingNode(), true, true, exprEvaluatorContext);
} else {
result = ResultSetProcessorUtil.getSelectJoinEventsHavingWithOrderBy(selectExprProcessor, orderByProcessor, joinSet, prototype.getOptionalHavingNode(), true, true, exprEvaluatorContext);
}
}
return new ArrayEventIterator(result);
}
public void clear() {
aggregationService.clearResults(exprEvaluatorContext);
}
public UniformPair<EventBean[]> processOutputLimitedJoin(List<UniformPair<Set<MultiKey<EventBean>>>> joinEventsSet, boolean generateSynthetic, OutputLimitLimitType outputLimitLimitType) {
if (outputLimitLimitType == OutputLimitLimitType.LAST) {
return processOutputLimitedJoinLast(joinEventsSet, generateSynthetic);
} else {
return processOutputLimitedJoinDefault(joinEventsSet, generateSynthetic);
}
}
public UniformPair<EventBean[]> processOutputLimitedView(List<UniformPair<EventBean[]>> viewEventsList, boolean generateSynthetic, OutputLimitLimitType outputLimitLimitType) {
if (outputLimitLimitType == OutputLimitLimitType.LAST) {
return processOutputLimitedViewLast(viewEventsList, generateSynthetic);
} else {
return processOutputLimitedViewDefault(viewEventsList, generateSynthetic);
}
}
public boolean hasAggregation() {
return true;
}
public void processOutputLimitedLastAllNonBufferedView(EventBean[] newData, EventBean[] oldData, boolean isGenerateSynthetic, boolean isAll) {
if (isAll) {
outputAllUnordHelper.processView(newData, oldData, isGenerateSynthetic);
} else {
outputLastUnordHelper.processView(newData, oldData, isGenerateSynthetic);
}
}
public void processOutputLimitedLastAllNonBufferedJoin(Set<MultiKey<EventBean>> newEvents, Set<MultiKey<EventBean>> oldEvents, boolean isGenerateSynthetic, boolean isAll) {
if (isAll) {
outputAllUnordHelper.processJoin(newEvents, oldEvents, isGenerateSynthetic);
} else {
outputLastUnordHelper.processJoin(newEvents, oldEvents, isGenerateSynthetic);
}
}
public UniformPair<EventBean[]> continueOutputLimitedLastAllNonBufferedView(boolean isSynthesize, boolean isAll) {
if (isAll) {
return outputAllUnordHelper.output();
}
return outputLastUnordHelper.output();
}
public UniformPair<EventBean[]> continueOutputLimitedLastAllNonBufferedJoin(boolean isSynthesize, boolean isAll) {
if (isAll) {
return outputAllUnordHelper.output();
}
return outputLastUnordHelper.output();
}
public void stop() {
if (outputLastUnordHelper != null) {
outputLastUnordHelper.destroy();
}
if (outputAllUnordHelper != null) {
outputAllUnordHelper.destroy();
}
}
private UniformPair<EventBean[]> processOutputLimitedJoinDefault(List<UniformPair<Set<MultiKey<EventBean>>>> joinEventsSet, boolean generateSynthetic) {
List<EventBean> newEvents = new LinkedList<EventBean>();
List<EventBean> oldEvents = null;
if (prototype.isSelectRStream()) {
oldEvents = new LinkedList<EventBean>();
}
List<Object> newEventsSortKey = null;
List<Object> oldEventsSortKey = null;
if (orderByProcessor != null) {
newEventsSortKey = new LinkedList<Object>();
if (prototype.isSelectRStream()) {
oldEventsSortKey = new LinkedList<Object>();
}
}
for (UniformPair<Set<MultiKey<EventBean>>> pair : joinEventsSet) {
Set<MultiKey<EventBean>> newData = pair.getFirst();
Set<MultiKey<EventBean>> oldData = pair.getSecond();
if (prototype.isUnidirectional()) {
this.clear();
}
if (newData != null) {
// apply new data to aggregates
for (MultiKey<EventBean> row : newData) {
aggregationService.applyEnter(row.getArray(), null, exprEvaluatorContext);
}
}
if (oldData != null) {
// apply old data to aggregates
for (MultiKey<EventBean> row : oldData) {
aggregationService.applyLeave(row.getArray(), null, exprEvaluatorContext);
}
}
// generate old events using select expressions
if (prototype.isSelectRStream()) {
if (prototype.getOptionalHavingNode() == null) {
if (orderByProcessor == null) {
ResultSetProcessorUtil.populateSelectJoinEventsNoHaving(selectExprProcessor, oldData, false, generateSynthetic, oldEvents, exprEvaluatorContext);
} else {
ResultSetProcessorUtil.populateSelectJoinEventsNoHavingWithOrderBy(selectExprProcessor, orderByProcessor, oldData, false, generateSynthetic, oldEvents, oldEventsSortKey, exprEvaluatorContext);
}
} else {
// generate old events using having then select
if (orderByProcessor == null) {
ResultSetProcessorUtil.populateSelectJoinEventsHaving(selectExprProcessor, oldData, prototype.getOptionalHavingNode(), false, generateSynthetic, oldEvents, exprEvaluatorContext);
} else {
ResultSetProcessorUtil.populateSelectJoinEventsHavingWithOrderBy(selectExprProcessor, orderByProcessor, oldData, prototype.getOptionalHavingNode(), false, generateSynthetic, oldEvents, oldEventsSortKey, exprEvaluatorContext);
}
}
}
// generate new events using select expressions
if (prototype.getOptionalHavingNode() == null) {
if (orderByProcessor == null) {
ResultSetProcessorUtil.populateSelectJoinEventsNoHaving(selectExprProcessor, newData, true, generateSynthetic, newEvents, exprEvaluatorContext);
} else {
ResultSetProcessorUtil.populateSelectJoinEventsNoHavingWithOrderBy(selectExprProcessor, orderByProcessor, newData, true, generateSynthetic, newEvents, newEventsSortKey, exprEvaluatorContext);
}
} else {
if (orderByProcessor == null) {
ResultSetProcessorUtil.populateSelectJoinEventsHaving(selectExprProcessor, newData, prototype.getOptionalHavingNode(), true, generateSynthetic, newEvents, exprEvaluatorContext);
} else {
ResultSetProcessorUtil.populateSelectJoinEventsHavingWithOrderBy(selectExprProcessor, orderByProcessor, newData, prototype.getOptionalHavingNode(), true, generateSynthetic, newEvents, newEventsSortKey, exprEvaluatorContext);
}
}
}
EventBean[] newEventsArr = (newEvents.isEmpty()) ? null : newEvents.toArray(new EventBean[newEvents.size()]);
EventBean[] oldEventsArr = null;
if (prototype.isSelectRStream()) {
oldEventsArr = (oldEvents.isEmpty()) ? null : oldEvents.toArray(new EventBean[oldEvents.size()]);
}
if (orderByProcessor != null) {
Object[] sortKeysNew = (newEventsSortKey.isEmpty()) ? null : newEventsSortKey.toArray(new Object[newEventsSortKey.size()]);
newEventsArr = orderByProcessor.sort(newEventsArr, sortKeysNew, exprEvaluatorContext);
if (prototype.isSelectRStream()) {
Object[] sortKeysOld = (oldEventsSortKey.isEmpty()) ? null : oldEventsSortKey.toArray(new Object[oldEventsSortKey.size()]);
oldEventsArr = orderByProcessor.sort(oldEventsArr, sortKeysOld, exprEvaluatorContext);
}
}
if ((newEventsArr == null) && (oldEventsArr == null)) {
return null;
}
return new UniformPair<EventBean[]>(newEventsArr, oldEventsArr);
}
private UniformPair<EventBean[]> processOutputLimitedJoinLast(List<UniformPair<Set<MultiKey<EventBean>>>> joinEventsSet, boolean generateSynthetic) {
EventBean lastOldEvent = null;
EventBean lastNewEvent = null;
for (UniformPair<Set<MultiKey<EventBean>>> pair : joinEventsSet) {
Set<MultiKey<EventBean>> newData = pair.getFirst();
Set<MultiKey<EventBean>> oldData = pair.getSecond();
if (prototype.isUnidirectional()) {
this.clear();
}
if (newData != null) {
// apply new data to aggregates
for (MultiKey<EventBean> eventsPerStream : newData) {
aggregationService.applyEnter(eventsPerStream.getArray(), null, exprEvaluatorContext);
}
}
if (oldData != null) {
// apply old data to aggregates
for (MultiKey<EventBean> eventsPerStream : oldData) {
aggregationService.applyLeave(eventsPerStream.getArray(), null, exprEvaluatorContext);
}
}
EventBean[] selectOldEvents;
if (prototype.isSelectRStream()) {
if (prototype.getOptionalHavingNode() == null) {
selectOldEvents = ResultSetProcessorUtil.getSelectJoinEventsNoHaving(selectExprProcessor, oldData, false, generateSynthetic, exprEvaluatorContext);
} else {
selectOldEvents = ResultSetProcessorUtil.getSelectJoinEventsHaving(selectExprProcessor, oldData, prototype.getOptionalHavingNode(), false, generateSynthetic, exprEvaluatorContext);
}
if ((selectOldEvents != null) && (selectOldEvents.length > 0)) {
lastOldEvent = selectOldEvents[selectOldEvents.length - 1];
}
}
// generate new events using select expressions
EventBean[] selectNewEvents;
if (prototype.getOptionalHavingNode() == null) {
selectNewEvents = ResultSetProcessorUtil.getSelectJoinEventsNoHaving(selectExprProcessor, newData, true, generateSynthetic, exprEvaluatorContext);
} else {
selectNewEvents = ResultSetProcessorUtil.getSelectJoinEventsHaving(selectExprProcessor, newData, prototype.getOptionalHavingNode(), true, generateSynthetic, exprEvaluatorContext);
}
if ((selectNewEvents != null) && (selectNewEvents.length > 0)) {
lastNewEvent = selectNewEvents[selectNewEvents.length - 1];
}
}
EventBean[] lastNew = (lastNewEvent != null) ? new EventBean[]{lastNewEvent} : null;
EventBean[] lastOld = (lastOldEvent != null) ? new EventBean[]{lastOldEvent} : null;
if ((lastNew == null) && (lastOld == null)) {
return null;
}
return new UniformPair<EventBean[]>(lastNew, lastOld);
}
private UniformPair<EventBean[]> processOutputLimitedViewDefault(List<UniformPair<EventBean[]>> viewEventsList, boolean generateSynthetic) {
List<EventBean> newEvents = new LinkedList<EventBean>();
List<EventBean> oldEvents = null;
if (prototype.isSelectRStream()) {
oldEvents = new LinkedList<EventBean>();
}
List<Object> newEventsSortKey = null;
List<Object> oldEventsSortKey = null;
if (orderByProcessor != null) {
newEventsSortKey = new LinkedList<Object>();
if (prototype.isSelectRStream()) {
oldEventsSortKey = new LinkedList<Object>();
}
}
for (UniformPair<EventBean[]> pair : viewEventsList) {
EventBean[] newData = pair.getFirst();
EventBean[] oldData = pair.getSecond();
EventBean[] eventsPerStream = new EventBean[1];
if (newData != null) {
// apply new data to aggregates
for (EventBean aNewData : newData) {
eventsPerStream[0] = aNewData;
aggregationService.applyEnter(eventsPerStream, null, exprEvaluatorContext);
}
}
if (oldData != null) {
// apply old data to aggregates
for (EventBean anOldData : oldData) {
eventsPerStream[0] = anOldData;
aggregationService.applyLeave(eventsPerStream, null, exprEvaluatorContext);
}
}
// generate old events using select expressions
if (prototype.isSelectRStream()) {
if (prototype.getOptionalHavingNode() == null) {
if (orderByProcessor == null) {
ResultSetProcessorUtil.populateSelectEventsNoHaving(selectExprProcessor, oldData, false, generateSynthetic, oldEvents, exprEvaluatorContext);
} else {
ResultSetProcessorUtil.populateSelectEventsNoHavingWithOrderBy(selectExprProcessor, orderByProcessor, oldData, false, generateSynthetic, oldEvents, oldEventsSortKey, exprEvaluatorContext);
}
} else {
// generate old events using having then select
if (orderByProcessor == null) {
ResultSetProcessorUtil.populateSelectEventsHaving(selectExprProcessor, oldData, prototype.getOptionalHavingNode(), false, generateSynthetic, oldEvents, exprEvaluatorContext);
} else {
ResultSetProcessorUtil.populateSelectEventsHavingWithOrderBy(selectExprProcessor, orderByProcessor, oldData, prototype.getOptionalHavingNode(), false, generateSynthetic, oldEvents, oldEventsSortKey, exprEvaluatorContext);
}
}
}
// generate new events using select expressions
if (prototype.getOptionalHavingNode() == null) {
if (orderByProcessor == null) {
ResultSetProcessorUtil.populateSelectEventsNoHaving(selectExprProcessor, newData, true, generateSynthetic, newEvents, exprEvaluatorContext);
} else {
ResultSetProcessorUtil.populateSelectEventsNoHavingWithOrderBy(selectExprProcessor, orderByProcessor, newData, true, generateSynthetic, newEvents, newEventsSortKey, exprEvaluatorContext);
}
} else {
if (orderByProcessor == null) {
ResultSetProcessorUtil.populateSelectEventsHaving(selectExprProcessor, newData, prototype.getOptionalHavingNode(), true, generateSynthetic, newEvents, exprEvaluatorContext);
} else {
ResultSetProcessorUtil.populateSelectEventsHavingWithOrderBy(selectExprProcessor, orderByProcessor, newData, prototype.getOptionalHavingNode(), true, generateSynthetic, newEvents, newEventsSortKey, exprEvaluatorContext);
}
}
}
EventBean[] newEventsArr = (newEvents.isEmpty()) ? null : newEvents.toArray(new EventBean[newEvents.size()]);
EventBean[] oldEventsArr = null;
if (prototype.isSelectRStream()) {
oldEventsArr = (oldEvents.isEmpty()) ? null : oldEvents.toArray(new EventBean[oldEvents.size()]);
}
if (orderByProcessor != null) {
Object[] sortKeysNew = (newEventsSortKey.isEmpty()) ? null : newEventsSortKey.toArray(new Object[newEventsSortKey.size()]);
newEventsArr = orderByProcessor.sort(newEventsArr, sortKeysNew, exprEvaluatorContext);
if (prototype.isSelectRStream()) {
Object[] sortKeysOld = (oldEventsSortKey.isEmpty()) ? null : oldEventsSortKey.toArray(new Object[oldEventsSortKey.size()]);
oldEventsArr = orderByProcessor.sort(oldEventsArr, sortKeysOld, exprEvaluatorContext);
}
}
if ((newEventsArr == null) && (oldEventsArr == null)) {
return null;
}
return new UniformPair<EventBean[]>(newEventsArr, oldEventsArr);
}
private UniformPair<EventBean[]> processOutputLimitedViewLast(List<UniformPair<EventBean[]>> viewEventsList, boolean generateSynthetic) {
EventBean lastOldEvent = null;
EventBean lastNewEvent = null;
EventBean[] eventsPerStream = new EventBean[1];
for (UniformPair<EventBean[]> pair : viewEventsList) {
EventBean[] newData = pair.getFirst();
EventBean[] oldData = pair.getSecond();
if (newData != null) {
// apply new data to aggregates
for (EventBean aNewData : newData) {
eventsPerStream[0] = aNewData;
aggregationService.applyEnter(eventsPerStream, null, exprEvaluatorContext);
}
}
if (oldData != null) {
// apply old data to aggregates
for (EventBean anOldData : oldData) {
eventsPerStream[0] = anOldData;
aggregationService.applyLeave(eventsPerStream, null, exprEvaluatorContext);
}
}
EventBean[] selectOldEvents;
if (prototype.isSelectRStream()) {
if (prototype.getOptionalHavingNode() == null) {
selectOldEvents = ResultSetProcessorUtil.getSelectEventsNoHaving(selectExprProcessor, oldData, false, generateSynthetic, exprEvaluatorContext);
} else {
selectOldEvents = ResultSetProcessorUtil.getSelectEventsHaving(selectExprProcessor, oldData, prototype.getOptionalHavingNode(), false, generateSynthetic, exprEvaluatorContext);
}
if ((selectOldEvents != null) && (selectOldEvents.length > 0)) {
lastOldEvent = selectOldEvents[selectOldEvents.length - 1];
}
}
// generate new events using select expressions
EventBean[] selectNewEvents;
if (prototype.getOptionalHavingNode() == null) {
selectNewEvents = ResultSetProcessorUtil.getSelectEventsNoHaving(selectExprProcessor, newData, true, generateSynthetic, exprEvaluatorContext);
} else {
selectNewEvents = ResultSetProcessorUtil.getSelectEventsHaving(selectExprProcessor, newData, prototype.getOptionalHavingNode(), true, generateSynthetic, exprEvaluatorContext);
}
if ((selectNewEvents != null) && (selectNewEvents.length > 0)) {
lastNewEvent = selectNewEvents[selectNewEvents.length - 1];
}
}
EventBean[] lastNew = (lastNewEvent != null) ? new EventBean[]{lastNewEvent} : null;
EventBean[] lastOld = (lastOldEvent != null) ? new EventBean[]{lastOldEvent} : null;
if ((lastNew == null) && (lastOld == null)) {
return null;
}
return new UniformPair<EventBean[]>(lastNew, lastOld);
}
public void acceptHelperVisitor(ResultSetProcessorOutputHelperVisitor visitor) {
if (outputLastUnordHelper != null) {
visitor.visit(outputLastUnordHelper);
}
if (outputAllUnordHelper != null) {
visitor.visit(outputAllUnordHelper);
}
}
}