// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections; using System.Collections.Generic; namespace Microsoft.AspNet.Mvc { /// /// A that defers creating a shallow copy of the source dictionary until /// a mutative operation has been performed on it. /// internal class CopyOnWriteDictionary : IDictionary { private readonly IDictionary _sourceDictionary; private readonly IEqualityComparer _comparer; private IDictionary _innerDictionary; public CopyOnWriteDictionary([NotNull] IDictionary sourceDictionary, [NotNull] IEqualityComparer comparer) { _sourceDictionary = sourceDictionary; _comparer = comparer; } private IDictionary ReadDictionary { get { return _innerDictionary ?? _sourceDictionary; } } private IDictionary WriteDictionary { get { if (_innerDictionary == null) { _innerDictionary = new Dictionary(_sourceDictionary, _comparer); } return _innerDictionary; } } public virtual ICollection Keys { get { return ReadDictionary.Keys; } } public virtual ICollection Values { get { return ReadDictionary.Values; } } public virtual int Count { get { return ReadDictionary.Count; } } public virtual bool IsReadOnly { get { return false; } } public virtual TValue this[[NotNull] TKey key] { get { return ReadDictionary[key]; } set { WriteDictionary[key] = value; } } public virtual bool ContainsKey([NotNull] TKey key) { return ReadDictionary.ContainsKey(key); } public virtual void Add([NotNull] TKey key, TValue value) { WriteDictionary.Add(key, value); } public virtual bool Remove([NotNull] TKey key) { return WriteDictionary.Remove(key); } public virtual bool TryGetValue([NotNull] TKey key, out TValue value) { return ReadDictionary.TryGetValue(key, out value); } public virtual void Add(KeyValuePair item) { WriteDictionary.Add(item); } public virtual void Clear() { WriteDictionary.Clear(); } public virtual bool Contains(KeyValuePair item) { return ReadDictionary.Contains(item); } public virtual void CopyTo([NotNull] KeyValuePair[] array, int arrayIndex) { ReadDictionary.CopyTo(array, arrayIndex); } public bool Remove(KeyValuePair item) { return WriteDictionary.Remove(item); } public virtual IEnumerator> GetEnumerator() { return ReadDictionary.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }