예제 #1
0
        protected override IDictionary <AnalysisEntity, TValue> MergeCore(IDictionary <AnalysisEntity, TValue> map1, IDictionary <AnalysisEntity, TValue> map2)
        {
            Debug.Assert(map1 != null);
            Debug.Assert(map2 != null);

            var resultMap = new Dictionary <AnalysisEntity, TValue>();

            foreach (var entry1 in map1)
            {
                AnalysisEntity key1            = entry1.Key;
                TValue         value1          = entry1.Value;
                var            equivalentKeys2 = map2.Keys.Where(key => key.EqualsIgnoringInstanceLocation(key1));
                if (!equivalentKeys2.Any())
                {
                    // Absence of entity from one branch indicates we don't know its values.
                    TValue mergedValue = ValueDomain.Merge(value1, ValueDomain.UnknownOrMayBeValue);
                    resultMap.Add(key1, mergedValue);
                    continue;
                }

                foreach (AnalysisEntity key2 in equivalentKeys2)
                {
                    TValue value2      = map2[key2];
                    TValue mergedValue = ValueDomain.Merge(value1, value2);
                    if (key1.InstanceLocation.Equals(key2.InstanceLocation))
                    {
                        resultMap[key1] = mergedValue;
                    }
                    else
                    {
                        AnalysisEntity mergedKey = key1.WithMergedInstanceLocation(key2);
                        if (resultMap.TryGetValue(mergedKey, out var existingValue))
                        {
                            mergedValue = ValueDomain.Merge(mergedValue, existingValue);
                        }
                        else if (ReferenceEquals(mergedValue, ValueDomain.UnknownOrMayBeValue))
                        {
                            // Do no add a new key-value pair to the resultMap if the value is UnknownOrMayBeValue.
                            continue;
                        }

                        resultMap[mergedKey] = mergedValue;
                    }
                }
            }

            foreach (var kvp in map2)
            {
                var key2   = kvp.Key;
                var value2 = kvp.Value;
                if (!resultMap.ContainsKey(key2))
                {
                    // Absence of entity from one branch indicates we don't know its values.
                    TValue mergedValue = ValueDomain.Merge(value2, ValueDomain.UnknownOrMayBeValue);
                    resultMap.Add(key2, mergedValue);
                }
            }

            return(resultMap);
        }
        public override IDictionary <AnalysisEntity, TValue> Merge(IDictionary <AnalysisEntity, TValue> map1, IDictionary <AnalysisEntity, TValue> map2)
        {
            Debug.Assert(map1 != null);
            Debug.Assert(map2 != null);

            TValue GetMergedValueForEntityPresentInOneMap(AnalysisEntity key, TValue value)
            {
                var defaultValue = GetDefaultValue(key);

                return(ValueDomain.Merge(value, defaultValue));
            }

            var resultMap = new Dictionary <AnalysisEntity, TValue>();
            var newKeys   = new HashSet <AnalysisEntity>();
            var map2LookupIgnoringInstanceLocation = map2.Keys.ToLookup(entity => entity.EqualsIgnoringInstanceLocationId);

            foreach (var entry1 in map1)
            {
                AnalysisEntity key1   = entry1.Key;
                TValue         value1 = entry1.Value;

                var equivalentKeys2 = map2LookupIgnoringInstanceLocation[key1.EqualsIgnoringInstanceLocationId];
                if (!equivalentKeys2.Any())
                {
                    TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key1, value1);
                    Debug.Assert(!map2.ContainsKey(key1));
                    Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0);
                    resultMap.Add(key1, mergedValue);
                    continue;
                }

                foreach (AnalysisEntity key2 in equivalentKeys2)
                {
                    TValue value2      = map2[key2];
                    TValue mergedValue = ValueDomain.Merge(value1, value2);
                    Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0);
                    Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0);

                    if (key1.InstanceLocation.Equals(key2.InstanceLocation))
                    {
                        resultMap[key1] = mergedValue;
                    }
                    else
                    {
                        if (key1.SymbolOpt == null || key1.SymbolOpt != key2.SymbolOpt)
                        {
                            // PERF: Do not add a new key-value pair to the resultMap for unrelated entities or non-symbol based entities.
                            continue;
                        }

                        AnalysisEntity mergedKey             = key1.WithMergedInstanceLocation(key2);
                        TValue         newMergedValue        = mergedValue;
                        var            isExistingKeyInInput  = false;
                        var            isExistingKeyInResult = false;
                        if (resultMap.TryGetValue(mergedKey, out var existingValue))
                        {
                            newMergedValue        = ValueDomain.Merge(newMergedValue, existingValue);
                            isExistingKeyInResult = true;
                        }

                        if (map1.TryGetValue(mergedKey, out existingValue))
                        {
                            newMergedValue       = ValueDomain.Merge(newMergedValue, existingValue);
                            isExistingKeyInInput = true;
                        }

                        if (map2.TryGetValue(mergedKey, out existingValue))
                        {
                            newMergedValue       = ValueDomain.Merge(newMergedValue, existingValue);
                            isExistingKeyInInput = true;
                        }

                        Debug.Assert(ValueDomain.Compare(value1, newMergedValue) <= 0);
                        Debug.Assert(ValueDomain.Compare(value2, newMergedValue) <= 0);
                        Debug.Assert(ValueDomain.Compare(mergedValue, newMergedValue) <= 0);
                        mergedValue = newMergedValue;

                        if (!isExistingKeyInInput && !isExistingKeyInResult && CanSkipNewEntry(mergedKey, mergedValue))
                        {
                            // PERF: Do not add a new key-value pair to the resultMap if the value can be skipped.
                            continue;
                        }

                        if (!isExistingKeyInInput)
                        {
                            newKeys.Add(mergedKey);
                        }

                        resultMap[mergedKey] = mergedValue;
                    }
                }

                if (!resultMap.ContainsKey(key1))
                {
                    resultMap[key1] = ValueDomain.UnknownOrMayBeValue;
                }
            }

            foreach (var kvp in map2)
            {
                var key2   = kvp.Key;
                var value2 = kvp.Value;
                if (!resultMap.ContainsKey(key2))
                {
                    TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key2, value2);
                    Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0);
                    resultMap.Add(key2, mergedValue);
                }
            }

            foreach (var newKey in newKeys)
            {
                Debug.Assert(!map1.ContainsKey(newKey));
                Debug.Assert(!map2.ContainsKey(newKey));
                if (ReferenceEquals(resultMap[newKey], GetDefaultValue(newKey)))
                {
                    resultMap.Remove(newKey);
                }
            }

            Debug.Assert(Compare(map1, resultMap) <= 0);
            Debug.Assert(Compare(map2, resultMap) <= 0);

            return(resultMap);
        }
        protected override IDictionary <AnalysisEntity, TValue> MergeCore(IDictionary <AnalysisEntity, TValue> map1, IDictionary <AnalysisEntity, TValue> map2)
        {
            Debug.Assert(map1 != null);
            Debug.Assert(map2 != null);

            TValue GetMergedValueForEntityPresentInOneMap(AnalysisEntity key, TValue value)
            {
                var defaultValue = GetDefaultValue(key);

                return(key.SymbolOpt != null?ValueDomain.Merge(value, defaultValue) : defaultValue);
            }

            var resultMap = new Dictionary <AnalysisEntity, TValue>();
            var map2LookupIgnoringInstanceLocation = map2.Keys.ToLookup(entity => entity.EqualsIgnoringInstanceLocationId);

            foreach (var entry1 in map1)
            {
                AnalysisEntity key1   = entry1.Key;
                TValue         value1 = entry1.Value;

                var equivalentKeys2 = map2LookupIgnoringInstanceLocation[key1.EqualsIgnoringInstanceLocationId];
                if (!equivalentKeys2.Any())
                {
                    TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key1, value1);
                    resultMap.Add(key1, mergedValue);
                    continue;
                }

                foreach (AnalysisEntity key2 in equivalentKeys2)
                {
                    TValue value2      = map2[key2];
                    TValue mergedValue = ValueDomain.Merge(value1, value2);
                    if (key1.InstanceLocation.Equals(key2.InstanceLocation))
                    {
                        resultMap[key1] = mergedValue;
                    }
                    else
                    {
                        AnalysisEntity mergedKey = key1.WithMergedInstanceLocation(key2);
                        if (resultMap.TryGetValue(mergedKey, out var existingValue))
                        {
                            mergedValue = ValueDomain.Merge(mergedValue, existingValue);
                        }
                        else if (ReferenceEquals(mergedValue, ValueDomain.UnknownOrMayBeValue))
                        {
                            // PERF: Do not add a new key-value pair to the resultMap if the value is UnknownOrMayBeValue.
                            continue;
                        }
                        else if (key1.SymbolOpt == null || key1.SymbolOpt != key2.SymbolOpt)
                        {
                            // PERF: Do not add a add a new key-value pair to the resultMap for unrelated entities or non-symbol based entities.
                            continue;
                        }

                        resultMap[mergedKey] = mergedValue;
                    }
                }
            }

            foreach (var kvp in map2)
            {
                var key2   = kvp.Key;
                var value2 = kvp.Value;
                if (!resultMap.ContainsKey(key2))
                {
                    TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key2, value2);
                    resultMap.Add(key2, mergedValue);
                }
            }

            return(resultMap);
        }