예제 #1
0
        private void RemoveFromRelationshipTable(UMatrixRule deletedRule)
        {
            superOrJointRulesDictionary.TryRemove(deletedRule, out _);

            foreach (var value in superOrJointRulesDictionary.Values)
            {
                value.Remove(deletedRule);
            }
        }
예제 #2
0
        /// <summary>
        /// 返回新的规则集
        /// </summary>
        /// <param name="thresholdToRemove">如果为<see cref="int.MaxValue"/>则只去除重复,不进行合并。</param>
        /// <returns></returns>
        public List <UMatrixRule> Clean(int thresholdToRemove)
        {
            HashSet <UMatrixRule> processedRules = new HashSet <UMatrixRule>();

            savedSearch = 0;

            List <UMatrixRule> newRules = new List <UMatrixRule>();

            for (int i = 0; i < rules.Count; i++)
            {
                var currentRule = rules[i];


                var  g             = currentRule.Selector;
                bool isGeneralized = false;
                while (g != null)
                {
                    var generalizedRule = new UMatrixRule(g.Source, g.Destination, g.Type, currentRule.IsAllow);
                    if (processedRules.Contains(generalizedRule))
                    {
                        savedSearch++;
                        break;
                    }

                    var subRules = (from r in rules
                                    where g.IsProperSuperOf(r.Selector) && r.IsAllow == currentRule.IsAllow
                                    select r).ToArray();


                    if (subRules.Length >= (isGeneralized ? thresholdToRemove : 1))
                    {
                        var toRemove = new List <UMatrixRule>();
                        foreach (var subRule in subRules)
                        {
                            var superOrJointRules = this.GetSuperOrJointRules(subRule).Union(newRules.Where(nr => nr.Selector.IsSuperOrHasJoint(subRule.Selector))).Where(r => r.IsAllow != subRule.IsAllow);
                            if (superOrJointRules.Any(s => s.Priority > generalizedRule.Priority) ||
                                generalizedRule.IsAllow && generalizedRule.Selector.Type == TypePredicate.All && subRule.Selector.Type != TypePredicate.All)
                            {
                                //不能删除
                            }
                            else
                            {
                                toRemove.Add(subRule);
                            }
                        }

                        Debug.Assert(toRemove.Contains(currentRule) || toRemove.Contains(currentRule) == false,
                                     "当前规则可能被更高优先级规则锁定,但当前规则的推广规则可能可用于合并其他规则。");

                        var groupings = toRemove.GroupBy(r => r.Selector.GetDistanceTo(generalizedRule.Selector)).ToArray();

                        MergeEventArgs     me = null;
                        DedupRuleEventArgs de = null;
                        foreach (var grouping in groupings)
                        {
                            if (grouping.Count() >= (isGeneralized ? GetDistance(grouping.Key) * thresholdToRemove : 1))
                            {
                                newRules.Add(generalizedRule);

                                if (isGeneralized)
                                {
                                    if (me == null)
                                    {
                                        me = new MergeEventArgs();
                                    }

                                    me.MasterRule = generalizedRule;
                                    me.RulesToDelete.AddRange(grouping);
                                }
                                else
                                {
                                    if (de == null)
                                    {
                                        de = new DedupRuleEventArgs();
                                    }

                                    de.MasterRule = generalizedRule;
                                    de.DuplicateRules.AddRange(grouping);
                                }

                                for (int j = rules.Count - 1; j >= i; j--)
                                {
                                    if (grouping.Contains(rules[j]))
                                    {
                                        RemoveFromRelationshipTable(rules[j]);
                                        rules[j] = rules[rules.Count - 1];
                                        rules.RemoveAt(rules.Count - 1);
                                    }
                                }
                            }
                        }

                        if (me != null)
                        {
                            MergeEvent?.Invoke(this, me);
                        }
                        if (de != null)
                        {
                            DedupEvent?.Invoke(this, de);
                        }

                        processedRules.Add(generalizedRule);

                        break;
                    }

                    g             = g.Generalize();
                    isGeneralized = true;
                    if (thresholdToRemove == Int32.MaxValue)
                    {
                        break;
                    }
                }
            }

            logger.LogDebug("变量{0}节省了{1}次查询。", nameof(processedRules), savedSearch);

            foreach (var newRule in newRules)
            {
                if (rules.Contains(newRule) == false)
                {
                    rules.Add(newRule);
                }
            }

            return(rules.ToList());
        }
예제 #3
0
 public ICollection <UMatrixRule> GetSuperOrJointRules(UMatrixRule rule)
 {
     return(superOrJointRulesDictionary[rule]);
 }