예제 #1
0
        public override void Process(
            EventBean lookupEvent,
            EventBean[] prefillPath,
            ICollection<EventBean[]> result,
            ExprEvaluatorContext exprEvaluatorContext)
        {
            lookupRows1Event[0] = prefillPath;
            var indexPerLookupRow = historicalEventViewable.Poll(
                lookupRows1Event,
                indexingStrategy,
                exprEvaluatorContext);

            foreach (var index in indexPerLookupRow) {
                // Using the index, determine a subset of the whole indexed table to process, unless
                // the strategy is a full table scan
                var subsetIter = indexLookupStrategy.Lookup(lookupEvent, index, exprEvaluatorContext);

                if (subsetIter != null) {
                    // Add each row to the join result or, for outer joins, run through the outer join filter
                    while (subsetIter.MoveNext()) {
                        var resultRow = new EventBean[numStreams];
                        Array.Copy(prefillPath, 0, resultRow, 0, numStreams);
                        resultRow[historicalStreamNumber] = subsetIter.Current;
                        result.Add(resultRow);
                    }
                }
            }
        }
예제 #2
0
        public override void Process(
            EventBean lookupEvent,
            EventBean[] prefillPath,
            ICollection<EventBean[]> result,
            ExprEvaluatorContext exprEvaluatorContext)
        {
            _lookupRows1Event[0] = prefillPath;
            EventTable[][] indexPerLookupRow = _historicalEventViewable.Poll(
                _lookupRows1Event, _indexingStrategy, exprEvaluatorContext);

            for(int ii = 0; ii < indexPerLookupRow.Length; ii++)
            {
                var index = indexPerLookupRow[ii];

                // Using the index, determine a subset of the whole indexed table to process, unless
                // the strategy is a full table scan
                IEnumerator<EventBean> subsetIter = _indexLookupStrategy.Lookup(
                    lookupEvent, index, exprEvaluatorContext);

                if (subsetIter != null)
                {
                    // Add each row to the join result or, for outer joins, run through the outer join filter
                    for (; subsetIter.MoveNext();)
                    {
                        var resultRow = new EventBean[_numStreams];
                        Array.Copy(prefillPath, 0, resultRow, 0, _numStreams);
                        resultRow[_historicalStreamNumber] = subsetIter.Current;
                        result.Add(resultRow);
                    }
                }
            }
        }
예제 #3
0
        public ICollection <EventBean> Lookup(EventBean theEvent, Cursor cursor, ExprEvaluatorContext exprEvaluatorContext)
        {
            int currStream = cursor.Stream;

            // fill the current stream and the deep cursor events
            _lookupEventsPerStream[0][currStream] = theEvent;
            RecursiveFill(_lookupEventsPerStream[0], cursor.Node);

            // poll
            EventTable[][] indexPerLookupRow = _viewable.Poll(
                _lookupEventsPerStream, _indexingStrategy, exprEvaluatorContext);

            ISet <EventBean> result = null;

            foreach (EventTable[] index in indexPerLookupRow)
            {
                // Using the index, determine a subset of the whole indexed table to process, unless
                // the strategy is a full table scan
                IEnumerator <EventBean> subsetIter = _lookupStrategy.Lookup(theEvent, index, exprEvaluatorContext);

                if (subsetIter != null)
                {
                    if (_outerJoinExprNode != null)
                    {
                        // Add each row to the join result or, for outer joins, run through the outer join filter
                        for (; subsetIter.MoveNext();)
                        {
                            EventBean candidate = subsetIter.Current;

                            _lookupEventsPerStream[0][_streamNum] = candidate;
                            var pass = _outerJoinExprNode.Evaluate(new EvaluateParams(_lookupEventsPerStream[0], true, exprEvaluatorContext));
                            if ((pass != null) && true.Equals(pass))
                            {
                                if (result == null)
                                {
                                    result = new HashSet <EventBean>();
                                }
                                result.Add(candidate);
                            }
                        }
                    }
                    else
                    {
                        // Add each row to the join result or, for outer joins, run through the outer join filter
                        for (; subsetIter.MoveNext();)
                        {
                            var candidate = subsetIter.Current;
                            if (result == null)
                            {
                                result = new HashSet <EventBean>();
                            }
                            result.Add(candidate);
                        }
                    }
                }
            }

            return(result);
        }
예제 #4
0
        public ICollection<EventBean> Lookup(
            EventBean theEvent,
            Cursor cursor,
            ExprEvaluatorContext exprEvaluatorContext)
        {
            var instrumentationCommon = exprEvaluatorContext.InstrumentationProvider;
            instrumentationCommon.QIndexJoinLookup(this, null);

            int currStream = cursor.Stream;

            // fill the current stream and the deep cursor events
            lookupEventsPerStream[0][currStream] = theEvent;
            RecursiveFill(lookupEventsPerStream[0], cursor.Node);

            // poll
            var indexPerLookupRow = viewable.Poll(lookupEventsPerStream, indexingStrategy, exprEvaluatorContext);

            ISet<EventBean> result = null;
            foreach (var index in indexPerLookupRow) {
                // Using the index, determine a subset of the whole indexed table to process, unless
                // the strategy is a full table scan
                var subsetIter = lookupStrategy.Lookup(theEvent, index, exprEvaluatorContext);

                if (subsetIter != null) {
                    if (outerJoinExprNode != null) {
                        // Add each row to the join result or, for outer joins, run through the outer join filter
                        for (; subsetIter.MoveNext();) {
                            var candidate = subsetIter.Current;

                            lookupEventsPerStream[0][streamNum] = candidate;
                            var pass = outerJoinExprNode.Evaluate(lookupEventsPerStream[0], true, exprEvaluatorContext);
                            if (pass != null && true.Equals(pass)) {
                                if (result == null) {
                                    result = new HashSet<EventBean>();
                                }

                                result.Add(candidate);
                            }
                        }
                    }
                    else {
                        // Add each row to the join result or, for outer joins, run through the outer join filter
                        for (; subsetIter.MoveNext();) {
                            var candidate = subsetIter.Current;
                            if (result == null) {
                                result = new HashSet<EventBean>();
                            }

                            result.Add(candidate);
                        }
                    }
                }
            }

            instrumentationCommon.AIndexJoinLookup(result, null);
            return result;
        }
예제 #5
0
        public void Lookup(
            EventBean[] lookupEvents,
            ICollection <MultiKeyArrayOfKeys <EventBean> > joinSet,
            ExprEvaluatorContext exprEvaluatorContext)
        {
            EventBean[][] lookupRows;

            // If looking up a single event, reuse the buffered array
            if (lookupEvents.Length == 1)
            {
                lookupRows = _lookupRows1Event;
                lookupRows[0][_myStreamNumber] = lookupEvents[0];
            }
            else
            {
                // Prepare rows with each row Count events where Count is the number of streams
                lookupRows = new EventBean[lookupEvents.Length][];
                for (int i = 0; i < lookupEvents.Length; i++)
                {
                    lookupRows[i] = new EventBean[2];
                    lookupRows[i][_myStreamNumber] = lookupEvents[i];
                }
            }

            EventTable[][] indexPerLookupRow = _historicalEventViewable.Poll(
                lookupRows,
                _pollResultIndexingStrategy,
                exprEvaluatorContext);

            int count = 0;

            foreach (EventTable[] index in indexPerLookupRow)
            {
                // Using the index, determine a subset of the whole indexed table to process, unless
                // the strategy is a full table scan
                IEnumerator <EventBean> subsetIter =
                    _indexLookupStrategy.Lookup(lookupEvents[count], index, exprEvaluatorContext);

                // Ensure that the subset enumerator is advanced; assuming that there
                // was an iterator at all.
                bool subsetIterAdvanced =
                    (subsetIter != null) &&
                    (subsetIter.MoveNext());

                // In an outer join
                if (_isOuterJoin && !subsetIterAdvanced)
                {
                    var resultRow = new EventBean[2];
                    resultRow[_myStreamNumber] = lookupEvents[count];
                    joinSet.Add(new MultiKeyArrayOfKeys <EventBean>(resultRow));
                }
                else
                {
                    bool foundMatch = false;
                    if (subsetIterAdvanced)
                    {
                        // Add each row to the join result or, for outer joins, run through the outer join filter

                        do
                        {
                            var resultRow = new EventBean[2];
                            resultRow[_myStreamNumber]         = lookupEvents[count];
                            resultRow[_historicalStreamNumber] = subsetIter.Current;

                            // In an outer join compare the on-fields
                            if (_outerJoinCompareNode != null)
                            {
                                var compareResult = _outerJoinCompareNode.Evaluate(
                                    resultRow,
                                    true,
                                    exprEvaluatorContext);
                                if ((compareResult != null) && true.Equals(compareResult))
                                {
                                    joinSet.Add(new MultiKeyArrayOfKeys <EventBean>(resultRow));
                                    foundMatch = true;
                                }
                            }
                            else
                            {
                                joinSet.Add(new MultiKeyArrayOfKeys <EventBean>(resultRow));
                            }
                        } while (subsetIter.MoveNext());
                    }

                    if ((_isOuterJoin) && (!foundMatch))
                    {
                        var resultRow = new EventBean[2];
                        resultRow[_myStreamNumber] = lookupEvents[count];
                        joinSet.Add(new MultiKeyArrayOfKeys <EventBean>(resultRow));
                    }
                }

                count++;
            }
        }
예제 #6
0
        /// <summary>Get the strategies to use for polling from a given stream. </summary>
        /// <param name="streamViewStreamNum">the stream providing the polling events</param>
        /// <returns>looking and indexing strategy</returns>
        public Pair <HistoricalIndexLookupStrategy, PollResultIndexingStrategy> GetStrategy(int streamViewStreamNum)
        {
            // If there is only a single polling stream, then build a single index
            if (_pollingStreams.Count == 1)
            {
                return(JoinSetComposerPrototypeFactory.DetermineIndexing(_queryGraph, _typesPerStream[_historicalStreamNum], _typesPerStream[streamViewStreamNum], _historicalStreamNum, streamViewStreamNum));
            }

            // If there are multiple polling streams, determine if a single index is appropriate.
            // An index can be reused if:
            //  (a) indexed property names are the same
            //  (b) indexed property types are the same
            //  (c) key property types are the same (because of coercion)
            // A index lookup strategy is always specific to the providing stream.
            if (_indexesUsedByStreams == null)
            {
                _indexesUsedByStreams = new LinkedHashMap <HistoricalStreamIndexDesc, IList <int> >();
                foreach (var pollingStream in _pollingStreams)
                {
                    var queryGraphValue = _queryGraph.GetGraphValue(pollingStream, _historicalStreamNum);
                    var hashKeyProps    = queryGraphValue.HashKeyProps;
                    var indexProperties = hashKeyProps.Indexed;

                    var keyTypes   = GetPropertyTypes(hashKeyProps.Keys);
                    var indexTypes = GetPropertyTypes(_typesPerStream[_historicalStreamNum], indexProperties);

                    var desc          = new HistoricalStreamIndexDesc(indexProperties, indexTypes, keyTypes);
                    var usedByStreams = _indexesUsedByStreams.Get(desc);
                    if (usedByStreams == null)
                    {
                        usedByStreams = new List <int>();
                        _indexesUsedByStreams.Put(desc, usedByStreams);
                    }
                    usedByStreams.Add(pollingStream);
                }

                // There are multiple indexes required:
                // Build a master indexing strategy that forms multiple indexes and numbers each.
                if (_indexesUsedByStreams.Count > 1)
                {
                    var numIndexes         = _indexesUsedByStreams.Count;
                    var indexingStrategies = new PollResultIndexingStrategy[numIndexes];

                    // create an indexing strategy for each index
                    var count = 0;
                    foreach (var desc in _indexesUsedByStreams)
                    {
                        var sampleStreamViewStreamNum = desc.Value[0];
                        indexingStrategies[count] = JoinSetComposerPrototypeFactory.DetermineIndexing(_queryGraph, _typesPerStream[_historicalStreamNum], _typesPerStream[sampleStreamViewStreamNum], _historicalStreamNum, sampleStreamViewStreamNum).Second;
                        count++;
                    }

                    // create a master indexing strategy that utilizes each indexing strategy to create a set of indexes
                    var streamNum = streamViewStreamNum;
                    _masterIndexingStrategy = new ProxyPollResultIndexingStrategy
                    {
                        ProcIndex = (pollResult, isActiveCache, statementContext) =>
                        {
                            var tables = new EventTable[numIndexes];
                            for (var i = 0; i < numIndexes; i++)
                            {
                                tables[i] = indexingStrategies[i].Index(pollResult, isActiveCache, statementContext)[0];
                            }

                            var organization = new EventTableOrganization(null, false, false, streamNum, null, EventTableOrganizationType.MULTIINDEX);
                            return(new EventTable[]
                            {
                                new MultiIndexEventTable(tables, organization)
                            });
                        },
                        ProcToQueryPlan = () =>
                        {
                            var writer    = new StringWriter();
                            var delimiter = "";
                            foreach (var strategy in indexingStrategies)
                            {
                                writer.Write(delimiter);
                                writer.Write(strategy.ToQueryPlan());
                                delimiter = ", ";
                            }
                            return(GetType().FullName + " " + writer);
                        }
                    };
                }
            }

            // there is one type of index
            if (_indexesUsedByStreams.Count == 1)
            {
                return(JoinSetComposerPrototypeFactory.DetermineIndexing(
                           _queryGraph, _typesPerStream[_historicalStreamNum], _typesPerStream[streamViewStreamNum], _historicalStreamNum, streamViewStreamNum));
            }

            // determine which index number the polling stream must use
            var indexUsed = 0;
            var found     = false;

            foreach (var desc in _indexesUsedByStreams.Values)
            {
                if (desc.Contains(streamViewStreamNum))
                {
                    found = true;
                    break;
                }
                indexUsed++;
            }
            if (!found)
            {
                throw new IllegalStateException("MapIndex not found for use by stream " + streamViewStreamNum);
            }

            // Use one of the indexes built by the master index and a lookup strategy
            var indexNumber = indexUsed;
            HistoricalIndexLookupStrategy innerLookupStrategy = JoinSetComposerPrototypeFactory.DetermineIndexing(_queryGraph, _typesPerStream[_historicalStreamNum], _typesPerStream[streamViewStreamNum], _historicalStreamNum, streamViewStreamNum).First;

            var lookupStrategy = new ProxyHistoricalIndexLookupStrategy
            {
                ProcLookup = (lookupEvent, index, context) =>
                {
                    var multiIndex = (MultiIndexEventTable)index[0];
                    var indexToUse = multiIndex.Tables[indexNumber];
                    return(innerLookupStrategy.Lookup(lookupEvent, new EventTable[] { indexToUse }, context));
                },
                ProcToQueryPlan = () => GetType().FullName + " inner: " + innerLookupStrategy.ToQueryPlan()
            };

            return(new Pair <HistoricalIndexLookupStrategy, PollResultIndexingStrategy> (lookupStrategy, _masterIndexingStrategy));
        }