/* *************************************************************************************** * 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.join.assemble; import com.espertech.esper.client.EventBean; import com.espertech.esper.epl.join.rep.Node; import com.espertech.esper.util.IndentWriter; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; /** * Represents a node in a tree responsible for assembling outer join query results. * <p> * The tree is double-linked, child nodes know each parent and parent know all child nodes. * <p> * Each specific subclass of this abstract assembly node is dedicated to assembling results for * a certain event stream. */ public abstract class BaseAssemblyNode implements ResultAssembler { /** * Parent node. */ protected ResultAssembler parentNode; /** * Child nodes. */ protected final List<BaseAssemblyNode> childNodes; /** * Stream number. */ protected final int streamNum; /** * Number of streams in statement. */ protected final int numStreams; /** * Ctor. * * @param streamNum - stream number of the event stream that this node assembles results for. * @param numStreams - number of streams */ protected BaseAssemblyNode(int streamNum, int numStreams) { this.streamNum = streamNum; this.numStreams = numStreams; childNodes = new ArrayList<BaseAssemblyNode>(4); } /** * Provides results to assembly nodes for initialization. * * @param result is a list of result nodes per stream */ public abstract void init(List<Node>[] result); /** * Process results. * * @param result is a list of result nodes per stream * @param resultFinalRows final row collection * @param resultRootEvent root event */ public abstract void process(List<Node>[] result, Collection<EventBean[]> resultFinalRows, EventBean resultRootEvent); /** * Output this node using writer, not outputting child nodes. * * @param indentWriter to use for output */ public abstract void print(IndentWriter indentWriter); /** * Set parent node. * * @param resultAssembler is the parent node */ public void setParentAssembler(ResultAssembler resultAssembler) { this.parentNode = resultAssembler; } /** * Add a child node. * * @param childNode to add */ public void addChild(BaseAssemblyNode childNode) { childNode.parentNode = this; childNodes.add(childNode); } /** * Returns the stream number. * * @return stream number */ protected int getStreamNum() { return streamNum; } /** * Returns child nodes. * * @return child nodes */ protected List<BaseAssemblyNode> getChildNodes() { return childNodes; } /** * Returns an array of stream numbers that lists all child node's stream numbers. * * @return child node stream numbers */ protected int[] getSubstreams() { List<Integer> substreams = new LinkedList<Integer>(); recusiveAddSubstreams(substreams); // copy to array int[] substreamArr = new int[substreams.size()]; int count = 0; for (Integer stream : substreams) { substreamArr[count++] = stream; } return substreamArr; } private void recusiveAddSubstreams(List<Integer> substreams) { substreams.add(streamNum); for (BaseAssemblyNode child : childNodes) { child.recusiveAddSubstreams(substreams); } } }