/// <summary> /// Obtains the value for the specified key from a dictionary, or adds a new value to the dictionary where the key did not previously exist. /// </summary> /// <typeparam name="TKey">The type of key stored by the dictionary.</typeparam> /// <typeparam name="TValue">The type of value stored by the dictionary.</typeparam> /// <typeparam name="TArg">The type of argument supplied to the value factory.</typeparam> /// <param name="location">The variable or field to atomically update if the specified <paramref name="key" /> is not in the dictionary.</param> /// <param name="key">The key for the value to retrieve or add.</param> /// <param name="valueFactory">The function to execute to obtain the value to insert into the dictionary if the key is not found.</param> /// <param name="factoryArgument">The argument to pass to the value factory.</param> /// <returns>The value obtained from the dictionary or <paramref name="valueFactory" /> if it was not present.</returns> public static TValue GetOrAdd <TKey, TValue, TArg>(ref ImmutableHashMap <TKey, TValue> location, TKey key, Func <TKey, TArg, TValue> valueFactory, TArg factoryArgument) { //#### Contract.ThrowIfNull(valueFactory); var map = Volatile.Read(ref location); //#### Contract.ThrowIfNull(map); // if the key exists return the value if (map.TryGetValue(key, out var existingValue)) { return(existingValue); } TValue newValue = valueFactory(key, factoryArgument); do { var augmentedMap = map.Add(key, newValue); // if location has not changed since "var map = Volatile.Read(ref location)" var replacedMap = Interlocked.CompareExchange(ref location, augmentedMap, map); if (replacedMap == map) { return(newValue); } map = replacedMap; } // ReSharper disable once PossibleNullReferenceException while (!map.TryGetValue(key, out existingValue)); return(existingValue); }
public ImmutableHashMap <TKey, TValue> WithComparers(IEqualityComparer <TKey> keyComparer, IEqualityComparer <TValue> valueComparer) { if (keyComparer == null) { keyComparer = EqualityComparer <TKey> .Default; } if (valueComparer == null) { valueComparer = EqualityComparer <TValue> .Default; } if (_keyComparer == keyComparer) { if (_valueComparer == valueComparer) { return(this); } else { return(new ImmutableHashMap <TKey, TValue>(_root, _keyComparer, valueComparer)); } } else { var set = new ImmutableHashMap <TKey, TValue>(keyComparer, valueComparer); set = set.AddRange(this, overwriteOnCollision: false, avoidToHashMap: true); return(set); } }
private static bool TryCastToImmutableMap(IEnumerable <KeyValuePair <TKey, TValue> > sequence, out ImmutableHashMap <TKey, TValue> other) { other = sequence as ImmutableHashMap <TKey, TValue>; if (other != null) { return(true); } return(false); }
public DebuggerProxy(ImmutableHashMap <TKey, TValue> map) { _map = map; }