/// <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));
        }
Example #2
0
        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)));
        }
Example #3
0
        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);
        }
Example #4
0
        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));
        }
Example #5
0
        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);
        }
Example #6
0
        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);
        }
Example #7
0
        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));
        }