// 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.Generic; namespace Microsoft.Extensions.Internal { internal struct CopyOnWriteDictionaryHolder { private readonly Dictionary _source; private Dictionary _copy; public CopyOnWriteDictionaryHolder(Dictionary source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } _source = source; _copy = null; } public CopyOnWriteDictionaryHolder(CopyOnWriteDictionaryHolder source) { _source = source._copy ?? source._source; _copy = null; } public bool HasBeenCopied => _copy != null; public Dictionary ReadDictionary { get { if (_copy != null) { return _copy; } else if (_source != null) { return _source; } else { // Default-Constructor case _copy = new Dictionary(); return _copy; } } } public Dictionary WriteDictionary { get { if (_copy == null && _source == null) { // Default-Constructor case _copy = new Dictionary(); } else if (_copy == null) { _copy = new Dictionary(_source, _source.Comparer); } return _copy; } } public Dictionary.KeyCollection Keys { get { return ReadDictionary.Keys; } } public Dictionary.ValueCollection Values { get { return ReadDictionary.Values; } } public int Count { get { return ReadDictionary.Count; } } public bool IsReadOnly { get { return false; } } public TValue this[TKey key] { get { return ReadDictionary[key]; } set { WriteDictionary[key] = value; } } public bool ContainsKey(TKey key) { return ReadDictionary.ContainsKey(key); } public void Add(TKey key, TValue value) { WriteDictionary.Add(key, value); } public bool Remove(TKey key) { return WriteDictionary.Remove(key); } public bool TryGetValue(TKey key, out TValue value) { return ReadDictionary.TryGetValue(key, out value); } public void Add(KeyValuePair item) { ((ICollection>)WriteDictionary).Add(item); } public void Clear() { WriteDictionary.Clear(); } public bool Contains(KeyValuePair item) { return ((ICollection>)ReadDictionary).Contains(item); } public void CopyTo(KeyValuePair[] array, int arrayIndex) { ((ICollection>)ReadDictionary).CopyTo(array, arrayIndex); } public bool Remove(KeyValuePair item) { return ((ICollection>)WriteDictionary).Remove(item); } public Dictionary.Enumerator GetEnumerator() { return ReadDictionary.GetEnumerator(); } } }