Package com.espertech.esper.epl.join.assemble

Source Code of com.espertech.esper.epl.join.assemble.AssemblyStrategyTreeBuilder

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.*;
import java.io.PrintWriter;
import java.io.StringWriter;

import com.espertech.esper.util.IndentWriter;
import com.espertech.esper.epl.join.plan.NStreamOuterQueryPlanBuilder;

/**
* Builds a tree of assembly nodes given a strategy for how to join streams.
*/
public class AssemblyStrategyTreeBuilder
{
    /**
     * Builds a tree of {@link BaseAssemblyNode} from join strategy information.
     * @param rootStream - the root stream supplying the event to evaluate
     * @param streamsJoinedPerStream - a map in which the key is the stream number to supply an event,
     * and the value is an array of streams to find events in for the given event
     * @param isRequiredPerStream - indicates which streams are required join streams versus optional streams
     * @return root assembly node
     */
    public static BaseAssemblyNode build(int rootStream, Map<Integer, int[]> streamsJoinedPerStream, boolean isRequiredPerStream[])
    {
        if (streamsJoinedPerStream.size() < 3)
        {
            throw new IllegalArgumentException("Not a 3-way join");
        }
        if ((rootStream < 0) || (rootStream >= streamsJoinedPerStream.size()))
        {
            throw new IllegalArgumentException("Invalid root stream");
        }
        if (isRequiredPerStream.length != streamsJoinedPerStream.size())
        {
            throw new IllegalArgumentException("Arrays not matching up");
        }

        NStreamOuterQueryPlanBuilder.verifyJoinedPerStream(rootStream, streamsJoinedPerStream);

        if (log.isDebugEnabled())
        {
            log.debug(".build Building node for root stream " + rootStream +
                            " streamsJoinedPerStream=" + NStreamOuterQueryPlanBuilder.print(streamsJoinedPerStream) +
                            " isRequiredPerStream=" + Arrays.toString(isRequiredPerStream));
        }

        BaseAssemblyNode topNode = createNode(true, rootStream, streamsJoinedPerStream.size(), streamsJoinedPerStream.get(rootStream), isRequiredPerStream);

        recursiveBuild(rootStream, topNode, streamsJoinedPerStream, isRequiredPerStream);

        if (log.isDebugEnabled())
        {
            StringWriter buf = new StringWriter();
            PrintWriter print = new PrintWriter(buf);
            IndentWriter indentWriter = new IndentWriter(print, 0, 2);
            topNode.printDescendends(indentWriter);

            log.debug(".build Dumping root node for stream " + rootStream + ": \n" + buf.toString());
        }

        return topNode;
    }

    private static void recursiveBuild(int parentStreamNum, BaseAssemblyNode parentNode,
                                Map<Integer, int[]> streamsJoinedPerStream, boolean isRequiredPerStream[])
    {
        int numStreams = streamsJoinedPerStream.size();

        for (int i = 0; i < streamsJoinedPerStream.get(parentStreamNum).length; i++)
        {
            int streamJoined = streamsJoinedPerStream.get(parentStreamNum)[i];
            BaseAssemblyNode childNode = createNode(false, streamJoined, numStreams, streamsJoinedPerStream.get(streamJoined), isRequiredPerStream);
            parentNode.addChild(childNode);

            if (streamsJoinedPerStream.get(streamJoined).length > 0)
            {
                recursiveBuild(streamJoined, childNode, streamsJoinedPerStream, isRequiredPerStream);
            }
        }
    }

    private static BaseAssemblyNode createNode(boolean isRoot, int streamNum, int numStreams, int[] joinedStreams, boolean isRequiredPerStream[])
    {
        if (joinedStreams.length == 0)
        {
            return new LeafAssemblyNode(streamNum, numStreams);
        }
        if (joinedStreams.length == 1)
        {
            int joinedStream = joinedStreams[0];
            boolean isRequired = isRequiredPerStream[joinedStream];
            if (isRequired)
            {
                if (isRoot)
                {
                    return new RootRequiredAssemblyNode(streamNum, numStreams);
                }
                else
                {
                    return new BranchRequiredAssemblyNode(streamNum, numStreams);
                }
            }
            else
            {
                if (isRoot)
                {
                    return new RootOptionalAssemblyNode(streamNum, numStreams);
                }
                else
                {
                    return new BranchOptionalAssemblyNode(streamNum, numStreams);
                }
            }
        }

        // Determine if all substream are outer (optional) joins
        boolean allSubStreamsOptional = true;
        for (int i = 0; i < joinedStreams.length; i++)
        {
            int stream = joinedStreams[i];
            if (isRequiredPerStream[stream])
            {
                allSubStreamsOptional = false;
            }
        }

        // Make node for building a cartesian product
        if (isRoot)
        {
            return new RootCartProdAssemblyNode(streamNum, numStreams, allSubStreamsOptional);
        }
        else
        {
            return new CartesianProdAssemblyNode(streamNum, numStreams, allSubStreamsOptional);
        }
    }

    private static final Log log = LogFactory.getLog(AssemblyStrategyTreeBuilder.class);
}
TOP

Related Classes of com.espertech.esper.epl.join.assemble.AssemblyStrategyTreeBuilder

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.