ln.collections/ln.collections/BTreeValueList.cs

164 lines
4.4 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace ln.collections
{
public class BTreeValueList<K, V> : IEnumerable<KeyValuePair<K,V>>
{
public bool Empty => bTree.Empty;
BTree<K, List<V>> bTree;
public BTreeValueList()
{
bTree = new BTree<K, List<V>>();
}
public BTreeValueList(Comparison<K> comparison)
{
bTree = new BTree<K, List<V>>(comparison);
}
public IEnumerable<V> this[K key]
{
get
{
if (TryGet(key,out IEnumerable<V> 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<V> values))
{
values = new List<V>();
bTree.Add(key, values);
}
values.Add(value);
return true;
}
public bool TryGet(K key,out IEnumerable<V> values)
{
if ((!bTree.TryGet(key, out List<V> 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<V> 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<V> _values))
return false;
return _values.Count > 0;
}
public bool ContainsValue(V value)
{
foreach (List<V> _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<V> _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<V> 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<V> 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<K> Keys => bTree.Keys;
public IEnumerable<V> Values => bTree.Values.SelectMany(vl => vl);
public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
{
foreach (KeyValuePair<K, List<V>> vl in this.bTree)
foreach (V v in vl.Value)
{
yield return new KeyValuePair<K, V>(vl.Key, v);
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public void AddRange(IEnumerable<KeyValuePair<K, V>> keyValuePairs)
{
foreach (KeyValuePair<K, V> keyValuePair in keyValuePairs)
Add(keyValuePair.Key, keyValuePair.Value);
}
}
}