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

Source Code of com.espertech.esper.epl.join.exec.base.LookupInstructionExec

/**************************************************************************************
* 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.exec.base;

import com.espertech.esper.epl.join.rep.Cursor;
import com.espertech.esper.epl.join.rep.Repository;
import com.espertech.esper.epl.expression.ExprEvaluatorContext;
import com.espertech.esper.client.EventBean;
import com.espertech.esper.util.IndentWriter;

import java.util.*;

/**
* Execution for a lookup instruction to look up in one or more event streams with a supplied event
* and using a given set of lookup strategies, and adding any lookup results to a lighweight repository object
* for later result assembly.
*/
public class LookupInstructionExec
{
    private final int fromStream;
    private final String fromStreamName;
    private final JoinExecTableLookupStrategy[] lookupStrategies;

    private final int numSubStreams;
    private final Set<EventBean>[] resultPerStream;
    private final int[] requiredSubStreams;
    private final int[] optionalSubStreams;
    private final boolean hasRequiredSubStreams;

    /**
     * Ctor.
     * @param fromStream - the stream supplying the lookup event
     * @param fromStreamName - the stream name supplying the lookup event
     * @param toStreams - the set of streams to look up in
     * @param lookupStrategies - the strategy to use for each stream to look up in
     * @param requiredPerStream - indicates which of the lookup streams are required to build a result and which are not
     */
    public LookupInstructionExec(int fromStream, String fromStreamName, int[] toStreams, JoinExecTableLookupStrategy[] lookupStrategies, boolean[] requiredPerStream)
    {
        if (toStreams.length != lookupStrategies.length)
        {
            throw new IllegalArgumentException("Invalid number of strategies for each stream");
        }
        if (requiredPerStream.length < lookupStrategies.length)
        {
            throw new IllegalArgumentException("Invalid required per stream array");
        }
        if ((fromStream < 0) || (fromStream >= requiredPerStream.length))
        {
            throw new IllegalArgumentException("Invalid from stream");
        }

        this.fromStream = fromStream;
        this.fromStreamName = fromStreamName;
        this.numSubStreams = toStreams.length;
        this.lookupStrategies = lookupStrategies;

        resultPerStream = new Set[numSubStreams];

        // Build a separate array for the required and for the optional streams
        List<Integer> required = new LinkedList<Integer>();
        List<Integer> optional = new LinkedList<Integer>();
        for (int stream : toStreams)
        {
            if (requiredPerStream[stream])
            {
                required.add(stream);
            }
            else
            {
                optional.add(stream);
            }
        }
        requiredSubStreams = toArray(required);
        optionalSubStreams = toArray(optional);
        hasRequiredSubStreams = requiredSubStreams.length > 0;
    }

    /**
     * Returns the stream number of the stream supplying the event to use for lookup.
     * @return stream number
     */
    public int getFromStream()
    {
        return fromStream;
    }

    /**
     * Returns true if there is one or more required substreams or false if no substreams are required joins.
     * @return true if any substreams are required (inner) joins, or false if not
     */
    public boolean hasRequiredStream()
    {
        return hasRequiredSubStreams;
    }

    /**
     * Execute the instruction adding results to the repository and obtaining events for lookup from the
     * repository.
     * @param repository supplies events for lookup, and place to add results to
     * @param exprEvaluatorContext expression evaluation context
     * @return true if one or more results, false if no results
     */
    public boolean process(Repository repository, ExprEvaluatorContext exprEvaluatorContext)
    {
        boolean hasOneResultRow = false;
        Iterator<Cursor> it = repository.getCursors(fromStream);

        // Loop over all events for that stream
        for (;it.hasNext();)
        {
            Cursor cursor = it.next();
            EventBean lookupEvent = cursor.getTheEvent();
            int streamCount = 0;

            // For that event, lookup in all required streams
            while (streamCount < requiredSubStreams.length)
            {
                Set<EventBean> lookupResult = lookupStrategies[streamCount].lookup(lookupEvent, cursor, exprEvaluatorContext);

                // There is no result, break if this is a required stream
                if (lookupResult == null)
                {
                    break;
                }
                resultPerStream[streamCount] = lookupResult;
                streamCount++;
            }

            // No results for a required stream, we are done with this event
            if (streamCount < requiredSubStreams.length)
            {
                continue;
            }
            else
            {
                // Add results to repository
                for (int i = 0; i < requiredSubStreams.length; i++)
                {
                    hasOneResultRow = true;
                    repository.addResult(cursor, resultPerStream[i], requiredSubStreams[i]);
                }
            }

            // For that event, lookup in all optional streams
            for (int i = 0; i < optionalSubStreams.length; i++)
            {
                Set<EventBean> lookupResult = lookupStrategies[streamCount].lookup(lookupEvent, cursor, exprEvaluatorContext);

                if (lookupResult != null)
                {
                    hasOneResultRow = true;
                    repository.addResult(cursor, lookupResult, optionalSubStreams[i]);
                }
                streamCount++;
            }
        }

        return hasOneResultRow;
    }

    private static int[] toArray(List<Integer> list)
    {
        int[] arr = new int[list.size()];
        int count = 0;
        for (int value : list)
        {
            arr[count++] = value;
        }
        return arr;
    }

    /**
     * Output the instruction.
     * @param writer is the write to output to
     */
    @SuppressWarnings({"StringContatenationInLoop"})
    public void print(IndentWriter writer)
    {
        writer.println("LookupInstructionExec" +
                " fromStream=" + fromStream +
                " fromStreamName=" + fromStreamName +
                " numSubStreams=" + numSubStreams +
                " requiredSubStreams=" + Arrays.toString(requiredSubStreams) +
                " optionalSubStreams=" + Arrays.toString(optionalSubStreams));

        writer.incrIndent();
        for (int i = 0; i < lookupStrategies.length; i++)
        {
            writer.println("lookupStrategies[" + i + "] : " + lookupStrategies[i].toString());
        }
        writer.decrIndent();
    }
}
TOP

Related Classes of com.espertech.esper.epl.join.exec.base.LookupInstructionExec

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.