135 lines
3.6 KiB
C#
135 lines
3.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
namespace ln.collections
|
|
{
|
|
public class BTreeValueSet<K, V>
|
|
{
|
|
public bool Empty => bTree.Empty;
|
|
|
|
BTree<K, HashSet<V>> bTree;
|
|
|
|
public BTreeValueSet()
|
|
{
|
|
bTree = new BTree<K, HashSet<V>>();
|
|
}
|
|
public BTreeValueSet(Comparison<K> comparison)
|
|
{
|
|
bTree = new BTree<K, HashSet<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 HashSet<V> values))
|
|
{
|
|
values = new HashSet<V>();
|
|
bTree.Add(key, values);
|
|
}
|
|
return values.Add(value);
|
|
}
|
|
public bool TryGet(K key,out IEnumerable<V> values)
|
|
{
|
|
if ((!bTree.TryGet(key, out HashSet<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 HashSet<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 HashSet<V> _values))
|
|
return false;
|
|
return _values.Count > 0;
|
|
}
|
|
public bool ContainsValue(V value)
|
|
{
|
|
foreach (HashSet<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 HashSet<V> _values)) || (_values.Count == 0))
|
|
return 0;
|
|
return _values.Count;
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
bTree.Clear();
|
|
}
|
|
|
|
public K First => bTree.First();
|
|
public K Last => bTree.Last();
|
|
|
|
public IEnumerable<K> Keys => bTree.Keys;
|
|
public IEnumerable<V> Values => bTree.Values.SelectMany(vl => vl);
|
|
|
|
public IEnumerable<KeyValuePair<K, V>> GetKeyValuePairs()
|
|
{
|
|
foreach (K key in Keys)
|
|
{
|
|
HashSet<V> lv = bTree[key];
|
|
foreach (V value in lv)
|
|
yield return new KeyValuePair<K, V>(key, value);
|
|
}
|
|
}
|
|
public void AddRange(IEnumerable<KeyValuePair<K, V>> keyValuePairs)
|
|
{
|
|
foreach (KeyValuePair<K, V> keyValuePair in keyValuePairs)
|
|
Add(keyValuePair.Key, keyValuePair.Value);
|
|
}
|
|
|
|
}
|
|
}
|