/// <summary> /// The AddExplicitIndexOrReuse /// </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="agentInstanceContext">The <see cref="AgentInstanceContext"/></param> /// <param name="optionalSerde">The <see cref="object"/></param> /// <returns>The <see cref="Pair{IndexMultiKey, EventTableAndNamePair}"/></returns> public Pair <IndexMultiKey, EventTableAndNamePair> AddExplicitIndexOrReuse( bool unique, IList <IndexedPropDesc> hashProps, IList <IndexedPropDesc> btreeProps, EventAdvancedIndexProvisionDesc advancedIndexProvisionDesc, IEnumerable <EventBean> prefilledEvents, EventType indexedType, string indexName, AgentInstanceContext agentInstanceContext, object optionalSerde) { if (hashProps.IsEmpty() && btreeProps.IsEmpty() && advancedIndexProvisionDesc == null) { throw new ArgumentException("Invalid zero element list for hash and btree columns"); } // Get an existing table, if any, matching the exact requirement var indexPropKeyMatch = EventTableIndexUtil.FindExactMatchNameAndType(_tableIndexesRefCount.Keys, unique, hashProps, btreeProps, advancedIndexProvisionDesc == null ? null : advancedIndexProvisionDesc.IndexDesc); if (indexPropKeyMatch != null) { EventTableIndexRepositoryEntry refTablePair = _tableIndexesRefCount.Get(indexPropKeyMatch); return(new Pair <IndexMultiKey, EventTableAndNamePair>(indexPropKeyMatch, new EventTableAndNamePair(refTablePair.Table, refTablePair.OptionalIndexName))); } return(AddIndex(unique, hashProps, btreeProps, advancedIndexProvisionDesc, prefilledEvents, indexedType, indexName, false, agentInstanceContext, optionalSerde)); }
public Pair <IndexMultiKey, EventTableAndNamePair> FindTable(ISet <string> keyPropertyNames, ISet <string> rangePropertyNames, IList <IndexHintInstruction> optionalIndexHintInstructions) { var pair = EventTableIndexUtil.FindIndexBestAvailable(_tableIndexesRefCount, keyPropertyNames, rangePropertyNames, optionalIndexHintInstructions); if (pair == null) { return(null); } EventTable tableFound = ((EventTableIndexRepositoryEntry)pair.Second).Table; return(new Pair <IndexMultiKey, EventTableAndNamePair>(pair.First, new EventTableAndNamePair(tableFound, pair.Second.OptionalIndexName))); }
public void ValidateAddExplicitIndex(bool unique, string indexName, IList <CreateIndexItem> columns, EventType eventType, IEnumerable <EventBean> dataWindowContents) { if (_explicitIndexes.ContainsKey(indexName)) { throw new ExprValidationException("Index by name '" + indexName + "' already exists"); } var desc = EventTableIndexUtil.ValidateCompileExplicitIndex(unique, columns, eventType); var pair = AddExplicitIndexOrReuse(unique, desc.HashProps, desc.BtreeProps, dataWindowContents, eventType, indexName); _explicitIndexes.Put(indexName, pair.Second.EventTable); }
public static Pair <IndexMultiKey, EventTableIndexEntryBase> FindIndexBestAvailable <T>( IDictionary <IndexMultiKey, T> tablesAvailable, ISet <string> keyPropertyNames, ISet <string> rangePropertyNames, IList <IndexHintInstruction> optionalIndexHintInstructions) where T : EventTableIndexEntryBase { if (keyPropertyNames.IsEmpty() && rangePropertyNames.IsEmpty()) { return(null); } // determine candidates IList <IndexedPropDesc> hashProps = new List <IndexedPropDesc>(); foreach (var keyPropertyName in keyPropertyNames) { hashProps.Add(new IndexedPropDesc(keyPropertyName, null)); } IList <IndexedPropDesc> rangeProps = new List <IndexedPropDesc>(); foreach (var rangePropertyName in rangePropertyNames) { rangeProps.Add(new IndexedPropDesc(rangePropertyName, null)); } var indexCandidates = EventTableIndexUtil .FindCandidates(tablesAvailable, hashProps, rangeProps) .Transform <IndexMultiKey, EventTableIndexEntryBase, IndexMultiKey, T>( k => k, v => v, k => k, v => v as T); // handle hint if (optionalIndexHintInstructions != null) { var found = EventTableIndexUtil.FindByIndexHint(indexCandidates, optionalIndexHintInstructions); if (found != null) { return(GetPair(tablesAvailable, found)); } } // no candidates if (indexCandidates == null || indexCandidates.IsEmpty()) { if (Log.IsDebugEnabled) { Log.Debug("No index found."); } return(null); } return(GetBestCandidate(indexCandidates)); }
public void ValidateAddExplicitIndex(bool unique, string indexName, IList <CreateIndexItem> columns, EventType eventType, IEnumerable <EventBean> dataWindowContents, AgentInstanceContext agentInstanceContext, bool allowIndexExists, object optionalSerde) { if (_explicitIndexes.ContainsKey(indexName)) { if (allowIndexExists) { return; } throw new ExprValidationException("Index by name '" + indexName + "' already exists"); } var desc = EventTableIndexUtil.ValidateCompileExplicitIndex(unique, columns, eventType); AddExplicitIndex(indexName, desc, eventType, dataWindowContents, agentInstanceContext, optionalSerde); }
public static IndexMultiKey FindIndexConsiderTyping(IDictionary <IndexMultiKey, EventTableIndexMetadataEntry> tableIndexesRefCount, IList <IndexedPropDesc> hashProps, IList <IndexedPropDesc> btreeProps, IList <IndexHintInstruction> optionalIndexHintInstructions) { if (hashProps.IsEmpty() && btreeProps.IsEmpty()) { throw new ArgumentException("Invalid zero element list for hash and btree columns"); } var indexCandidates = //(IDictionary<IndexMultiKey, EventTableIndexRepositoryEntry>) EventTableIndexUtil.FindCandidates(tableIndexesRefCount, hashProps, btreeProps); // if there are hints, follow these if (optionalIndexHintInstructions != null) { var found = EventTableIndexUtil.FindByIndexHint(indexCandidates, optionalIndexHintInstructions); if (found != null) { return(found); } } // Get an existing table, if any, matching the exact requirement, prefer unique var indexPropKeyMatch = EventTableIndexUtil.FindExactMatchNameAndType(tableIndexesRefCount.Keys, true, hashProps, btreeProps); if (indexPropKeyMatch == null) { indexPropKeyMatch = EventTableIndexUtil.FindExactMatchNameAndType(tableIndexesRefCount.Keys, false, hashProps, btreeProps); } if (indexPropKeyMatch != null) { return(indexPropKeyMatch); } if (indexCandidates.IsEmpty()) { return(null); } var transIndexCandidates = indexCandidates.Transform <IndexMultiKey, EventTableIndexEntryBase, IndexMultiKey, EventTableIndexMetadataEntry>( k => k, v => v, k => k, v => (EventTableIndexMetadataEntry)v); return(GetBestCandidate(transIndexCandidates).First); }
public Pair <IndexMultiKey, EventTableAndNamePair> AddExplicitIndexOrReuse( bool unique, IList <IndexedPropDesc> hashProps, IList <IndexedPropDesc> btreeProps, IEnumerable <EventBean> prefilledEvents, EventType indexedType, string indexName) { if (hashProps.IsEmpty() && btreeProps.IsEmpty()) { throw new ArgumentException("Invalid zero element list for hash and btree columns"); } // Get an existing table, if any, matching the exact requirement var indexPropKeyMatch = EventTableIndexUtil.FindExactMatchNameAndType(_tableIndexesRefCount.Keys, unique, hashProps, btreeProps); if (indexPropKeyMatch != null) { var refTablePair = _tableIndexesRefCount.Get(indexPropKeyMatch); return(new Pair <IndexMultiKey, EventTableAndNamePair>(indexPropKeyMatch, new EventTableAndNamePair(refTablePair.Table, refTablePair.OptionalIndexName))); } return(AddIndex(unique, hashProps, btreeProps, prefilledEvents, indexedType, indexName, false)); }
private static SubordinateQueryIndexDesc FindOrSuggestIndex( IDictionary <String, SubordPropHashKey> hashProps, IDictionary <String, SubordPropRangeKey> rangeProps, IndexHint optionalIndexHint, bool isIndexShare, int subqueryNumber, EventTableIndexMetadata indexMetadata, ICollection <string> optionalUniqueKeyProps, bool onlyUseExistingIndexes) { var indexProps = GetIndexPropDesc(hashProps, rangeProps); var hashedAndBtreeProps = indexProps.ListPair; // Get or create the table for this index (exact match or property names, type of index and coercion type is expected) IndexKeyInfo indexKeyInfo; // how needs all of IndexKeyInfo+QueryPlanIndexItem+IndexMultiKey IndexMultiKey indexMultiKey; string indexName = null; QueryPlanIndexItem planIndexItem = null; if (hashedAndBtreeProps.HashedProps.IsEmpty() && hashedAndBtreeProps.BtreeProps.IsEmpty()) { return(null); } Pair <IndexMultiKey, string> existing = null; Pair <QueryPlanIndexItem, IndexMultiKey> planned = null; // consider index hints IList <IndexHintInstruction> optionalIndexHintInstructions = null; if (optionalIndexHint != null) { optionalIndexHintInstructions = optionalIndexHint.GetInstructionsSubquery(subqueryNumber); } var indexFoundPair = EventTableIndexUtil.FindIndexConsiderTyping(indexMetadata.Indexes, hashedAndBtreeProps.HashedProps, hashedAndBtreeProps.BtreeProps, optionalIndexHintInstructions); if (indexFoundPair != null) { var hintIndex = indexMetadata.Indexes.Get(indexFoundPair); existing = new Pair <IndexMultiKey, string>(indexFoundPair, hintIndex.OptionalIndexName); } // nothing found: plan one if (existing == null && !onlyUseExistingIndexes) { // not found, see if the item is declared unique var proposedHashedProps = hashedAndBtreeProps.HashedProps; var proposedBtreeProps = hashedAndBtreeProps.BtreeProps; // match against unique-key properties when suggesting an index var unique = false; var coerce = !isIndexShare; if (optionalUniqueKeyProps != null && !optionalUniqueKeyProps.IsEmpty()) { IList <IndexedPropDesc> newHashProps = new List <IndexedPropDesc>(); foreach (var uniqueKey in optionalUniqueKeyProps) { var found = false; foreach (var hashProp in hashedAndBtreeProps.HashedProps) { if (hashProp.IndexPropName.Equals(uniqueKey)) { newHashProps.Add(hashProp); found = true; break; } } if (!found) { newHashProps = null; break; } } if (newHashProps != null) { proposedHashedProps = newHashProps; proposedBtreeProps = Collections.GetEmptyList <IndexedPropDesc>(); unique = true; coerce = false; } } planned = PlanIndex(unique, proposedHashedProps, proposedBtreeProps, coerce); } // compile index information if (existing == null && planned == null) { return(null); } // handle existing if (existing != null) { indexKeyInfo = SubordinateQueryPlannerUtil.CompileIndexKeyInfo(existing.First, indexProps.HashIndexPropsProvided, indexProps.HashJoinedProps, indexProps.RangeIndexPropsProvided, indexProps.RangeJoinedProps); indexName = existing.Second; indexMultiKey = existing.First; } // handle planned else { indexKeyInfo = SubordinateQueryPlannerUtil.CompileIndexKeyInfo(planned.Second, indexProps.HashIndexPropsProvided, indexProps.HashJoinedProps, indexProps.RangeIndexPropsProvided, indexProps.RangeJoinedProps); indexMultiKey = planned.Second; planIndexItem = planned.First; } return(new SubordinateQueryIndexDesc(indexKeyInfo, indexName, indexMultiKey, planIndexItem)); }