/// <summary>
        /// Returns all descendent nodes to the top node in a list in which the utmost descendants are
        /// listed first and the top node itself is listed last.
        /// </summary>
        /// <param name="topNode">is the root node of a tree structure</param>
        /// <returns>list of nodes with utmost descendants first ordered by level of depth in tree with top node last</returns>
        public static IList <BaseAssemblyNodeFactory> GetDescendentNodesBottomUp(BaseAssemblyNodeFactory topNode)
        {
            var result = new List <BaseAssemblyNodeFactory>();

            // Map to hold per level of the node (1 to Count depth) of node a list of nodes, if any
            // exist at that level
            var nodesPerLevel = new OrderedDictionary <int, ICollection <BaseAssemblyNodeFactory> >();

            // Recursively enter all aggregate functions and their level into map
            RecursiveAggregateEnter(topNode, nodesPerLevel, 1);

            // Done if none found
            if (nodesPerLevel.IsEmpty())
            {
                throw new IllegalStateException("EmptyFalse collection for nodes per level");
            }

            // From the deepest (highest) level to the lowest, add aggregates to list
            int deepLevel = nodesPerLevel.Keys.Last();

            for (int i = deepLevel; i >= 1; i--)
            {
                var list = nodesPerLevel.Get(i);
                if (list == null)
                {
                    continue;
                }
                result.AddAll(list);
            }

            return(result);
        }
Beispiel #2
0
        /// <summary> Builds a tree of <see cref="BaseAssemblyNode" /> from join strategy information.</summary>
        /// <param name="rootStream">the root stream supplying the event to evaluate
        /// </param>
        /// <param name="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>
        /// <param name="isRequiredPerStream">indicates which streams are required join streams versus optional streams
        /// </param>
        /// <returns> root assembly node
        /// </returns>

        public static BaseAssemblyNodeFactory Build(int rootStream, IDictionary <Int32, int[]> streamsJoinedPerStream, bool[] isRequiredPerStream)
        {
            if (streamsJoinedPerStream.Count < 3)
            {
                throw new ArgumentException("Not a 3-way join");
            }
            if ((rootStream < 0) || (rootStream >= streamsJoinedPerStream.Count))
            {
                throw new ArgumentException("Invalid root stream");
            }
            if (isRequiredPerStream.Length != streamsJoinedPerStream.Count)
            {
                throw new ArgumentException("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=" + isRequiredPerStream.Render());
            }

            BaseAssemblyNodeFactory topNode = CreateNode(
                true,
                rootStream,
                streamsJoinedPerStream.Count,
                streamsJoinedPerStream[rootStream],
                isRequiredPerStream);

            RecursiveBuild(rootStream, topNode, streamsJoinedPerStream, isRequiredPerStream);

            if (Log.IsDebugEnabled)
            {
                StringWriter buf          = new StringWriter();
                IndentWriter indentWriter = new IndentWriter(buf, 0, 2);
                topNode.PrintDescendends(indentWriter);

                Log.Debug(".build Dumping root node for stream " + rootStream + ": \n" + buf.ToString());
            }

            return(topNode);
        }
        private static void RecursiveAggregateEnter(BaseAssemblyNodeFactory currentNode, IDictionary <int, ICollection <BaseAssemblyNodeFactory> > nodesPerLevel, int currentLevel)
        {
            // ask all child nodes to enter themselves
            foreach (BaseAssemblyNodeFactory node in currentNode._childNodes)
            {
                RecursiveAggregateEnter(node, nodesPerLevel, currentLevel + 1);
            }

            // Add myself to list
            var aggregates = nodesPerLevel.Get(currentLevel);

            if (aggregates == null)
            {
                aggregates = new LinkedList <BaseAssemblyNodeFactory>();
                nodesPerLevel.Put(currentLevel, aggregates);
            }
            aggregates.Add(currentNode);
        }
Beispiel #4
0
        private static void RecursiveBuild(int parentStreamNum, BaseAssemblyNodeFactory parentNode, IDictionary <Int32, int[]> streamsJoinedPerStream, bool[] isRequiredPerStream)
        {
            int numStreams = streamsJoinedPerStream.Count;

            for (int i = 0; i < streamsJoinedPerStream[parentStreamNum].Length; i++)
            {
                int streamJoined = streamsJoinedPerStream[parentStreamNum][i];
                BaseAssemblyNodeFactory childNode = CreateNode(
                    false,
                    streamJoined,
                    numStreams,
                    streamsJoinedPerStream[streamJoined],
                    isRequiredPerStream);
                parentNode.AddChild(childNode);

                if (streamsJoinedPerStream[streamJoined].Length > 0)
                {
                    RecursiveBuild(streamJoined, childNode, streamsJoinedPerStream, isRequiredPerStream);
                }
            }
        }
 public override void AddChild(BaseAssemblyNodeFactory childNode)
 {
     _childStreamIndex[childNode.StreamNum] = ChildNodes.Count;
     base.AddChild(childNode);
 }
 /// <summary>
 /// Add a child node.
 /// </summary>
 /// <param name="childNode">to add</param>
 public virtual void AddChild(BaseAssemblyNodeFactory childNode)
 {
     childNode._parentNode = this;
     _childNodes.Add(childNode);
 }
 /// <summary>
 /// Set parent node.
 /// </summary>
 public void SetParent(BaseAssemblyNodeFactory parent)
 {
     _parentNode = parent;
 }