1
0
Fork 0
TweetDuck/Data/TwoKeyDictionary.cs

102 lines
3.0 KiB
C#

using System.Collections.Generic;
using System.Linq;
namespace TweetDuck.Data{
sealed class TwoKeyDictionary<K1, K2, V>{
private readonly Dictionary<K1, Dictionary<K2, V>> dict;
private readonly int innerCapacity;
public TwoKeyDictionary() : this(16, 16){}
public TwoKeyDictionary(int outerCapacity, int innerCapacity){
this.dict = new Dictionary<K1, Dictionary<K2, V>>(outerCapacity);
this.innerCapacity = innerCapacity;
}
// Properties
public V this[K1 outerKey, K2 innerKey]{
get{ // throws on missing key
return dict[outerKey][innerKey];
}
set{
if (!dict.TryGetValue(outerKey, out Dictionary<K2, V> innerDict)){
dict.Add(outerKey, innerDict = new Dictionary<K2, V>(innerCapacity));
}
innerDict[innerKey] = value;
}
}
public IEnumerable<V> InnerValues{
get{
foreach(Dictionary<K2, V> innerDict in dict.Values){
foreach(V value in innerDict.Values){
yield return value;
}
}
}
}
// Members
public void Add(K1 outerKey, K2 innerKey, V value){ // throws on duplicate
if (!dict.TryGetValue(outerKey, out Dictionary<K2, V> innerDict)){
dict.Add(outerKey, innerDict = new Dictionary<K2, V>(innerCapacity));
}
innerDict.Add(innerKey, value);
}
public void Clear(){
dict.Clear();
}
public void Clear(K1 outerKey){ // throws on missing key, but keeps the key unlike Remove(K1)
dict[outerKey].Clear();
}
public bool Contains(K1 outerKey){
return dict.ContainsKey(outerKey);
}
public bool Contains(K1 outerKey, K2 innerKey){
return dict.TryGetValue(outerKey, out Dictionary<K2, V> innerDict) && innerDict.ContainsKey(innerKey);
}
public int Count(){
return dict.Values.Sum(d => d.Count);
}
public int Count(K1 outerKey){ // throws on missing key
return dict[outerKey].Count;
}
public bool Remove(K1 outerKey){
return dict.Remove(outerKey);
}
public bool Remove(K1 outerKey, K2 innerKey){
if (dict.TryGetValue(outerKey, out Dictionary<K2, V> innerDict) && innerDict.Remove(innerKey)){
if (innerDict.Count == 0) {
dict.Remove(outerKey);
}
return true;
}
else return false;
}
public bool TryGetValue(K1 outerKey, K2 innerKey, out V value){
if (dict.TryGetValue(outerKey, out Dictionary<K2, V> innerDict)){
return innerDict.TryGetValue(innerKey, out value);
}
else{
value = default(V);
return false;
}
}
}
}