/* *************************************************************************************** * 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.TransformEventIterator; import com.espertech.esper.collection.UniformPair; import com.espertech.esper.core.context.util.AgentInstanceContext; import com.espertech.esper.epl.expression.core.ExprEvaluatorContext; import com.espertech.esper.metrics.instrumentation.InstrumentationHelper; import com.espertech.esper.util.CollectionUtil; import com.espertech.esper.view.Viewable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; /** * Result set processor for the simplest case: no aggregation functions used in the select clause, and no group-by. * <p> * The processor generates one row for each event entering (new event) and one row for each event leaving (old event). */ public class ResultSetProcessorSimple extends ResultSetProcessorBaseSimple { protected final ResultSetProcessorSimpleFactory prototype; private final SelectExprProcessor selectExprProcessor; private final OrderByProcessor orderByProcessor; protected ExprEvaluatorContext exprEvaluatorContext; private ResultSetProcessorSimpleOutputLastHelper outputLastHelper; private ResultSetProcessorSimpleOutputAllHelper outputAllHelper; public ResultSetProcessorSimple(ResultSetProcessorSimpleFactory prototype, SelectExprProcessor selectExprProcessor, OrderByProcessor orderByProcessor, AgentInstanceContext agentInstanceContext) { this.prototype = prototype; this.selectExprProcessor = selectExprProcessor; this.orderByProcessor = orderByProcessor; this.exprEvaluatorContext = agentInstanceContext; if (prototype.isOutputLast()) { // output-last always uses this mechanism outputLastHelper = prototype.getResultSetProcessorHelperFactory().makeRSSimpleOutputLast(prototype, this, agentInstanceContext); } else if (prototype.isOutputAll() && prototype.isEnableOutputLimitOpt()) { outputAllHelper = prototype.getResultSetProcessorHelperFactory().makeRSSimpleOutputAll(prototype, this, agentInstanceContext); } } public void setAgentInstanceContext(AgentInstanceContext context) { exprEvaluatorContext = context; } public EventType getResultEventType() { return prototype.getResultEventType(); } public UniformPair<EventBean[]> processJoinResult(Set<MultiKey<EventBean>> newEvents, Set<MultiKey<EventBean>> oldEvents, boolean isSynthesize) { if (InstrumentationHelper.ENABLED) { InstrumentationHelper.get().qResultSetProcessSimple(); } EventBean[] selectOldEvents = null; EventBean[] selectNewEvents; if (prototype.getOptionalHavingExpr() == 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.getOptionalHavingExpr(), false, isSynthesize, exprEvaluatorContext); } else { selectOldEvents = ResultSetProcessorUtil.getSelectJoinEventsHavingWithOrderBy(selectExprProcessor, orderByProcessor, oldEvents, prototype.getOptionalHavingExpr(), false, isSynthesize, exprEvaluatorContext); } } if (orderByProcessor == null) { selectNewEvents = ResultSetProcessorUtil.getSelectJoinEventsHaving(selectExprProcessor, newEvents, prototype.getOptionalHavingExpr(), true, isSynthesize, exprEvaluatorContext); } else { selectNewEvents = ResultSetProcessorUtil.getSelectJoinEventsHavingWithOrderBy(selectExprProcessor, orderByProcessor, newEvents, prototype.getOptionalHavingExpr(), true, isSynthesize, exprEvaluatorContext); } } if (InstrumentationHelper.ENABLED) { InstrumentationHelper.get().aResultSetProcessSimple(selectNewEvents, selectOldEvents); } return new UniformPair<EventBean[]>(selectNewEvents, selectOldEvents); } public UniformPair<EventBean[]> processViewResult(EventBean[] newData, EventBean[] oldData, boolean isSynthesize) { if (InstrumentationHelper.ENABLED) { InstrumentationHelper.get().qResultSetProcessSimple(); } EventBean[] selectOldEvents = null; EventBean[] selectNewEvents; if (prototype.getOptionalHavingExpr() == 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.getOptionalHavingExpr(), false, isSynthesize, exprEvaluatorContext); } else { selectOldEvents = ResultSetProcessorUtil.getSelectEventsHavingWithOrderBy(selectExprProcessor, orderByProcessor, oldData, prototype.getOptionalHavingExpr(), false, isSynthesize, exprEvaluatorContext); } } if (orderByProcessor == null) { selectNewEvents = ResultSetProcessorUtil.getSelectEventsHaving(selectExprProcessor, newData, prototype.getOptionalHavingExpr(), true, isSynthesize, exprEvaluatorContext); } else { selectNewEvents = ResultSetProcessorUtil.getSelectEventsHavingWithOrderBy(selectExprProcessor, orderByProcessor, newData, prototype.getOptionalHavingExpr(), true, isSynthesize, exprEvaluatorContext); } } if (InstrumentationHelper.ENABLED) { InstrumentationHelper.get().aResultSetProcessSimple(selectNewEvents, selectOldEvents); } return new UniformPair<EventBean[]>(selectNewEvents, selectOldEvents); } /** * Process view results for the iterator. * * @param newData new events * @return pair of insert and remove stream */ public UniformPair<EventBean[]> processViewResultIterator(EventBean[] newData) { EventBean[] selectNewEvents; if (prototype.getOptionalHavingExpr() == null) { // ignore orderByProcessor selectNewEvents = ResultSetProcessorUtil.getSelectEventsNoHaving(selectExprProcessor, newData, true, true, exprEvaluatorContext); } else { // ignore orderByProcessor selectNewEvents = ResultSetProcessorUtil.getSelectEventsHaving(selectExprProcessor, newData, prototype.getOptionalHavingExpr(), true, true, exprEvaluatorContext); } return new UniformPair<EventBean[]>(selectNewEvents, null); } public Iterator<EventBean> getIterator(Viewable parent) { if (orderByProcessor != null) { // Pull all events, generate order keys EventBean[] eventsPerStream = new EventBean[1]; List<EventBean> events = new ArrayList<EventBean>(); List<Object> orderKeys = new ArrayList<Object>(); Iterator parentIterator = parent.iterator(); if (parentIterator == null) { return CollectionUtil.NULL_EVENT_ITERATOR; } for (EventBean aParent : parent) { eventsPerStream[0] = aParent; Object orderKey = orderByProcessor.getSortKey(eventsPerStream, true, exprEvaluatorContext); UniformPair<EventBean[]> pair = processViewResultIterator(eventsPerStream); EventBean[] result = pair.getFirst(); if (result != null && result.length != 0) { events.add(result[0]); } orderKeys.add(orderKey); } // sort EventBean[] outgoingEvents = events.toArray(new EventBean[events.size()]); Object[] orderKeysArr = orderKeys.toArray(new Object[orderKeys.size()]); EventBean[] orderedEvents = orderByProcessor.sort(outgoingEvents, orderKeysArr, exprEvaluatorContext); return new ArrayEventIterator(orderedEvents); } // Return an iterator that gives row-by-row a result return new TransformEventIterator(parent.iterator(), new ResultSetProcessorSimpleTransform(this)); } public Iterator<EventBean> getIterator(Set<MultiKey<EventBean>> joinSet) { // Process join results set as a regular join, includes sorting and having-clause filter UniformPair<EventBean[]> result = processJoinResult(joinSet, CollectionUtil.EMPTY_ROW_SET, true); return new ArrayEventIterator(result.getFirst()); } public void clear() { // No need to clear state, there is no state held } public boolean hasAggregation() { return false; } public void applyViewResult(EventBean[] newData, EventBean[] oldData) { } public void applyJoinResult(Set<MultiKey<EventBean>> newEvents, Set<MultiKey<EventBean>> oldEvents) { } public void processOutputLimitedLastAllNonBufferedView(EventBean[] newData, EventBean[] oldData, boolean isGenerateSynthetic, boolean isAll) { if (isAll) { outputAllHelper.processView(newData, oldData); } else { outputLastHelper.processView(newData, oldData); } } public void processOutputLimitedLastAllNonBufferedJoin(Set<MultiKey<EventBean>> newEvents, Set<MultiKey<EventBean>> oldEvents, boolean isGenerateSynthetic, boolean isAll) { if (isAll) { outputAllHelper.processJoin(newEvents, oldEvents); } else { outputLastHelper.processJoin(newEvents, oldEvents); } } public UniformPair<EventBean[]> continueOutputLimitedLastAllNonBufferedView(boolean isSynthesize, boolean isAll) { if (isAll) { return outputAllHelper.outputView(isSynthesize); } return outputLastHelper.outputView(isSynthesize); } public UniformPair<EventBean[]> continueOutputLimitedLastAllNonBufferedJoin(boolean isSynthesize, boolean isAll) { if (isAll) { return outputAllHelper.outputJoin(isSynthesize); } return outputLastHelper.outputJoin(isSynthesize); } public void stop() { if (outputLastHelper != null) { outputLastHelper.destroy(); } if (outputAllHelper != null) { outputAllHelper.destroy(); } } public void acceptHelperVisitor(ResultSetProcessorOutputHelperVisitor visitor) { if (outputLastHelper != null) { visitor.visit(outputLastHelper); } if (outputAllHelper != null) { visitor.visit(outputAllHelper); } } }