/// <summary> /// Gets or sets the value associated with the given index. /// <para>The getter might return null if the item at that index is collected but not /// yet removed.</para> /// </summary> /// <param name="index"></param> /// <returns></returns> public T this[int index] { get { lock (SyncRoot) { var entry = _List[index]; if (!entry.IsAlive) { return(null); } var target = (T)entry.Target; return(target); } } set { if (value == null) { throw new ArgumentNullException("value"); } lock (SyncRoot) { var entry = new SoftReference(value) { GCCycles = this.GCCycles, GCTicks = this.GCTicks }; _List[index] = entry; } } }
/// <summary> /// Initializes a new instance, capturing the key's hash code, and using the /// inherited GC Listener properties as appropriate. /// </summary> /// <param name="owner"></param> /// <param name="key"></param> /// <param name="value"></param> internal Entry(SoftKeyDictionary <TKey, TValue> owner, TKey key, TValue value) { HashCode = owner._KeysComparer.GetHashCode(key); SoftKey = new SoftReference(key); SoftKey.GCCycles = owner.GCCycles; SoftKey.GCTicks = owner.GCTicks; Value = value; }
/// <summary> /// Initializes a new instance, capturing the key's hash code, and using the /// inherited GC Listener properties as appropriate. /// </summary> /// <param name="owner"></param> /// <param name="key"></param> internal Bucket(SoftKeyBucketDictionary <TKey, TValue> owner, TKey key) { HashCode = owner._KeysComparer.GetHashCode(key); SoftKey = new SoftReference(key); SoftKey.GCCycles = owner.GCCycles; SoftKey.GCTicks = owner.GCTicks; Values = new List <TValue>(); }
/// <summary> /// Adds the given value into the bucket associated with the given key. /// </summary> /// <param name="key"></param> /// <param name="value"></param> public void Add(TKey key, TValue value) { if (value == null) { throw new ArgumentNullException("value"); } lock (SyncRoot) { var entry = new SoftReference(value); entry.GCCycles = this.GCCycles; entry.GCTicks = this.GCTicks; _Dict.Add(key, entry); } }
/// <summary> /// Inserts the given target at the index on this collection. /// </summary> /// <param name="index"></param> /// <param name="item"></param> public void Insert(int index, T item) { if (item == null) { throw new ArgumentNullException("item"); } lock (SyncRoot) { var entry = new SoftReference(item); entry.GCCycles = this.GCCycles; entry.GCTicks = this.GCTicks; _List.Insert(index, entry); } }
/// <summary> /// Tries to get the value of the pair whose key is given. Returns true if such a /// valid pair was found, or false otherwise. /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> public bool TryGetValue(TKey key, out TValue value) { value = null; lock (SyncRoot) { SoftReference entry = null; _Dict.TryGetValue(key, out entry); if (entry == null) { return(false); } if (!entry.IsAlive) { return(false); } value = (TValue)entry.Target; return(value != null); } }
/// <summary> /// Whether this collection contains the given key, or not. /// </summary> /// <param name="key"></param> /// <returns></returns> public bool ContainsKey(TKey key) { lock (SyncRoot) { SoftReference entry = null; if (_Dict.TryGetValue(key, out entry)) { if (!entry.IsAlive) { return(false); } var value = entry.Target; if (value == null) { return(false); } return(true); } return(false); } }
/// <summary> /// Gets or sets the value associated with the given index. /// <para> /// The getter returns the requested value, or null if the key is found but the value /// has been collected.</para> /// <para> /// The setter throws an exception if the given key or value are null.</para> /// </summary> /// <param name="key"></param> /// <returns></returns> public TValue this[TKey key] { get { lock (SyncRoot) { SoftReference entry = null; _Dict.TryGetValue(key, out entry); if (entry == null) { throw new KeyNotFoundException("Key:'{0}'".FormatWith(key)); } if (!entry.IsAlive) { throw new KeyNotFoundException("Key:'{0}'".FormatWith(key)); } var value = (TValue)entry.Target; return(value); } } set { if (value == null) { throw new ArgumentNullException("value"); } lock (SyncRoot) { var entry = new SoftReference(value); entry.GCCycles = this.GCCycles; entry.GCTicks = this.GCTicks; _Dict[key] = entry; } } }
/// <summary> /// Adds the given range of items into this collection. /// </summary> /// <param name="range"></param> public void AddRange(IEnumerable <T> range) { if (range == null) { throw new ArgumentNullException("range"); } lock (SyncRoot) { int i = 0; foreach (var item in range) { if (item == null) { throw new ArgumentException("Item #{0} is null.".FormatWith(i)); } var entry = new SoftReference(item); entry.GCCycles = this.GCCycles; entry.GCTicks = this.GCTicks; _List.Add(entry); i++; } } }