using System; using System.Collections; using System.Linq; using System.Collections.Generic; using System.Diagnostics.Contracts; namespace DataStructures.HashSpace { /// /// /// /// /// [Serializable] public class LinkedDictionary : IDictionary where TValue : LinkedDictionary.Value { private Dictionary> dic; private readonly Value headValue = new Value(default(TValue)); private Value lastAdded; private Pair lastAddedPair; public LinkedDictionary(int capacity) { Contract.Requires(capacity > 0); Dic = new Dictionary>(capacity); lastAdded = headValue; Dic.Add(default(TKey), headValue); } public bool ContainsValue(TValue value) { return Dic.ContainsValue(new Value(value)); } public void Add(TKey key, TValue value) { Contract.Requires(key != null); var newValue = new Value(value, lastAddedPair); var newPair = new Pair(key, newValue); lastAdded.next = newPair; lastAdded = newValue; lastAddedPair = newPair; Dic.Add(newPair.key, newPair.value); } public bool Remove(TKey key) { if (!Dic.ContainsKey(key)) { return false; } if (lastAdded.Equals(Dic[key])) { lastAddedPair = lastAdded.prev; } var prev = lastAdded.prev; //TODO: remove element return false; } public bool ContainsKey(TKey key) { Contract.Requires(key != null); return Dic.ContainsKey(key); } public ICollection Keys { get { return Dic.Keys; } } public bool Remove(KeyValuePair item) { if(!Dic.ContainsKey(item.Key)) { return false; } if(lastAdded.Equals(Dic[item.Key])) { lastAddedPair = lastAdded.prev; } var prev = lastAdded.prev; //TODO: remove element return false; } public bool TryGetValue(TKey key, out TValue value) { value = default(TValue); var valueDic = new Value(value); return Dic.TryGetValue(key, out valueDic); } public ICollection Values { //TODO: fix get { return null; } } public TValue this[TKey key] { get { Contract.Requires(key != null); return Dic[key].value; } set { Contract.Requires(key != null); Dic[key] = value; } } public void Add(KeyValuePair item) { Add(item.Key, item.Value); } public void Clear() { Dic.Clear(); lastAdded = headValue; } public bool Contains(KeyValuePair item) { return (Dic.ContainsKey(item.Key) && Dic[item.Key].Equals(item.Value)); } public void CopyTo(KeyValuePair[] array, int arrayIndex) { Contract.Requires(array.Length >= Dic.Count+arrayIndex); } public int Count { get { return Dic.Count; } } public bool IsReadOnly { get; private set; } public Dictionary> Dic { get { return dic; } set { dic = value; } } public IEnumerator> GetEnumerator() { var key = headValue.next; while (key != null) { var tempKey = key; key = key.value.next; yield return new KeyValuePair(tempKey.key, Dic[tempKey.key].value); } } IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } public class Pair where TValue : Value { public TKey key; public Value value; public Pair(TKey key = default(TKey), Value value = null) { this.key = key; this.value = value; } } public class Value where TValue:Value { public TValue value; public Pair next; public Pair prev; public Value(TValue value, Pair prev = null, Pair next = null) { this.value = value; this.prev = prev; this.next = next; } public override int GetHashCode() { return value.GetHashCode(); } public override bool Equals(object otherObj) { var otherKey = otherObj as Value; if(otherKey == null) { return false; } return otherKey.value.Equals(value); } } } }