mirror of
https://github.com/chylex/TweetDuck.git
synced 2024-11-23 08:42:47 +01:00
102 lines
3.0 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|