예제 #1
0
 public AnalysisSetTwoUnion(AnalysisProxy value1, AnalysisProxy value2, UnionComparer comparer)
 {
     Debug.Assert(!comparer.Equals(value1, value2));
     Value1    = value1;
     Value2    = value2;
     _comparer = comparer;
 }
예제 #2
0
            public IAnalysisSet Add(AnalysisProxy item, out bool wasChanged)
            {
                if (!item.IsAlive)
                {
                    wasChanged = false;
                    return(this);
                }

                if (!Value.IsAlive)
                {
                    wasChanged = true;
                    return(item);
                }

                if (Object.ReferenceEquals(Value, item))
                {
                    wasChanged = false;
                    return(this);
                }
                else if (Comparer.Equals(Value, item))
                {
                    var newItem = Comparer.MergeTypes(Value, item, out wasChanged);
                    return(wasChanged ? new AnalysisSetOneUnion(newItem, Comparer) : this);
                }
                else
                {
                    wasChanged = true;
                    return(new AnalysisSetTwoUnion(Value, item, Comparer));
                }
            }
예제 #3
0
        private bool Contains(Bucket[] buckets, AnalysisProxy key, int hc)
        {
            int index      = hc % buckets.Length;
            int startIndex = index;

            do
            {
                var existingKey = buckets[index].Key;
                if (existingKey == null)
                {
                    break;
                }
                else
                {
                    if (Object.ReferenceEquals(key, existingKey) ||
                        (existingKey != _removed &&
                         buckets[index].HashCode == hc &&
                         _comparer.Equals(key, (AnalysisProxy)existingKey)))
                    {
                        return(true);
                    }
                }

                index = ProbeNext(buckets, index);
            } while (startIndex != index);

            return(false);
        }
예제 #4
0
            public IAnalysisSet Add(AnalysisProxy item, out bool wasChanged)
            {
                if (!item.IsAlive)
                {
                    wasChanged = false;
                    return(this);
                }

                if (ObjectComparer.Instance.Equals(Value1, item) || ObjectComparer.Instance.Equals(Value2, item))
                {
                    wasChanged = false;
                    return(this);
                }
                wasChanged = true;
                if (!Value1.IsAlive)
                {
                    if (!Value2.IsAlive)
                    {
                        return(item);
                    }
                    return(new AnalysisSetTwoObject(Value2, item));
                }
                else if (!Value2.IsAlive)
                {
                    return(new AnalysisSetTwoObject(Value1, item));
                }

                return(new AnalysisHashSet(this).Add(item));
            }
예제 #5
0
 /// <summary>
 /// Checks to see if the key exists in the dictionary.
 /// </summary>
 public bool Contains(AnalysisProxy key)
 {
     if (key == null)
     {
         throw new ArgumentNullException("key");
     }
     return(Contains(_buckets, key));
 }
예제 #6
0
        private static string GetDescription(AnalysisProxy value)
        {
            var res = value.Value.ShortDescription;

            if (string.IsNullOrWhiteSpace(res))
            {
                res = value.Value.GetType().FullName;
            }
            return(res);
        }
예제 #7
0
            public IAnalysisSet Add(AnalysisProxy item, out bool wasChanged)
            {
                if (!item.IsAlive)
                {
                    wasChanged = false;
                    return(this);
                }

                wasChanged = true;
                return(item);
            }
예제 #8
0
            public IAnalysisSet Add(AnalysisProxy item, out bool wasChanged)
            {
                if (!item.IsAlive)
                {
                    wasChanged = false;
                    return(this);
                }

                wasChanged = true;
                return(new AnalysisSetOneUnion(item, Comparer));
            }
예제 #9
0
            public AnalysisSetTwoUnion(IEnumerable <AnalysisProxy> set, UnionComparer comparer)
            {
                _comparer = comparer;
                var tup = FromEnumerable(set, comparer);

                if (tup == null || tup.Item2 == null)
                {
                    throw new InvalidOperationException("Sequence requires exactly two values");
                }
                Value1 = tup.Item1;
                Value2 = tup.Item2;
            }
예제 #10
0
        /// <summary>
        /// Add helper which adds the given key/value (where the key is not null) with
        /// a pre-computed hash code.
        /// </summary>
        private bool AddOne(Bucket[] buckets, AnalysisProxy /*!*/ key, int hc)
        {
            Debug.Assert(key != null);

            Debug.Assert(_count < buckets.Length);
            int index      = hc % buckets.Length;
            int startIndex = index;
            int addIndex   = -1;

            for (; ;)
            {
                Bucket cur         = buckets[index];
                var    existingKey = cur.Key;
                if (existingKey == null || existingKey == _removed || !existingKey.IsAlive)
                {
                    if (addIndex == -1)
                    {
                        addIndex = index;
                    }
                    if (cur.Key == null)
                    {
                        break;
                    }
                }
                else if (Object.ReferenceEquals(key, existingKey) ||
                         (cur.HashCode == hc && _comparer.Equals(key, (AnalysisProxy)existingKey)))
                {
                    return(false);
                }

                index = ProbeNext(buckets, index);

                if (index == startIndex)
                {
                    break;
                }
            }

            if (buckets[addIndex].Key != null &&
                buckets[addIndex].Key != _removed &&
                !buckets[addIndex].Key.IsAlive)
            {
                _count--;
            }
            buckets[addIndex].HashCode = hc;
            Thread.MemoryBarrier();
            // we write the key last so that we can check for null to
            // determine if a bucket is available.
            buckets[addIndex].Key = key;

            return(true);
        }
예제 #11
0
        /// <summary>
        /// Static helper to try and get the value from the dictionary.
        ///
        /// Used so the value lookup can run against a buckets while a writer
        /// replaces the buckets.
        /// </summary>
        private bool Contains(Bucket[] buckets, AnalysisProxy /*!*/ key)
        {
            Debug.Assert(key != null);

            if (_count > 0 && buckets != null)
            {
                int hc = _comparer.GetHashCode(key) & Int32.MaxValue;

                return(Contains(buckets, key, hc));
            }

            return(false);
        }
예제 #12
0
        public IAnalysisSet GetValueType(IAnalysisSet keyTypes, AnalysisUnit accessor, ProjectEntry declaringScope)
        {
            var res = AnalysisSet.Empty;

            if (_dependencies.Count != 0)
            {
                AnalysisProxy ns = keyTypes as AnalysisProxy;
                foreach (var keyValue in _dependencies)
                {
                    if (!IsVisible(accessor.ProjectEntry, declaringScope, keyValue.Key))
                    {
                        continue;
                    }
                    IAnalysisSet union;
                    if (ns != null)
                    {
                        // optimize for the case where we're just looking up
                        // a single AnalysisValue object which hasn't been copied into
                        // a set
                        if (keyValue.Value.KeyValues.TryGetValue(ns, out union))
                        {
                            res = res.Union(union);
                        }
                    }
                    else
                    {
                        foreach (var keyType in keyTypes)
                        {
                            if (keyValue.Value.KeyValues.TryGetValue(keyType, out union))
                            {
                                res = res.Union(union);
                            }
                        }
                    }
                }

                if (res == null || res.Count == 0)
                {
                    // This isn't ideal, but it's the best we can do for now.  We could
                    // later receive a key which would satisfy getting this value type.  If that
                    // happens we will re-analyze the code which is doing this get.  But currently
                    // we have no way to either remove the types that were previously returned, and
                    // we have no way to schedule the re-analysis of the code which is doing the get
                    // after we've completed the analysis.  So we simply don't return AllValueTypes
                    // here.
                    return(AnalysisSet.Empty);
                }
            }

            return(res ?? AnalysisSet.Empty);
        }
예제 #13
0
            public IAnalysisSet Add(AnalysisProxy item, out bool wasChanged)
            {
                if (!item.IsAlive)
                {
                    wasChanged = false;
                    return(this);
                }

                bool dummy;

                if (Object.ReferenceEquals(Value1, item) || Object.ReferenceEquals(Value2, item))
                {
                    wasChanged = false;
                    return(this);
                }
                else if (Comparer.Equals(Value1, item))
                {
                    var newValue = Comparer.MergeTypes(Value1, item, out wasChanged);
                    if (!wasChanged)
                    {
                        return(this);
                    }
                    if (Comparer.Equals(Value2, newValue))
                    {
                        return(new AnalysisSetOneUnion(Comparer.MergeTypes(Value2, newValue, out dummy), Comparer));
                    }
                    else
                    {
                        return(new AnalysisSetTwoUnion(newValue, Value2, Comparer));
                    }
                }
                else if (Comparer.Equals(Value2, item))
                {
                    var newValue = Comparer.MergeTypes(Value2, item, out wasChanged);
                    if (!wasChanged)
                    {
                        return(this);
                    }
                    if (Comparer.Equals(Value1, newValue))
                    {
                        return(new AnalysisSetOneUnion(Comparer.MergeTypes(Value1, newValue, out dummy), Comparer));
                    }
                    else
                    {
                        return(new AnalysisSetTwoUnion(Value1, newValue, Comparer));
                    }
                }
                wasChanged = true;
                return(new AnalysisHashSet(this, Comparer).Add(item));
            }
예제 #14
0
 public AnalysisSetTwoObject(IEnumerable <AnalysisProxy> set)
 {
     using (var e = set.GetEnumerator()) {
         if (!e.MoveNext())
         {
             throw new InvalidOperationException("Sequence requires exactly two values");
         }
         Value1 = e.Current;
         if (!e.MoveNext() && !ObjectComparer.Instance.Equals(e.Current, Value1))
         {
             throw new InvalidOperationException("Sequence requires exactly two values");
         }
         Value2 = e.Current;
         if (e.MoveNext())
         {
             throw new InvalidOperationException("Sequence requires exactly two values");
         }
     }
 }
예제 #15
0
        public bool AddType(AnalysisProxy proxy)
        {
            bool         wasChanged;
            IAnalysisSet prev;

            if (TAKE_COPIES)
            {
                prev = _types.Clone();
            }
            else
            {
                prev = _types;
            }
            _types = prev.Add(proxy, out wasChanged);
#if FULL_VALIDATION
            _changeCount += wasChanged ? 1 : 0;
            // The value doesn't mean anything, we just want to know if a variable is being
            // updated too often.
            Validation.Assert <ChangeCountExceededException>(_changeCount < 10000);
#endif
            return(wasChanged);
        }
예제 #16
0
        /// <summary>
        /// Adds a new item to the dictionary, replacing an existing one if it already exists.
        /// </summary>
        private bool AddOne(AnalysisProxy key)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            if (key.IsAlive)
            {
                if (_buckets == null)
                {
                    Initialize();
                }

                if (Add(_buckets, key))
                {
                    _count++;

                    CheckGrow();
                    return(true);
                }
            }
            return(false);
        }
예제 #17
0
        /// <summary>
        /// Add helper that works over a single set of buckets.  Used for
        /// both the normal add case as well as the resize case.
        /// </summary>
        private bool Add(Bucket[] buckets, AnalysisProxy key)
        {
            int hc = _comparer.GetHashCode(key) & Int32.MaxValue;

            return(AddOne(buckets, key, hc));
        }
 internal AnalysisValue(ProjectEntry projectEntry) {
     _proxy = projectEntry.WrapAnalysisValue(this);
 }
예제 #19
0
        public bool AddType(AnalysisProxy proxy) {
            bool wasChanged;
            IAnalysisSet prev;
            if (TAKE_COPIES) {
                prev = _types.Clone();
            } else {
                prev = _types;
            }
            _types = prev.Add(proxy, out wasChanged);
#if FULL_VALIDATION
            _changeCount += wasChanged ? 1 : 0;
            // The value doesn't mean anything, we just want to know if a variable is being
            // updated too often.
            Validation.Assert<ChangeCountExceededException>(_changeCount < 10000);
#endif
            return wasChanged;
        }
예제 #20
0
 public bool Contains(AnalysisProxy item)
 {
     return(ObjectComparer.Instance.Equals(Value1, item) || ObjectComparer.Instance.Equals(Value2, item));
 }
예제 #21
0
            public IAnalysisSet Union(IEnumerable <AnalysisProxy> items, out bool wasChanged)
            {
                AnalysisProxy ns;

                if (items == null)
                {
                    wasChanged = false;
                    return(this);
                }
                else if ((ns = items as AnalysisProxy) != null)
                {
                    return(Add(ns, out wasChanged));
                }
                else
                {
                    int count = items.Count();
                    if (Value1.IsAlive)
                    {
                        if (!items.Contains(Value1))
                        {
                            count++;
                        }
                    }
                    if (Value2.IsAlive)
                    {
                        if (!items.Contains(Value2))
                        {
                            count++;
                        }
                    }

                    switch (count)
                    {
                    case 0:
                        wasChanged = false;
                        return(AnalysisSetEmptyObject.Instance);

                    case 1:
                        if (Value1.IsAlive)
                        {
                            wasChanged = false;
                            return(Value1);
                        }
                        else if (Value2.IsAlive)
                        {
                            wasChanged = false;
                            return(Value2);
                        }
                        wasChanged = true;
                        return(items.First());

                    case 2:
                        AnalysisProxy first = null;
                        if (Value1.IsAlive)
                        {
                            first = Value1;
                        }
                        if (Value2.IsAlive)
                        {
                            if (first == null)
                            {
                                first = Value2;
                            }
                            else
                            {
                                // items is empty...
                                wasChanged = false;
                                return(this);
                            }
                        }
                        if (first == null)
                        {
                            // Value1 & Value2 are gone
                            wasChanged = true;
                            return(new AnalysisSetTwoObject(items));
                        }
                        // Value1 or Value2 is gone...
                        if (!items.First().IsAlive)
                        {
                            // and so is the 1 item we have...
                            wasChanged = false;
                            return(first);
                        }
                        wasChanged = true;
                        return(new AnalysisSetTwoObject(first, items.First()));

                    default:
                        var res = new AnalysisHashSet();
                        if (Value1.IsAlive)
                        {
                            res.Add(Value1);
                        }
                        if (Value2.IsAlive)
                        {
                            res.Add(Value2);
                        }
                        res.Union(items, out wasChanged);
                        return(res);
                    }
                }
            }
예제 #22
0
        /// <summary>
        /// Static helper to try and get the value from the dictionary.
        /// 
        /// Used so the value lookup can run against a buckets while a writer
        /// replaces the buckets.
        /// </summary>
        private bool Contains(Bucket[] buckets, AnalysisProxy/*!*/ key) {
            Debug.Assert(key != null);

            if (_count > 0 && buckets != null) {
                int hc = _comparer.GetHashCode(key) & Int32.MaxValue;

                return Contains(buckets, key, hc);
            }

            return false;
        }
예제 #23
0
 public bool Contains(AnalysisProxy item)
 {
     return(false);
 }
예제 #24
0
 public AnalysisSetTwoObject(AnalysisProxy value1, AnalysisProxy value2)
 {
     Value1 = value1;
     Value2 = value2;
 }
예제 #25
0
 /// <summary>
 /// Checks to see if the key exists in the dictionary.
 /// </summary>
 public bool Contains(AnalysisProxy key) {
     if (key == null) {
         throw new ArgumentNullException("key");
     }
     return Contains(_buckets, key);
 }
 private static string GetDescription(AnalysisProxy value) {
     var res = value.Value.ShortDescription;
     if (string.IsNullOrWhiteSpace(res)) {
         res = value.Value.GetType().FullName;
     }
     return res;
 }
예제 #27
0
 public IAnalysisSet Add(AnalysisProxy item, out bool wasChanged)
 {
     wasChanged = AddOne(item);
     return(this);
 }
예제 #28
0
        /// <summary>
        /// Add helper that works over a single set of buckets.  Used for
        /// both the normal add case as well as the resize case.
        /// </summary>
        private bool Add(Bucket[] buckets, AnalysisProxy key) {
            int hc = _comparer.GetHashCode(key) & Int32.MaxValue;

            return AddOne(buckets, key, hc);
        }
예제 #29
0
 public IAnalysisSet Add(AnalysisProxy item, out bool wasChanged) {
     wasChanged = AddOne(item);
     return this;
 }
예제 #30
0
        /// <summary>
        /// Adds a new item to the dictionary, replacing an existing one if it already exists.
        /// </summary>
        private bool AddOne(AnalysisProxy key) {
            if (key == null) {
                throw new ArgumentNullException("key");
            }
            if (key.IsAlive) {
                if (_buckets == null) {
                    Initialize();
                }

                if (Add(_buckets, key)) {
                    _count++;

                    CheckGrow();
                    return true;
                }
            }
            return false;
        }
예제 #31
0
        private bool Contains(Bucket[] buckets, AnalysisProxy key, int hc) {
            int index = hc % buckets.Length;
            int startIndex = index;
            do {
                var existingKey = buckets[index].Key;
                if (existingKey == null) {
                    break;
                } else {
                    if (Object.ReferenceEquals(key, existingKey) ||
                        (existingKey != _removed &&
                        buckets[index].HashCode == hc &&
                        _comparer.Equals(key, (AnalysisProxy)existingKey))) {

                        return true;
                    }
                }

                index = ProbeNext(buckets, index);
            } while (startIndex != index);

            return false;
        }
예제 #32
0
        /// <summary>
        /// Add helper which adds the given key/value (where the key is not null) with
        /// a pre-computed hash code.
        /// </summary>
        private bool AddOne(Bucket[] buckets, AnalysisProxy/*!*/ key, int hc) {
            Debug.Assert(key != null);

            Debug.Assert(_count < buckets.Length);
            int index = hc % buckets.Length;
            int startIndex = index;
            int addIndex = -1;

            for (; ; ) {
                Bucket cur = buckets[index];
                var existingKey = cur.Key;
                if (existingKey == null || existingKey == _removed || !existingKey.IsAlive) {
                    if (addIndex == -1) {
                        addIndex = index;
                    }
                    if (cur.Key == null) {
                        break;
                    }
                } else if (Object.ReferenceEquals(key, existingKey) ||
                    (cur.HashCode == hc && _comparer.Equals(key, (AnalysisProxy)existingKey))) {
                    return false;
                }

                index = ProbeNext(buckets, index);

                if (index == startIndex) {
                    break;
                }
            }

            if (buckets[addIndex].Key != null &&
                buckets[addIndex].Key != _removed && 
                !buckets[addIndex].Key.IsAlive) {
                _count--;
            }
            buckets[addIndex].HashCode = hc;
            Thread.MemoryBarrier();
            // we write the key last so that we can check for null to
            // determine if a bucket is available.
            buckets[addIndex].Key = key;            

            return true;
        }
예제 #33
0
 public AnalysisSetOneUnion(AnalysisProxy value, UnionComparer comparer)
 {
     Value     = value;
     _comparer = comparer;
 }
 public AnalysisProxy WrapAnalysisValue(AnalysisValue value) {
     var res = new AnalysisProxy(value);
     _proxies.Add(res);
     return res;
 }
예제 #35
0
 public bool Contains(AnalysisProxy item)
 {
     return(Comparer.Equals(Value1, item) || Comparer.Equals(Value2, item));
 }