Package com.espertech.esper.epl.join.base

Source Code of com.espertech.esper.epl.join.base.JoinSetComposerPrototypeImpl

/*
* *************************************************************************************
*  Copyright (C) 2008 EsperTech, Inc. All rights reserved.                            *
*  http://esper.codehaus.org                                                          *
*  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.join.base;

import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.EventType;
import com.espertech.esper.core.service.StreamJoinAnalysisResult;
import com.espertech.esper.epl.expression.*;
import com.espertech.esper.epl.join.exec.base.ExecNode;
import com.espertech.esper.epl.join.plan.QueryPlan;
import com.espertech.esper.epl.join.plan.QueryPlanIndex;
import com.espertech.esper.epl.join.plan.QueryPlanIndexItem;
import com.espertech.esper.epl.join.plan.QueryPlanNode;
import com.espertech.esper.epl.join.table.EventTable;
import com.espertech.esper.epl.join.table.EventTableUtil;
import com.espertech.esper.epl.join.table.HistoricalStreamIndexList;
import com.espertech.esper.epl.spec.OuterJoinDesc;
import com.espertech.esper.view.HistoricalEventViewable;
import com.espertech.esper.view.Viewable;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.lang.annotation.Annotation;
import java.util.*;

public class JoinSetComposerPrototypeImpl implements JoinSetComposerPrototype {

    private static final Log log = LogFactory.getLog(JoinSetComposerPrototypeFactory.class);

    private final String statementName;
    private final String statementId;
    private final OuterJoinDesc[] outerJoinDescList;
    private final ExprNode optionalFilterNode;
    private final EventType[] streamTypes;
    private final String[] streamNames;
    private final StreamJoinAnalysisResult streamJoinAnalysisResult;
    private final Annotation[] annotations;
    private final HistoricalViewableDesc historicalViewableDesc;
    private final ExprEvaluatorContext exprEvaluatorContext;
    private final QueryPlanIndex[] indexSpecs;
    private final QueryPlan queryPlan;
    private final HistoricalStreamIndexList[] historicalStreamIndexLists;
    private final boolean joinRemoveStream;
    private final boolean isOuterJoins;

    public JoinSetComposerPrototypeImpl(String statementName,
                                        String statementId,
                                        OuterJoinDesc[] outerJoinDescList,
                                        ExprNode optionalFilterNode,
                                        EventType[] streamTypes,
                                        String[] streamNames,
                                        StreamJoinAnalysisResult streamJoinAnalysisResult,
                                        Annotation[] annotations,
                                        HistoricalViewableDesc historicalViewableDesc,
                                        ExprEvaluatorContext exprEvaluatorContext,
                                        QueryPlanIndex[] indexSpecs,
                                        QueryPlan queryPlan,
                                        HistoricalStreamIndexList[] historicalStreamIndexLists,
                                        boolean joinRemoveStream,
                                        boolean isOuterJoins) {
        this.statementName = statementName;
        this.statementId = statementId;
        this.outerJoinDescList = outerJoinDescList;
        this.optionalFilterNode = optionalFilterNode;
        this.streamTypes = streamTypes;
        this.streamNames = streamNames;
        this.streamJoinAnalysisResult = streamJoinAnalysisResult;
        this.annotations = annotations;
        this.historicalViewableDesc = historicalViewableDesc;
        this.exprEvaluatorContext = exprEvaluatorContext;
        this.indexSpecs = indexSpecs;
        this.queryPlan = queryPlan;
        this.historicalStreamIndexLists = historicalStreamIndexLists;
        this.joinRemoveStream = joinRemoveStream;
        this.isOuterJoins = isOuterJoins;
    }

    public JoinSetComposerDesc create(Viewable[] streamViews, boolean isFireAndForget) {

        // Build indexes
        Map<String, EventTable>[] indexesPerStream = new HashMap[indexSpecs.length];
        for (int streamNo = 0; streamNo < indexSpecs.length; streamNo++)
        {
            if (indexSpecs[streamNo] == null)
            {
                continue;
            }

            Map<String, QueryPlanIndexItem> items = indexSpecs[streamNo].getItems();
            indexesPerStream[streamNo] = new LinkedHashMap<String, EventTable>();

            for (Map.Entry<String, QueryPlanIndexItem> entry : items.entrySet()) {
                EventTable index;
                if (streamJoinAnalysisResult.getViewExternal()[streamNo] != null) {
                    index = streamJoinAnalysisResult.getViewExternal()[streamNo].getJoinIndexTable(items.get(entry.getKey()));
                }
                else {
                    index = EventTableUtil.buildIndex(streamNo, items.get(entry.getKey()), streamTypes[streamNo], false, entry.getValue().isUnique(), null);
                }
                indexesPerStream[streamNo].put(entry.getKey(), index);
            }
        }

        // Build strategies
        QueryPlanNode[] queryExecSpecs = queryPlan.getExecNodeSpecs();
        QueryStrategy[] queryStrategies = new QueryStrategy[queryExecSpecs.length];
        for (int i = 0; i < queryExecSpecs.length; i++)
        {
            QueryPlanNode planNode = queryExecSpecs[i];
            if (planNode == null)
            {
                log.debug(".makeComposer No execution node for stream " + i + " '" + streamNames[i] + "'");
                continue;
            }

            ExecNode executionNode = planNode.makeExec(statementName, statementId, annotations, indexesPerStream, streamTypes, streamViews, historicalStreamIndexLists, streamJoinAnalysisResult.getViewExternal());

            if (log.isDebugEnabled())
            {
                log.debug(".makeComposer Execution nodes for stream " + i + " '" + streamNames[i] +
                    "' : \n" + ExecNode.print(executionNode));
            }

            queryStrategies[i] = new ExecNodeQueryStrategy(i, streamTypes.length, executionNode);
        }

        // If this is not unidirectional and not a self-join (excluding self-outer-join)
        JoinSetComposerDesc joinSetComposerDesc;
        if ((!streamJoinAnalysisResult.isUnidirectional()) &&
            (!streamJoinAnalysisResult.isPureSelfJoin() || outerJoinDescList.length > 0))
        {
            JoinSetComposer composer;
            if (historicalViewableDesc.isHasHistorical())
            {
                composer = new JoinSetComposerHistoricalImpl(indexesPerStream, queryStrategies, streamViews, exprEvaluatorContext);
            }
            else
            {
                if (isFireAndForget) {
                    composer = new JoinSetComposerFAFImpl(indexesPerStream, queryStrategies, streamJoinAnalysisResult.isPureSelfJoin(), exprEvaluatorContext, joinRemoveStream, isOuterJoins);
                }
                else {
                    composer = new JoinSetComposerImpl(indexesPerStream, queryStrategies, streamJoinAnalysisResult.isPureSelfJoin(), exprEvaluatorContext, joinRemoveStream);
                }
            }

            // rewrite the filter expression for all-inner joins in case "on"-clause outer join syntax was used to include those expressions
            ExprNode filterExpression = getFilterExpressionInclOnClause(optionalFilterNode, outerJoinDescList);

            ExprEvaluator postJoinEval = filterExpression == null ? null : filterExpression.getExprEvaluator();
            joinSetComposerDesc = new JoinSetComposerDesc(composer, postJoinEval);
        }
        else
        {
            QueryStrategy driver;
            int unidirectionalStream;
            if (streamJoinAnalysisResult.getUnidirectionalStreamNumber() != -1)
            {
                unidirectionalStream = streamJoinAnalysisResult.getUnidirectionalStreamNumber();
                driver = queryStrategies[unidirectionalStream];
            }
            else
            {
                unidirectionalStream = 0;
                driver = queryStrategies[0];
            }
            JoinSetComposer composer = new JoinSetComposerStreamToWinImpl(indexesPerStream, streamJoinAnalysisResult.isPureSelfJoin(),
                    unidirectionalStream, driver, streamJoinAnalysisResult.getUnidirectionalNonDriving());
            ExprEvaluator postJoinEval = optionalFilterNode == null ? null : optionalFilterNode.getExprEvaluator();
            joinSetComposerDesc = new JoinSetComposerDesc(composer, postJoinEval);
        }

        // compile prior events per stream to preload any indexes
        EventBean[][] eventsPerStream = new EventBean[streamNames.length][];
        ArrayList<EventBean> events = new ArrayList<EventBean>();
        for (int i = 0; i < eventsPerStream.length; i++)
        {
            // For named windows, we don't need to preload indexes from the iterators as this is always done already
            if (streamJoinAnalysisResult.getNamedWindow()[i])
            {
                continue;
            }

            Iterator<EventBean> it = null;
            if (!(streamViews[i] instanceof HistoricalEventViewable))
            {
                try
                {
                    it = streamViews[i].iterator();
                }
                catch (UnsupportedOperationException ex)
                {
                    // Joins do not support the iterator
                }
            }

            if (it != null)
            {
                for (;it.hasNext();)
                {
                    events.add(it.next());
                }
                eventsPerStream[i] = events.toArray(new EventBean[events.size()]);
                events.clear();
            }
            else
            {
                eventsPerStream[i] = new EventBean[0];
            }
        }

        // init
        joinSetComposerDesc.getJoinSetComposer().init(eventsPerStream);

        return joinSetComposerDesc;
    }

    private ExprNode getFilterExpressionInclOnClause(ExprNode optionalFilterNode, OuterJoinDesc[] outerJoinDescList)
    {
        if (optionalFilterNode == null) {   // no need to add as query planning is fully based on on-clause
            return null;
        }
        if (outerJoinDescList.length == 0) {  // not an outer-join syntax
            return optionalFilterNode;
        }
        if (!OuterJoinDesc.consistsOfAllInnerJoins(outerJoinDescList)) {    // all-inner joins
            return optionalFilterNode;
        }
        ExprAndNode andNode = new ExprAndNodeImpl();
        andNode.addChildNode(optionalFilterNode);
        for (OuterJoinDesc outerJoinDesc : outerJoinDescList) {
            andNode.addChildNode(outerJoinDesc.makeExprNode(null));
        }
        try {
            andNode.validate(null);
        }
        catch (ExprValidationException ex) {
            throw new RuntimeException("Unexpected exception validating expression: " + ex.getMessage(), ex);
        }
        return andNode;
    }
}
TOP

Related Classes of com.espertech.esper.epl.join.base.JoinSetComposerPrototypeImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.