#if MONO
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Threading;
namespace System.Collections.Concurrent
{
/// <summary>Represents a thread-safe collection of key-value pairs that can be accessed by multiple threads concurrently. </summary>
/// <typeparam name="TKey">The type of the keys in the dictionary.</typeparam>
/// <typeparam name="TValue">The type of the values in the dictionary.</typeparam>
[__DynamicallyInvokable, DebuggerDisplay("Count = {Count}"), ComVisible(false)]
[HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
[Serializable]
public class ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable
{
private class Tables
{
internal readonly ConcurrentDictionary<TKey, TValue>.Node[] m_buckets;
internal readonly object[] m_locks;
internal volatile int[] m_countPerLock;
internal Tables(ConcurrentDictionary<TKey, TValue>.Node[] buckets, object[] locks, int[] countPerLock)
{
this.m_buckets = buckets;
this.m_locks = locks;
this.m_countPerLock = countPerLock;
}
}
private class Node
{
internal TKey m_key;
internal TValue m_value;
internal volatile ConcurrentDictionary<TKey, TValue>.Node m_next;
internal int m_hashcode;
internal Node(TKey key, TValue value, int hashcode, ConcurrentDictionary<TKey, TValue>.Node next)
{
this.m_key = key;
this.m_value = value;
this.m_next = next;
this.m_hashcode = hashcode;
}
}
private class DictionaryEnumerator : IDictionaryEnumerator, IEnumerator
{
private IEnumerator<KeyValuePair<TKey, TValue>> m_enumerator;
public DictionaryEntry Entry
{
get
{
KeyValuePair<TKey, TValue> current = this.m_enumerator.Current;
object arg_30_0 = current.Key;
KeyValuePair<TKey, TValue> current2 = this.m_enumerator.Current;
return new DictionaryEntry(arg_30_0, current2.Value);
}
}
public object Key
{
get
{
KeyValuePair<TKey, TValue> current = this.m_enumerator.Current;
return current.Key;
}
}
public object Value
{
get
{
KeyValuePair<TKey, TValue> current = this.m_enumerator.Current;
return current.Value;
}
}
public object Current
{
get
{
return this.Entry;
}
}
internal DictionaryEnumerator(ConcurrentDictionary<TKey, TValue> dictionary)
{
this.m_enumerator = dictionary.GetEnumerator();
}
public bool MoveNext()
{
return this.m_enumerator.MoveNext();
}
public void Reset()
{
this.m_enumerator.Reset();
}
}
[NonSerialized]
private volatile ConcurrentDictionary<TKey, TValue>.Tables m_tables;
private readonly IEqualityComparer<TKey> m_comparer;
[NonSerialized]
private readonly bool m_growLockArray;
[NonSerialized]
private int m_budget;
private KeyValuePair<TKey, TValue>[] m_serializationArray;
private int m_serializationConcurrencyLevel;
private int m_serializationCapacity;
private static readonly bool s_isValueWriteAtomic = ConcurrentDictionary<TKey, TValue>.IsValueWriteAtomic();
private const int DEFAULT_CONCURRENCY_MULTIPLIER = 4;
private const int DEFAULT_CAPACITY = 31;
private const int MAX_LOCK_NUMBER = 1024;
/// <summary>Gets or sets the value associated with the specified key.</summary>
/// <returns>Returns the Value property of the <see cref="T:System.Collections.Generic.KeyValuePair`2" /> at the specified index.</returns>
/// <param name="key">The key of the value to get or set.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="key" /> is a null reference (Nothing in Visual Basic).</exception>
/// <exception cref="T:System.Collections.Generic.KeyNotFoundException">The property is retrieved and <paramref name="key" /> does not exist in the collection.</exception>
[__DynamicallyInvokable]
public TValue this[TKey key]
{
[__DynamicallyInvokable]
get
{
TValue result;
if (!this.TryGetValue(key, out result))
{
throw new KeyNotFoundException();
}
return result;
}
[__DynamicallyInvokable]
set
{
if (key == null)
{
throw new ArgumentNullException("key");
}
TValue tValue;
this.TryAddInternal(key, value, true, true, out tValue);
}
}
/// <summary>Gets the number of key/value pairs contained in the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</summary>
/// <returns>The number of key/value pairs contained in the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</returns>
/// <exception cref="T:System.OverflowException">The dictionary already contains the maximum number of elements, <see cref="F:System.Int32.MaxValue" />.</exception>
[__DynamicallyInvokable]
public int Count
{
[__DynamicallyInvokable]
get
{
int num = 0;
int toExclusive = 0;
try
{
this.AcquireAllLocks(ref toExclusive);
for (int i = 0; i < this.m_tables.m_countPerLock.Length; i++)
{
num += this.m_tables.m_countPerLock[i];
}
}
finally
{
this.ReleaseLocks(0, toExclusive);
}
return num;
}
}
/// <summary>Gets a value that indicates whether the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> is empty.</summary>
/// <returns>true if the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> is empty; otherwise, false.</returns>
[__DynamicallyInvokable]
public bool IsEmpty
{
[__DynamicallyInvokable]
get
{
int toExclusive = 0;
try
{
this.AcquireAllLocks(ref toExclusive);
for (int i = 0; i < this.m_tables.m_countPerLock.Length; i++)
{
if (this.m_tables.m_countPerLock[i] != 0)
{
return false;
}
}
}
finally
{
this.ReleaseLocks(0, toExclusive);
}
return true;
}
}
/// <summary>Gets a collection containing the keys in the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}" />.</summary>
/// <returns>An <see cref="T:System.Collections.Generic.ICollection{TKey}" /> containing the keys in the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}" />.</returns>
[__DynamicallyInvokable]
public ICollection<TKey> Keys
{
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
get
{
return this.GetKeys();
}
}
/// <summary>Gets a collection containing the values in the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}" />.</summary>
/// <returns>An <see cref="T:System.Collections.Generic.ICollection{TValue}" /> containing the values in the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}" />.</returns>
[__DynamicallyInvokable]
public ICollection<TValue> Values
{
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
get
{
return this.GetValues();
}
}
[__DynamicallyInvokable]
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
{
[__DynamicallyInvokable]
get
{
return false;
}
}
/// <summary>Gets a value indicating whether the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" /> has a fixed size.</summary>
/// <returns>true if the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" /> has a fixed size; otherwise, false. For <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" />, this property always returns false.</returns>
[__DynamicallyInvokable]
bool IDictionary.IsFixedSize
{
[__DynamicallyInvokable]
get
{
return false;
}
}
/// <summary>Gets a value indicating whether the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" /> is read-only.</summary>
/// <returns>true if the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" /> is read-only; otherwise, false. For <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" />, this property always returns false.</returns>
[__DynamicallyInvokable]
bool IDictionary.IsReadOnly
{
[__DynamicallyInvokable]
get
{
return false;
}
}
/// <summary>Gets an <see cref="T:System.Collections.ICollection" /> containing the keys of the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" />.</summary>
/// <returns>An <see cref="T:System.Collections.ICollection" /> containing the keys of the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" />.</returns>
[__DynamicallyInvokable]
ICollection IDictionary.Keys
{
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
get
{
return this.GetKeys();
}
}
/// <summary>Gets an <see cref="T:System.Collections.ICollection" /> containing the values in the <see cref="T:System.Collections.IDictionary" />.</summary>
/// <returns>An <see cref="T:System.Collections.ICollection" /> containing the values in the <see cref="T:System.Collections.IDictionary" />.</returns>
[__DynamicallyInvokable]
ICollection IDictionary.Values
{
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
get
{
return this.GetValues();
}
}
/// <summary>Gets or sets the value associated with the specified key.</summary>
/// <returns>The value associated with the specified key, or a null reference (Nothing in Visual Basic) if <paramref name="key" /> is not in the dictionary or <paramref name="key" /> is of a type that is not assignable to the key type of the <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" />.</returns>
/// <param name="key">The key of the value to get or set.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="key" /> is a null reference (Nothing in Visual Basic).</exception>
/// <exception cref="T:System.ArgumentException">A value is being assigned, and <paramref name="key" /> is of a type that is not assignable to the key type of the <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" />. -or- A value is being assigned, and <paramref name="key" /> is of a type that is not assignable to the value type of the <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" /></exception>
[__DynamicallyInvokable]
object IDictionary.this[object key]
{
[__DynamicallyInvokable]
get
{
if (key == null)
{
throw new ArgumentNullException("key");
}
TValue tValue;
if (key is TKey && this.TryGetValue((TKey)((object)key), out tValue))
{
return tValue;
}
return null;
}
[__DynamicallyInvokable]
set
{
if (key == null)
{
throw new ArgumentNullException("key");
}
if (!(key is TKey))
{
throw new ArgumentException(this.GetResource("ConcurrentDictionary_TypeOfKeyIncorrect"));
}
if (!(value is TValue))
{
throw new ArgumentException(this.GetResource("ConcurrentDictionary_TypeOfValueIncorrect"));
}
this[(TKey)((object)key)] = (TValue)((object)value);
}
}
/// <summary>Gets a value indicating whether access to the <see cref="T:System.Collections.ICollection" /> is synchronized with the SyncRoot.</summary>
/// <returns>true if access to the <see cref="T:System.Collections.ICollection" /> is synchronized (thread safe); otherwise, false. For <see cref="T:System.Collections.Concurrent.ConcurrentDictionary{TKey,TValue}" />, this property always returns false.</returns>
[__DynamicallyInvokable]
bool ICollection.IsSynchronized
{
[__DynamicallyInvokable]
get
{
return false;
}
}
/// <summary>Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection" />. This property is not supported.</summary>
/// <returns>Always returns null.</returns>
/// <exception cref="T:System.NotSupportedException">The SyncRoot property is not supported.</exception>
[__DynamicallyInvokable]
object ICollection.SyncRoot
{
[__DynamicallyInvokable]
get
{
throw new NotSupportedException("ConcurrentCollection_SyncRoot_NotSupported");
}
}
private static int DefaultConcurrencyLevel
{
get
{
return 4 * PlatformHelper.ProcessorCount;
}
}
private static bool IsValueWriteAtomic()
{
Type typeFromHandle = typeof(TValue);
bool flag = typeFromHandle.IsClass || typeFromHandle == typeof(bool) || typeFromHandle == typeof(char) || typeFromHandle == typeof(byte) || typeFromHandle == typeof(sbyte) || typeFromHandle == typeof(short) || typeFromHandle == typeof(ushort) || typeFromHandle == typeof(int) || typeFromHandle == typeof(uint) || typeFromHandle == typeof(float);
if (!flag && IntPtr.Size == 8)
{
flag |= (typeFromHandle == typeof(double) || typeFromHandle == typeof(long));
}
return flag;
}
/// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that is empty, has the default concurrency level, has the default initial capacity, and uses the default comparer for the key type.</summary>
[__DynamicallyInvokable]
public ConcurrentDictionary()
: this(ConcurrentDictionary<TKey, TValue>.DefaultConcurrencyLevel, 31, true, EqualityComparer<TKey>.Default)
{
}
/// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that is empty, has the specified concurrency level and capacity, and uses the default comparer for the key type.</summary>
/// <param name="concurrencyLevel">The estimated number of threads that will update the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> concurrently.</param>
/// <param name="capacity">The initial number of elements that the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> can contain.</param>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="concurrencyLevel" /> is less than 1.-or-<paramref name="capacity" /> is less than 0.</exception>
[__DynamicallyInvokable]
public ConcurrentDictionary(int concurrencyLevel, int capacity)
: this(concurrencyLevel, capacity, false, EqualityComparer<TKey>.Default)
{
}
/// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that contains elements copied from the specified <see cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}" />, has the default concurrency level, has the default initial capacity, and uses the default comparer for the key type.</summary>
/// <param name="collection">The <see cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}" /> whose elements are copied to the new <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="collection" /> or any of its keys is a null reference (Nothing in Visual Basic)</exception>
/// <exception cref="T:System.ArgumentException">
/// <paramref name="collection" /> contains one or more duplicate keys.</exception>
[__DynamicallyInvokable]
public ConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection)
: this(collection, EqualityComparer<TKey>.Default)
{
}
/// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that is empty, has the default concurrency level and capacity, and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" />.</summary>
/// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" /> implementation to use when comparing keys.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="comparer" /> is a null reference (Nothing in Visual Basic).</exception>
[__DynamicallyInvokable]
public ConcurrentDictionary(IEqualityComparer<TKey> comparer)
: this(ConcurrentDictionary<TKey, TValue>.DefaultConcurrencyLevel, 31, true, comparer)
{
}
/// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that contains elements copied from the specified <see cref="T:System.Collections.IEnumerable" />, has the default concurrency level, has the default initial capacity, and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" />.</summary>
/// <param name="collection">The <see cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}" /> whose elements are copied to the new <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</param>
/// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" /> implementation to use when comparing keys.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="collection" /> is a null reference (Nothing in Visual Basic). -or- <paramref name="comparer" /> is a null reference (Nothing in Visual Basic).</exception>
[__DynamicallyInvokable]
public ConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
: this(comparer)
{
if (collection == null)
{
throw new ArgumentNullException("collection");
}
this.InitializeFromCollection(collection);
}
/// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that contains elements copied from the specified <see cref="T:System.Collections.IEnumerable" />, and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" />.</summary>
/// <param name="concurrencyLevel">The estimated number of threads that will update the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> concurrently.</param>
/// <param name="collection">The <see cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}" /> whose elements are copied to the new <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</param>
/// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" /> implementation to use when comparing keys.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="collection" /> is a null reference (Nothing in Visual Basic). -or- <paramref name="comparer" /> is a null reference (Nothing in Visual Basic).</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="concurrencyLevel" /> is less than 1.</exception>
/// <exception cref="T:System.ArgumentException">
/// <paramref name="collection" /> contains one or more duplicate keys.</exception>
[__DynamicallyInvokable]
public ConcurrentDictionary(int concurrencyLevel, IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
: this(concurrencyLevel, 31, false, comparer)
{
if (collection == null)
{
throw new ArgumentNullException("collection");
}
if (comparer == null)
{
throw new ArgumentNullException("comparer");
}
this.InitializeFromCollection(collection);
}
private void InitializeFromCollection(IEnumerable<KeyValuePair<TKey, TValue>> collection)
{
foreach (KeyValuePair<TKey, TValue> current in collection)
{
if (current.Key == null)
{
throw new ArgumentNullException("key");
}
TValue tValue;
if (!this.TryAddInternal(current.Key, current.Value, false, false, out tValue))
{
throw new ArgumentException(this.GetResource("ConcurrentDictionary_SourceContainsDuplicateKeys"));
}
}
if (this.m_budget == 0)
{
this.m_budget = this.m_tables.m_buckets.Length / this.m_tables.m_locks.Length;
}
}
/// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that is empty, has the specified concurrency level, has the specified initial capacity, and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" />.</summary>
/// <param name="concurrencyLevel">The estimated number of threads that will update the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> concurrently.</param>
/// <param name="capacity">The initial number of elements that the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> can contain.</param>
/// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" /> implementation to use when comparing keys.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="comparer" /> is a null reference (Nothing in Visual Basic).</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="concurrencyLevel" /> is less than 1. -or- <paramref name="capacity" /> is less than 0.</exception>
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public ConcurrentDictionary(int concurrencyLevel, int capacity, IEqualityComparer<TKey> comparer)
: this(concurrencyLevel, capacity, false, comparer)
{
}
internal ConcurrentDictionary(int concurrencyLevel, int capacity, bool growLockArray, IEqualityComparer<TKey> comparer)
{
if (concurrencyLevel < 1)
{
throw new ArgumentOutOfRangeException("concurrencyLevel", this.GetResource("ConcurrentDictionary_ConcurrencyLevelMustBePositive"));
}
if (capacity < 0)
{
throw new ArgumentOutOfRangeException("capacity", this.GetResource("ConcurrentDictionary_CapacityMustNotBeNegative"));
}
if (comparer == null)
{
throw new ArgumentNullException("comparer");
}
if (capacity < concurrencyLevel)
{
capacity = concurrencyLevel;
}
object[] array = new object[concurrencyLevel];
for (int i = 0; i < array.Length; i++)
{
array[i] = new object();
}
int[] countPerLock = new int[array.Length];
ConcurrentDictionary<TKey, TValue>.Node[] array2 = new ConcurrentDictionary<TKey, TValue>.Node[capacity];
this.m_tables = new ConcurrentDictionary<TKey, TValue>.Tables(array2, array, countPerLock);
this.m_comparer = comparer;
this.m_growLockArray = growLockArray;
this.m_budget = array2.Length / array.Length;
}
/// <summary>Attempts to add the specified key and value to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</summary>
/// <returns>true if the key/value pair was added to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> successfully. If the key already exists, this method returns false.</returns>
/// <param name="key">The key of the element to add.</param>
/// <param name="value">The value of the element to add. The value can be a null reference (Nothing in Visual Basic) for reference types.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="key" /> is null reference (Nothing in Visual Basic).</exception>
/// <exception cref="T:System.OverflowException">The dictionary already contains the maximum number of elements, <see cref="F:System.Int32.MaxValue" />.</exception>
[__DynamicallyInvokable]
public bool TryAdd(TKey key, TValue value)
{
if (key == null)
{
throw new ArgumentNullException("key");
}
TValue tValue;
Lines 1–500 of 1413. Load more
#if MONO using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Runtime; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Security.Permissions; using System.Threading; namespace System.Collections.Concurrent { /// <summary>Represents a thread-safe collection of key-value pairs that can be accessed by multiple threads concurrently. </summary> /// <typeparam name="TKey">The type of the keys in the dictionary.</typeparam> /// <typeparam name="TValue">The type of the values in the dictionary.</typeparam> [__DynamicallyInvokable, DebuggerDisplay("Count = {Count}"), ComVisible(false)] [HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)] [Serializable] public class ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable { private class Tables { internal readonly ConcurrentDictionary<TKey, TValue>.Node[] m_buckets; internal readonly object[] m_locks; internal volatile int[] m_countPerLock; internal Tables(ConcurrentDictionary<TKey, TValue>.Node[] buckets, object[] locks, int[] countPerLock) { this.m_buckets = buckets; this.m_locks = locks; this.m_countPerLock = countPerLock; } } private class Node { internal TKey m_key; internal TValue m_value; internal volatile ConcurrentDictionary<TKey, TValue>.Node m_next; internal int m_hashcode; internal Node(TKey key, TValue value, int hashcode, ConcurrentDictionary<TKey, TValue>.Node next) { this.m_key = key; this.m_value = value; this.m_next = next; this.m_hashcode = hashcode; } } private class DictionaryEnumerator : IDictionaryEnumerator, IEnumerator { private IEnumerator<KeyValuePair<TKey, TValue>> m_enumerator; public DictionaryEntry Entry { get { KeyValuePair<TKey, TValue> current = this.m_enumerator.Current; object arg_30_0 = current.Key; KeyValuePair<TKey, TValue> current2 = this.m_enumerator.Current; return new DictionaryEntry(arg_30_0, current2.Value); } } public object Key { get { KeyValuePair<TKey, TValue> current = this.m_enumerator.Current; return current.Key; } } public object Value { get { KeyValuePair<TKey, TValue> current = this.m_enumerator.Current; return current.Value; } } public object Current { get { return this.Entry; } } internal DictionaryEnumerator(ConcurrentDictionary<TKey, TValue> dictionary) { this.m_enumerator = dictionary.GetEnumerator(); } public bool MoveNext() { return this.m_enumerator.MoveNext(); } public void Reset() { this.m_enumerator.Reset(); } } [NonSerialized] private volatile ConcurrentDictionary<TKey, TValue>.Tables m_tables; private readonly IEqualityComparer<TKey> m_comparer; [NonSerialized] private readonly bool m_growLockArray; [NonSerialized] private int m_budget; private KeyValuePair<TKey, TValue>[] m_serializationArray; private int m_serializationConcurrencyLevel; private int m_serializationCapacity; private static readonly bool s_isValueWriteAtomic = ConcurrentDictionary<TKey, TValue>.IsValueWriteAtomic(); private const int DEFAULT_CONCURRENCY_MULTIPLIER = 4; private const int DEFAULT_CAPACITY = 31; private const int MAX_LOCK_NUMBER = 1024; /// <summary>Gets or sets the value associated with the specified key.</summary> /// <returns>Returns the Value property of the <see cref="T:System.Collections.Generic.KeyValuePair`2" /> at the specified index.</returns> /// <param name="key">The key of the value to get or set.</param> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="key" /> is a null reference (Nothing in Visual Basic).</exception> /// <exception cref="T:System.Collections.Generic.KeyNotFoundException">The property is retrieved and <paramref name="key" /> does not exist in the collection.</exception> [__DynamicallyInvokable] public TValue this[TKey key] { [__DynamicallyInvokable] get { TValue result; if (!this.TryGetValue(key, out result)) { throw new KeyNotFoundException(); } return result; } [__DynamicallyInvokable] set { if (key == null) { throw new ArgumentNullException("key"); } TValue tValue; this.TryAddInternal(key, value, true, true, out tValue); } } /// <summary>Gets the number of key/value pairs contained in the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</summary> /// <returns>The number of key/value pairs contained in the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</returns> /// <exception cref="T:System.OverflowException">The dictionary already contains the maximum number of elements, <see cref="F:System.Int32.MaxValue" />.</exception> [__DynamicallyInvokable] public int Count { [__DynamicallyInvokable] get { int num = 0; int toExclusive = 0; try { this.AcquireAllLocks(ref toExclusive); for (int i = 0; i < this.m_tables.m_countPerLock.Length; i++) { num += this.m_tables.m_countPerLock[i]; } } finally { this.ReleaseLocks(0, toExclusive); } return num; } } /// <summary>Gets a value that indicates whether the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> is empty.</summary> /// <returns>true if the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> is empty; otherwise, false.</returns> [__DynamicallyInvokable] public bool IsEmpty { [__DynamicallyInvokable] get { int toExclusive = 0; try { this.AcquireAllLocks(ref toExclusive); for (int i = 0; i < this.m_tables.m_countPerLock.Length; i++) { if (this.m_tables.m_countPerLock[i] != 0) { return false; } } } finally { this.ReleaseLocks(0, toExclusive); } return true; } } /// <summary>Gets a collection containing the keys in the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}" />.</summary> /// <returns>An <see cref="T:System.Collections.Generic.ICollection{TKey}" /> containing the keys in the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}" />.</returns> [__DynamicallyInvokable] public ICollection<TKey> Keys { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get { return this.GetKeys(); } } /// <summary>Gets a collection containing the values in the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}" />.</summary> /// <returns>An <see cref="T:System.Collections.Generic.ICollection{TValue}" /> containing the values in the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}" />.</returns> [__DynamicallyInvokable] public ICollection<TValue> Values { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get { return this.GetValues(); } } [__DynamicallyInvokable] bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly { [__DynamicallyInvokable] get { return false; } } /// <summary>Gets a value indicating whether the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" /> has a fixed size.</summary> /// <returns>true if the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" /> has a fixed size; otherwise, false. For <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" />, this property always returns false.</returns> [__DynamicallyInvokable] bool IDictionary.IsFixedSize { [__DynamicallyInvokable] get { return false; } } /// <summary>Gets a value indicating whether the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" /> is read-only.</summary> /// <returns>true if the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" /> is read-only; otherwise, false. For <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" />, this property always returns false.</returns> [__DynamicallyInvokable] bool IDictionary.IsReadOnly { [__DynamicallyInvokable] get { return false; } } /// <summary>Gets an <see cref="T:System.Collections.ICollection" /> containing the keys of the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" />.</summary> /// <returns>An <see cref="T:System.Collections.ICollection" /> containing the keys of the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" />.</returns> [__DynamicallyInvokable] ICollection IDictionary.Keys { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get { return this.GetKeys(); } } /// <summary>Gets an <see cref="T:System.Collections.ICollection" /> containing the values in the <see cref="T:System.Collections.IDictionary" />.</summary> /// <returns>An <see cref="T:System.Collections.ICollection" /> containing the values in the <see cref="T:System.Collections.IDictionary" />.</returns> [__DynamicallyInvokable] ICollection IDictionary.Values { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get { return this.GetValues(); } } /// <summary>Gets or sets the value associated with the specified key.</summary> /// <returns>The value associated with the specified key, or a null reference (Nothing in Visual Basic) if <paramref name="key" /> is not in the dictionary or <paramref name="key" /> is of a type that is not assignable to the key type of the <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" />.</returns> /// <param name="key">The key of the value to get or set.</param> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="key" /> is a null reference (Nothing in Visual Basic).</exception> /// <exception cref="T:System.ArgumentException">A value is being assigned, and <paramref name="key" /> is of a type that is not assignable to the key type of the <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" />. -or- A value is being assigned, and <paramref name="key" /> is of a type that is not assignable to the value type of the <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" /></exception> [__DynamicallyInvokable] object IDictionary.this[object key] { [__DynamicallyInvokable] get { if (key == null) { throw new ArgumentNullException("key"); } TValue tValue; if (key is TKey && this.TryGetValue((TKey)((object)key), out tValue)) { return tValue; } return null; } [__DynamicallyInvokable] set { if (key == null) { throw new ArgumentNullException("key"); } if (!(key is TKey)) { throw new ArgumentException(this.GetResource("ConcurrentDictionary_TypeOfKeyIncorrect")); } if (!(value is TValue)) { throw new ArgumentException(this.GetResource("ConcurrentDictionary_TypeOfValueIncorrect")); } this[(TKey)((object)key)] = (TValue)((object)value); } } /// <summary>Gets a value indicating whether access to the <see cref="T:System.Collections.ICollection" /> is synchronized with the SyncRoot.</summary> /// <returns>true if access to the <see cref="T:System.Collections.ICollection" /> is synchronized (thread safe); otherwise, false. For <see cref="T:System.Collections.Concurrent.ConcurrentDictionary{TKey,TValue}" />, this property always returns false.</returns> [__DynamicallyInvokable] bool ICollection.IsSynchronized { [__DynamicallyInvokable] get { return false; } } /// <summary>Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection" />. This property is not supported.</summary> /// <returns>Always returns null.</returns> /// <exception cref="T:System.NotSupportedException">The SyncRoot property is not supported.</exception> [__DynamicallyInvokable] object ICollection.SyncRoot { [__DynamicallyInvokable] get { throw new NotSupportedException("ConcurrentCollection_SyncRoot_NotSupported"); } } private static int DefaultConcurrencyLevel { get { return 4 * PlatformHelper.ProcessorCount; } } private static bool IsValueWriteAtomic() { Type typeFromHandle = typeof(TValue); bool flag = typeFromHandle.IsClass || typeFromHandle == typeof(bool) || typeFromHandle == typeof(char) || typeFromHandle == typeof(byte) || typeFromHandle == typeof(sbyte) || typeFromHandle == typeof(short) || typeFromHandle == typeof(ushort) || typeFromHandle == typeof(int) || typeFromHandle == typeof(uint) || typeFromHandle == typeof(float); if (!flag && IntPtr.Size == 8) { flag |= (typeFromHandle == typeof(double) || typeFromHandle == typeof(long)); } return flag; } /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that is empty, has the default concurrency level, has the default initial capacity, and uses the default comparer for the key type.</summary> [__DynamicallyInvokable] public ConcurrentDictionary() : this(ConcurrentDictionary<TKey, TValue>.DefaultConcurrencyLevel, 31, true, EqualityComparer<TKey>.Default) { } /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that is empty, has the specified concurrency level and capacity, and uses the default comparer for the key type.</summary> /// <param name="concurrencyLevel">The estimated number of threads that will update the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> concurrently.</param> /// <param name="capacity">The initial number of elements that the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> can contain.</param> /// <exception cref="T:System.ArgumentOutOfRangeException"> /// <paramref name="concurrencyLevel" /> is less than 1.-or-<paramref name="capacity" /> is less than 0.</exception> [__DynamicallyInvokable] public ConcurrentDictionary(int concurrencyLevel, int capacity) : this(concurrencyLevel, capacity, false, EqualityComparer<TKey>.Default) { } /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that contains elements copied from the specified <see cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}" />, has the default concurrency level, has the default initial capacity, and uses the default comparer for the key type.</summary> /// <param name="collection">The <see cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}" /> whose elements are copied to the new <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</param> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="collection" /> or any of its keys is a null reference (Nothing in Visual Basic)</exception> /// <exception cref="T:System.ArgumentException"> /// <paramref name="collection" /> contains one or more duplicate keys.</exception> [__DynamicallyInvokable] public ConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection) : this(collection, EqualityComparer<TKey>.Default) { } /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that is empty, has the default concurrency level and capacity, and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" />.</summary> /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" /> implementation to use when comparing keys.</param> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="comparer" /> is a null reference (Nothing in Visual Basic).</exception> [__DynamicallyInvokable] public ConcurrentDictionary(IEqualityComparer<TKey> comparer) : this(ConcurrentDictionary<TKey, TValue>.DefaultConcurrencyLevel, 31, true, comparer) { } /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that contains elements copied from the specified <see cref="T:System.Collections.IEnumerable" />, has the default concurrency level, has the default initial capacity, and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" />.</summary> /// <param name="collection">The <see cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}" /> whose elements are copied to the new <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</param> /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" /> implementation to use when comparing keys.</param> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="collection" /> is a null reference (Nothing in Visual Basic). -or- <paramref name="comparer" /> is a null reference (Nothing in Visual Basic).</exception> [__DynamicallyInvokable] public ConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer) : this(comparer) { if (collection == null) { throw new ArgumentNullException("collection"); } this.InitializeFromCollection(collection); } /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that contains elements copied from the specified <see cref="T:System.Collections.IEnumerable" />, and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" />.</summary> /// <param name="concurrencyLevel">The estimated number of threads that will update the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> concurrently.</param> /// <param name="collection">The <see cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}" /> whose elements are copied to the new <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</param> /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" /> implementation to use when comparing keys.</param> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="collection" /> is a null reference (Nothing in Visual Basic). -or- <paramref name="comparer" /> is a null reference (Nothing in Visual Basic).</exception> /// <exception cref="T:System.ArgumentOutOfRangeException"> /// <paramref name="concurrencyLevel" /> is less than 1.</exception> /// <exception cref="T:System.ArgumentException"> /// <paramref name="collection" /> contains one or more duplicate keys.</exception> [__DynamicallyInvokable] public ConcurrentDictionary(int concurrencyLevel, IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer) : this(concurrencyLevel, 31, false, comparer) { if (collection == null) { throw new ArgumentNullException("collection"); } if (comparer == null) { throw new ArgumentNullException("comparer"); } this.InitializeFromCollection(collection); } private void InitializeFromCollection(IEnumerable<KeyValuePair<TKey, TValue>> collection) { foreach (KeyValuePair<TKey, TValue> current in collection) { if (current.Key == null) { throw new ArgumentNullException("key"); } TValue tValue; if (!this.TryAddInternal(current.Key, current.Value, false, false, out tValue)) { throw new ArgumentException(this.GetResource("ConcurrentDictionary_SourceContainsDuplicateKeys")); } } if (this.m_budget == 0) { this.m_budget = this.m_tables.m_buckets.Length / this.m_tables.m_locks.Length; } } /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that is empty, has the specified concurrency level, has the specified initial capacity, and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" />.</summary> /// <param name="concurrencyLevel">The estimated number of threads that will update the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> concurrently.</param> /// <param name="capacity">The initial number of elements that the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> can contain.</param> /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" /> implementation to use when comparing keys.</param> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="comparer" /> is a null reference (Nothing in Visual Basic).</exception> /// <exception cref="T:System.ArgumentOutOfRangeException"> /// <paramref name="concurrencyLevel" /> is less than 1. -or- <paramref name="capacity" /> is less than 0.</exception> [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public ConcurrentDictionary(int concurrencyLevel, int capacity, IEqualityComparer<TKey> comparer) : this(concurrencyLevel, capacity, false, comparer) { } internal ConcurrentDictionary(int concurrencyLevel, int capacity, bool growLockArray, IEqualityComparer<TKey> comparer) { if (concurrencyLevel < 1) { throw new ArgumentOutOfRangeException("concurrencyLevel", this.GetResource("ConcurrentDictionary_ConcurrencyLevelMustBePositive")); } if (capacity < 0) { throw new ArgumentOutOfRangeException("capacity", this.GetResource("ConcurrentDictionary_CapacityMustNotBeNegative")); } if (comparer == null) { throw new ArgumentNullException("comparer"); } if (capacity < concurrencyLevel) { capacity = concurrencyLevel; } object[] array = new object[concurrencyLevel]; for (int i = 0; i < array.Length; i++) { array[i] = new object(); } int[] countPerLock = new int[array.Length]; ConcurrentDictionary<TKey, TValue>.Node[] array2 = new ConcurrentDictionary<TKey, TValue>.Node[capacity]; this.m_tables = new ConcurrentDictionary<TKey, TValue>.Tables(array2, array, countPerLock); this.m_comparer = comparer; this.m_growLockArray = growLockArray; this.m_budget = array2.Length / array.Length; } /// <summary>Attempts to add the specified key and value to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</summary> /// <returns>true if the key/value pair was added to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> successfully. If the key already exists, this method returns false.</returns> /// <param name="key">The key of the element to add.</param> /// <param name="value">The value of the element to add. The value can be a null reference (Nothing in Visual Basic) for reference types.</param> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="key" /> is null reference (Nothing in Visual Basic).</exception> /// <exception cref="T:System.OverflowException">The dictionary already contains the maximum number of elements, <see cref="F:System.Int32.MaxValue" />.</exception> [__DynamicallyInvokable] public bool TryAdd(TKey key, TValue value) { if (key == null) { throw new ArgumentNullException("key"); } TValue tValue;