// Copyright (c) .NET Foundation. 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.Extensions.Internal { internal class CopyOnWriteDictionary : IDictionary { private readonly IDictionary _sourceDictionary; private readonly IEqualityComparer _comparer; private IDictionary _innerDictionary; public CopyOnWriteDictionary( IDictionary sourceDictionary, IEqualityComparer comparer) { if (sourceDictionary == null) { throw new ArgumentNullException(nameof(sourceDictionary)); } if (comparer == null) { throw new ArgumentNullException(nameof(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[TKey key] { get { return ReadDictionary[key]; } set { WriteDictionary[key] = value; } } public virtual bool ContainsKey(TKey key) { return ReadDictionary.ContainsKey(key); } public virtual void Add(TKey key, TValue value) { WriteDictionary.Add(key, value); } public virtual bool Remove(TKey key) { return WriteDictionary.Remove(key); } public virtual bool TryGetValue(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(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(); } } }