using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Collections.ObjectModel;

public class SpinLockDictionary<K, V> : IDictionary<K, V>
{
	Dictionary<K, V> d = new Dictionary<K, V>();
	SpinLock m_lock = new SpinLock();

	public void Add(K key, V value)
	{
		bool entered = false;
		try
		{
			m_lock.Enter(ref entered);
			d.Add(key, value);
		}
		finally
		{
			if (entered)
				m_lock.Exit();
		}
	}

	public bool ContainsKey(K key)
	{
		bool entered = false;
		try
		{
			m_lock.Enter(ref entered);
			return d.ContainsKey(key);
		}
		finally
		{
			if (entered)
				m_lock.Exit();
		}
	}

	public ICollection<K> Keys
	{
		get
		{
			bool entered = false;
			try
			{
				m_lock.Enter(ref entered);
				return new ReadOnlyCollection<K>(d.Keys.ToArray());
			}
			finally
			{
				if (entered)
					m_lock.Exit();
			}
		}
	}

	public bool Remove(K key)
	{
		bool entered = false;
		try
		{
			m_lock.Enter(ref entered);
			return d.Remove(key);
		}
		finally
		{
			if (entered)
				m_lock.Exit();
		}
	}

	public bool TryGetValue(K key, out V value)
	{
		bool entered = false;
		try
		{
			m_lock.Enter(ref entered);
			return d.TryGetValue(key, out value);
		}
		finally
		{
			if (entered)
				m_lock.Exit();
		}
	}

	public ICollection<V> Values
	{
		get
		{
			bool entered = false;
			try
			{
				m_lock.Enter(ref entered);
				return new ReadOnlyCollection<V>(d.Values.ToArray());
			}
			finally
			{
				if (entered)
					m_lock.Exit();
			}
		}
	}

	public V this[K key]
	{
		get
		{
			bool entered = false;
			try
			{
				m_lock.Enter(ref entered);
				return d[key];
			}
			finally
			{
				if (entered)
					m_lock.Exit();
			}
		}
		set
		{
			bool entered = false;
			try
			{
				m_lock.Enter(ref entered);
				d[key] = value;
			}
			finally
			{
				if (entered)
					m_lock.Exit();
			}
		}
	}

	public void Add(KeyValuePair<K, V> item)
	{
		bool entered = false;
		try
		{
			m_lock.Enter(ref entered);
			d.Add(item.Key, item.Value);
		}
		finally
		{
			if (entered)
				m_lock.Exit();
		}
	}

	public void Clear()
	{
		bool entered = false;
		try
		{
			m_lock.Enter(ref entered);
			d.Clear();
		}
		finally
		{
			if (entered)
				m_lock.Exit();
		}
	}

	public bool Contains(KeyValuePair<K, V> item)
	{
		bool entered = false;
		try
		{
			m_lock.Enter(ref entered);
			return d.Contains(item);
		}
		finally
		{
			if (entered)
				m_lock.Exit();
		}
	}

	public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex)
	{
		bool entered = false;
		try
		{
			m_lock.Enter(ref entered);
			d.ToArray().CopyTo(array, arrayIndex);
		}
		finally
		{
			if (entered)
				m_lock.Exit();
		}
	}

	public int Count
	{
		get
		{
			bool entered = false;
			try
			{
				m_lock.Enter(ref entered);
				return d.Count;
			}
			finally
			{
				if (entered)
					m_lock.Exit();
			}
		}
	}

	public bool IsReadOnly
	{
		get { return true; }
	}

	public bool Remove(KeyValuePair<K, V> item)
	{
		throw new NotImplementedException();
	}

	public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
	{
		throw new NotImplementedException();
	}

	System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
	{
		return GetEnumerator();
	}
}


public class MonitorLockDictionary<K, V> : IDictionary<K, V>
{
	Dictionary<K, V> d = new Dictionary<K, V>();
	Object m_lock = new Object();

	public void Add(K key, V value)
	{
		lock (m_lock)
		{
			d.Add(key, value);
		}
	}

	public bool ContainsKey(K key)
	{
		lock (m_lock)
		{
			return d.ContainsKey(key);
		}
	}

	public bool Remove(K key)
	{
		lock (m_lock)
		{
			return d.Remove(key);
		}
	}

	public bool TryGetValue(K key, out V value)
	{
		lock (m_lock)
		{
			return d.TryGetValue(key, out value);
		}
	}

	public V this[K key]
	{
		get
		{
			lock (m_lock)
			{
				return d[key];
			}
		}
		set
		{
			lock (m_lock)
			{
				d[key] = value;
			}
		}
	}

	public void Add(KeyValuePair<K, V> item)
	{
		lock (m_lock)
		{
			d.Add(item.Key, item.Value);
		}
	}

	public void Clear()
	{
		lock (m_lock)
		{
			d.Clear();
		}
	}

	public bool Contains(KeyValuePair<K, V> item)
	{
		lock (m_lock)
		{
			return d.Contains(item);
		}
	}

	public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex)
	{
		lock (m_lock)
		{
			d.ToArray().CopyTo(array, arrayIndex);
		}
	}

	public int Count
	{
		get
		{
			lock (m_lock)
			{
				return d.Count;
			}
		}
	}

	public bool IsReadOnly { get { return true; } }

	public bool Remove(KeyValuePair<K, V> item)
	{
		throw new NotImplementedException();
	}

	public ICollection<K> Keys
	{
		get
		{
			lock (m_lock)
			{
				return new ReadOnlyCollection<K>(d.Keys.ToArray());
			}
		}
	}

	public ICollection<V> Values
	{
		get
		{
			lock (m_lock)
			{
				return new ReadOnlyCollection<V>(d.Values.ToArray());
			}
		}
	}

	public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
	{
		throw new NotImplementedException();
	}

	System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
	{
		return GetEnumerator();
	}
}