/*
***************************************************************************************
* 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.collection.MultiKey;
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.metrics.instrumentation.InstrumentationHelper;
import com.espertech.esper.view.Viewable;
import java.util.*;
public class ResultSetProcessorUtil {
public static void applyAggViewResult(AggregationService aggregationService, ExprEvaluatorContext exprEvaluatorContext, EventBean[] newData, EventBean[] oldData, EventBean[] eventsPerStream) {
if (newData != null) {
// apply new data to aggregates
for (int i = 0; i < newData.length; i++) {
eventsPerStream[0] = newData[i];
aggregationService.applyEnter(eventsPerStream, null, exprEvaluatorContext);
}
}
if (oldData != null) {
// apply old data to aggregates
for (int i = 0; i < oldData.length; i++) {
eventsPerStream[0] = oldData[i];
aggregationService.applyLeave(eventsPerStream, null, exprEvaluatorContext);
}
}
}
public static void applyAggJoinResult(AggregationService aggregationService, ExprEvaluatorContext exprEvaluatorContext, Set<MultiKey<EventBean>> newEvents, Set<MultiKey<EventBean>> oldEvents) {
if (!newEvents.isEmpty()) {
// apply new data to aggregates
for (MultiKey<EventBean> events : newEvents) {
aggregationService.applyEnter(events.getArray(), null, exprEvaluatorContext);
}
}
if (!oldEvents.isEmpty()) {
// apply old data to aggregates
for (MultiKey<EventBean> events : oldEvents) {
aggregationService.applyLeave(events.getArray(), null, exprEvaluatorContext);
}
}
}
/**
* Applies the select-clause to the given events returning the selected events. The number of events stays the
* same, i.e. this method does not filter it just transforms the result set.
*
* @param exprProcessor - processes each input event and returns output event
* @param events - input events
* @param isNewData - indicates whether we are dealing with new data (istream) or old data (rstream)
* @param isSynthesize - set to true to indicate that synthetic events are required for an iterator result set
* @param exprEvaluatorContext context for expression evalauation
* @return output events, one for each input event
*/
protected static EventBean[] getSelectEventsNoHaving(SelectExprProcessor exprProcessor, EventBean[] events, boolean isNewData, boolean isSynthesize, ExprEvaluatorContext exprEvaluatorContext) {
if (events == null) {
return null;
}
EventBean[] result = new EventBean[events.length];
EventBean[] eventsPerStream = new EventBean[1];
for (int i = 0; i < events.length; i++) {
eventsPerStream[0] = events[i];
result[i] = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
}
return result;
}
/**
* Applies the select-clause to the given events returning the selected events. The number of events stays the
* same, i.e. this method does not filter it just transforms the result set.
*
* @param exprProcessor - processes each input event and returns output event
* @param orderByProcessor - orders the outgoing events according to the order-by clause
* @param events - input events
* @param isNewData - indicates whether we are dealing with new data (istream) or old data (rstream)
* @param isSynthesize - set to true to indicate that synthetic events are required for an iterator result set
* @param exprEvaluatorContext context for expression evalauation
* @return output events, one for each input event
*/
protected static EventBean[] getSelectEventsNoHavingWithOrderBy(SelectExprProcessor exprProcessor, OrderByProcessor orderByProcessor, EventBean[] events, boolean isNewData, boolean isSynthesize, ExprEvaluatorContext exprEvaluatorContext) {
if (events == null) {
return null;
}
EventBean[] result = new EventBean[events.length];
EventBean[][] eventGenerators = new EventBean[events.length][];
EventBean[] eventsPerStream = new EventBean[1];
for (int i = 0; i < events.length; i++) {
eventsPerStream[0] = events[i];
result[i] = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
eventGenerators[i] = new EventBean[]{events[i]};
}
return orderByProcessor.sort(result, eventGenerators, isNewData, exprEvaluatorContext);
}
/**
* Applies the select-clause to the given events returning the selected events. The number of events stays the
* same, i.e. this method does not filter it just transforms the result set.
* <p>
* Also applies a having clause.
*
* @param exprProcessor - processes each input event and returns output event
* @param orderByProcessor - for sorting output events according to the order-by clause
* @param events - input events
* @param havingNode - supplies the having-clause expression
* @param isNewData - indicates whether we are dealing with new data (istream) or old data (rstream)
* @param isSynthesize - set to true to indicate that synthetic events are required for an iterator result set
* @param exprEvaluatorContext context for expression evalauation
* @return output events, one for each input event
*/
protected static EventBean[] getSelectEventsHavingWithOrderBy(SelectExprProcessor exprProcessor, OrderByProcessor orderByProcessor, EventBean[] events, ExprEvaluator havingNode, boolean isNewData, boolean isSynthesize, ExprEvaluatorContext exprEvaluatorContext) {
if (events == null) {
return null;
}
ArrayDeque<EventBean> result = null;
ArrayDeque<EventBean[]> eventGenerators = null;
EventBean[] eventsPerStream = new EventBean[1];
for (EventBean theEvent : events) {
eventsPerStream[0] = theEvent;
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().qHavingClauseNonJoin(theEvent);
}
Boolean passesHaving = (Boolean) havingNode.evaluate(eventsPerStream, isNewData, exprEvaluatorContext);
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().aHavingClauseNonJoin(passesHaving);
}
if ((passesHaving == null) || (!passesHaving)) {
continue;
}
EventBean generated = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
if (generated != null) {
if (result == null) {
result = new ArrayDeque<EventBean>(events.length);
eventGenerators = new ArrayDeque<EventBean[]>(events.length);
}
result.add(generated);
eventGenerators.add(new EventBean[]{theEvent});
}
}
if (result != null) {
return orderByProcessor.sort(result.toArray(new EventBean[result.size()]), eventGenerators.toArray(new EventBean[eventGenerators.size()][]), isNewData, exprEvaluatorContext);
}
return null;
}
/**
* Applies the select-clause to the given events returning the selected events. The number of events stays the
* same, i.e. this method does not filter it just transforms the result set.
* <p>
* Also applies a having clause.
*
* @param exprProcessor - processes each input event and returns output event
* @param events - input events
* @param havingNode - supplies the having-clause expression
* @param isNewData - indicates whether we are dealing with new data (istream) or old data (rstream)
* @param isSynthesize - set to true to indicate that synthetic events are required for an iterator result set
* @param exprEvaluatorContext context for expression evalauation
* @return output events, one for each input event
*/
protected static EventBean[] getSelectEventsHaving(SelectExprProcessor exprProcessor,
EventBean[] events,
ExprEvaluator havingNode,
boolean isNewData,
boolean isSynthesize,
ExprEvaluatorContext exprEvaluatorContext) {
if (events == null) {
return null;
}
ArrayDeque<EventBean> result = null;
EventBean[] eventsPerStream = new EventBean[1];
for (EventBean theEvent : events) {
eventsPerStream[0] = theEvent;
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().qHavingClauseNonJoin(theEvent);
}
Boolean passesHaving = (Boolean) havingNode.evaluate(eventsPerStream, isNewData, exprEvaluatorContext);
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().aHavingClauseNonJoin(passesHaving);
}
if ((passesHaving == null) || (!passesHaving)) {
continue;
}
EventBean generated = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
if (generated != null) {
if (result == null) {
result = new ArrayDeque<EventBean>(events.length);
}
result.add(generated);
}
}
if (result != null) {
return result.toArray(new EventBean[result.size()]);
}
return null;
}
/**
* Applies the select-clause to the given events returning the selected events. The number of events stays the
* same, i.e. this method does not filter it just transforms the result set.
*
* @param exprProcessor - processes each input event and returns output event
* @param orderByProcessor - for sorting output events according to the order-by clause
* @param events - input events
* @param isNewData - indicates whether we are dealing with new data (istream) or old data (rstream)
* @param isSynthesize - set to true to indicate that synthetic events are required for an iterator result set
* @param exprEvaluatorContext context for expression evalauation
* @return output events, one for each input event
*/
protected static EventBean[] getSelectJoinEventsNoHavingWithOrderBy(SelectExprProcessor exprProcessor, OrderByProcessor orderByProcessor, Set<MultiKey<EventBean>> events, boolean isNewData, boolean isSynthesize, ExprEvaluatorContext exprEvaluatorContext) {
if ((events == null) || (events.isEmpty())) {
return null;
}
EventBean[] result = new EventBean[events.size()];
EventBean[][] eventGenerators = new EventBean[events.size()][];
int count = 0;
for (MultiKey<EventBean> key : events) {
EventBean[] eventsPerStream = key.getArray();
result[count] = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
eventGenerators[count] = eventsPerStream;
count++;
}
return orderByProcessor.sort(result, eventGenerators, isNewData, exprEvaluatorContext);
}
/**
* Applies the select-clause to the given events returning the selected events. The number of events stays the
* same, i.e. this method does not filter it just transforms the result set.
*
* @param exprProcessor - processes each input event and returns output event
* @param events - input events
* @param isNewData - indicates whether we are dealing with new data (istream) or old data (rstream)
* @param isSynthesize - set to true to indicate that synthetic events are required for an iterator result set
* @param exprEvaluatorContext context for expression evalauation
* @return output events, one for each input event
*/
protected static EventBean[] getSelectJoinEventsNoHaving(SelectExprProcessor exprProcessor, Set<MultiKey<EventBean>> events, boolean isNewData, boolean isSynthesize, ExprEvaluatorContext exprEvaluatorContext) {
if ((events == null) || (events.isEmpty())) {
return null;
}
EventBean[] result = new EventBean[events.size()];
int count = 0;
for (MultiKey<EventBean> key : events) {
EventBean[] eventsPerStream = key.getArray();
result[count] = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
count++;
}
return result;
}
/**
* Applies the select-clause to the given events returning the selected events. The number of events stays the
* same, i.e. this method does not filter it just transforms the result set.
* <p>
* Also applies a having clause.
*
* @param exprProcessor - processes each input event and returns output event
* @param events - input events
* @param havingNode - supplies the having-clause expression
* @param isNewData - indicates whether we are dealing with new data (istream) or old data (rstream)
* @param isSynthesize - set to true to indicate that synthetic events are required for an iterator result set
* @param exprEvaluatorContext context for expression evalauation
* @return output events, one for each input event
*/
protected static EventBean[] getSelectJoinEventsHaving(SelectExprProcessor exprProcessor, Set<MultiKey<EventBean>> events, ExprEvaluator havingNode, boolean isNewData, boolean isSynthesize, ExprEvaluatorContext exprEvaluatorContext) {
if ((events == null) || (events.isEmpty())) {
return null;
}
ArrayDeque<EventBean> result = null;
for (MultiKey<EventBean> key : events) {
EventBean[] eventsPerStream = key.getArray();
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().qHavingClauseJoin(eventsPerStream);
}
Boolean passesHaving = (Boolean) havingNode.evaluate(eventsPerStream, isNewData, exprEvaluatorContext);
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().aHavingClauseJoin(passesHaving);
}
if ((passesHaving == null) || (!passesHaving)) {
continue;
}
EventBean resultEvent = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
if (resultEvent != null) {
if (result == null) {
result = new ArrayDeque<EventBean>(events.size());
}
result.add(resultEvent);
}
}
if (result != null) {
return result.toArray(new EventBean[result.size()]);
}
return null;
}
/**
* Applies the select-clause to the given events returning the selected events. The number of events stays the
* same, i.e. this method does not filter it just transforms the result set.
* <p>
* Also applies a having clause.
*
* @param exprProcessor - processes each input event and returns output event
* @param orderByProcessor - for sorting output events according to the order-by clause
* @param events - input events
* @param havingNode - supplies the having-clause expression
* @param isNewData - indicates whether we are dealing with new data (istream) or old data (rstream)
* @param isSynthesize - set to true to indicate that synthetic events are required for an iterator result set
* @param exprEvaluatorContext context for expression evalauation
* @return output events, one for each input event
*/
protected static EventBean[] getSelectJoinEventsHavingWithOrderBy(SelectExprProcessor exprProcessor, OrderByProcessor orderByProcessor, Set<MultiKey<EventBean>> events, ExprEvaluator havingNode, boolean isNewData, boolean isSynthesize, ExprEvaluatorContext exprEvaluatorContext) {
if ((events == null) || (events.isEmpty())) {
return null;
}
ArrayDeque<EventBean> result = null;
ArrayDeque<EventBean[]> eventGenerators = null;
for (MultiKey<EventBean> key : events) {
EventBean[] eventsPerStream = key.getArray();
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().qHavingClauseJoin(eventsPerStream);
}
Boolean passesHaving = (Boolean) havingNode.evaluate(eventsPerStream, isNewData, exprEvaluatorContext);
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().aHavingClauseJoin(passesHaving);
}
if ((passesHaving == null) || (!passesHaving)) {
continue;
}
EventBean resultEvent = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
if (resultEvent != null) {
if (result == null) {
result = new ArrayDeque<EventBean>(events.size());
eventGenerators = new ArrayDeque<EventBean[]>(events.size());
}
result.add(resultEvent);
eventGenerators.add(eventsPerStream);
}
}
if (result != null) {
return orderByProcessor.sort(result.toArray(new EventBean[result.size()]), eventGenerators.toArray(new EventBean[eventGenerators.size()][]), isNewData, exprEvaluatorContext);
}
return null;
}
protected static void populateSelectEventsNoHaving(SelectExprProcessor exprProcessor, EventBean[] events, boolean isNewData, boolean isSynthesize, Collection<EventBean> result, ExprEvaluatorContext exprEvaluatorContext) {
if (events == null) {
return;
}
EventBean[] eventsPerStream = new EventBean[1];
for (EventBean theEvent : events) {
eventsPerStream[0] = theEvent;
EventBean resultEvent = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
if (resultEvent != null) {
result.add(resultEvent);
}
}
}
protected static void populateSelectEventsNoHavingWithOrderBy(SelectExprProcessor exprProcessor, OrderByProcessor orderByProcessor, EventBean[] events, boolean isNewData, boolean isSynthesize, Collection<EventBean> result, List<Object> sortKeys, ExprEvaluatorContext exprEvaluatorContext) {
if (events == null) {
return;
}
EventBean[] eventsPerStream = new EventBean[1];
for (EventBean theEvent : events) {
eventsPerStream[0] = theEvent;
EventBean resultEvent = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
if (resultEvent != null) {
result.add(resultEvent);
sortKeys.add(orderByProcessor.getSortKey(eventsPerStream, isNewData, exprEvaluatorContext));
}
}
}
protected static void populateSelectEventsHaving(SelectExprProcessor exprProcessor, EventBean[] events, ExprEvaluator havingNode, boolean isNewData, boolean isSynthesize, List<EventBean> result, ExprEvaluatorContext exprEvaluatorContext) {
if (events == null) {
return;
}
EventBean[] eventsPerStream = new EventBean[1];
for (EventBean theEvent : events) {
eventsPerStream[0] = theEvent;
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().qHavingClauseNonJoin(theEvent);
}
Boolean passesHaving = (Boolean) havingNode.evaluate(eventsPerStream, isNewData, exprEvaluatorContext);
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().aHavingClauseNonJoin(passesHaving);
}
if ((passesHaving == null) || (!passesHaving)) {
continue;
}
EventBean resultEvent = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
if (resultEvent != null) {
result.add(resultEvent);
}
}
}
protected static void populateSelectEventsHavingWithOrderBy(SelectExprProcessor exprProcessor, OrderByProcessor orderByProcessor, EventBean[] events, ExprEvaluator havingNode, boolean isNewData, boolean isSynthesize, List<EventBean> result, List<Object> optSortKeys, ExprEvaluatorContext exprEvaluatorContext) {
if (events == null) {
return;
}
EventBean[] eventsPerStream = new EventBean[1];
for (EventBean theEvent : events) {
eventsPerStream[0] = theEvent;
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().qHavingClauseNonJoin(theEvent);
}
Boolean passesHaving = (Boolean) havingNode.evaluate(eventsPerStream, isNewData, exprEvaluatorContext);
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().aHavingClauseNonJoin(passesHaving);
}
if ((passesHaving == null) || (!passesHaving)) {
continue;
}
EventBean resultEvent = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
if (resultEvent != null) {
result.add(resultEvent);
optSortKeys.add(orderByProcessor.getSortKey(eventsPerStream, isNewData, exprEvaluatorContext));
}
}
}
protected static void populateSelectJoinEventsHaving(SelectExprProcessor exprProcessor, Set<MultiKey<EventBean>> events, ExprEvaluator havingNode, boolean isNewData, boolean isSynthesize, List<EventBean> result, ExprEvaluatorContext exprEvaluatorContext) {
if (events == null) {
return;
}
for (MultiKey<EventBean> key : events) {
EventBean[] eventsPerStream = key.getArray();
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().qHavingClauseJoin(eventsPerStream);
}
Boolean passesHaving = (Boolean) havingNode.evaluate(eventsPerStream, isNewData, exprEvaluatorContext);
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().aHavingClauseJoin(passesHaving);
}
if ((passesHaving == null) || (!passesHaving)) {
continue;
}
EventBean resultEvent = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
if (resultEvent != null) {
result.add(resultEvent);
}
}
}
protected static void populateSelectJoinEventsHavingWithOrderBy(SelectExprProcessor exprProcessor, OrderByProcessor orderByProcessor, Set<MultiKey<EventBean>> events, ExprEvaluator havingNode, boolean isNewData, boolean isSynthesize, List<EventBean> result, List<Object> sortKeys, ExprEvaluatorContext exprEvaluatorContext) {
if (events == null) {
return;
}
for (MultiKey<EventBean> key : events) {
EventBean[] eventsPerStream = key.getArray();
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().qHavingClauseJoin(eventsPerStream);
}
Boolean passesHaving = (Boolean) havingNode.evaluate(eventsPerStream, isNewData, exprEvaluatorContext);
if (InstrumentationHelper.ENABLED) {
InstrumentationHelper.get().aHavingClauseJoin(passesHaving);
}
if ((passesHaving == null) || (!passesHaving)) {
continue;
}
EventBean resultEvent = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
if (resultEvent != null) {
result.add(resultEvent);
sortKeys.add(orderByProcessor.getSortKey(eventsPerStream, isNewData, exprEvaluatorContext));
}
}
}
protected static void populateSelectJoinEventsNoHaving(SelectExprProcessor exprProcessor, Set<MultiKey<EventBean>> events, boolean isNewData, boolean isSynthesize, List<EventBean> result, ExprEvaluatorContext exprEvaluatorContext) {
int length = (events != null) ? events.size() : 0;
if (length == 0) {
return;
}
for (MultiKey<EventBean> key : events) {
EventBean[] eventsPerStream = key.getArray();
EventBean resultEvent = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
if (resultEvent != null) {
result.add(resultEvent);
}
}
}
protected static void populateSelectJoinEventsNoHavingWithOrderBy(SelectExprProcessor exprProcessor, OrderByProcessor orderByProcessor, Set<MultiKey<EventBean>> events, boolean isNewData, boolean isSynthesize, List<EventBean> result, List<Object> optSortKeys, ExprEvaluatorContext exprEvaluatorContext) {
int length = (events != null) ? events.size() : 0;
if (length == 0) {
return;
}
for (MultiKey<EventBean> key : events) {
EventBean[] eventsPerStream = key.getArray();
EventBean resultEvent = exprProcessor.process(eventsPerStream, isNewData, isSynthesize, exprEvaluatorContext);
if (resultEvent != null) {
result.add(resultEvent);
optSortKeys.add(orderByProcessor.getSortKey(eventsPerStream, isNewData, exprEvaluatorContext));
}
}
}
public static void clearAndAggregateUngrouped(ExprEvaluatorContext exprEvaluatorContext, AggregationService aggregationService, Viewable parent) {
aggregationService.clearResults(exprEvaluatorContext);
Iterator<EventBean> it = parent.iterator();
EventBean[] eventsPerStream = new EventBean[1];
for (; it.hasNext(); ) {
eventsPerStream[0] = it.next();
aggregationService.applyEnter(eventsPerStream, null, exprEvaluatorContext);
}
}
public static ArrayDeque<EventBean> iteratorToDeque(Iterator<EventBean> it) {
ArrayDeque<EventBean> deque = new ArrayDeque<EventBean>();
for (; it.hasNext(); ) {
deque.add(it.next());
}
return deque;
}
}