/// <summary> /// Either get the existing value or create a /// new one in a single operation. /// </summary> /// <param name="key">The key.</param> /// <param name="value">The value.</param> private void AddUnique(DDIndex key, WeakReference <DD> value) { int hashCode = key.GetHashCode() & 0x7FFFFFFF; int targetBucket = hashCode & this.mask; int index = this.Count; this.Count++; this.entries[index] = new Entry { Next = this.buckets[targetBucket], Key = key, Value = value }; this.buckets[targetBucket] = index; }
/// <summary> /// Either get the existing value or create a /// new one in a single operation. /// </summary> /// <param name="key">The key.</param> /// <returns>The value, possibly freshly created.</returns> public DD GetOrAdd(DDIndex key) { int hashCode = key.GetHashCode() & 0x7FFFFFFF; int targetBucket = hashCode & this.mask; for (int i = this.buckets[targetBucket]; i >= 0; i = this.entries[i].Next) { if (this.entries[i].Key.Equals(key)) { var wref = this.entries[i].Value; if (!wref.TryGetTarget(out DD target)) { target = new DD(this.manager.Uid, key); wref.SetTarget(target); } return(target); } } int index; if (this.Count == this.entries.Length) { this.Resize(); targetBucket = hashCode & this.mask; } index = this.Count; this.Count++; var dd = new DD(this.manager.Uid, key); var value = new WeakReference <DD>(dd); this.entries[index] = new Entry { Next = this.buckets[targetBucket], Key = key, Value = value }; this.buckets[targetBucket] = index; return(dd); }