public AnalysisSetTwoUnion(AnalysisProxy value1, AnalysisProxy value2, UnionComparer comparer) { Debug.Assert(!comparer.Equals(value1, value2)); Value1 = value1; Value2 = value2; _comparer = comparer; }
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)); } }
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); }
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)); }
/// <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); }
public IAnalysisSet Add(AnalysisProxy item, out bool wasChanged) { if (!item.IsAlive) { wasChanged = false; return(this); } wasChanged = true; return(item); }
public IAnalysisSet Add(AnalysisProxy item, out bool wasChanged) { if (!item.IsAlive) { wasChanged = false; return(this); } wasChanged = true; return(new AnalysisSetOneUnion(item, Comparer)); }
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; }
/// <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); }
/// <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); }
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); }
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)); }
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"); } } }
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); }
/// <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); }
/// <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); }
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; }
public bool Contains(AnalysisProxy item) { return(ObjectComparer.Instance.Equals(Value1, item) || ObjectComparer.Instance.Equals(Value2, item)); }
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); } } }
/// <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; }
public bool Contains(AnalysisProxy item) { return(false); }
public AnalysisSetTwoObject(AnalysisProxy value1, AnalysisProxy value2) { Value1 = value1; Value2 = value2; }
/// <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; }
public IAnalysisSet Add(AnalysisProxy item, out bool wasChanged) { wasChanged = AddOne(item); return(this); }
/// <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); }
public IAnalysisSet Add(AnalysisProxy item, out bool wasChanged) { wasChanged = AddOne(item); return this; }
/// <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; }
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; }
/// <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; }
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; }
public bool Contains(AnalysisProxy item) { return(Comparer.Equals(Value1, item) || Comparer.Equals(Value2, item)); }