框架更新

This commit is contained in:
Bob.Song
2025-10-29 17:59:43 +08:00
parent fc18c8626a
commit a2cb248512
429 changed files with 7173 additions and 38748 deletions

View File

@@ -1,31 +0,0 @@
using System.Collections.Generic;
#pragma warning disable CS8601 // Possible null reference assignment.
namespace Fantasy.DataStructure.Dictionary
{
/// <summary>
/// 提供对字典的扩展方法。
/// </summary>
public static class DictionaryExtensions
{
/// <summary>
/// 尝试从字典中移除指定键,并返回相应的值。
/// </summary>
/// <typeparam name="T">字典中键的类型。</typeparam>
/// <typeparam name="TV">字典中值的类型。</typeparam>
/// <param name="self">要操作的字典实例。</param>
/// <param name="key">要移除的键。</param>
/// <param name="value">从字典中移除的值(如果成功移除)。</param>
/// <returns>如果成功移除键值对,则为 true否则为 false。</returns>
public static bool TryRemove<T, TV>(this IDictionary<T, TV> self, T key, out TV value)
{
if (!self.TryGetValue(key, out value))
{
return false;
}
self.Remove(key);
return true;
}
}
}

View File

@@ -1,70 +0,0 @@
using System;
using System.Collections.Generic;
using Fantasy.Pool;
namespace Fantasy.DataStructure.Dictionary
{
/// <summary>
/// 提供一个可以使用对象池管理的字典类。
/// </summary>
/// <typeparam name="TM">字典中键的类型。</typeparam>
/// <typeparam name="TN">字典中值的类型。</typeparam>
public sealed class DictionaryPool<TM, TN> : Dictionary<TM, TN>, IDisposable, IPool where TM : notnull
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 释放实例占用的资源。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
#if FANTASY_WEBGL
Pool<DictionaryPool<TM, TN>>.Return(this);
#else
MultiThreadPool.Return(this);
#endif
}
/// <summary>
/// 创建一个新的 <see cref="DictionaryPool{TM, TN}"/> 实例。
/// </summary>
/// <returns>新创建的实例。</returns>
public static DictionaryPool<TM, TN> Create()
{
#if FANTASY_WEBGL
var dictionary = Pool<DictionaryPool<TM, TN>>.Rent();
#else
var dictionary = MultiThreadPool.Rent<DictionaryPool<TM, TN>>();
#endif
dictionary._isDispose = false;
dictionary._isPool = true;
return dictionary;
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
}

View File

@@ -1,289 +0,0 @@
using System;
using System.Collections.Generic;
using Fantasy.Pool;
#pragma warning disable CS8601 // Possible null reference assignment.
#pragma warning disable CS8604 // Possible null reference argument.
#pragma warning disable CS8603 // Possible null reference return.
namespace Fantasy.DataStructure.Dictionary
{
/// <summary>
/// 提供一个双向映射字典对象池类,用于双向键值对映射。
/// </summary>
/// <typeparam name="TKey">字典中键的类型。</typeparam>
/// <typeparam name="TValue">字典中值的类型。</typeparam>
public class DoubleMapDictionaryPool<TKey, TValue> : DoubleMapDictionary<TKey, TValue>, IDisposable, IPool where TKey : notnull where TValue : notnull
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 创建一个新的 <see cref="DoubleMapDictionaryPool{TKey, TValue}"/> 实例。
/// </summary>
/// <returns>新创建的实例。</returns>
public static DoubleMapDictionaryPool<TKey, TValue> Create()
{
#if FANTASY_WEBGL
var a = Pool<DoubleMapDictionaryPool<TKey, TValue>>.Rent();
#else
var a = MultiThreadPool.Rent<DoubleMapDictionaryPool<TKey, TValue>>();
#endif
a._isDispose = false;
a._isPool = true;
return a;
}
/// <summary>
/// 释放实例占用的资源。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
#if FANTASY_WEBGL
Pool<DoubleMapDictionaryPool<TKey, TValue>>.Return(this);
#else
MultiThreadPool.Return(this);
#endif
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
/// <summary>
/// 可以实现双向映射的字典类,用于将键和值进行双向映射。
/// </summary>
/// <typeparam name="TK">键的类型,不能为 null。</typeparam>
/// <typeparam name="TV">值的类型,不能为 null。</typeparam>
public class DoubleMapDictionary<TK, TV> where TK : notnull where TV : notnull
{
private readonly Dictionary<TK, TV> _kv = new Dictionary<TK, TV>();
private readonly Dictionary<TV, TK> _vk = new Dictionary<TV, TK>();
/// <summary>
/// 创建一个新的空的 <see cref="DoubleMapDictionary{TK, TV}"/> 实例。
/// </summary>
public DoubleMapDictionary() { }
/// <summary>
/// 创建一个新的具有指定初始容量的 <see cref="DoubleMapDictionary{TK, TV}"/> 实例。
/// </summary>
/// <param name="capacity">初始容量。</param>
public DoubleMapDictionary(int capacity)
{
_kv = new Dictionary<TK, TV>(capacity);
_vk = new Dictionary<TV, TK>(capacity);
}
/// <summary>
/// 获取包含字典中所有键的列表。
/// </summary>
public List<TK> Keys => new List<TK>(_kv.Keys);
/// <summary>
/// 获取包含字典中所有值的列表。
/// </summary>
public List<TV> Values => new List<TV>(_vk.Keys);
/// <summary>
/// 对字典中的每个键值对执行指定的操作。
/// </summary>
/// <param name="action">要执行的操作。</param>
public void ForEach(Action<TK, TV> action)
{
if (action == null)
{
return;
}
var keys = _kv.Keys;
foreach (var key in keys)
{
action(key, _kv[key]);
}
}
/// <summary>
/// 将指定的键值对添加到字典中。
/// </summary>
/// <param name="key">要添加的键。</param>
/// <param name="value">要添加的值。</param>
public void Add(TK key, TV value)
{
if (key == null || value == null || _kv.ContainsKey(key) || _vk.ContainsKey(value))
{
return;
}
_kv.Add(key, value);
_vk.Add(value, key);
}
/// <summary>
/// 根据指定的键获取相应的值。
/// </summary>
/// <param name="key">要查找值的键。</param>
/// <returns>与指定键关联的值,如果找不到键,则返回默认值。</returns>
public TV GetValueByKey(TK key)
{
if (key != null && _kv.ContainsKey(key))
{
return _kv[key];
}
return default;
}
/// <summary>
/// 尝试根据指定的键获取相应的值。
/// </summary>
/// <param name="key">要查找值的键。</param>
/// <param name="value">如果找到,则为与指定键关联的值;否则为值的默认值。</param>
/// <returns>如果找到键,则为 true否则为 false。</returns>
public bool TryGetValueByKey(TK key, out TV value)
{
var result = key != null && _kv.ContainsKey(key);
value = result ? _kv[key] : default;
return result;
}
/// <summary>
/// 根据指定的值获取相应的键。
/// </summary>
/// <param name="value">要查找键的值。</param>
/// <returns>与指定值关联的键,如果找不到值,则返回默认键。</returns>
public TK GetKeyByValue(TV value)
{
if (value != null && _vk.ContainsKey(value))
{
return _vk[value];
}
return default;
}
/// <summary>
/// 尝试根据指定的值获取相应的键。
/// </summary>
/// <param name="value">要查找键的值。</param>
/// <param name="key">如果找到,则为与指定值关联的键;否则为键的默认值。</param>
/// <returns>如果找到值,则为 true否则为 false。</returns>
public bool TryGetKeyByValue(TV value, out TK key)
{
var result = value != null && _vk.ContainsKey(value);
key = result ? _vk[value] : default;
return result;
}
/// <summary>
/// 根据指定的键移除键值对。
/// </summary>
/// <param name="key">要移除的键。</param>
public void RemoveByKey(TK key)
{
if (key == null)
{
return;
}
if (!_kv.TryGetValue(key, out var value))
{
return;
}
_kv.Remove(key);
_vk.Remove(value);
}
/// <summary>
/// 根据指定的值移除键值对。
/// </summary>
/// <param name="value">要移除的值。</param>
public void RemoveByValue(TV value)
{
if (value == null)
{
return;
}
if (!_vk.TryGetValue(value, out var key))
{
return;
}
_kv.Remove(key);
_vk.Remove(value);
}
/// <summary>
/// 清空字典中的所有键值对。
/// </summary>
public void Clear()
{
_kv.Clear();
_vk.Clear();
}
/// <summary>
/// 判断字典是否包含指定的键。
/// </summary>
/// <param name="key">要检查的键。</param>
/// <returns>如果字典包含指定的键,则为 true否则为 false。</returns>
public bool ContainsKey(TK key)
{
return key != null && _kv.ContainsKey(key);
}
/// <summary>
/// 判断字典是否包含指定的值。
/// </summary>
/// <param name="value">要检查的值。</param>
/// <returns>如果字典包含指定的值,则为 true否则为 false。</returns>
public bool ContainsValue(TV value)
{
return value != null && _vk.ContainsKey(value);
}
/// <summary>
/// 判断字典是否包含指定的键值对。
/// </summary>
/// <param name="key">要检查的键。</param>
/// <param name="value">要检查的值。</param>
/// <returns>如果字典包含指定的键值对,则为 true否则为 false。</returns>
public bool Contains(TK key, TV value)
{
if (key == null || value == null)
{
return false;
}
return _kv.ContainsKey(key) && _vk.ContainsKey(value);
}
}
}

View File

@@ -1,91 +0,0 @@
using System;
using System.Collections.Generic;
using Fantasy.Pool;
namespace Fantasy.DataStructure.Dictionary
{
/// <summary>
/// 提供一个带资源释放功能的实体字典类,支持使用对象池管理。
/// </summary>
/// <typeparam name="TM">字典中键的类型。</typeparam>
/// <typeparam name="TN">字典中值的类型,必须实现 IDisposable 接口。</typeparam>
public sealed class EntityDictionary<TM, TN> : Dictionary<TM, TN>, IDisposable, IPool where TN : IDisposable where TM : notnull
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 创建一个新的 <see cref="EntityDictionary{TM, TN}"/> 实例。
/// </summary>
/// <returns>新创建的实例。</returns>
public static EntityDictionary<TM, TN> Create()
{
#if FANTASY_WEBGL
var entityDictionary = Pool<EntityDictionary<TM, TN>>.Rent();
#else
var entityDictionary = MultiThreadPool.Rent<EntityDictionary<TM, TN>>();
#endif
entityDictionary._isDispose = false;
entityDictionary._isPool = true;
return entityDictionary;
}
/// <summary>
/// 清空字典中的所有键值对,并释放值的资源。
/// </summary>
public new void Clear()
{
foreach (var keyValuePair in this)
{
keyValuePair.Value.Dispose();
}
base.Clear();
}
/// <summary>
/// 清空字典中的所有键值对,但不释放值的资源。
/// </summary>
public void ClearNotDispose()
{
base.Clear();
}
/// <summary>
/// 释放实例占用的资源。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
#if FANTASY_WEBGL
Pool<EntityDictionary<TM, TN>>.Return(this);
#else
MultiThreadPool.Return(this);
#endif
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
}

View File

@@ -1,247 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Fantasy.Pool;
#pragma warning disable CS8603
#pragma warning disable CS8601
namespace Fantasy.DataStructure.Dictionary
{
/// <summary>
/// 一对多映射关系的字典对象池。
/// </summary>
/// <typeparam name="TKey">外部字典中的键类型。</typeparam>
/// <typeparam name="TValueKey">内部字典中的键类型。</typeparam>
/// <typeparam name="TValue">内部字典中的值类型。</typeparam>
public class OneToManyDictionaryPool<TKey, TValueKey, TValue> : OneToManyDictionary<TKey, TValueKey, TValue>, IDisposable, IPool where TKey : notnull where TValueKey : notnull
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 创建一个 <see cref="OneToManyDictionaryPool{TKey, TValueKey, TValue}"/> 的实例。
/// </summary>
/// <returns>新创建的 OneToManyDictionaryPool 实例。</returns>
public static OneToManyDictionaryPool<TKey, TValueKey, TValue> Create()
{
#if FANTASY_WEBGL
var a = Pool<OneToManyDictionaryPool<TKey, TValueKey, TValue>>.Rent();
#else
var a = MultiThreadPool.Rent<OneToManyDictionaryPool<TKey, TValueKey, TValue>>();
#endif
a._isDispose = false;
a._isPool = true;
return a;
}
/// <summary>
/// 释放当前实例及其资源。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
#if FANTASY_WEBGL
Pool<OneToManyDictionaryPool<TKey, TValueKey, TValue>>.Return(this);
#else
MultiThreadPool.Return(this);
#endif
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
/// <summary>
/// 一对多映射关系的字典。每个键都对应一个内部字典,该内部字典将键值映射到相应的值。
/// </summary>
/// <typeparam name="TKey">外部字典中的键类型。</typeparam>
/// <typeparam name="TValueKey">内部字典中的键类型。</typeparam>
/// <typeparam name="TValue">内部字典中的值类型。</typeparam>
public class OneToManyDictionary<TKey, TValueKey, TValue> : Dictionary<TKey, Dictionary<TValueKey, TValue>>
where TKey : notnull where TValueKey : notnull
{
private readonly Queue<Dictionary<TValueKey, TValue>> _queue = new Queue<Dictionary<TValueKey, TValue>>();
private readonly int _recyclingLimit = 120;
/// <summary>
/// 创建一个新的 <see cref="OneToManyDictionary{TKey, TValueKey, TValue}"/> 实例。
/// </summary>
public OneToManyDictionary() { }
/// <summary>
/// 创建一个新的 <see cref="OneToManyDictionary{TKey, TValueKey, TValue}"/> 实例,并指定最大缓存数量。
/// </summary>
/// <param name="recyclingLimit">
/// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC.
/// 2:设置成0不控制数量全部缓存
/// </param>
public OneToManyDictionary(int recyclingLimit = 0)
{
_recyclingLimit = recyclingLimit;
}
/// <summary>
/// 检查是否包含指定的键值对。
/// </summary>
/// <param name="key">外部字典中的键。</param>
/// <param name="valueKey">内部字典中的键。</param>
/// <returns>如果包含指定的键值对,则为 true否则为 false。</returns>
public bool Contains(TKey key, TValueKey valueKey)
{
TryGetValue(key, out var dic);
return dic != null && dic.ContainsKey(valueKey);
}
/// <summary>
/// 尝试获取指定键值对的值。
/// </summary>
/// <param name="key">外部字典中的键。</param>
/// <param name="valueKey">内部字典中的键。</param>
/// <param name="value">获取的值,如果操作成功,则为值;否则为默认值。</param>
/// <returns>如果操作成功,则为 true否则为 false。</returns>
public bool TryGetValue(TKey key, TValueKey valueKey, out TValue value)
{
value = default;
return TryGetValue(key, out var dic) && dic.TryGetValue(valueKey, out value);
}
/// <summary>
/// 获取指定键的第一个值。
/// </summary>
/// <param name="key">要获取第一个值的键。</param>
public TValue First(TKey key)
{
return !TryGetValue(key, out var dic) ? default : dic.First().Value;
}
/// <summary>
/// 向字典中添加指定的键值对。
/// </summary>
/// <param name="key">要添加键值对的键。</param>
/// <param name="valueKey">要添加键值对的内部字典键。</param>
/// <param name="value">要添加的值。</param>
public void Add(TKey key, TValueKey valueKey, TValue value)
{
if (!TryGetValue(key, out var dic))
{
dic = Fetch();
dic[valueKey] = value;
// dic.Add(valueKey, value);
Add(key, dic);
return;
}
dic[valueKey] = value;
// dic.Add(valueKey, value);
}
/// <summary>
/// 从字典中移除指定的键值对。
/// </summary>
/// <param name="key">要移除键值对的键。</param>
/// <param name="valueKey">要移除键值对的内部字典键。</param>
/// <returns>如果成功移除键值对,则为 true否则为 false。</returns>
public bool Remove(TKey key, TValueKey valueKey)
{
if (!TryGetValue(key, out var dic)) return false;
var result = dic.Remove(valueKey);
if (dic.Count == 0) RemoveKey(key);
return result;
}
/// <summary>
/// 从字典中移除指定的键值对。
/// </summary>
/// <param name="key">要移除键值对的键。</param>
/// <param name="valueKey">要移除键值对的内部字典键。</param>
/// <param name="value">如果成功移除键值对,则为移除的值;否则为默认值。</param>
/// <returns>如果成功移除键值对,则为 true否则为 false。</returns>
public bool Remove(TKey key, TValueKey valueKey, out TValue value)
{
if (!TryGetValue(key, out var dic))
{
value = default;
return false;
}
var result = dic.TryGetValue(valueKey, out value);
if (result) dic.Remove(valueKey);
if (dic.Count == 0) RemoveKey(key);
return result;
}
/// <summary>
/// 移除字典中的指定键及其相关的所有键值对。
/// </summary>
/// <param name="key">要移除的键。</param>
public void RemoveKey(TKey key)
{
if (!TryGetValue(key, out var dic)) return;
Remove(key);
Recycle(dic);
}
/// <summary>
/// 从对象池中获取一个内部字典实例,如果池中没有,则创建一个新实例。
/// </summary>
/// <returns>获取的内部字典实例。</returns>
private Dictionary<TValueKey, TValue> Fetch()
{
return _queue.Count <= 0 ? new Dictionary<TValueKey, TValue>() : _queue.Dequeue();
}
/// <summary>
/// 将不再使用的内部字典实例放回对象池中,以便后续重用。
/// </summary>
/// <param name="dic">要放回对象池的内部字典实例。</param>
private void Recycle(Dictionary<TValueKey, TValue> dic)
{
dic.Clear();
if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return;
_queue.Enqueue(dic);
}
/// <summary>
/// 清空字典中的所有键值对,并将不再使用的内部字典实例放回对象池中。
/// </summary>
public new void Clear()
{
foreach (var keyValuePair in this) Recycle(keyValuePair.Value);
base.Clear();
}
}
}

View File

@@ -1,250 +0,0 @@
using System;
using System.Collections.Generic;
using Fantasy.Pool;
#pragma warning disable CS8601
namespace Fantasy.DataStructure.Dictionary
{
/// <summary>
/// 一对多映射关系的排序字典对象池。
/// </summary>
/// <typeparam name="TKey">外部字典中的键类型。</typeparam>
/// <typeparam name="TSortedKey">内部字典中的排序键类型。</typeparam>
/// <typeparam name="TValue">内部字典中的值类型。</typeparam>
public class OneToManySortedDictionaryPool<TKey, TSortedKey, TValue> : OneToManySortedDictionary<TKey, TSortedKey, TValue>, IDisposable, IPool where TKey : notnull where TSortedKey : notnull
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 创建一个 <see cref="OneToManySortedDictionaryPool{TKey, TSortedKey, TValue}"/> 的实例。
/// </summary>
/// <returns>新创建的 OneToManySortedDictionaryPool 实例。</returns>
public static OneToManySortedDictionaryPool<TKey, TSortedKey, TValue> Create()
{
#if FANTASY_WEBGL
var a = Pool<OneToManySortedDictionaryPool<TKey, TSortedKey, TValue>>.Rent();
#else
var a = MultiThreadPool.Rent<OneToManySortedDictionaryPool<TKey, TSortedKey, TValue>>();
#endif
a._isDispose = false;
a._isPool = true;
return a;
}
/// <summary>
/// 释放当前实例及其资源。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
#if FANTASY_WEBGL
Pool<OneToManySortedDictionaryPool<TKey, TSortedKey, TValue>>.Return(this);
#else
MultiThreadPool.Return(this);
#endif
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
/// <summary>
/// 一对多映射关系的排序字典。每个外部键映射到一个内部排序字典,该内部排序字典将排序键映射到相应的值。
/// </summary>
/// <typeparam name="TKey">外部字典中的键类型。</typeparam>
/// <typeparam name="TSortedKey">内部字典中的排序键类型。</typeparam>
/// <typeparam name="TValue">内部字典中的值类型。</typeparam>
public class
OneToManySortedDictionary<TKey, TSortedKey, TValue> : Dictionary<TKey, SortedDictionary<TSortedKey, TValue>>
where TSortedKey : notnull where TKey : notnull
{
/// 缓存队列的回收限制
private readonly int _recyclingLimit = 120;
/// 缓存队列,用于存储已回收的内部排序字典
private readonly Queue<SortedDictionary<TSortedKey, TValue>> _queue = new Queue<SortedDictionary<TSortedKey, TValue>>();
/// <summary>
/// 创建一个新的 <see cref="OneToManySortedDictionary{TKey, TSortedKey, TValue}"/> 实例。
/// </summary>
protected OneToManySortedDictionary() { }
/// <summary>
/// 创建一个新的 <see cref="OneToManySortedDictionary{TKey, TSortedKey, TValue}"/> 实例。设置最大缓存数量
/// </summary>
/// <param name="recyclingLimit">
/// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC.
/// 2:设置成0不控制数量全部缓存
/// </param>
public OneToManySortedDictionary(int recyclingLimit)
{
_recyclingLimit = recyclingLimit;
}
/// <summary>
/// 检查字典是否包含指定的外部键。
/// </summary>
/// <param name="key">要检查的外部键。</param>
/// <returns>如果字典包含指定的外部键,则为 true否则为 false。</returns>
public bool Contains(TKey key)
{
return this.ContainsKey(key);
}
/// <summary>
/// 检查字典是否包含指定的外部键和排序键。
/// </summary>
/// <param name="key">要检查的外部键。</param>
/// <param name="sortedKey">要检查的排序键。</param>
/// <returns>如果字典包含指定的外部键和排序键,则为 true否则为 false。</returns>
public bool Contains(TKey key, TSortedKey sortedKey)
{
return TryGetValue(key, out var dic) && dic.ContainsKey(sortedKey);
}
/// <summary>
/// 尝试从字典中获取指定外部键对应的内部排序字典。
/// </summary>
/// <param name="key">要获取内部排序字典的外部键。</param>
/// <param name="dic">获取到的内部排序字典,如果找不到则为 null。</param>
/// <returns>如果找到内部排序字典,则为 true否则为 false。</returns>
public new bool TryGetValue(TKey key, out SortedDictionary<TSortedKey, TValue> dic)
{
return base.TryGetValue(key, out dic);
}
/// <summary>
/// 尝试从字典中获取指定外部键和排序键对应的值。
/// </summary>
/// <param name="key">要获取值的外部键。</param>
/// <param name="sortedKey">要获取值的排序键。</param>
/// <param name="value">获取到的值,如果找不到则为 default。</param>
/// <returns>如果找到值,则为 true否则为 false。</returns>
public bool TryGetValueBySortedKey(TKey key, TSortedKey sortedKey, out TValue value)
{
if (base.TryGetValue(key, out var dic))
{
return dic.TryGetValue(sortedKey, out value);
}
value = default;
return false;
}
/// <summary>
/// 向字典中添加一个值,关联到指定的外部键和排序键。
/// </summary>
/// <param name="key">要关联值的外部键。</param>
/// <param name="sortedKey">要关联值的排序键。</param>
/// <param name="value">要添加的值。</param>
public void Add(TKey key, TSortedKey sortedKey, TValue value)
{
if (!TryGetValue(key, out var dic))
{
dic = Fetch();
dic.Add(sortedKey, value);
Add(key, dic);
return;
}
dic.Add(sortedKey, value);
}
/// <summary>
/// 从字典中移除指定外部键和排序键关联的值。
/// </summary>
/// <param name="key">要移除值的外部键。</param>
/// <param name="sortedKey">要移除值的排序键。</param>
/// <returns>如果成功移除值,则为 true否则为 false。</returns>
public bool RemoveSortedKey(TKey key, TSortedKey sortedKey)
{
if (!TryGetValue(key, out var dic))
{
return false;
}
var isRemove = dic.Remove(sortedKey);
if (dic.Count == 0)
{
isRemove = RemoveKey(key);
}
return isRemove;
}
/// <summary>
/// 从字典中移除指定外部键及其关联的所有值。
/// </summary>
/// <param name="key">要移除的外部键。</param>
/// <returns>如果成功移除外部键及其关联的所有值,则为 true否则为 false。</returns>
public bool RemoveKey(TKey key)
{
if (!TryGetValue(key, out var list))
{
return false;
}
Remove(key);
Recycle(list);
return true;
}
/// <summary>
/// 从缓存队列中获取一个内部排序字典。
/// </summary>
/// <returns>一个内部排序字典。</returns>
private SortedDictionary<TSortedKey, TValue> Fetch()
{
return _queue.Count <= 0 ? new SortedDictionary<TSortedKey, TValue>() : _queue.Dequeue();
}
/// <summary>
/// 回收一个内部排序字典到缓存队列。
/// </summary>
/// <param name="dic">要回收的内部排序字典。</param>
private void Recycle(SortedDictionary<TSortedKey, TValue> dic)
{
dic.Clear();
if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit)
{
return;
}
_queue.Enqueue(dic);
}
/// <summary>
/// 清空字典以及内部排序字典缓存队列,释放所有资源。
/// </summary>
protected new void Clear()
{
base.Clear();
_queue.Clear();
}
}
}

View File

@@ -1,70 +0,0 @@
using System;
using System.Collections.Generic;
using Fantasy.Pool;
namespace Fantasy.DataStructure.Dictionary
{
/// <summary>
/// 提供一个可以重用的字典类,支持使用对象池管理。
/// </summary>
/// <typeparam name="TM">字典中键的类型。</typeparam>
/// <typeparam name="TN">字典中值的类型。</typeparam>
public sealed class ReuseDictionary<TM, TN> : Dictionary<TM, TN>, IDisposable, IPool where TM : notnull
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 创建一个新的 <see cref="ReuseDictionary{TM, TN}"/> 实例。
/// </summary>
/// <returns>新创建的实例。</returns>
public static ReuseDictionary<TM, TN> Create()
{
#if FANTASY_WEBGL
var entityDictionary = Pool<ReuseDictionary<TM, TN>>.Rent();
#else
var entityDictionary = MultiThreadPool.Rent<ReuseDictionary<TM, TN>>();
#endif
entityDictionary._isDispose = false;
entityDictionary._isPool = true;
return entityDictionary;
}
/// <summary>
/// 释放实例占用的资源。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
#if FANTASY_WEBGL
Pool<ReuseDictionary<TM, TN>>.Return(this);
#else
MultiThreadPool.Return(this);
#endif
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
}

View File

@@ -1,70 +0,0 @@
using System;
using System.Collections.Generic;
using Fantasy.Pool;
namespace Fantasy.DataStructure.Dictionary
{
/// <summary>
/// 提供一个可以使用对象池管理的排序字典类。
/// </summary>
/// <typeparam name="TM"></typeparam>
/// <typeparam name="TN"></typeparam>
public sealed class SortedDictionaryPool<TM, TN> : SortedDictionary<TM, TN>, IDisposable, IPool where TM : notnull
{
private bool _isPool;
private bool _isDispose;
/// <summary>
/// 释放实例占用的资源。
/// </summary>
public void Dispose()
{
if (_isDispose)
{
return;
}
_isDispose = true;
Clear();
#if FANTASY_WEBGL
Pool<SortedDictionaryPool<TM, TN>>.Return(this);
#else
MultiThreadPool.Return(this);
#endif
}
/// <summary>
/// 创建一个新的 <see cref="SortedDictionaryPool{TM, TN}"/> 实例。
/// </summary>
/// <returns>新创建的实例。</returns>
public static SortedDictionaryPool<TM, TN> Create()
{
#if FANTASY_WEBGL
var dictionary = Pool<SortedDictionaryPool<TM, TN>>.Rent();
#else
var dictionary = MultiThreadPool.Rent<SortedDictionaryPool<TM, TN>>();
#endif
dictionary._isDispose = false;
dictionary._isPool = true;
return dictionary;
}
/// <summary>
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <returns></returns>
public bool IsPool()
{
return _isPool;
}
/// <summary>
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
/// </summary>
/// <param name="isPool"></param>
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
}