bool IEqualityComparer.Equals(object x, object y) { if (x == null) { return(y == null); } if (y != null && x.GetHashCode() == y.GetHashCode()) { EqualityWeakReference wX = x as EqualityWeakReference; EqualityWeakReference wY = y as EqualityWeakReference; //Both WeakReferences are gc'd and they both had the same hash //Since this is only used in Weak Hash table races are not really an issue. if (wX != null && wY != null && !wY.IsAlive && !wX.IsAlive) { return(true); } if (wX != null) { x = wX.Target; } if (wY != null) { y = wY.Target; } return(object.ReferenceEquals(x, y)); } return(false); }
private void WrapKey(ref object key) { if (key != null && !key.GetType().IsValueType) { key = new EqualityWeakReference(key); } }
/// <devdoc> /// This method checks to see if it is necessary to /// scavenge keys, and if it is it performs a scan /// of all keys to see which ones are no longer valid. /// To determine if we need to scavenge keys we need to /// try to track the current GC memory. Our rule of /// thumb is that if GC memory is decreasing and our /// key count is constant we need to scavenge. We /// will need to see if this is too often for extreme /// use cases like the CompactFramework (they add /// custom type data for every object at design time). /// </devdoc> private void ScavengeKeys() { int hashCount = Count; if (hashCount == 0) { return; } if (_lastHashCount == 0) { _lastHashCount = hashCount; return; } long globalMem = GC.GetTotalMemory(false); if (_lastGlobalMem == 0) { _lastGlobalMem = globalMem; return; } float memDelta = (float)(globalMem - _lastGlobalMem) / (float)_lastGlobalMem; float hashDelta = (float)(hashCount - _lastHashCount) / (float)_lastHashCount; if (memDelta < 0 && hashDelta >= 0) { // Perform a scavenge through our keys, looking // for dead references. ArrayList cleanupList = null; foreach (object o in Keys) { EqualityWeakReference wr = o as EqualityWeakReference; if (wr != null && !wr.IsAlive) { if (cleanupList == null) { cleanupList = new ArrayList(); } cleanupList.Add(wr); } } if (cleanupList != null) { foreach (object o in cleanupList) { Remove(o); } } } _lastGlobalMem = globalMem; _lastHashCount = hashCount; }
bool IEqualityComparer.Equals(object x, object y) { if (x == null) { return(y == null); } if (y != null && x.GetHashCode() == y.GetHashCode()) { EqualityWeakReference wX = x as EqualityWeakReference; EqualityWeakReference wY = y as EqualityWeakReference; if (wX != null) { if (!wX.IsAlive) { return(false); } x = wX.Target; } if (wY != null) { if (!wY.IsAlive) { return(false); } y = wY.Target; } return(object.ReferenceEquals(x, y)); } return(false); }
public object UnwrapKey(object key) { EqualityWeakReference keyRef = key as EqualityWeakReference; return((keyRef != null) ? keyRef.Target : key); }