diff --git a/TYLDDB.Utils.FastCache.Test/Program.cs b/TYLDDB.Utils.FastCache.Test/Program.cs
index da4dde3..1b06543 100644
--- a/TYLDDB.Utils.FastCache.Test/Program.cs
+++ b/TYLDDB.Utils.FastCache.Test/Program.cs
@@ -1,11 +1,15 @@
-using TYLDDB.Utils.FastCache;
+using TYLDDB.Utils.FastCache;
using TYLDDB.Utils.FastCache.Test;
+Console.WriteLine("基于信号量的缓存读写运行");
SemaphoreSlimDefault();
+Console.WriteLine();
+Console.WriteLine("基于信号量的缓存读写运行");
+ConcurrentDictionary();
Console.ReadLine();
-// 普通线程锁的数据库读写运行
+// 基于信号量的缓存读写运行
static async void SemaphoreSlimDefault()
{
var setTime = new HighPrecisionTimer();
@@ -17,7 +21,7 @@ static async void SemaphoreSlimDefault()
var getAllCacheTime = new HighPrecisionTimer();
var getAllCacheAsyncTime = new HighPrecisionTimer();
- var cache = new Cache();
+ ICache cache = new SemaphoreThreadLock();
setTime.Start();
cache.Set("TESTKEY1", "TESTVALUE1");
@@ -68,6 +72,75 @@ static async void SemaphoreSlimDefault()
getAllCacheAsyncTime.Stop();
+ Console.WriteLine("时间消耗:");
+ Console.WriteLine($"设置键值(同步):{setTime.ElapsedMilliseconds()}ms 设置键值(异步):{setAsyncTime.ElapsedMilliseconds()}ms");
+ Console.WriteLine($"根据键获取值(同步):{getByKeyTime.ElapsedMilliseconds()}ms 根据键获取值(异步):{getByKeyAsyncTime.ElapsedMilliseconds()}ms");
+ Console.WriteLine($"根据值获取键(同步):{getKeysByValueTime.ElapsedMilliseconds()}ms 根据值获取键(异步):{getKeysByValueAsyncTime.ElapsedMilliseconds()}ms");
+ Console.WriteLine($"获取所有缓存项(同步):{getAllCacheTime.ElapsedMilliseconds()}ms 获取所有缓存项(异步):{getAllCacheAsyncTime.ElapsedMilliseconds()}ms");
+}
+
+// 基于并发词典的缓存读写运行
+static async void ConcurrentDictionary()
+{
+ var setTime = new HighPrecisionTimer();
+ var setAsyncTime = new HighPrecisionTimer();
+ var getByKeyTime = new HighPrecisionTimer();
+ var getByKeyAsyncTime = new HighPrecisionTimer();
+ var getKeysByValueTime = new HighPrecisionTimer();
+ var getKeysByValueAsyncTime = new HighPrecisionTimer();
+ var getAllCacheTime = new HighPrecisionTimer();
+ var getAllCacheAsyncTime = new HighPrecisionTimer();
+
+ ICache cache = new ConcurrentDictionary();
+
+ setTime.Start();
+ cache.Set("TESTKEY1", "TESTVALUE1");
+ setTime.Stop();
+
+ setAsyncTime.Start();
+ await cache.SetAsync("TESTKEY2", "TESTVALUE2");
+ setAsyncTime.Stop();
+
+ getByKeyTime.Start();
+ Console.WriteLine("TESTKEY1对应的值:" + cache.GetByKey("TESTKEY1"));
+ getByKeyTime.Stop();
+
+ getByKeyAsyncTime.Start();
+ Console.WriteLine("TESTKEY2对应的值:" + await cache.GetByKeyAsync("TESTKEY2"));
+ getByKeyAsyncTime.Stop();
+
+ cache.Set("TESTKEY3", "TESTVALUE2");
+
+ Console.WriteLine("TESTVALUE2对应的所有键:");
+ getKeysByValueTime.Start();
+ Console.WriteLine(string.Join(", ", cache.GetKeysByValue("TESTVALUE2")));
+ getKeysByValueTime.Stop();
+
+ Console.WriteLine("TESTVALUE2对应的所有键:");
+ getKeysByValueAsyncTime.Start();
+ Console.WriteLine(string.Join(", ", await cache.GetKeysByValueAsync("TESTVALUE2")));
+ getKeysByValueAsyncTime.Stop();
+
+ // 获取并输出所有缓存项(同步方法)
+ getAllCacheTime.Start();
+ var allCacheSync = cache.GetAllCache();
+ Console.WriteLine("同步获取所有缓存项:");
+ foreach (var kvp in allCacheSync)
+ {
+ Console.WriteLine($"{kvp.Key}: {kvp.Value}");
+ }
+ getAllCacheTime.Stop();
+
+ // 获取并输出所有缓存项(异步方法)
+ getAllCacheAsyncTime.Start();
+ var allCacheAsync = await cache.GetAllCacheAsync();
+ Console.WriteLine("异步获取所有缓存项:");
+ foreach (var kvp in allCacheAsync)
+ {
+ Console.WriteLine($"{kvp.Key}: {kvp.Value}");
+ }
+ getAllCacheAsyncTime.Stop();
+
Console.WriteLine("时间消耗:");
Console.WriteLine($"设置键值(同步):{setTime.ElapsedMilliseconds()}ms 设置键值(异步):{setAsyncTime.ElapsedMilliseconds()}ms");
Console.WriteLine($"根据键获取值(同步):{getByKeyTime.ElapsedMilliseconds()}ms 根据键获取值(异步):{getByKeyAsyncTime.ElapsedMilliseconds()}ms");
diff --git a/TYLDDB/TYLDDB.cs b/TYLDDB/TYLDDB.cs
index 0fe14ba..359ce37 100644
--- a/TYLDDB/TYLDDB.cs
+++ b/TYLDDB/TYLDDB.cs
@@ -78,25 +78,23 @@ public void ReadingFile()
/// name of the database
数据库名称
public void LoadDatabase(string db)
{
- if (_isRead == true)
+ switch (_isRead)
{
- _databaseContent = database.GetDatabaseContent(_fileContent, db);
- }
- else
- {
- ReadingFile();
- _databaseContent = database.GetDatabaseContent(_fileContent, db);
- }
+ case true:
+ _databaseContent = database.GetDatabaseContent(_fileContent, db);
+ break;
+ default:
+ ReadingFile();
+ _databaseContent = database.GetDatabaseContent(_fileContent, db);
+ break;
}
+ }
///
/// Gets the contents of the database being loaded
/// 获取正在加载的数据库内容
///
- public string GetLoadingDatabaseContent()
- {
- return _databaseContent;
- }
+ public string GetLoadingDatabaseContent() => _databaseContent;
///
/// Read the names of all databases
diff --git a/TYLDDB/TYLDDB.csproj b/TYLDDB/TYLDDB.csproj
index 4a1776d..7a9222e 100644
--- a/TYLDDB/TYLDDB.csproj
+++ b/TYLDDB/TYLDDB.csproj
@@ -1,11 +1,11 @@
-
+
netstandard2.0;netstandard2.1;net6.0;net8.0;net9.0
True
TTYPDB.NET
- 1.0.0-alpha.1
- QingYi-Studio
+ 1.0.0-alpha.2
+ TYLDDB-Project
LICENSE
True
icon.png
@@ -17,6 +17,8 @@
True
True
DataBase
+ QingYi-Studio
+ README.md
@@ -37,6 +39,10 @@
True
\
+
+ True
+ \
+
diff --git a/TYLDDB/Utils/FastCache/ConcurrentDictionary.cs b/TYLDDB/Utils/FastCache/ConcurrentDictionary.cs
new file mode 100644
index 0000000..55a4d5f
--- /dev/null
+++ b/TYLDDB/Utils/FastCache/ConcurrentDictionary.cs
@@ -0,0 +1,159 @@
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace TYLDDB.Utils.FastCache
+{
+ ///
+ /// Use thread locks based on concurrent dictionaries to achieve high concurrency stability.
+ /// 使用基于信号量的线程锁来实现高并发的稳定性。
+ ///
+ public class ConcurrentDictionary : ICache
+ {
+ ///
+ /// Thread-safe dictionary to store cache data.
+ /// 线程安全的字典,用于存储缓存数据。
+ ///
+ private readonly ConcurrentDictionary _cache = new ConcurrentDictionary();
+
+ ///
+ /// Synchronization method: Obtain the corresponding value by key.
+ /// 同步方法:根据键获取对应的值。
+ ///
+ /// Key
键
+ /// Value
值
+ public string GetByKey(string key)
+ {
+ _cache.TryGetValue(key, out var value);
+ return value;
+ }
+
+ ///
+ /// Asynchronous method to get the corresponding value by key.
+ /// 异步方法:根据键获取对应的值。
+ ///
+ /// Key
键
+ /// Value
值
+ public async Task GetByKeyAsync(string key)
+ {
+ return await Task.FromResult(GetByKey(key));
+ }
+
+ ///
+ /// Get a list of keys that correspond to a specific value.
+ /// 获取与指定值对应的所有键的列表。
+ ///
+ /// Value to match
要匹配的值
+ /// List of keys
键的列表
+ public List GetKeysByValue(string value)
+ {
+ var keys = new List();
+ foreach (var kvp in _cache)
+ {
+ if (kvp.Value == value)
+ {
+ keys.Add(kvp.Key);
+ }
+ }
+ return keys;
+ }
+
+ ///
+ /// Asynchronous method to get a list of keys that correspond to a specific value.
+ /// 异步方法:获取与指定值对应的所有键的列表。
+ ///
+ /// Value to match
要匹配的值
+ /// List of keys
键的列表
+ public async Task> GetKeysByValueAsync(string value)
+ {
+ return await Task.FromResult(GetKeysByValue(value));
+ }
+
+ ///
+ /// Set a cache entry for a specified key.
+ /// 为指定键设置缓存项。
+ ///
+ /// Key
键
+ /// Value
值
+ /// Whether the operation is successful.
操作是否成功。
+ public bool Set(string key, string value)
+ {
+ // Using AddOrUpdate to ensure atomic insert or update operation
+ _cache.AddOrUpdate(key, value, (existingKey, existingValue) => value);
+ return true;
+ }
+
+ ///
+ /// Asynchronous method to set a cache entry for a specified key.
+ /// 异步方法:为指定键设置缓存项。
+ ///
+ /// Key
键
+ /// Value
值
+ /// Whether the operation is successful.
操作是否成功。
+ public async Task SetAsync(string key, string value)
+ {
+ return await Task.FromResult(Set(key, value));
+ }
+
+ ///
+ /// Remove a cache entry by its key.
+ /// 根据键移除缓存项。
+ ///
+ /// Key
键
+ /// Whether the removal is successful.
移除操作是否成功。
+ public bool RemoveByKey(string key)
+ {
+ return _cache.TryRemove(key, out _);
+ }
+
+ ///
+ /// Asynchronous method to remove a cache entry by its key.
+ /// 异步方法:根据键移除缓存项。
+ ///
+ /// Key
键
+ /// Whether the removal is successful.
移除操作是否成功。
+ public async Task RemoveByKeyAsync(string key)
+ {
+ return await Task.FromResult(RemoveByKey(key));
+ }
+
+ ///
+ /// Clear all cache entries.
+ /// 清空所有缓存项。
+ ///
+ public void Clear()
+ {
+ _cache.Clear();
+ }
+
+ ///
+ /// Asynchronous method to clear all cache entries.
+ /// 异步方法:清空所有缓存项。
+ ///
+ /// Asynchronous task for clearing.
清空操作的异步任务。
+ public async Task ClearAsync()
+ {
+ await Task.Run(() => Clear());
+ }
+
+ ///
+ /// Get all cache entries as a dictionary.
+ /// 获取所有缓存项,返回字典。
+ ///
+ /// All cache entries as a dictionary.
所有缓存项的字典。
+ public Dictionary GetAllCache()
+ {
+ return new Dictionary(_cache);
+ }
+
+ ///
+ /// Asynchronous method to get all cache entries as a dictionary.
+ /// 异步方法:获取所有缓存项,返回字典。
+ ///
+ /// All cache entries as a dictionary.
所有缓存项的字典。
+ public async Task> GetAllCacheAsync()
+ {
+ return await Task.FromResult(GetAllCache());
+ }
+ }
+}
diff --git a/TYLDDB/Utils/FastCache/ICache.cs b/TYLDDB/Utils/FastCache/ICache.cs
new file mode 100644
index 0000000..76561be
--- /dev/null
+++ b/TYLDDB/Utils/FastCache/ICache.cs
@@ -0,0 +1,99 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace TYLDDB.Utils.FastCache
+{
+ ///
+ /// Use cached key-value pairs for fast reads and writes.
+ /// 使用缓存的键值对来快速读写。
+ ///
+ public interface ICache
+ {
+ ///
+ /// Synchronization method: Obtain the corresponding value by key.
+ /// 同步方法:根据键获取对应的值。
+ ///
+ /// Key
键
+ /// Value
值
+ string GetByKey(string key);
+
+ ///
+ /// Asynchronous method: Obtains the corresponding value based on the key.
+ /// 异步方法:根据键获取对应的值。
+ ///
+ /// Key
键
+ /// Value
值
+ Task GetByKeyAsync(string key);
+
+ ///
+ /// Synchronization method: Obtains one or more keys according to the value.
+ /// 同步方法:根据值获取对应的一个或多个键。
+ ///
+ /// Value
值
+ /// Key (List)
键 (List)
+ List GetKeysByValue(string value);
+
+ ///
+ /// Asynchronous method: Get one or more keys based on the value.
+ /// 异步方法:根据值获取对应的一个或多个键。
+ ///
+ /// Value
值
+ /// Key (List)
键 (List)
+ Task> GetKeysByValueAsync(string value);
+
+ ///
+ /// 同步方法:设置一个键值对。
+ ///
+ ///
+ ///
+ ///
+ bool Set(string key, string value);
+
+ ///
+ /// 异步方法:设置一个键值对。
+ ///
+ ///
+ ///
+ ///
+ Task SetAsync(string key, string value);
+
+ ///
+ /// 同步方法:移除一个键值对。
+ ///
+ ///
+ ///
+ bool RemoveByKey(string key);
+
+ ///
+ /// 异步方法:移除一个键值对。
+ ///
+ ///
+ ///
+ Task RemoveByKeyAsync(string key);
+
+ ///
+ /// 同步方法:清空缓存。
+ ///
+ void Clear();
+
+ ///
+ /// 异步方法:清空缓存。
+ ///
+ ///
+ Task ClearAsync();
+
+ ///
+ /// Gets all key-value pairs.
+ /// 获取所有的键值对。
+ ///
+ /// Key-value pair
键值对
+ Dictionary GetAllCache();
+
+ ///
+ /// Gets all key-value pairs.
+ /// 获取所有的键值对。
+ ///
+ /// Key-value pair
键值对
+ Task> GetAllCacheAsync();
+ }
+}
diff --git a/TYLDDB/Utils/FastCache/SemaphoreThreadLock.cs b/TYLDDB/Utils/FastCache/SemaphoreThreadLock.cs
new file mode 100644
index 0000000..ff661cd
--- /dev/null
+++ b/TYLDDB/Utils/FastCache/SemaphoreThreadLock.cs
@@ -0,0 +1,286 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace TYLDDB.Utils.FastCache
+{
+ ///
+ /// Use semaphore based thread locks to achieve high concurrency stability.
+ /// 使用基于信号量的线程锁来实现高并发的稳定性。
+ ///
+ public class SemaphoreThreadLock : ICache
+ {
+ private readonly Dictionary keyValueDict; // 存储键->值映射
+ private readonly Dictionary> valueKeyDict; // 存储值->键的映射
+ private readonly SemaphoreSlim semaphore; // 控制并发访问
+
+ ///
+ /// Use cached key-value pairs for fast reads and writes.
+ /// 使用缓存的键值对来快速读写。
+ ///
+ public SemaphoreThreadLock()
+ {
+ keyValueDict = new Dictionary();
+ valueKeyDict = new Dictionary>();
+ semaphore = new SemaphoreSlim(1, 1); // 使用信号量来同步
+ }
+
+ ///
+ /// Synchronization method: Obtain the corresponding value by key.
+ /// 同步方法:根据键获取对应的值。
+ ///
+ /// Key
键
+ /// Value
值
+ public string GetByKey(string key)
+ {
+ lock (semaphore)
+ {
+ keyValueDict.TryGetValue(key, out var value);
+ return value;
+ }
+ }
+
+ ///
+ /// Asynchronous method: Obtains the corresponding value based on the key.
+ /// 异步方法:根据键获取对应的值。
+ ///
+ /// Key
键
+ /// Value
值
+ public async Task GetByKeyAsync(string key)
+ {
+ await semaphore.WaitAsync();
+ try
+ {
+ keyValueDict.TryGetValue(key, out var value);
+ return value;
+ }
+ finally
+ {
+ semaphore.Release();
+ }
+ }
+
+ ///
+ /// Synchronization method: Obtains one or more keys according to the value.
+ /// 同步方法:根据值获取对应的一个或多个键。
+ ///
+ /// Value
值
+ /// Key (List)
键 (List)
+ public List GetKeysByValue(string value)
+ {
+ lock (semaphore)
+ {
+ if (valueKeyDict.ContainsKey(value))
+ {
+ return valueKeyDict[value].ToList();
+ }
+ return new List();
+ }
+ }
+
+ ///
+ /// Asynchronous method: Get one or more keys based on the value.
+ /// 异步方法:根据值获取对应的一个或多个键。
+ ///
+ /// Value
值
+ /// Key (List)
键 (List)
+ public async Task> GetKeysByValueAsync(string value)
+ {
+ await semaphore.WaitAsync();
+ try
+ {
+ if (valueKeyDict.ContainsKey(value))
+ {
+ return valueKeyDict[value].ToList();
+ }
+ return new List();
+ }
+ finally
+ {
+ semaphore.Release();
+ }
+ }
+
+ ///
+ /// 同步方法:设置一个键值对。
+ ///
+ ///
+ ///
+ ///
+ public bool Set(string key, string value)
+ {
+ lock (semaphore)
+ {
+ if (keyValueDict.ContainsKey(key))
+ {
+ return false; // 键已存在,不允许重复的键
+ }
+
+ keyValueDict[key] = value;
+
+ if (!valueKeyDict.ContainsKey(value))
+ {
+ valueKeyDict[value] = new HashSet();
+ }
+ valueKeyDict[value].Add(key);
+ return true;
+ }
+ }
+
+ ///
+ /// 异步方法:设置一个键值对。
+ ///
+ ///
+ ///
+ ///
+ public async Task SetAsync(string key, string value)
+ {
+ await semaphore.WaitAsync();
+ try
+ {
+ if (keyValueDict.ContainsKey(key))
+ {
+ return false; // 键已存在,不允许重复的键
+ }
+
+ keyValueDict[key] = value;
+
+ if (!valueKeyDict.ContainsKey(value))
+ {
+ valueKeyDict[value] = new HashSet();
+ }
+ valueKeyDict[value].Add(key);
+ return true;
+ }
+ finally
+ {
+ semaphore.Release();
+ }
+ }
+
+ ///
+ /// 同步方法:移除一个键值对。
+ ///
+ ///
+ ///
+ public bool RemoveByKey(string key)
+ {
+ lock (semaphore)
+ {
+ if (!keyValueDict.ContainsKey(key))
+ {
+ return false;
+ }
+ var value = keyValueDict[key];
+ keyValueDict.Remove(key);
+
+ if (valueKeyDict.ContainsKey(value))
+ {
+ valueKeyDict[value].Remove(key);
+ if (valueKeyDict[value].Count == 0)
+ {
+ valueKeyDict.Remove(value);
+ }
+ }
+ return true;
+ }
+ }
+
+ ///
+ /// 异步方法:移除一个键值对。
+ ///
+ ///
+ ///
+ public async Task RemoveByKeyAsync(string key)
+ {
+ await semaphore.WaitAsync();
+ try
+ {
+ if (!keyValueDict.ContainsKey(key))
+ {
+ return false;
+ }
+ var value = keyValueDict[key];
+ keyValueDict.Remove(key);
+
+ if (valueKeyDict.ContainsKey(value))
+ {
+ valueKeyDict[value].Remove(key);
+ if (valueKeyDict[value].Count == 0)
+ {
+ valueKeyDict.Remove(value);
+ }
+ }
+ return true;
+ }
+ finally
+ {
+ semaphore.Release();
+ }
+ }
+
+ ///
+ /// 同步方法:清空缓存。
+ ///
+ public void Clear()
+ {
+ lock (semaphore)
+ {
+ keyValueDict.Clear();
+ valueKeyDict.Clear();
+ }
+ }
+
+ ///
+ /// 异步方法:清空缓存。
+ ///
+ ///
+ public async Task ClearAsync()
+ {
+ await semaphore.WaitAsync();
+ try
+ {
+ keyValueDict.Clear();
+ valueKeyDict.Clear();
+ }
+ finally
+ {
+ semaphore.Release();
+ }
+ }
+
+ ///
+ /// Gets all key-value pairs.
+ /// 获取所有的键值对。
+ ///
+ /// Key-value pair
键值对
+ public Dictionary GetAllCache()
+ {
+ lock (semaphore)
+ {
+ // 返回完整的键值对字典
+ return new Dictionary(keyValueDict);
+ }
+ }
+
+ ///
+ /// Gets all key-value pairs.
+ /// 获取所有的键值对。
+ ///
+ /// Key-value pair
键值对
+ public async Task> GetAllCacheAsync()
+ {
+ await semaphore.WaitAsync();
+ try
+ {
+ // 返回完整的键值对字典
+ return new Dictionary(keyValueDict);
+ }
+ finally
+ {
+ semaphore.Release();
+ }
+ }
+ }
+}