// 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;
using System.Diagnostics.Contracts;
namespace System.Web.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(IDictionary sourceDictionary,
IEqualityComparer comparer)
{
Contract.Assert(sourceDictionary != null);
Contract.Assert(comparer != null);
_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();
}
}
}