/// <summary> /// The FafTableLookup /// </summary> /// <param name="virtualDataWindow">The <see cref="VirtualDWView"/></param> /// <param name="indexMultiKey">The <see cref="IndexMultiKey"/></param> /// <param name="eventTable">The <see cref="EventTable"/></param> /// <param name="keyValues">The <see cref="Object"/> array</param> /// <param name="rangeValues">The <see cref="RangeIndexLookupValue" /> array</param> /// <param name="attributes">The <see cref="Attribute" /> array</param> /// <returns>The <see cref="ICollection{EventBean}"/></returns> private static ICollection <EventBean> FafTableLookup( VirtualDWView virtualDataWindow, IndexMultiKey indexMultiKey, EventTable eventTable, Object[] keyValues, RangeIndexLookupValue[] rangeValues, Attribute[] attributes) { if (virtualDataWindow != null) { return(virtualDataWindow.GetFireAndForgetData(eventTable, keyValues, rangeValues, attributes)); } ISet <EventBean> result; if (indexMultiKey.HashIndexedProps.Length > 0 && indexMultiKey.RangeIndexedProps.Length == 0) { if (indexMultiKey.HashIndexedProps.Length == 1) { var table = (PropertyIndexedEventTableSingle)eventTable; result = table.Lookup(keyValues[0]); } else { var table = (PropertyIndexedEventTable)eventTable; result = table.Lookup(keyValues); } } else if (indexMultiKey.HashIndexedProps.Length == 0 && indexMultiKey.RangeIndexedProps.Length == 1) { var table = (PropertySortedEventTable)eventTable; result = table.LookupConstants(rangeValues[0]); } else { var table = (PropertyCompositeEventTable)eventTable; var rangeCoercion = table.OptRangeCoercedTypes; var lookup = CompositeIndexLookupFactory.Make(keyValues, rangeValues, rangeCoercion); result = new HashSet <EventBean>(); lookup.Lookup(table.MapIndex, result, table.PostProcessor); } if (result != null) { return(result); } return(Collections.GetEmptyList <EventBean>()); }
private static ICollection<EventBean> FafTableLookup( VirtualDWView virtualDataWindow, IndexMultiKey indexMultiKey, EventTable eventTable, object[] keyValues, RangeIndexLookupValue[] rangeValues, Attribute[] annotations, AgentInstanceContext agentInstanceContext) { if (virtualDataWindow != null) { return virtualDataWindow.GetFireAndForgetData(eventTable, keyValues, rangeValues, annotations); } ISet<EventBean> result; if (indexMultiKey.HashIndexedProps.Length > 0 && indexMultiKey.RangeIndexedProps.Length == 0) { var table = (PropertyHashedEventTable) eventTable; var lookupKey = table.MultiKeyTransform.From(keyValues); result = table.Lookup(lookupKey); } else if (indexMultiKey.HashIndexedProps.Length == 0 && indexMultiKey.RangeIndexedProps.Length == 1) { var table = (PropertySortedEventTable) eventTable; result = table.LookupConstants(rangeValues[0]); } else { var table = (PropertyCompositeEventTable) eventTable; var rangeCoercion = table.OptRangeCoercedTypes; var lookup = CompositeIndexLookupFactory.Make(keyValues, table.MultiKeyTransform, rangeValues, rangeCoercion); result = new HashSet<EventBean>(); lookup.Lookup(table.Index, result, table.PostProcessor); } if (result != null) { return result; } return EmptyList<EventBean>.Instance; }
public static ICollection <EventBean> Snapshot( FilterSpecCompiled optionalFilter, Attribute[] annotations, VirtualDWView virtualDataWindow, EventTableIndexRepository indexRepository, bool queryPlanLogging, ILog queryPlanLogDestination, string objectName, AgentInstanceContext agentInstanceContext) { if (optionalFilter == null || optionalFilter.Parameters.Length == 0) { if (virtualDataWindow != null) { var pair = virtualDataWindow.GetFireAndForgetDesc(Collections.GetEmptySet <string>(), Collections.GetEmptySet <string>()); return(virtualDataWindow.GetFireAndForgetData(pair.Second, new object[0], new RangeIndexLookupValue[0], annotations)); } return(null); } // Determine what straight-equals keys and which ranges are available. // Widening/Coercion is part of filter spec compile. ISet <string> keysAvailable = new HashSet <string>(); ISet <string> rangesAvailable = new HashSet <string>(); if (optionalFilter.Parameters.Length == 1) { foreach (FilterSpecParam param in optionalFilter.Parameters[0]) { if (!(param is FilterSpecParamConstant || param is FilterSpecParamRange || param is FilterSpecParamIn)) { continue; } if (param.FilterOperator == FilterOperator.EQUAL || param.FilterOperator == FilterOperator.IS || param.FilterOperator == FilterOperator.IN_LIST_OF_VALUES) { keysAvailable.Add(param.Lookupable.Expression); } else if (param.FilterOperator.IsRangeOperator() || param.FilterOperator.IsInvertedRangeOperator() || param.FilterOperator.IsComparisonOperator()) { rangesAvailable.Add(param.Lookupable.Expression); } else if (param.FilterOperator.IsRangeOperator()) { rangesAvailable.Add(param.Lookupable.Expression); } } } // Find an index that matches the needs Pair <IndexMultiKey, EventTableAndNamePair> tablePair; if (virtualDataWindow != null) { var tablePairNoName = virtualDataWindow.GetFireAndForgetDesc(keysAvailable, rangesAvailable); tablePair = new Pair <IndexMultiKey, EventTableAndNamePair>(tablePairNoName.First, new EventTableAndNamePair(tablePairNoName.Second, null)); } else { var indexHint = IndexHint.GetIndexHint(annotations); IList <IndexHintInstruction> optionalIndexHintInstructions = null; if (indexHint != null) { optionalIndexHintInstructions = indexHint.InstructionsFireAndForget; } tablePair = indexRepository.FindTable(keysAvailable, rangesAvailable, optionalIndexHintInstructions); } var hook = QueryPlanIndexHookUtil.GetHook(annotations); if (queryPlanLogging && (queryPlanLogDestination.IsInfoEnabled || hook != null)) { var prefix = "Fire-and-forget from " + objectName + " "; var indexName = tablePair != null && tablePair.Second != null ? tablePair.Second.IndexName : null; var indexText = indexName != null ? "index " + indexName + " " : "full table scan "; indexText += "(snapshot only, for join see separate query plan)"; if (tablePair == null) { queryPlanLogDestination.Info(prefix + indexText); } else { queryPlanLogDestination.Info(prefix + indexText + tablePair.Second.EventTable.ToQueryPlan()); } if (hook != null) { hook.FireAndForget(new QueryPlanIndexDescFAF( new IndexNameAndDescPair[] { new IndexNameAndDescPair(indexName, tablePair != null ? tablePair.Second.EventTable.ProviderClass.Name : null) })); } } if (tablePair == null) { return(null); // indicates table scan } // Compile key sets which contain key index lookup values var keyIndexProps = IndexedPropDesc.GetIndexProperties(tablePair.First.HashIndexedProps); var hasKeyWithInClause = false; var keyValues = new object[keyIndexProps.Length]; for (var keyIndex = 0; keyIndex < keyIndexProps.Length; keyIndex++) { foreach (var param in optionalFilter.Parameters[0]) { if (param.Lookupable.Expression.Equals(keyIndexProps[keyIndex])) { if (param.FilterOperator == FilterOperator.IN_LIST_OF_VALUES) { var keyValuesList = ((MultiKeyUntyped)param.GetFilterValue(null, agentInstanceContext)).Keys; if (keyValuesList.Length == 0) { continue; } else if (keyValuesList.Length == 1) { keyValues[keyIndex] = keyValuesList[0]; } else { keyValues[keyIndex] = keyValuesList; hasKeyWithInClause = true; } } else { keyValues[keyIndex] = param.GetFilterValue(null, agentInstanceContext); } break; } } } // Analyze ranges - these may include key lookup value (EQUALS semantics) var rangeIndexProps = IndexedPropDesc.GetIndexProperties(tablePair.First.RangeIndexedProps); RangeIndexLookupValue[] rangeValues; if (rangeIndexProps.Length > 0) { rangeValues = CompileRangeLookupValues(rangeIndexProps, optionalFilter.Parameters[0], agentInstanceContext); } else { rangeValues = new RangeIndexLookupValue[0]; } var eventTable = tablePair.Second.EventTable; var indexMultiKey = tablePair.First; // table lookup without in-clause if (!hasKeyWithInClause) { return(FafTableLookup(virtualDataWindow, indexMultiKey, eventTable, keyValues, rangeValues, annotations)); } // table lookup with in-clause: determine combinations var combinations = new object[keyIndexProps.Length][]; for (var i = 0; i < keyValues.Length; i++) { if (keyValues[i] is object[]) { combinations[i] = (object[])keyValues[i]; } else { combinations[i] = new object[] { keyValues[i] }; } } // enumerate combinations var enumeration = new CombinationEnumeration(combinations); var events = new HashSet <EventBean>(); for (; enumeration.MoveNext();) { object[] keys = enumeration.Current; var result = FafTableLookup(virtualDataWindow, indexMultiKey, eventTable, keys, rangeValues, annotations); events.AddAll(result); } return(events); }
/// <summary> /// The snapshot /// </summary> /// <param name="queryGraph">The <see cref="QueryGraph"/></param> /// <param name="attributes">The <see cref="Attribute" /> array</param> /// <param name="virtualDataWindow">The <see cref="VirtualDWView"/></param> /// <param name="indexRepository">The <see cref="EventTableIndexRepository"/></param> /// <param name="queryPlanLogging">The <see cref="bool"/></param> /// <param name="queryPlanLogDestination">The <see cref="ILog"/></param> /// <param name="objectName">The <see cref="string"/></param> /// <param name="agentInstanceContext">The <see cref="AgentInstanceContext"/></param> /// <returns>The <see cref="ICollection{EventBean}"/></returns> public static ICollection <EventBean> Snapshot( QueryGraph queryGraph, Attribute[] attributes, VirtualDWView virtualDataWindow, EventTableIndexRepository indexRepository, bool queryPlanLogging, ILog queryPlanLogDestination, string objectName, AgentInstanceContext agentInstanceContext) { var queryGraphValue = queryGraph == null ? null : queryGraph.GetGraphValue(QueryGraph.SELF_STREAM, 0); if (queryGraphValue == null || queryGraphValue.Items.IsEmpty()) { if (virtualDataWindow != null) { var pair = virtualDataWindow.GetFireAndForgetDesc(Collections.GetEmptySet <string>(), Collections.GetEmptySet <string>()); return(virtualDataWindow.GetFireAndForgetData(pair.Second, new Object[0], new RangeIndexLookupValue[0], attributes)); } return(null); } // determine custom index var customResult = SnapshotCustomIndex( queryGraphValue, indexRepository, attributes, agentInstanceContext, queryPlanLogging, queryPlanLogDestination, objectName); if (customResult != null) { return(customResult.Value); } // determine lookup based on hash-keys and ranges var keysAvailable = queryGraphValue.HashKeyProps; var keyNamesAvailable = keysAvailable.Indexed.Count == 0 ? Collections.GetEmptySet <string>() : new HashSet <string>(keysAvailable.Indexed); var rangesAvailable = queryGraphValue.RangeProps; var rangeNamesAvailable = rangesAvailable.Indexed.Count == 0 ? Collections.GetEmptySet <string>() : new HashSet <string>(rangesAvailable.Indexed); // find index that matches the needs var tablePair = FindIndex(keyNamesAvailable, rangeNamesAvailable, indexRepository, virtualDataWindow, attributes); // regular index lookup if (tablePair != null) { return(SnapshotIndex(keysAvailable, rangesAvailable, tablePair, virtualDataWindow, attributes, agentInstanceContext, queryPlanLogging, queryPlanLogDestination, objectName)); } // in-keyword lookup var inkwResult = SnapshotInKeyword(queryGraphValue, indexRepository, virtualDataWindow, attributes, agentInstanceContext, queryPlanLogging, queryPlanLogDestination, objectName); if (inkwResult != null) { return(inkwResult.Value); } QueryPlanReportTableScan(attributes, agentInstanceContext, queryPlanLogging, queryPlanLogDestination, objectName); return(null); }
public static ICollection<EventBean> Snapshot( QueryGraph filterQueryGraph, Attribute[] annotations, VirtualDWView virtualDataWindow, EventTableIndexRepository indexRepository, string objectName, AgentInstanceContext agentInstanceContext) { var queryGraphValue = filterQueryGraph == null ? null : filterQueryGraph.GetGraphValue(QueryGraphForge.SELF_STREAM, 0); if (queryGraphValue == null || queryGraphValue.Items.IsEmpty()) { if (virtualDataWindow != null) { Pair<IndexMultiKey, EventTable> pair = VirtualDWQueryPlanUtil.GetFireAndForgetDesc( virtualDataWindow.EventType, new EmptySet<string>(), new EmptySet<string>()); return virtualDataWindow.GetFireAndForgetData( pair.Second, CollectionUtil.OBJECTARRAY_EMPTY, new RangeIndexLookupValue[0], annotations); } return null; } // determine custom index var customResult = SnapshotCustomIndex( queryGraphValue, indexRepository, annotations, agentInstanceContext, objectName); if (customResult != null) { return customResult.Value; } // determine lookup based on hash-keys and ranges var keysAvailable = queryGraphValue.HashKeyProps; ISet<string> keyNamesAvailable = keysAvailable.Indexed.Length == 0 ? (ISet<string>) new EmptySet<string>() : (ISet<string>) new HashSet<string>(keysAvailable.Indexed); var rangesAvailable = queryGraphValue.RangeProps; ISet<string> rangeNamesAvailable = rangesAvailable.Indexed.Length == 0 ? (ISet<string>) new EmptySet<string>() : (ISet<string>) new HashSet<string>(rangesAvailable.Indexed); Pair<IndexMultiKey, EventTableAndNamePair> tablePair; // find index that matches the needs tablePair = FindIndex( keyNamesAvailable, rangeNamesAvailable, indexRepository, virtualDataWindow, annotations); // regular index lookup if (tablePair != null) { return SnapshotIndex( keysAvailable, rangesAvailable, tablePair, virtualDataWindow, annotations, agentInstanceContext, objectName); } // in-keyword lookup var inkwResult = SnapshotInKeyword( queryGraphValue, indexRepository, virtualDataWindow, annotations, agentInstanceContext, objectName); if (inkwResult != null) { return inkwResult.Value; } QueryPlanReportTableScan(annotations, agentInstanceContext, objectName); return null; }