Package com.espertech.esper.core.context.factory

Source Code of com.espertech.esper.core.context.factory.StatementAgentInstanceFactorySelect

/*
* *************************************************************************************
*  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.core.context.factory;

import com.espertech.esper.client.EventBean;
import com.espertech.esper.collection.Pair;
import com.espertech.esper.core.context.activator.ViewableActivationResult;
import com.espertech.esper.core.context.activator.ViewableActivator;
import com.espertech.esper.core.context.subselect.SubSelectStrategyCollection;
import com.espertech.esper.core.context.subselect.SubSelectStrategyHolder;
import com.espertech.esper.core.context.util.AgentInstanceContext;
import com.espertech.esper.core.context.util.AgentInstanceViewFactoryChainContext;
import com.espertech.esper.core.context.util.StatementAgentInstanceUtil;
import com.espertech.esper.core.service.EPServicesContext;
import com.espertech.esper.core.service.StatementContext;
import com.espertech.esper.core.service.StreamJoinAnalysisResult;
import com.espertech.esper.core.start.EPStatementStartMethodHelperPrevious;
import com.espertech.esper.core.start.EPStatementStartMethodHelperPrior;
import com.espertech.esper.core.start.EPStatementStartMethodHelperSubselect;
import com.espertech.esper.core.start.EPStatementStartMethodHelperUtil;
import com.espertech.esper.epl.agg.AggregationService;
import com.espertech.esper.epl.core.ResultSetProcessor;
import com.espertech.esper.epl.core.ResultSetProcessorFactoryDesc;
import com.espertech.esper.epl.core.StreamTypeService;
import com.espertech.esper.epl.core.ViewResourceDelegateVerified;
import com.espertech.esper.epl.expression.*;
import com.espertech.esper.epl.join.base.*;
import com.espertech.esper.epl.named.NamedWindowConsumerView;
import com.espertech.esper.epl.named.NamedWindowProcessor;
import com.espertech.esper.epl.named.NamedWindowProcessorInstance;
import com.espertech.esper.epl.named.NamedWindowTailViewInstance;
import com.espertech.esper.epl.spec.NamedWindowConsumerStreamSpec;
import com.espertech.esper.epl.spec.StatementSpecCompiled;
import com.espertech.esper.epl.spec.StreamSpecCompiled;
import com.espertech.esper.epl.view.FilterExprView;
import com.espertech.esper.epl.view.OutputProcessViewBase;
import com.espertech.esper.epl.view.OutputProcessViewFactory;
import com.espertech.esper.util.StopCallback;
import com.espertech.esper.view.ViewFactory;
import com.espertech.esper.view.ViewFactoryChain;
import com.espertech.esper.view.Viewable;
import com.espertech.esper.view.internal.BufferView;
import com.espertech.esper.view.internal.PriorEventViewFactory;
import com.espertech.esper.view.internal.SingleStreamDispatchView;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class StatementAgentInstanceFactorySelect implements StatementAgentInstanceFactory {

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

    private final int numStreams;
    private final ViewableActivator[] eventStreamParentViewableActivators;
    private final StatementContext statementContext;
    private final StatementSpecCompiled statementSpec;
    private final EPServicesContext services;
    private final StreamTypeService typeService;
    private final ViewFactoryChain[] unmaterializedViewChain;
    private final ResultSetProcessorFactoryDesc resultSetProcessorFactoryDesc;
    private final StreamJoinAnalysisResult joinAnalysisResult;
    private final boolean isRecoveringResilient;
    private final JoinSetComposerPrototype joinSetComposerPrototype;
    private final SubSelectStrategyCollection subSelectStrategyCollection;
    private final ViewResourceDelegateVerified viewResourceDelegate;
    private final OutputProcessViewFactory outputProcessViewFactory;

    public StatementAgentInstanceFactorySelect(int numStreams, ViewableActivator[] eventStreamParentViewableActivators, StatementContext statementContext, StatementSpecCompiled statementSpec, EPServicesContext services, StreamTypeService typeService, ViewFactoryChain[] unmaterializedViewChain, ResultSetProcessorFactoryDesc resultSetProcessorFactoryDesc, StreamJoinAnalysisResult joinAnalysisResult, boolean recoveringResilient, JoinSetComposerPrototype joinSetComposerPrototype, SubSelectStrategyCollection subSelectStrategyCollection, ViewResourceDelegateVerified viewResourceDelegate, OutputProcessViewFactory outputProcessViewFactory) {
        this.numStreams = numStreams;
        this.eventStreamParentViewableActivators = eventStreamParentViewableActivators;
        this.statementContext = statementContext;
        this.statementSpec = statementSpec;
        this.services = services;
        this.typeService = typeService;
        this.unmaterializedViewChain = unmaterializedViewChain;
        this.resultSetProcessorFactoryDesc = resultSetProcessorFactoryDesc;
        this.joinAnalysisResult = joinAnalysisResult;
        isRecoveringResilient = recoveringResilient;
        this.joinSetComposerPrototype = joinSetComposerPrototype;
        this.subSelectStrategyCollection = subSelectStrategyCollection;
        this.viewResourceDelegate = viewResourceDelegate;
        this.outputProcessViewFactory = outputProcessViewFactory;
    }

    public StatementAgentInstanceFactorySelectResult newContext(final AgentInstanceContext agentInstanceContext)
    {
        // register agent instance resources for use in HA
        if (services.getSchedulableAgentInstanceDirectory() != null) {
            services.getSchedulableAgentInstanceDirectory().add(agentInstanceContext.getEpStatementAgentInstanceHandle());
        }

        final List<StopCallback> stopCallbacks = new ArrayList<StopCallback>();
        StopCallback stopCallback = new StopCallback() {
            public void stop() {
                StatementAgentInstanceUtil.stopSafe(agentInstanceContext.getTerminationCallbacks(), stopCallbacks, statementContext);
            }
        };

        Viewable finalView;
        ViewableActivationResult[] viewableActivationResult = new ViewableActivationResult[eventStreamParentViewableActivators.length];
        Map<ExprSubselectNode, SubSelectStrategyHolder> subselectStrategies;
        AggregationService aggregationService;
        Viewable[] streamViews;
        Map<ExprPriorNode, ExprPriorEvalStrategy> priorNodeStrategies;
        Map<ExprPreviousNode, ExprPreviousEvalStrategy> previousNodeStrategies;

        try {
            // create root viewables
            Viewable[] eventStreamParentViewable = new Viewable[numStreams];
            for (int stream = 0; stream < eventStreamParentViewableActivators.length; stream++) {
                ViewableActivationResult activationResult = eventStreamParentViewableActivators[stream].activate(agentInstanceContext);
                viewableActivationResult[stream] = activationResult;
                stopCallbacks.add(activationResult.getStopCallback());

                eventStreamParentViewable[stream] = activationResult.getViewable();

                if (activationResult.getOptionalLock() != null) {
                    agentInstanceContext.getEpStatementAgentInstanceHandle().setStatementAgentInstanceLock(activationResult.getOptionalLock());
                    statementContext.setDefaultAgentInstanceLock(activationResult.getOptionalLock());
                }
            }

            // compile view factories adding "prior" as necessary
            List<ViewFactory>[] viewFactoryChains = new List[numStreams];
            for (int i = 0; i < numStreams; i++)
            {
                List<ViewFactory> viewFactoryChain = unmaterializedViewChain[i].getViewFactoryChain();

                // add "prior" view factory
                boolean hasPrior = viewResourceDelegate.getPerStream()[i].getPriorRequests() != null && !viewResourceDelegate.getPerStream()[i].getPriorRequests().isEmpty();
                if (hasPrior) {
                    PriorEventViewFactory priorEventViewFactory = EPStatementStartMethodHelperPrior.getPriorEventViewFactory(agentInstanceContext.getStatementContext(), i, viewFactoryChain.size() + 1, viewFactoryChain.isEmpty());
                    viewFactoryChain = new ArrayList<ViewFactory>(viewFactoryChain);
                    viewFactoryChain.add(priorEventViewFactory);
                }
                viewFactoryChains[i] = viewFactoryChain;
            }

            // create view factory chain context: holds stream-specific services
            AgentInstanceViewFactoryChainContext viewFactoryChainContexts[] = new AgentInstanceViewFactoryChainContext[numStreams];
            for (int i = 0; i < numStreams; i++)
            {
                viewFactoryChainContexts[i] = AgentInstanceViewFactoryChainContext.create(viewFactoryChains[i], agentInstanceContext, viewResourceDelegate.getPerStream()[i]);
            }

            // handle "prior" nodes and their strategies
            priorNodeStrategies = EPStatementStartMethodHelperPrior.compilePriorNodeStrategies(viewResourceDelegate, viewFactoryChainContexts);

            // handle "previous" nodes and their strategies
            previousNodeStrategies = EPStatementStartMethodHelperPrevious.compilePreviousNodeStrategies(viewResourceDelegate, viewFactoryChainContexts);

            // materialize views
            streamViews = new Viewable[numStreams];
            for (int i = 0; i < numStreams; i++) {
                boolean hasPreviousNode = viewResourceDelegate.getPerStream()[i].getPreviousRequests() != null && !viewResourceDelegate.getPerStream()[i].getPreviousRequests().isEmpty();
                streamViews[i] = services.getViewService().createViews(eventStreamParentViewable[i], viewFactoryChains[i], viewFactoryChainContexts[i], hasPreviousNode);
            }

            // start subselects
            subselectStrategies = EPStatementStartMethodHelperSubselect.startSubselects(services, subSelectStrategyCollection, agentInstanceContext, stopCallbacks);

            // obtain result set processor and aggregation services
            Pair<ResultSetProcessor, AggregationService> processorPair = EPStatementStartMethodHelperUtil.startResultSetAndAggregation(resultSetProcessorFactoryDesc, agentInstanceContext);
            ResultSetProcessor resultSetProcessor = processorPair.getFirst();
            aggregationService = processorPair.getSecond();

            // for just 1 event stream without joins, handle the one-table process separatly.
            JoinPreloadMethod joinPreloadMethod = null;
            if (streamViews.length == 1)
            {
                finalView = handleSimpleSelect(streamViews[0], resultSetProcessor, agentInstanceContext);
            }
            else
            {
                Pair<Viewable, JoinPreloadMethod> pair = handleJoin(typeService.getStreamNames(), streamViews, resultSetProcessor,
                        agentInstanceContext, stopCallbacks, joinAnalysisResult);
                finalView = pair.getFirst();
                joinPreloadMethod = pair.getSecond();
            }

            // Replay any named window data, for later consumers of named data windows
            boolean hasNamedWindow = false;
            for (int i = 0; i < statementSpec.getStreamSpecs().size(); i++)
            {
                StreamSpecCompiled streamSpec = statementSpec.getStreamSpecs().get(i);
                if (streamSpec instanceof NamedWindowConsumerStreamSpec)
                {
                    hasNamedWindow = true;
                    NamedWindowConsumerStreamSpec namedSpec = (NamedWindowConsumerStreamSpec) streamSpec;
                    NamedWindowProcessor processor = services.getNamedWindowService().getProcessor(namedSpec.getWindowName());
                    NamedWindowProcessorInstance processorInstance = processor.getProcessorInstance(agentInstanceContext);
                    if (processorInstance != null) {
                        NamedWindowTailViewInstance consumerView = processorInstance.getTailViewInstance();
                        NamedWindowConsumerView view = (NamedWindowConsumerView) viewableActivationResult[i].getViewable();

                        // preload view for stream unless the expiry policy is batch window
                        ArrayList<EventBean> eventsInWindow = new ArrayList<EventBean>();
                        if (!consumerView.getTailView().isParentBatchWindow())
                        {
                            for (EventBean aConsumerView : consumerView)
                            {
                                eventsInWindow.add(aConsumerView);
                            }
                        }
                        if (!eventsInWindow.isEmpty() && !isRecoveringResilient)
                        {
                            EventBean[] newEvents = eventsInWindow.toArray(new EventBean[eventsInWindow.size()]);
                            view.update(newEvents, null);
                            if (joinPreloadMethod != null && !joinPreloadMethod.isPreloading() && agentInstanceContext.getEpStatementAgentInstanceHandle().getOptionalDispatchable() != null) {
                                agentInstanceContext.getEpStatementAgentInstanceHandle().getOptionalDispatchable().execute(agentInstanceContext);
                            }
                        }
                    }
                    else {
                        log.info("Named window access is out-of-context, the named window '" + namedSpec.getWindowName() + "' has been declared for a different context then the current statement, the aggregation and join state will not be initialized for statement expression [" + statementContext.getExpression() + "]");
                    }

                    // in a join, preload indexes, if any
                    if (joinPreloadMethod != null)
                    {
                        joinPreloadMethod.preloadFromBuffer(i);
                    }
                    else
                    {
                        if (agentInstanceContext.getEpStatementAgentInstanceHandle().getOptionalDispatchable() != null) {
                            agentInstanceContext.getEpStatementAgentInstanceHandle().getOptionalDispatchable().execute(agentInstanceContext);
                        }
                    }
                }
            }
            // last, for aggregation we need to send the current join results to the result set processor
            if ((hasNamedWindow) && (joinPreloadMethod != null) && (!isRecoveringResilient) && resultSetProcessorFactoryDesc.getResultSetProcessorFactory().hasAggregation())
            {
                joinPreloadMethod.preloadAggregation(resultSetProcessor);
            }
        }
        catch (RuntimeException ex) {
            StatementAgentInstanceUtil.stopSafe(stopCallback, statementContext);
            throw ex;
        }

        return new StatementAgentInstanceFactorySelectResult(finalView, stopCallback, agentInstanceContext, aggregationService, subselectStrategies, priorNodeStrategies, previousNodeStrategies);
    }

    private Viewable handleSimpleSelect(Viewable view,
                                        ResultSetProcessor resultSetProcessor,
                                        AgentInstanceContext agentInstanceContext)
    {
        Viewable finalView = view;

        // Add filter view that evaluates the filter expression
        if (statementSpec.getFilterRootNode() != null)
        {
            FilterExprView filterView = new FilterExprView(statementSpec.getFilterRootNode().getExprEvaluator(), agentInstanceContext);
            finalView.addView(filterView);
            finalView = filterView;
        }

        // for ordered deliver without output limit/buffer
        if (!statementSpec.getOrderByList().isEmpty() && (statementSpec.getOutputLimitSpec() == null)) {
            SingleStreamDispatchView bf = new SingleStreamDispatchView();
            agentInstanceContext.getEpStatementAgentInstanceHandle().setOptionalDispatchable(bf);
            finalView.addView(bf);
            finalView = bf;
        }

        com.espertech.esper.view.View selectView = outputProcessViewFactory.makeView(resultSetProcessor, agentInstanceContext);

        finalView.addView(selectView);
        finalView = selectView;

        return finalView;
    }

    private Pair<Viewable, JoinPreloadMethod> handleJoin(String[] streamNames,
                                                         Viewable[] streamViews,
                                                         ResultSetProcessor resultSetProcessor,
                                                         AgentInstanceContext agentInstanceContext,
                                                         List<StopCallback> stopCallbacks,
                                                         StreamJoinAnalysisResult joinAnalysisResult)
    {
        final JoinSetComposerDesc joinSetComposerDesc = joinSetComposerPrototype.create(streamViews);

        stopCallbacks.add(new StopCallback(){
            public void stop()
            {
                joinSetComposerDesc.getJoinSetComposer().destroy();
            }
        });

        JoinSetFilter filter = new JoinSetFilter(joinSetComposerDesc.getPostJoinFilterEvaluator());
        OutputProcessViewBase indicatorView = outputProcessViewFactory.makeView(resultSetProcessor, agentInstanceContext);

        // Create strategy for join execution
        JoinExecutionStrategy execution = new JoinExecutionStrategyImpl(joinSetComposerDesc.getJoinSetComposer(), filter, indicatorView, agentInstanceContext);

        // The view needs a reference to the join execution to pull iterator values
        indicatorView.setJoinExecutionStrategy(execution);

        // Hook up dispatchable with buffer and execution strategy
        JoinExecStrategyDispatchable joinStatementDispatch = new JoinExecStrategyDispatchable(execution, statementSpec.getStreamSpecs().size());
        agentInstanceContext.getEpStatementAgentInstanceHandle().setOptionalDispatchable(joinStatementDispatch);

        JoinPreloadMethod preloadMethod;
        if (joinAnalysisResult.getUnidirectionalStreamNumber() >= 0)
        {
            preloadMethod = new JoinPreloadMethodNull();
        }
        else
        {
            preloadMethod = new JoinPreloadMethodImpl(streamNames.length, joinSetComposerDesc.getJoinSetComposer());
        }

        // Create buffer for each view. Point buffer to dispatchable for join.
        for (int i = 0; i < statementSpec.getStreamSpecs().size(); i++)
        {
            BufferView buffer = new BufferView(i);
            streamViews[i].addView(buffer);
            buffer.setObserver(joinStatementDispatch);
            preloadMethod.setBuffer(buffer, i);
        }

        return new Pair<Viewable, JoinPreloadMethod>(indicatorView, preloadMethod);
    }
}
TOP

Related Classes of com.espertech.esper.core.context.factory.StatementAgentInstanceFactorySelect

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.