Esempio n. 1
0
        /// <summary>
        /// Returns a list of conditon groups and an associated list of supporting indexes to satisify each group (nested conditions).
        /// </summary>
        /// <param name="transaction"></param>
        /// <param name="schemaMeta"></param>
        /// <param name="conditions"></param>
        /// <returns></returns>
        public List <IndexSelections> SelectIndexes(Transaction transaction, PersistSchema schemaMeta, Conditions conditions)
        {
            List <IndexSelections> indexSelections = new List <IndexSelections>();
            IndexSelections        indexSelection  = new IndexSelections(conditions);

            SelectIndexes(transaction, schemaMeta, conditions.Root, ref indexSelection);
            indexSelections.Add(indexSelection);

            if (conditions.Children != null && conditions.Children.Count > 0)
            {
                foreach (var childConditions in conditions.Children)
                {
                    var childIndexSelections = SelectIndexes(transaction, schemaMeta, childConditions);
                    if (childIndexSelections != null && childIndexSelections.Count > 0)
                    {
                        indexSelections.AddRange(childIndexSelections);
                    }
                }
            }

            return(indexSelections);
        }
Esempio n. 2
0
        private void SelectIndexes(Transaction transaction, PersistSchema schemaMeta, List <Condition> conditions, ref IndexSelections indexSelection)
        {
            try
            {
                var indexCatalog = GetIndexCatalog(transaction, schemaMeta, LockOperation.Read);
                List <PotentialIndex> potentialIndexs = new List <PotentialIndex>();

                var indexConditions = new IndexConditions(conditions);

                //Loop though each index in the schema and create a list of all indexes which could potentially be used to match the conditions.
                foreach (var indexMeta in indexCatalog.Collection)
                {
                    var indexHandledCondition = new List <IndexHandledCondition>();

                    for (int i = 0; i < indexMeta.Attributes.Count; i++)
                    {
                        var indexConditonMatches = indexConditions.FindAll(o => o.Key == indexMeta.Attributes[i].Name.ToLower() && o.Handled == false);

                        if (indexConditonMatches.Count > 0)
                        {
                            foreach (var indexConditonMatche in indexConditonMatches)
                            {
                                indexHandledCondition.Add(new IndexHandledCondition(indexConditonMatche, i));
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (indexHandledCondition.Count > 0)
                    {
                        potentialIndexs.Add(new PotentialIndex(indexMeta, indexHandledCondition));
                    }
                }

                //Group the indexes by their first attribute.
                var distinctFirstAttributes = potentialIndexs.Select(o => o.Index.Attributes[0].Name).Distinct();
                foreach (var distinctFirstAttribute in distinctFirstAttributes)
                {
                    //Find all idexes with the same first attribute:
                    var indexGroup = potentialIndexs.Where(o => o.FirstAttributeName == distinctFirstAttribute);

                    //For the group of indexes, find the one index that handles the most keys but also has the fewest atributes.
                    var firstIndexInGroup = (from o in indexGroup select o)
                                            .OrderByDescending(s => s.IndexHandledConditions.Count)
                                            .ThenBy(t => t.Index.Attributes.Count).FirstOrDefault();

                    foreach (var indexHandledCondition in firstIndexInGroup.IndexHandledConditions)
                    {
                        //Mark the keys which are handled by this index as "handled".
                        var handledKeys = (from o in indexConditions where o.Id == indexHandledCondition.Id select o).ToList();
                        foreach (var handledKey in handledKeys)
                        {
                            handledKey.Handled = true;
                        }
                    }

                    indexSelection.Add(new IndexSelection(firstIndexInGroup.Index, firstIndexInGroup.IndexHandledConditions));
                }

                indexSelection.UnhandledKeys.AddRange((from o in indexConditions where o.Handled == false select o.Key).ToList());
            }
            catch (Exception ex)
            {
                core.Log.Write(String.Format("Failed to select indexes for process {0}.", transaction.ProcessId), ex);
                throw;
            }
        }