using System; using System.Collections.Generic; namespace AssetServer { public class DoubleDictionary { Dictionary Dictionary1; Dictionary Dictionary2; object syncObject = new object(); public DoubleDictionary() { Dictionary1 = new Dictionary(); Dictionary2 = new Dictionary(); } public DoubleDictionary(int capacity) { Dictionary1 = new Dictionary(capacity); Dictionary2 = new Dictionary(capacity); } public void Add(TKey1 key1, TKey2 key2, TValue value) { lock (syncObject) { if (Dictionary1.ContainsKey(key1)) { if (!Dictionary2.ContainsKey(key2)) throw new ArgumentException("key1 exists in the dictionary but not key2"); } else if (Dictionary2.ContainsKey(key2)) { if (!Dictionary1.ContainsKey(key1)) throw new ArgumentException("key2 exists in the dictionary but not key1"); } Dictionary1[key1] = value; Dictionary2[key2] = value; } } public bool Remove(TKey1 key1, TKey2 key2) { lock (syncObject) { Dictionary1.Remove(key1); return Dictionary2.Remove(key2); } } public bool Remove(TKey1 key1) { // This is an O(n) operation! lock (syncObject) { TValue value; if (Dictionary1.TryGetValue(key1, out value)) { foreach (KeyValuePair kvp in Dictionary2) { if (kvp.Value.Equals(value)) { Dictionary1.Remove(key1); Dictionary2.Remove(kvp.Key); return true; } } } } return false; } public bool Remove(TKey2 key2) { // This is an O(n) operation! lock (syncObject) { TValue value; if (Dictionary2.TryGetValue(key2, out value)) { foreach (KeyValuePair kvp in Dictionary1) { if (kvp.Value.Equals(value)) { Dictionary2.Remove(key2); Dictionary1.Remove(kvp.Key); return true; } } } } return false; } public void Clear() { lock (syncObject) { Dictionary1.Clear(); Dictionary2.Clear(); } } public int Count { get { return Dictionary1.Count; } } public bool ContainsKey(TKey1 key) { return Dictionary1.ContainsKey(key); } public bool ContainsKey(TKey2 key) { return Dictionary2.ContainsKey(key); } public bool TryGetValue(TKey1 key, out TValue value) { return Dictionary1.TryGetValue(key, out value); } public bool TryGetValue(TKey2 key, out TValue value) { return Dictionary2.TryGetValue(key, out value); } public void ForEach(Action action) { lock (syncObject) { foreach (TValue value in Dictionary1.Values) action(value); } } public TValue this[TKey1 key1] { get { return Dictionary1[key1]; } } public TValue this[TKey2 key2] { get { return Dictionary2[key2]; } } } }