Files
Nitrox/NitroxModel/DataStructures/ThreadSafeDictionary.cs
2025-07-06 00:23:46 +02:00

185 lines
4.2 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
namespace NitroxModel.DataStructures
{
[DebuggerDisplay($"Items = {{{nameof(Entries)}}}")]
[DataContract]
public class ThreadSafeDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[IgnoreDataMember]
private readonly IDictionary<TKey, TValue> dictionary;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[IgnoreDataMember]
private readonly object locker = new();
[IgnoreDataMember]
public ICollection<TKey> Keys
{
get
{
lock (locker)
{
return new List<TKey>(dictionary.Keys);
}
}
}
[IgnoreDataMember]
public ICollection<TValue> Values
{
get
{
lock (locker)
{
return new List<TValue>(dictionary.Values);
}
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[IgnoreDataMember]
public ICollection<KeyValuePair<TKey, TValue>> Entries
{
get
{
lock (locker)
{
return dictionary.ToList();
}
}
}
public TValue this[TKey key]
{
get
{
lock (locker)
{
return dictionary[key];
}
}
set
{
lock (locker)
{
dictionary[key] = value;
}
}
}
public int Count
{
get
{
lock (locker)
{
return dictionary.Count;
}
}
}
public bool IsReadOnly { get; } = false;
public ThreadSafeDictionary()
{
dictionary = new Dictionary<TKey, TValue>();
}
public ThreadSafeDictionary(IDictionary<TKey, TValue> dictionary, bool createCopy = true)
{
this.dictionary = createCopy ? new Dictionary<TKey, TValue>(dictionary) : dictionary;
}
public void Add(KeyValuePair<TKey, TValue> item)
{
lock (locker)
{
dictionary.Add(item);
}
}
public void Clear()
{
lock (locker)
{
dictionary.Clear();
}
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
lock (locker)
{
return dictionary.Contains(item);
}
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
lock (locker)
{
dictionary.CopyTo(array, arrayIndex);
}
}
public bool Remove(KeyValuePair<TKey, TValue> item)
{
lock (locker)
{
return dictionary.Remove(item);
}
}
public bool ContainsKey(TKey key)
{
lock (locker)
{
return dictionary.ContainsKey(key);
}
}
public void Add(TKey key, TValue value)
{
lock (locker)
{
dictionary.Add(key, value);
}
}
public bool Remove(TKey key)
{
lock (locker)
{
return dictionary.Remove(key);
}
}
public bool TryGetValue(TKey key, out TValue value)
{
lock (locker)
{
return dictionary.TryGetValue(key, out value);
}
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
lock (locker)
{
return new Dictionary<TKey, TValue>(dictionary).GetEnumerator();
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}