#if FAT using System; using System.Collections.Generic; using LinqInternal.Core; namespace LinqInternal.Collections { [Serializable] [System.Diagnostics.DebuggerNonUserCode] internal class ProgressiveDictionary : ProgressiveCollection>, IReadOnlyDictionary, IExtendedDictionary, IDictionary { private readonly IDictionary _cache; private readonly IEqualityComparer _keyComparer; private readonly ProgressiveSet _keysReadonly; private readonly ProgressiveSet _valuesReadonly; public ProgressiveDictionary(IEnumerable> wrapped) : this(wrapped, new Dictionary(), null, null) { //Empty } public ProgressiveDictionary(IEnumerable> wrapped, IEqualityComparer keyComparer, IEqualityComparer valueComparer) : this(wrapped, new Dictionary(keyComparer), keyComparer, valueComparer) { //Empty } protected ProgressiveDictionary(IEnumerable> wrapped, IDictionary cache, IEqualityComparer keyComparer, IEqualityComparer valueComparer) : this(wrapped.GetEnumerator(), cache, new KeyValuePairEqualityComparer(keyComparer, valueComparer)) { if (cache == null) { throw new ArgumentNullException("cache"); } _cache = cache; _keyComparer = keyComparer ?? EqualityComparer.Default; _valuesReadonly = new ProgressiveSet(Progressor.CreateConverted(Progressor, input => input.Value), valueComparer); _keysReadonly = new ProgressiveSet(Progressor.CreateConverted(Progressor, input => input.Key), keyComparer); } protected ProgressiveDictionary(Progressor> wrapped, IDictionary cache, IEqualityComparer keyComparer, IEqualityComparer valueComparer) : base ((out KeyValuePair pair) => { again: if (wrapped.TryTake(out pair)) { if (cache.ContainsKey(pair.Key)) { goto again; } return true; } else { return false; } }, cache, new KeyValuePairEqualityComparer(keyComparer, valueComparer)) { if (cache == null) { throw new ArgumentNullException("cache"); } _cache = cache; _keyComparer = keyComparer ?? EqualityComparer.Default; _keyComparer = EqualityComparer.Default; _valuesReadonly = new ProgressiveSet(Progressor.CreateConverted(Progressor, input => input.Value), valueComparer); _keysReadonly = new ProgressiveSet(Progressor.CreateConverted(Progressor, input => input.Key), keyComparer); } private ProgressiveDictionary(IEnumerator> enumerator, IDictionary cache, KeyValuePairEqualityComparer comparer) : base((out KeyValuePair pair) => { again: if (enumerator.MoveNext()) { pair = enumerator.Current; if (cache.ContainsKey(pair.Key)) { goto again; } return true; } else { enumerator.Dispose(); pair = default(KeyValuePair); return false; } }, cache, comparer) { //Empty } bool ICollection>.IsReadOnly { get { return true; } } ICollection IDictionary.Keys { get { return _keysReadonly; } } ICollection IDictionary.Values { get { return _valuesReadonly; } } IReadOnlyCollection> IExtendedCollection>.AsReadOnly { get { return this; } } IReadOnlyDictionary IExtendedDictionary.AsReadOnly { get { return this; } } IEnumerable IReadOnlyDictionary.Keys { get { return _keysReadonly; } } IEnumerable IReadOnlyDictionary.Values { get { return _valuesReadonly; } } public IReadOnlyCollection Keys { get { return _keysReadonly; } } public IReadOnlyCollection Values { get { return _valuesReadonly; } } TValue IDictionary.this[TKey key] { get { try { return _cache[key]; } catch (KeyNotFoundException) { KeyValuePair item; while (Progressor.TryTake(out item)) { if (_keyComparer.Equals(key, item.Key)) { return item.Value; } } throw; } } set { throw new NotSupportedException(); } } public TValue this[TKey key] { get { try { return _cache[key]; } catch (KeyNotFoundException) { KeyValuePair item; while (Progressor.TryTake(out item)) { if (_keyComparer.Equals(key, item.Key)) { return item.Value; } } throw; } } } public bool ContainsKey(TKey key) { if (_cache.ContainsKey(key)) { return true; } else { KeyValuePair item; while (Progressor.TryTake(out item)) { if (_keyComparer.Equals(key, item.Key)) { return true; } } return false; } } void ICollection>.Add(KeyValuePair item) { throw new NotSupportedException(); } void ICollection>.Clear() { throw new NotSupportedException(); } bool ICollection>.Remove(KeyValuePair item) { throw new NotSupportedException(); } void IDictionary.Add(TKey key, TValue value) { throw new NotSupportedException(); } bool IDictionary.Remove(TKey key) { throw new NotSupportedException(); } bool IExtendedCollection>.Remove(KeyValuePair item, IEqualityComparer> comparer) { throw new NotSupportedException(); } public bool IsProperSubsetOf(IEnumerable> other) { return Extensions.IsProperSubsetOf(this, other); } public bool IsProperSupersetOf(IEnumerable> other) { return Extensions.IsProperSupersetOf(this, other); } public bool IsSubsetOf(IEnumerable> other) { return Extensions.IsSubsetOf(this, other); } public bool IsSupersetOf(IEnumerable> other) { return Extensions.IsSupersetOf(this, other); } public bool Overlaps(IEnumerable> other) { return Extensions.Overlaps(this, other); } public bool SetEquals(IEnumerable> other) { return Extensions.SetEquals(this, other); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } public bool TryGetValue(TKey key, out TValue value) { try { value = this[key]; return true; } catch (KeyNotFoundException) { value = default(TValue); return false; } } } } #endif