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); } } } }
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); } } } }
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); }
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; }
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++; } }
/// <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)); }