Esempio n. 1
0
        public static EventTable[] RealizeTables(
            SubordinateQueryIndexDesc[] indexDescriptors,
            EventType eventType,
            EventTableIndexRepository indexRepository,
            IEnumerable <EventBean> contents,
            AgentInstanceContext agentInstanceContext,
            bool isRecoveringResilient)
        {
            var tables = new EventTable[indexDescriptors.Length];

            for (var i = 0; i < tables.Length; i++)
            {
                var desc  = indexDescriptors[i];
                var table = indexRepository.GetIndexByDesc(desc.IndexMultiKey);
                if (table == null)
                {
                    table = EventTableUtil.BuildIndex(agentInstanceContext, 0, desc.QueryPlanIndexItem, eventType, true, desc.IndexMultiKey.IsUnique, null, null, false);

                    // fill table since its new
                    if (!isRecoveringResilient)
                    {
                        var events = new EventBean[1];
                        foreach (var prefilledEvent in contents)
                        {
                            events[0] = prefilledEvent;
                            table.Add(events);
                        }
                    }

                    indexRepository.AddIndex(desc.IndexMultiKey, new EventTableIndexRepositoryEntry(null, table));
                }
                tables[i] = table;
            }
            return(tables);
        }
Esempio n. 2
0
        public NamedWindowRootViewInstance(
            NamedWindowRootView rootView,
            AgentInstanceContext agentInstanceContext,
            EventTableIndexMetadata eventTableIndexMetadata)
        {
            this.rootView = rootView;
            AgentInstanceContext = agentInstanceContext;

            IndexRepository = new EventTableIndexRepository(eventTableIndexMetadata);
            foreach (var entry in eventTableIndexMetadata.Indexes
            ) {
                if (entry.Value.OptionalQueryPlanIndexItem != null) {
                    var index = EventTableUtil.BuildIndex(
                        agentInstanceContext,
                        0,
                        entry.Value.OptionalQueryPlanIndexItem,
                        rootView.EventType,
                        true,
                        entry.Key.IsUnique,
                        entry.Value.OptionalIndexName,
                        null,
                        false);
                    IndexRepository.AddIndex(
                        entry.Key,
                        new EventTableIndexRepositoryEntry(
                            entry.Value.OptionalIndexName,
                            entry.Value.OptionalIndexModuleName,
                            index));
                }
            }
        }
        /// <summary>
        /// The AddIndex
        /// </summary>
        /// <param name="unique">The <see cref="bool"/></param>
        /// <param name="hashProps">The <see cref="IList{IndexedPropDesc}"/></param>
        /// <param name="btreeProps">The <see cref="IList{IndexedPropDesc}"/></param>
        /// <param name="advancedIndexProvisionDesc">The <see cref="EventAdvancedIndexProvisionDesc"/></param>
        /// <param name="prefilledEvents">The <see cref="IEnumerable{EventBean}"/></param>
        /// <param name="indexedType">The <see cref="EventType"/></param>
        /// <param name="indexName">The <see cref="string"/></param>
        /// <param name="mustCoerce">The <see cref="bool"/></param>
        /// <param name="agentInstanceContext">The <see cref="AgentInstanceContext"/></param>
        /// <param name="optionalSerde">The <see cref="object"/></param>
        /// <returns>The <see cref="Pair{IndexMultiKey, EventTableAndNamePair}"/></returns>
        private Pair <IndexMultiKey, EventTableAndNamePair> AddIndex(
            bool unique,
            IList <IndexedPropDesc> hashProps,
            IList <IndexedPropDesc> btreeProps,
            EventAdvancedIndexProvisionDesc advancedIndexProvisionDesc,
            IEnumerable <EventBean> prefilledEvents,
            EventType indexedType,
            string indexName,
            bool mustCoerce,
            AgentInstanceContext agentInstanceContext,
            object optionalSerde)
        {
            // not resolved as full match and not resolved as unique index match, allocate
            var indexPropKey = new IndexMultiKey(unique, hashProps, btreeProps, advancedIndexProvisionDesc == null ? null : advancedIndexProvisionDesc.IndexDesc);

            var indexedPropDescs   = hashProps.ToArray();
            var indexProps         = IndexedPropDesc.GetIndexProperties(indexedPropDescs);
            var indexCoercionTypes = IndexedPropDesc.GetCoercionTypes(indexedPropDescs);

            if (!mustCoerce)
            {
                indexCoercionTypes = null;
            }

            var rangePropDescs     = btreeProps.ToArray();
            var rangeProps         = IndexedPropDesc.GetIndexProperties(rangePropDescs);
            var rangeCoercionTypes = IndexedPropDesc.GetCoercionTypes(rangePropDescs);

            var indexItem = new QueryPlanIndexItem(indexProps, indexCoercionTypes, rangeProps, rangeCoercionTypes, unique, advancedIndexProvisionDesc);
            var table     = EventTableUtil.BuildIndex(agentInstanceContext, 0, indexItem, indexedType, true, unique, indexName, optionalSerde, false);

            // fill table since its new
            var events = new EventBean[1];

            foreach (EventBean prefilledEvent in prefilledEvents)
            {
                events[0] = prefilledEvent;
                table.Add(events, agentInstanceContext);
            }

            // add table
            _tables.Add(table);

            // add index, reference counted
            _tableIndexesRefCount.Put(indexPropKey, new EventTableIndexRepositoryEntry(indexName, table));

            return(new Pair <IndexMultiKey, EventTableAndNamePair>(indexPropKey, new EventTableAndNamePair(table, indexName)));
        }
        public NamedWindowRootViewInstance(NamedWindowRootView rootView, AgentInstanceContext agentInstanceContext, EventTableIndexMetadata eventTableIndexMetadata)
        {
            _rootView             = rootView;
            _agentInstanceContext = agentInstanceContext;

            _indexRepository = new EventTableIndexRepository();
            foreach (KeyValuePair <IndexMultiKey, EventTableIndexMetadataEntry> entry in eventTableIndexMetadata.Indexes)
            {
                if (entry.Value.QueryPlanIndexItem != null)
                {
                    EventTable index = EventTableUtil.BuildIndex(agentInstanceContext, 0, entry.Value.QueryPlanIndexItem, rootView.EventType, true, entry.Key.IsUnique, entry.Value.OptionalIndexName, null, false);
                    _indexRepository.AddIndex(entry.Key, new EventTableIndexRepositoryEntry(entry.Value.OptionalIndexName, index));
                }
            }

            _tablePerMultiLookup = new Dictionary <SubordWMatchExprLookupStrategy, EventTable[]>();
        }
        public JoinSetComposerDesc Create(Viewable[] streamViews, bool isFireAndForget, AgentInstanceContext agentInstanceContext)
        {
            // Build indexes
            var indexesPerStream         = new IDictionary <TableLookupIndexReqKey, EventTable> [_indexSpecs.Length];
            var tableSecondaryIndexLocks = new ILockable[_indexSpecs.Length];
            var hasTable = false;

            for (var streamNo = 0; streamNo < _indexSpecs.Length; streamNo++)
            {
                if (_indexSpecs[streamNo] == null)
                {
                    continue;
                }

                var items = _indexSpecs[streamNo].Items;
                indexesPerStream[streamNo] = new LinkedHashMap <TableLookupIndexReqKey, EventTable>();

                if (_streamJoinAnalysisResult.TablesPerStream[streamNo] != null)
                {
                    // build for tables
                    var metadata = _streamJoinAnalysisResult.TablesPerStream[streamNo];
                    var state    = _tableService.GetState(metadata.TableName, agentInstanceContext.AgentInstanceId);
                    foreach (var indexName in state.SecondaryIndexes)       // add secondary indexes
                    {
                        var eventTable = state.GetIndex(indexName);
                        indexesPerStream[streamNo].Put(new TableLookupIndexReqKey(indexName, metadata.TableName), eventTable);
                    }
                    var index = state.GetIndex(metadata.TableName);     // add primary index
                    indexesPerStream[streamNo].Put(new TableLookupIndexReqKey(metadata.TableName, metadata.TableName), index);
                    hasTable = true;
                    tableSecondaryIndexLocks[streamNo] = agentInstanceContext.StatementContext.IsWritesToTables
                        ? state.TableLevelRWLock.WriteLock
                        : state.TableLevelRWLock.ReadLock;
                }
                else
                {
                    // build tables for implicit indexes
                    foreach (var entry in items)
                    {
                        EventTable index;
                        if (_streamJoinAnalysisResult.ViewExternal[streamNo] != null)
                        {
                            var view = _streamJoinAnalysisResult.ViewExternal[streamNo].Invoke(agentInstanceContext);
                            index = view.GetJoinIndexTable(items.Get(entry.Key));
                        }
                        else
                        {
                            index = EventTableUtil.BuildIndex(streamNo, items.Get(entry.Key), _streamTypes[streamNo], false, entry.Value.IsUnique, null);
                        }
                        indexesPerStream[streamNo].Put(entry.Key, index);
                    }
                }
            }

            // obtain any external views
            var externalViewProviders = _streamJoinAnalysisResult.ViewExternal;
            var externalViews         = new VirtualDWView[externalViewProviders.Length];

            for (var i = 0; i < externalViews.Length; i++)
            {
                if (externalViewProviders[i] != null)
                {
                    externalViews[i] = _streamJoinAnalysisResult.ViewExternal[i].Invoke(agentInstanceContext);
                }
            }

            // Build strategies
            var queryExecSpecs  = _queryPlan.ExecNodeSpecs;
            var queryStrategies = new QueryStrategy[queryExecSpecs.Length];

            for (var i = 0; i < queryExecSpecs.Length; i++)
            {
                var planNode = queryExecSpecs[i];
                if (planNode == null)
                {
                    Log.Debug(".makeComposer No execution node for stream " + i + " '" + _streamNames[i] + "'");
                    continue;
                }

                var executionNode = planNode.MakeExec(_statementName, _statementId, _annotations, indexesPerStream, _streamTypes, streamViews, _historicalStreamIndexLists, externalViews, tableSecondaryIndexLocks);

                if (Log.IsDebugEnabled)
                {
                    Log.Debug(".makeComposer Execution nodes for stream " + i + " '" + _streamNames[i] +
                              "' : \n" + ExecNode.Print(executionNode));
                }

                queryStrategies[i] = new ExecNodeQueryStrategy(i, _streamTypes.Length, executionNode);
            }

            // Remove indexes that are from tables as these are only available to query strategies
            if (hasTable)
            {
                indexesPerStream = RemoveTableIndexes(indexesPerStream, _streamJoinAnalysisResult.TablesPerStream);
            }

            // If this is not unidirectional and not a self-join (excluding self-outer-join)
            JoinSetComposerDesc joinSetComposerDesc;

            if ((!_streamJoinAnalysisResult.IsUnidirectional) &&
                (!_streamJoinAnalysisResult.IsPureSelfJoin || _outerJoinDescList.Length > 0))
            {
                JoinSetComposer composer;
                if (_historicalViewableDesc.HasHistorical)
                {
                    composer = new JoinSetComposerHistoricalImpl(indexesPerStream, queryStrategies, streamViews, _exprEvaluatorContext);
                }
                else
                {
                    if (isFireAndForget)
                    {
                        composer = new JoinSetComposerFAFImpl(indexesPerStream, queryStrategies, _streamJoinAnalysisResult.IsPureSelfJoin, _exprEvaluatorContext, _joinRemoveStream, _isOuterJoins);
                    }
                    else
                    {
                        composer = new JoinSetComposerImpl(indexesPerStream, queryStrategies, _streamJoinAnalysisResult.IsPureSelfJoin, _exprEvaluatorContext, _joinRemoveStream);
                    }
                }

                // rewrite the filter expression for all-inner joins in case "on"-clause outer join syntax was used to include those expressions
                var filterExpression = GetFilterExpressionInclOnClause(_optionalFilterNode, _outerJoinDescList);

                var postJoinEval = filterExpression == null ? null : filterExpression.ExprEvaluator;
                joinSetComposerDesc = new JoinSetComposerDesc(composer, postJoinEval);
            }
            else
            {
                QueryStrategy driver;
                int           unidirectionalStream;
                if (_streamJoinAnalysisResult.UnidirectionalStreamNumber != -1)
                {
                    unidirectionalStream = _streamJoinAnalysisResult.UnidirectionalStreamNumber;
                    driver = queryStrategies[unidirectionalStream];
                }
                else
                {
                    unidirectionalStream = 0;
                    driver = queryStrategies[0];
                }

                JoinSetComposer composer = new JoinSetComposerStreamToWinImpl(indexesPerStream, _streamJoinAnalysisResult.IsPureSelfJoin,
                                                                              unidirectionalStream, driver, _streamJoinAnalysisResult.UnidirectionalNonDriving);
                var postJoinEval = _optionalFilterNode == null ? null : _optionalFilterNode.ExprEvaluator;
                joinSetComposerDesc = new JoinSetComposerDesc(composer, postJoinEval);
            }

            // compile prior events per stream to preload any indexes
            var eventsPerStream = new EventBean[_streamNames.Length][];
            var events          = new List <EventBean>();

            for (var i = 0; i < eventsPerStream.Length; i++)
            {
                // For named windows and tables, we don't need to preload indexes from the iterators as this is always done already
                if (_streamJoinAnalysisResult.NamedWindow[i] || _streamJoinAnalysisResult.TablesPerStream[i] != null)
                {
                    continue;
                }

                IEnumerator <EventBean> en = null;
                if (!(streamViews[i] is HistoricalEventViewable) && !(streamViews[i] is DerivedValueView))
                {
                    try
                    {
                        en = streamViews[i].GetEnumerator();
                    }
                    catch (UnsupportedOperationException)
                    {
                        // Joins do not support the iterator
                    }
                }

                if (en != null)
                {
                    while (en.MoveNext())
                    {
                        events.Add(en.Current);
                    }
                    eventsPerStream[i] = events.ToArray();
                    events.Clear();
                }
                else
                {
                    eventsPerStream[i] = new EventBean[0];
                }
            }

            // init
            joinSetComposerDesc.JoinSetComposer.Init(eventsPerStream);

            return(joinSetComposerDesc);
        }