34 namespace System.Collections.Concurrent
36 [DebuggerDisplay (
"Count={Count}")]
37 [DebuggerTypeProxy (typeof (CollectionDebuggerView<,>))]
39 ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>,
40 IDictionary, ICollection, IEnumerable
42 IEqualityComparer<TKey> comparer;
44 SplitOrderedList<TKey, KeyValuePair<TKey, TValue>> internalDictionary;
51 : this (collection, EqualityComparer<TKey>.Default)
57 this.comparer = comparer;
58 this.internalDictionary =
new SplitOrderedList<TKey, KeyValuePair<TKey, TValue>> (comparer);
61 public ConcurrentDictionary (IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
64 foreach (KeyValuePair<TKey, TValue> pair
in collection)
65 Add (pair.Key, pair.Value);
70 : this (EqualityComparer<TKey>.Default)
76 IEnumerable<KeyValuePair<TKey, TValue>> collection,
77 IEqualityComparer<TKey> comparer)
78 : this (collection, comparer)
90 void CheckKey (TKey key)
93 throw new ArgumentNullException (
"key");
96 void Add (TKey key, TValue value)
98 while (!TryAdd (key, value));
101 void IDictionary<TKey, TValue>.Add (TKey key, TValue value)
106 public bool TryAdd (TKey key, TValue value)
109 return internalDictionary.Insert (Hash (key), key, Make (key, value));
112 void ICollection<KeyValuePair<TKey,TValue>>.Add (KeyValuePair<TKey, TValue> pair)
114 Add (pair.Key, pair.Value);
117 public TValue
AddOrUpdate (TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)
120 if (addValueFactory == null)
121 throw new ArgumentNullException (
"addValueFactory");
122 if (updateValueFactory == null)
123 throw new ArgumentNullException (
"updateValueFactory");
124 return internalDictionary.InsertOrUpdate (Hash (key),
126 () => Make (key, addValueFactory (key)),
127 (e) => Make (key, updateValueFactory (key, e.Value))).Value;
130 public TValue
AddOrUpdate (TKey key, TValue addValue, Func<TKey, TValue, TValue> updateValueFactory)
132 return AddOrUpdate (key, (_) => addValue, updateValueFactory);
135 TValue AddOrUpdate (TKey key, TValue addValue, TValue updateValue)
138 return internalDictionary.InsertOrUpdate (Hash (key),
140 Make (key, addValue),
141 Make (key, updateValue)).Value;
144 TValue GetValue (TKey key)
147 if (!TryGetValue (key, out temp))
148 throw new KeyNotFoundException (key.ToString ());
155 KeyValuePair<TKey, TValue> pair;
156 bool result = internalDictionary.Find (Hash (key), key, out pair);
162 public bool TryUpdate (TKey key, TValue newValue, TValue comparisonValue)
165 return internalDictionary.CompareExchange (Hash (key), key, Make (key, newValue), (e) => e.Value.Equals (comparisonValue));
168 public TValue
this[TKey key] {
170 return GetValue (key);
173 AddOrUpdate (key, value, value);
177 public TValue
GetOrAdd (TKey key, Func<TKey, TValue> valueFactory)
180 return internalDictionary.InsertOrGet (Hash (key), key, Make (key,
default(TValue)), () => Make (key, valueFactory (key))).Value;
186 return internalDictionary.InsertOrGet (Hash (key), key, Make (key, value), null).Value;
192 KeyValuePair<TKey, TValue> data;
193 bool result = internalDictionary.Delete (Hash (key), key, out data);
198 bool Remove (TKey key)
202 return TryRemove (key, out dummy);
205 bool IDictionary<TKey, TValue>.Remove (TKey key)
210 bool ICollection<KeyValuePair<TKey,TValue>>.Remove (KeyValuePair<TKey,TValue> pair)
212 return Remove (pair.Key);
218 KeyValuePair<TKey, TValue> dummy;
219 return internalDictionary.Find (Hash (key), key, out dummy);
222 bool IDictionary.Contains (
object key)
227 return ContainsKey ((TKey)key);
230 void IDictionary.Remove (
object key)
238 object IDictionary.this [
object key]
242 throw new ArgumentException (
"key isn't of correct type",
"key");
244 return this[(TKey)key];
247 if (!(key is TKey) || !(value is TValue))
248 throw new ArgumentException (
"key or value aren't of correct type");
250 this[(TKey)key] = (TValue)value;
254 void IDictionary.Add (
object key,
object value)
256 if (!(key is TKey) || !(value is TValue))
257 throw new ArgumentException (
"key or value aren't of correct type");
259 Add ((TKey)key, (TValue)value);
262 bool ICollection<KeyValuePair<TKey,TValue>>.Contains (KeyValuePair<TKey, TValue> pair)
264 return ContainsKey (pair.Key);
272 return new List<KeyValuePair<TKey,TValue>> (
this).ToArray ();
278 internalDictionary =
new SplitOrderedList<TKey, KeyValuePair<TKey, TValue>> (comparer);
283 return internalDictionary.Count;
287 public bool IsEmpty {
293 bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly {
299 bool IDictionary.IsReadOnly {
305 public ICollection<TKey> Keys {
307 return GetPart<TKey> ((kvp) => kvp.Key);
311 public ICollection<TValue> Values {
313 return GetPart<TValue> ((kvp) => kvp.Value);
317 ICollection IDictionary.Keys {
319 return (ICollection)Keys;
323 ICollection IDictionary.Values {
325 return (ICollection)Values;
329 ICollection<T> GetPart<T> (Func<KeyValuePair<TKey, TValue>, T> extractor)
331 List<T> temp =
new List<T> ();
333 foreach (KeyValuePair<TKey, TValue> kvp
in this)
334 temp.Add (extractor (kvp));
336 return temp.AsReadOnly ();
339 void ICollection.CopyTo (Array array,
int startIndex)
341 KeyValuePair<TKey, TValue>[] arr = array as KeyValuePair<TKey, TValue>[];
345 CopyTo (arr, startIndex, Count);
348 void CopyTo (KeyValuePair<TKey, TValue>[] array,
int startIndex)
350 CopyTo (array, startIndex, Count);
353 void ICollection<KeyValuePair<TKey, TValue>>.CopyTo (KeyValuePair<TKey, TValue>[] array,
int startIndex)
355 CopyTo (array, startIndex);
358 void CopyTo (KeyValuePair<TKey, TValue>[] array,
int startIndex,
int num)
360 foreach (var kvp
in this) {
361 array [startIndex++] = kvp;
370 return GetEnumeratorInternal ();
373 IEnumerator IEnumerable.GetEnumerator ()
375 return (IEnumerator)GetEnumeratorInternal ();
378 IEnumerator<KeyValuePair<TKey, TValue>> GetEnumeratorInternal ()
380 return internalDictionary.GetEnumerator ();
383 IDictionaryEnumerator IDictionary.GetEnumerator ()
385 return new ConcurrentDictionaryEnumerator (GetEnumeratorInternal ());
388 class ConcurrentDictionaryEnumerator : IDictionaryEnumerator
390 IEnumerator<KeyValuePair<TKey, TValue>> internalEnum;
392 public ConcurrentDictionaryEnumerator (IEnumerator<KeyValuePair<TKey, TValue>> internalEnum)
394 this.internalEnum = internalEnum;
397 public bool MoveNext ()
399 return internalEnum.MoveNext ();
404 internalEnum.Reset ();
407 public object Current {
413 public DictionaryEntry Entry {
415 KeyValuePair<TKey, TValue> current = internalEnum.Current;
416 return new DictionaryEntry (current.Key, current.Value);
422 return internalEnum.Current.Key;
426 public object Value {
428 return internalEnum.Current.Value;
433 object ICollection.SyncRoot {
439 bool IDictionary.IsFixedSize {
445 bool ICollection.IsSynchronized {
449 static KeyValuePair<U, V> Make<U, V> (U key, V value)
451 return new KeyValuePair<U, V> (key, value);
456 return (uint)comparer.GetHashCode (key);
bool TryAdd(TKey key, TValue value)
ConcurrentDictionary(int concurrencyLevel, int capacity, IEqualityComparer< TKey > comparer)
bool TryRemove(TKey key, out TValue value)
bool TryGetValue(TKey key, out TValue value)
TValue AddOrUpdate(TKey key, TValue addValue, Func< TKey, TValue, TValue > updateValueFactory)
TValue GetOrAdd(TKey key, TValue value)
KeyValuePair< TKey, TValue >[] ToArray()
ConcurrentDictionary(IEqualityComparer< TKey > comparer)
TValue GetOrAdd(TKey key, Func< TKey, TValue > valueFactory)
bool ContainsKey(TKey key)
ConcurrentDictionary(int concurrencyLevel, int capacity)
IEnumerator< KeyValuePair< TKey, TValue > > GetEnumerator()
TValue AddOrUpdate(TKey key, Func< TKey, TValue > addValueFactory, Func< TKey, TValue, TValue > updateValueFactory)
ConcurrentDictionary(IEnumerable< KeyValuePair< TKey, TValue >> collection, IEqualityComparer< TKey > comparer)
bool TryUpdate(TKey key, TValue newValue, TValue comparisonValue)
ConcurrentDictionary(int concurrencyLevel, IEnumerable< KeyValuePair< TKey, TValue >> collection, IEqualityComparer< TKey > comparer)
ConcurrentDictionary(IEnumerable< KeyValuePair< TKey, TValue >> collection)