Reputation: 19276
There seem to be no way to nest ConcurrentDictionary so that they share one lock
I am trying to create a class that will wrap a 3-deep nested dictionary with a lock
So that I can do NestedDict[k1][k2][k3] and get a value in a concurrent safe way And do NestedDict[k1][k2] and get a ConcurrentDictionary or equivalent.
I am not looking for a solution inheriting or composing ConcurrentDictionary<Tuple<TK1,TK2,TK3>,V>
as it is not the same, it will not allow me to ie efficiently get all keys of dict[k1, k2]
How can this be implemented ?
Is there an existing generic library/code showing such nested dictionary implementation (including iterators etc) ?
Upvotes: 0
Views: 718
Reputation: 1323
Here is one approach that you can take
using System;
using System.Collections.Concurrent;
public class Program
{
public class NestedDictionary<TK1, TK2, TK3, TValue>
{
private readonly ConcurrentDictionary<Tuple<TK1, TK2, TK3>, TValue> storage = new ConcurrentDictionary<Tuple<TK1, TK2, TK3>, TValue>();
public TValue this[TK1 key1, TK2 key2, TK3 key3]
{
get => this.storage[new Tuple<TK1, TK2, TK3>(key1, key2, key3)];
set => this.storage[new Tuple<TK1, TK2, TK3>(key1, key2, key3)] = value;
}
public bool TryGetValue(TK1 key1, TK2 key2, TK3 key3, out TValue value)
{
return this.storage.TryGetValue(new Tuple<TK1, TK2, TK3>(key1, key2, key3), out value);
}
public bool TryAdd(TK1 key1, TK2 key2, TK3 key3, TValue value)
{
return this.storage.TryAdd(new Tuple<TK1, TK2, TK3>(key1, key2, key3), value);
}
// etc etc
}
public static void Main()
{
NestedDictionary<int, bool, DateTime, string> d = new NestedDictionary<int, bool, DateTime, string>();
d[1, false, new DateTime(2018, 6, 18)] = "Hello";
d[1, true, new DateTime(2018, 6, 18)] = "World";
d[2, false, new DateTime(2018, 6, 18)] = "Foo";
d[2, false, new DateTime(2018, 6, 19)] = "Bar";
Console.WriteLine(d[1, true, new DateTime(2018, 6, 18)]); // World
}
}
You could even at a pinch implement the IDictionary methods. Given that Tuple internally gives you a good spread on your hashcodes from the composite keys, it should have very similar performance characteristics of three separate dictionaries in a nest.
Upvotes: 2