using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;

namespace System.Reactive.Linq.ObservableImpl
{
	internal sealed class Map<TKey, TValue>
	{
		private static int DefaultConcurrencyLevel
		{
			get
			{
				return 4 * Environment.ProcessorCount;
			}
		}

		public Map(int? capacity, IEqualityComparer<TKey> comparer)
		{
			if (capacity != null)
			{
				this._map = new ConcurrentDictionary<TKey, TValue>(Map<TKey, TValue>.DefaultConcurrencyLevel, capacity.Value, comparer);
				return;
			}
			this._map = new ConcurrentDictionary<TKey, TValue>(comparer);
		}

		public TValue GetOrAdd(TKey key, Func<TValue> valueFactory, out bool added)
		{
			added = false;
			TValue tvalue = default(TValue);
			bool flag = false;
			TValue tvalue2;
			while (!this._map.TryGetValue(key, out tvalue2))
			{
				if (!flag)
				{
					tvalue = valueFactory();
					flag = true;
				}
				if (this._map.TryAdd(key, tvalue))
				{
					added = true;
					tvalue2 = tvalue;
					break;
				}
			}
			return tvalue2;
		}

		public IEnumerable<TValue> Values
		{
			get
			{
				return this._map.Values.ToArray<TValue>();
			}
		}

		public bool Remove(TKey key)
		{
			TValue tvalue;
			return this._map.TryRemove(key, out tvalue);
		}

		private readonly ConcurrentDictionary<TKey, TValue> _map;
	}
}
