using System; using System.Collections.Generic; using System.Linq; namespace ln.collections { public class BTreeValueList { public bool Empty => bTree.Empty; BTree> bTree; public BTreeValueList() { bTree = new BTree>(); } public BTreeValueList(Comparison comparison) { bTree = new BTree>(comparison); } public IEnumerable this[K key] { get { if (TryGet(key,out IEnumerable values)) { return values; } throw new KeyNotFoundException(); } } public void Add(K key, V value) { if (!TryAdd(key, value)) throw new ArgumentException("duplicate key"); } public void Remove(K key, V value) { if (!TryRemove(key, value)) throw new KeyNotFoundException(); } public void Remove(K key) { if (!TryRemove(key)) throw new KeyNotFoundException(); } public bool TryAdd(K key,V value) { if (!bTree.TryGet(key, out List values)) { values = new List(); bTree.Add(key, values); } values.Add(value); return true; } public bool TryGet(K key,out IEnumerable values) { if ((!bTree.TryGet(key, out List v)) || (v.Count == 0)) { values = v; return false; } values = v; return true; } public bool TryRemove(K key) { return bTree.TryRemove(key); } public bool TryRemove(K key,V value) { if (bTree.TryGet(key, out List values)) { bool success = values.Remove(value); if (values.Count == 0) bTree.Remove(key); return success; } return false; } public bool ContainsKey(K key) { if (!bTree.TryGet(key, out List _values)) return false; return _values.Count > 0; } public bool ContainsValue(V value) { foreach (List _values in bTree.Values) { foreach (V v in _values) if (v.Equals(value)) return true; } return false; } public int Count(K key) { if ((!bTree.TryGet(key, out List _values)) || (_values.Count == 0)) return 0; return _values.Count; } public void Clear() { bTree.Clear(); } public V Shift() { K k = bTree.First(); if (bTree.TryGet(k,out List values)) { V f = values[0]; Remove(k, f); return f; } throw new Exception("Serious BUG"); } public V Pop() { K k = bTree.Last(); if (bTree.TryGet(k, out List values)) { V f = values[values.Count-1]; Remove(k, f); return f; } throw new Exception("Serious BUG"); } public K First => bTree.First(); public K Last => bTree.Last(); public bool TryGetNextOrCurrent(K current, out K nextOrEqual) => bTree.TryGetNextOrCurrent(current, out nextOrEqual); public IEnumerable Keys => bTree.Keys; public IEnumerable Values => bTree.Values.SelectMany(vl => vl); public IEnumerable> GetKeyValuePairs() { foreach (K key in Keys) { List lv = bTree[key]; foreach (V value in lv) yield return new KeyValuePair(key, value); } } public void AddRange(IEnumerable> keyValuePairs) { foreach (KeyValuePair keyValuePair in keyValuePairs) Add(keyValuePair.Key, keyValuePair.Value); } } }