/// <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 JoinSetComposerPrototypeHistoricalDesc GetStrategy( int streamViewStreamNum, StatementRawInfo raw, SerdeCompileTimeResolver serdeResolver) { // If there is only a single polling stream, then build a single index if (_pollingStreams.Count == 1) { return JoinSetComposerPrototypeForgeFactory.DetermineIndexing( _queryGraph, _typesPerStream[_historicalStreamNum], _typesPerStream[streamViewStreamNum], _historicalStreamNum, streamViewStreamNum, raw, serdeResolver); } // 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. var additionalForgeables = new List<StmtClassForgeableFactory>(); 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 PollResultIndexingStrategyForge[numIndexes]; // create an indexing strategy for each index var count = 0; foreach (var desc in _indexesUsedByStreams) { var sampleStreamViewStreamNum = desc.Value[0]; var indexingX = JoinSetComposerPrototypeForgeFactory.DetermineIndexing( _queryGraph, _typesPerStream[_historicalStreamNum], _typesPerStream[sampleStreamViewStreamNum], _historicalStreamNum, sampleStreamViewStreamNum, raw, serdeResolver); indexingStrategies[count] = indexingX.IndexingForge; additionalForgeables.AddAll(indexingX.AdditionalForgeables); count++; } // create a master indexing strategy that utilizes each indexing strategy to create a set of indexes _masterIndexingStrategy = new PollResultIndexingStrategyMultiForge( streamViewStreamNum, indexingStrategies); } } // there is one type of index if (_indexesUsedByStreams.Count == 1) { return JoinSetComposerPrototypeForgeFactory.DetermineIndexing( _queryGraph, _typesPerStream[_historicalStreamNum], _typesPerStream[streamViewStreamNum], _historicalStreamNum, streamViewStreamNum, raw, serdeResolver); } // 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("Index not found for use by stream " + streamViewStreamNum); } // Use one of the indexes built by the master index and a lookup strategy JoinSetComposerPrototypeHistoricalDesc indexing = JoinSetComposerPrototypeForgeFactory.DetermineIndexing( _queryGraph, _typesPerStream[_historicalStreamNum], _typesPerStream[streamViewStreamNum], _historicalStreamNum, streamViewStreamNum, raw, serdeResolver); HistoricalIndexLookupStrategyForge innerLookupStrategy = indexing.LookupForge; HistoricalIndexLookupStrategyForge lookupStrategy = new HistoricalIndexLookupStrategyMultiForge(indexUsed, innerLookupStrategy); additionalForgeables.AddAll(indexing.AdditionalForgeables); return new JoinSetComposerPrototypeHistoricalDesc(lookupStrategy, _masterIndexingStrategy, additionalForgeables); }
/// <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<HistoricalIndexLookupStrategyForge, PollResultIndexingStrategyForge> GetStrategy( int streamViewStreamNum) { // If there is only a single polling stream, then build a single index if (pollingStreams.Count == 1) { return JoinSetComposerPrototypeForgeFactory.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 (int pollingStream in pollingStreams) { QueryGraphValueForge queryGraphValue = queryGraph.GetGraphValue(pollingStream, historicalStreamNum); QueryGraphValuePairHashKeyIndexForge hashKeyProps = queryGraphValue.HashKeyProps; string[] indexProperties = hashKeyProps.Indexed; Type[] keyTypes = GetPropertyTypes(hashKeyProps.Keys); Type[] indexTypes = GetPropertyTypes(typesPerStream[historicalStreamNum], indexProperties); HistoricalStreamIndexDesc desc = new HistoricalStreamIndexDesc( indexProperties, indexTypes, keyTypes); IList<int> 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) { int numIndexes = indexesUsedByStreams.Count; PollResultIndexingStrategyForge[] indexingStrategies = new PollResultIndexingStrategyForge[numIndexes]; // create an indexing strategy for each index int count = 0; foreach (KeyValuePair<HistoricalStreamIndexDesc, IList<int>> desc in indexesUsedByStreams) { int sampleStreamViewStreamNum = desc.Value[0]; indexingStrategies[count] = JoinSetComposerPrototypeForgeFactory.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 masterIndexingStrategy = new PollResultIndexingStrategyMultiForge( streamViewStreamNum, indexingStrategies); } } // there is one type of index if (indexesUsedByStreams.Count == 1) { return JoinSetComposerPrototypeForgeFactory.DetermineIndexing( queryGraph, typesPerStream[historicalStreamNum], typesPerStream[streamViewStreamNum], historicalStreamNum, streamViewStreamNum); } // determine which index number the polling stream must use int indexUsed = 0; bool found = false; foreach (IList<int> desc in indexesUsedByStreams.Values) { if (desc.Contains(streamViewStreamNum)) { found = true; break; } indexUsed++; } if (!found) { throw new IllegalStateException("Index not found for use by stream " + streamViewStreamNum); } // Use one of the indexes built by the master index and a lookup strategy HistoricalIndexLookupStrategyForge innerLookupStrategy = JoinSetComposerPrototypeForgeFactory .DetermineIndexing( queryGraph, typesPerStream[historicalStreamNum], typesPerStream[streamViewStreamNum], historicalStreamNum, streamViewStreamNum) .First; HistoricalIndexLookupStrategyForge lookupStrategy = new HistoricalIndexLookupStrategyMultiForge(indexUsed, innerLookupStrategy); return new Pair<HistoricalIndexLookupStrategyForge, PollResultIndexingStrategyForge>( lookupStrategy, masterIndexingStrategy); }