Esempio n. 1
0
        public void TestGetNavigableStreams()
        {
            _queryGraph = new QueryGraph(5, null, false);
            _queryGraph.AddStrictEquals(3, "p3", null, 4, "p4", null);
            _queryGraph.AddStrictEquals(2, "p2", null, 3, "p3", null);
            _queryGraph.AddStrictEquals(1, "p1", null, 2, "p2", null);

            Assert.AreEqual(0, _queryGraph.GetNavigableStreams(0).Count);
            EPAssertionUtil.AssertEqualsAnyOrder(new int[] { 2 }, _queryGraph.GetNavigableStreams(1));
            EPAssertionUtil.AssertEqualsAnyOrder(new int[] { 1, 3 }, _queryGraph.GetNavigableStreams(2));
            EPAssertionUtil.AssertEqualsAnyOrder(new int[] { 2, 4 }, _queryGraph.GetNavigableStreams(3));
            EPAssertionUtil.AssertEqualsAnyOrder(new int[] { 3 }, _queryGraph.GetNavigableStreams(4));
        }
Esempio n. 2
0
        /// <summary>
        /// Recusivly builds a substream-per-stream ordered tree graph using the
        /// join information supplied for outer joins and from the query graph (where clause).
        /// <para />Required streams are considered first and their lookup is placed first in the list
        /// to gain performance.
        /// </summary>
        /// <param name="streamNum">is the root stream number that supplies the incoming event to build the tree for</param>
        /// <param name="queryGraph">contains where-clause stream relationship info</param>
        /// <param name="completedStreams">is a temporary holder for streams already considered</param>
        /// <param name="substreamsPerStream">is the ordered, tree-like structure to be filled</param>
        /// <param name="streamCallStack">the query plan call stack of streams available via cursor</param>
        /// <param name="dependencyGraph">dependencies between historical streams</param>
        /// <throws>ExprValidationException if the query planning failed</throws>
        internal static void RecursiveBuildInnerJoin(
            int streamNum,
            Stack <int> streamCallStack,
            QueryGraph queryGraph,
            ISet <int> completedStreams,
            IDictionary <int, int[]> substreamsPerStream,
            DependencyGraph dependencyGraph)
        {
            // add this stream to the set of completed streams
            completedStreams.Add(streamNum);

            // check if the dependencies have been satisfied
            if (dependencyGraph.HasDependency(streamNum))
            {
                var dependencies = dependencyGraph.GetDependenciesForStream(streamNum);
                foreach (var dependentStream in dependencies)
                {
                    if (!streamCallStack.Contains(dependentStream))
                    {
                        throw new ExprValidationException("Historical stream " + streamNum + " parameter dependency originating in stream " + dependentStream + " cannot or may not be satisfied by the join");
                    }
                }
            }

            // Determine the streams we can navigate to from this stream
            var navigableStreams = queryGraph.GetNavigableStreams(streamNum);

            // remove streams with a dependency on other streams not yet processed
            var navigableStreamArr = navigableStreams.ToArray();

            foreach (int navigableStream in navigableStreamArr)
            {
                if (dependencyGraph.HasUnsatisfiedDependency(navigableStream, completedStreams))
                {
                    navigableStreams.Remove(navigableStream);
                }
            }

            // remove those already done
            navigableStreams.RemoveAll(completedStreams);

            // if we are a leaf node, we are done
            if (navigableStreams.IsEmpty())
            {
                substreamsPerStream.Put(streamNum, new int[0]);
                return;
            }

            // First the outer (required) streams to this stream, then the inner (optional) streams
            var substreams = new int[navigableStreams.Count];

            substreamsPerStream.Put(streamNum, substreams);
            var count = 0;

            foreach (int stream in navigableStreams)
            {
                substreams[count++] = stream;
                completedStreams.Add(stream);
            }

            foreach (int stream in navigableStreams)
            {
                streamCallStack.Push(stream);
                RecursiveBuildInnerJoin(stream, streamCallStack, queryGraph, completedStreams, substreamsPerStream, dependencyGraph);
                streamCallStack.Pop();
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Recusivly builds a substream-per-stream ordered tree graph using the
        /// join information supplied for outer joins and from the query graph (where clause).
        /// <para />Required streams are considered first and their lookup is placed first in the list
        /// to gain performance.
        /// </summary>
        /// <param name="streamNum">is the root stream number that supplies the incoming event to build the tree for</param>
        /// <param name="streamCallStack">the query plan call stack of streams available via cursor</param>
        /// <param name="queryGraph">contains where-clause stream relationship info</param>
        /// <param name="outerInnerGraph">contains the outer join stream relationship info</param>
        /// <param name="innerJoinGraph">The inner join graph.</param>
        /// <param name="completedStreams">is a temporary holder for streams already considered</param>
        /// <param name="substreamsPerStream">is the ordered, tree-like structure to be filled</param>
        /// <param name="requiredPerStream">indicates which streams are required and which are optional</param>
        /// <param name="dependencyGraph">dependencies between historical streams</param>
        /// <exception cref="ExprValidationException">Historical stream  + streamNum +  parameter dependency originating in stream  + dependentStream +  cannot or may not be satisfied by the join</exception>
        /// <throws>ExprValidationException if the query planning failed</throws>
        internal static void RecursiveBuild(
            int streamNum,
            Stack <int> streamCallStack,
            QueryGraph queryGraph,
            OuterInnerDirectionalGraph outerInnerGraph,
            InnerJoinGraph innerJoinGraph,
            ISet <int> completedStreams,
            IDictionary <int, int[]> substreamsPerStream,
            bool[] requiredPerStream,
            DependencyGraph dependencyGraph)
        {
            // add this stream to the set of completed streams
            completedStreams.Add(streamNum);

            // check if the dependencies have been satisfied
            if (dependencyGraph.HasDependency(streamNum))
            {
                var dependencies = dependencyGraph.GetDependenciesForStream(streamNum);
                foreach (var dependentStream in dependencies)
                {
                    if (!streamCallStack.Contains(dependentStream))
                    {
                        throw new ExprValidationException("Historical stream " + streamNum + " parameter dependency originating in stream " + dependentStream + " cannot or may not be satisfied by the join");
                    }
                }
            }

            // Determine the streams we can navigate to from this stream
            var navigableStreams = queryGraph.GetNavigableStreams(streamNum);

            // add unqualified navigable streams (since on-expressions in outer joins are optional)
            var unqualifiedNavigable = outerInnerGraph.UnqualifiedNavigableStreams.Get(streamNum);

            if (unqualifiedNavigable != null)
            {
                navigableStreams.AddAll(unqualifiedNavigable);
            }

            // remove those already done
            navigableStreams.RemoveAll(completedStreams);

            // Which streams are inner streams to this stream (optional), which ones are outer to the stream (required)
            var requiredStreams = GetOuterStreams(streamNum, navigableStreams, outerInnerGraph);

            // Add inner joins, if any, unless already completed for this stream
            innerJoinGraph.AddRequiredStreams(streamNum, requiredStreams, completedStreams);

            var optionalStreams = GetInnerStreams(streamNum, navigableStreams, outerInnerGraph, innerJoinGraph, completedStreams);

            // Remove from the required streams the optional streams which places 'full' joined streams
            // into the optional stream category
            requiredStreams.RemoveAll(optionalStreams);

            // if we are a leaf node, we are done
            if (navigableStreams.IsEmpty())
            {
                substreamsPerStream.Put(streamNum, new int[0]);
                return;
            }

            // First the outer (required) streams to this stream, then the inner (optional) streams
            var substreams = new int[requiredStreams.Count + optionalStreams.Count];

            substreamsPerStream.Put(streamNum, substreams);
            var count = 0;

            foreach (int stream in requiredStreams)
            {
                substreams[count++]       = stream;
                requiredPerStream[stream] = true;
            }
            foreach (int stream in optionalStreams)
            {
                substreams[count++] = stream;
            }

            // next we look at all the required streams and add their dependent streams
            foreach (int stream in requiredStreams)
            {
                completedStreams.Add(stream);
            }

            foreach (int stream in requiredStreams)
            {
                streamCallStack.Push(stream);
                RecursiveBuild(stream, streamCallStack, queryGraph, outerInnerGraph, innerJoinGraph,
                               completedStreams, substreamsPerStream, requiredPerStream, dependencyGraph);
                streamCallStack.Pop();
            }
            // look at all the optional streams and add their dependent streams
            foreach (int stream in optionalStreams)
            {
                streamCallStack.Push(stream);
                RecursiveBuild(stream, streamCallStack, queryGraph, outerInnerGraph, innerJoinGraph,
                               completedStreams, substreamsPerStream, requiredPerStream, dependencyGraph);
                streamCallStack.Pop();
            }
        }