From 3fc1302cfbf315956040f5592442c4edcc593ab4 Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Sat, 21 Dec 2024 20:35:40 +0800 Subject: [PATCH 01/18] style: remove unused using --- TYLDDB/TYLDDB.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/TYLDDB/TYLDDB.cs b/TYLDDB/TYLDDB.cs index a8c6986..569a5c9 100644 --- a/TYLDDB/TYLDDB.cs +++ b/TYLDDB/TYLDDB.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Threading.Tasks; using TYLDDB.Basic; using TYLDDB.Utils; From e405fca5339d85ab39f083076321be3b29fc154e Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Sat, 21 Dec 2024 20:36:07 +0800 Subject: [PATCH 02/18] docs: change some comments --- TYLDDB.Test/Program.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TYLDDB.Test/Program.cs b/TYLDDB.Test/Program.cs index 942e036..d2f6cee 100644 --- a/TYLDDB.Test/Program.cs +++ b/TYLDDB.Test/Program.cs @@ -5,7 +5,7 @@ LDDB lddb = new LDDB(); ///////////////////////////////////////////////////////////////////////////////////////////////////////// 读取文件 -HighPrecisionTimer readDbTimer = new(); // 从发起读取文件指令到成功读取的总时间 +HighPrecisionTimer readDbTimer = new(); // 从发起读取文件到成功读取的总时间 readDbTimer.Start(); lddb.FilePath = "./example.lddb"; lddb.ReadingFile(); @@ -13,7 +13,7 @@ WriteTime("从发起读取文件指令到成功读取的总时间为: ", readDbTimer.ElapsedMilliseconds()); ///////////////////////////////////////////////////////////////////////////////////////////////////////// 读取数据库 -HighPrecisionTimer loadDbTimer = new(); // 从发起读取数据库指令到成功返回读取内容的总时间 +HighPrecisionTimer loadDbTimer = new(); // 从发起读取数据库到成功返回读取内容的总时间 loadDbTimer.Start(); lddb.LoadDatabase("database1"); Console.WriteLine(lddb.GetLoadingDatabaseContent()); // 输出database1内容 @@ -21,7 +21,7 @@ WriteTime("从发起读取数据库指令到成功返回读取内容的总时间为: ", loadDbTimer.ElapsedMilliseconds()); ///////////////////////////////////////////////////////////////////////////////////////////////////////// 获取所有数据库名称 -HighPrecisionTimer readAllDbNameTimer = new(); // 从发起读取数据库指令到成功返回读取内容的总时间 +HighPrecisionTimer readAllDbNameTimer = new(); // 从发起读取数据库名称到成功返回读取内容的总时间 readAllDbNameTimer.Start(); lddb.ReadAllDatabaseName(); readAllDbNameTimer.Stop(); @@ -32,7 +32,7 @@ Console.WriteLine(dbName); } } -WriteTime("从发起读取数据库指令到成功返回读取内容的总时间为: ", readAllDbNameTimer.ElapsedMilliseconds()); +WriteTime("从发起读取数据库名称到成功返回读取内容的总时间为: ", readAllDbNameTimer.ElapsedMilliseconds()); From f0f43e886163ad35029f1c007087ae8aaaf8558e Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Sun, 22 Dec 2024 13:33:11 +0800 Subject: [PATCH 03/18] docs: add "How To Use" file --- TYLDDB/How-To-Use.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 TYLDDB/How-To-Use.md diff --git a/TYLDDB/How-To-Use.md b/TYLDDB/How-To-Use.md new file mode 100644 index 0000000..ebee15e --- /dev/null +++ b/TYLDDB/How-To-Use.md @@ -0,0 +1,43 @@ +# How to use TYLDDB + +## Basic content + +### Read database + +#### Instantiate the LDDB class + +```c# +LDDB lddb = new LDDB(); +``` + +If you are using a higher version .NET, you can also write a little simpler. + +```c# +LDDB lddb = new(); +``` + +#### Read file + +```c# +lddb.FilePath = "./example.lddb"; +lddb.ReadingFile(); +``` + +The contents of the file are then loaded into memory. + +#### Select the database to read + +```c# +lddb.LoadDatabase("database1"); +``` + +This allows you to select the contents of the database for the next operation + +If you want to get all the contents of this database, you can use `lddb.GetLoadingDatabaseContent()` , which returns a string. + +#### Gets all database names + +```c# +lddb.ReadAllDatabaseName(); +``` + From 9a0aa6c1268158754bb0ee81593a7dcd1005186c Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Mon, 23 Dec 2024 21:48:49 +0800 Subject: [PATCH 04/18] =?UTF-8?q?=E5=86=99=E4=B8=89=E4=B8=AA=E6=96=B0?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E7=94=A8=E4=BA=8E=E8=AF=BB=E5=8F=96=E4=B8=8D?= =?UTF-8?q?=E5=90=8C=E5=A4=A7=E5=B0=8F=E7=9A=84=E6=96=87=E4=BB=B6=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TYLDDB/Utils/ReadFile.cs | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/TYLDDB/Utils/ReadFile.cs b/TYLDDB/Utils/ReadFile.cs index ebd4d55..8dc7b88 100644 --- a/TYLDDB/Utils/ReadFile.cs +++ b/TYLDDB/Utils/ReadFile.cs @@ -22,4 +22,46 @@ public static string ReadTylddbFile(string filePath) } } } +internal class NewReader +{ +public static string ReadFile(string fPath) +{return null;} +public static string ReadSmallFile(string path) +{return File.ReadAllText(path);} +public static string ReadMediumFile(string filePath) + { + // 使用 FileStream 和 BufferedStream 进行高效读取 + using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) + using (BufferedStream bs = new BufferedStream(fs)) + { + // 使用 MemoryStream 来动态存储文件内容 + using (MemoryStream ms = new MemoryStream()) + { + byte[] buffer = new byte[8192]; // 缓冲区大小 + int bytesRead; + + // 读取文件并将其内容写入 MemoryStream + while ((bytesRead = bs.Read(buffer, 0, buffer.Length)) > 0) + { + ms.Write(buffer, 0, bytesRead); + } + + // 返回完整文件内容的字符串 + return Encoding.UTF8.GetString(ms.ToArray()); + } + } + } +public static string ReadLargeFile(string filePath) + { + using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(filePath, FileMode.Open)) + { + using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor()) + { + byte[] buffer = new byte[accessor.Capacity]; + accessor.ReadArray(0, buffer, 0, (int)accessor.Capacity); + return Encoding.UTF8.GetString(buffer); + } + } + } +} } From 21800da092a0c61863f88f5ad000066531cee06f Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Mon, 23 Dec 2024 21:50:13 +0800 Subject: [PATCH 05/18] =?UTF-8?q?=E7=BB=9F=E4=B8=80=E4=BC=A0=E5=8F=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TYLDDB/Utils/ReadFile.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TYLDDB/Utils/ReadFile.cs b/TYLDDB/Utils/ReadFile.cs index 8dc7b88..5cc4731 100644 --- a/TYLDDB/Utils/ReadFile.cs +++ b/TYLDDB/Utils/ReadFile.cs @@ -24,10 +24,10 @@ public static string ReadTylddbFile(string filePath) } internal class NewReader { -public static string ReadFile(string fPath) +public static string ReadFile(string filePath) {return null;} -public static string ReadSmallFile(string path) -{return File.ReadAllText(path);} +public static string ReadSmallFile(string filePath) +{return File.ReadAllText(filePath);} public static string ReadMediumFile(string filePath) { // 使用 FileStream 和 BufferedStream 进行高效读取 From 5cb8fe1ab1bb6a5f434757008c6ce566a969f15d Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Mon, 23 Dec 2024 21:55:14 +0800 Subject: [PATCH 06/18] =?UTF-8?q?=E6=89=A9=E5=A4=A7=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TYLDDB/Utils/ReadFile.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TYLDDB/Utils/ReadFile.cs b/TYLDDB/Utils/ReadFile.cs index 5cc4731..7807120 100644 --- a/TYLDDB/Utils/ReadFile.cs +++ b/TYLDDB/Utils/ReadFile.cs @@ -37,7 +37,7 @@ public static string ReadMediumFile(string filePath) // 使用 MemoryStream 来动态存储文件内容 using (MemoryStream ms = new MemoryStream()) { - byte[] buffer = new byte[8192]; // 缓冲区大小 + byte[] buffer = new byte[65536]; // 缓冲区大小 int bytesRead; // 读取文件并将其内容写入 MemoryStream From fa35dad15527339ece932bfc53692a3ceafa3960 Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Mon, 23 Dec 2024 22:03:46 +0800 Subject: [PATCH 07/18] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E8=87=AA=E5=8A=A8readf?= =?UTF-8?q?ile=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TYLDDB/Utils/ReadFile.cs | 52 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/TYLDDB/Utils/ReadFile.cs b/TYLDDB/Utils/ReadFile.cs index 7807120..f27479d 100644 --- a/TYLDDB/Utils/ReadFile.cs +++ b/TYLDDB/Utils/ReadFile.cs @@ -25,7 +25,57 @@ public static string ReadTylddbFile(string filePath) internal class NewReader { public static string ReadFile(string filePath) -{return null;} +{ +// 获取文件信息 + FileInfo fileInfo = new FileInfo(filePath); + + // 获取文件大小 (单位字节) + long fileSize = fileInfo.Length; + + // 根据文件大小区间进行不同的处理 + if (fileSize < 1 * 1024 * 1024) // 小于 1MB + { + ReadSmallFile(filePath); + } + else if (fileSize < 15 * 1024 * 1024) // 小于 15MB + { + ReadMediumFile(filePath); + } + else + { + Console.WriteLine("文件较大 (> 10MB 且 <= 25MB),使用缓冲读取方式处理。"); + ReadLargeFile(filePath); + } +} +// 定义委托类型,表示文件处理的方式 + private delegate void FileProcessingStrategy(string filePath); + + // 使用一个字典来映射文件大小区间到处理方法 + private static readonly Dictionary<(long, long), FileProcessingStrategy> FileProcessingStrategies + = new Dictionary<(long, long), FileProcessingStrategy> + { + { (0, 1 * 1024 * 1024), ReadSmallFile }, // 小于 1MB + { (1 * 1024 * 1024, 15 * 1024 * 1024), ReadMediumFile }, // 1MB 到 15MB + { (15 * 1024 * 1024, long.MaxValue), ReadLargeFile } // 大于 15MB + }; + + public static void ReadFilePlus(string filePath) + { + // 获取文件信息 + FileInfo fileInfo = new FileInfo(filePath); + long fileSize = fileInfo.Length; + + // 根据文件大小选择合适的处理方法 + foreach (var entry in FileProcessingStrategies) + { + var (minSize, maxSize) = entry.Key; + if (fileSize > minSize && fileSize <= maxSize) + { + entry.Value(filePath); // 调用相应的处理策略 + break; + } + } + } public static string ReadSmallFile(string filePath) {return File.ReadAllText(filePath);} public static string ReadMediumFile(string filePath) From 9750411a4af83646f03ca026e2f6b86c9b9a96a5 Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Tue, 24 Dec 2024 15:46:59 +0800 Subject: [PATCH 08/18] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TYLDDB/Basic/Exception.cs | 43 --------------------------------------- 1 file changed, 43 deletions(-) diff --git a/TYLDDB/Basic/Exception.cs b/TYLDDB/Basic/Exception.cs index 5a20261..c354060 100644 --- a/TYLDDB/Basic/Exception.cs +++ b/TYLDDB/Basic/Exception.cs @@ -2,48 +2,6 @@ namespace TYLDDB.Basic { -#if NET8_0_OR_GREATER - /// - /// The main error module, most of them use this
- /// 主要的错误模块,大部分都使用这个 - ///
- public class TylddbException(string message) : Exception(message) { } - /// - /// File opening failure
- /// 文件打开失败 - ///
- public class FileOpenFailException(string message) : TylddbException(message) { } - /// - /// File read failure
- /// 文件读取失败 - ///
- public class FileReadingFailException(string message) : TylddbException(message) { } - /// - /// File not found
- /// 文件未找到 - ///
- public class FileNotFoundException(string message) : TylddbException(message) { } - /// - /// The file path is null or space
- /// 文件路径为null或空白 - ///
- public class FilePathIsNullOrWhiteSpace(string message) : TylddbException(message) { } - /// - /// Incorrect or invalid data
- /// 错误或无效的数据 - ///
- public class InvalidDataException(string message) : TylddbException(message) { } - /// - /// Database not found
- /// 未找到数据库 - ///
- public class DatabaseNotFoundException(string message) : TylddbException(message) { } - /// - /// Description Failed to obtain the database content
- /// 数据库内容获取失败 - ///
- public class GetDatabaseContentErrorException(string message) : TylddbException(message) { } -#else /// /// The main error module, most of them use this
/// 主要的错误模块,大部分都使用这个 @@ -140,5 +98,4 @@ public class GetDatabaseContentErrorException : TylddbException ///
public GetDatabaseContentErrorException(string message) : base(message) { } } -#endif } From ecc02915f1983c11015597205365a49069620b4b Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Tue, 24 Dec 2024 15:47:11 +0800 Subject: [PATCH 09/18] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=AF=B9=E6=97=A7?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TYLDDB/TYLDDB.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TYLDDB/TYLDDB.csproj b/TYLDDB/TYLDDB.csproj index 5b2f837..55ebde2 100644 --- a/TYLDDB/TYLDDB.csproj +++ b/TYLDDB/TYLDDB.csproj @@ -1,7 +1,7 @@  - netstandard1.6;netstandard2.0;netstandard2.1;net6.0;net8.0;net9.0 + netstandard2.0;netstandard2.1;net6.0;net8.0;net9.0 True TTYPDB.NET 1.0.0-beta.1 From c8e9a4d58bbfda61a614494cef71363c1a7e828a Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Tue, 24 Dec 2024 16:24:09 +0800 Subject: [PATCH 10/18] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AF=BB=E5=8F=96?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TYLDDB/Utils/ReadFile.cs | 244 ++++++++++++++++++++++++++++----------- 1 file changed, 175 insertions(+), 69 deletions(-) diff --git a/TYLDDB/Utils/ReadFile.cs b/TYLDDB/Utils/ReadFile.cs index f27479d..4695455 100644 --- a/TYLDDB/Utils/ReadFile.cs +++ b/TYLDDB/Utils/ReadFile.cs @@ -1,10 +1,22 @@ using System.IO; +using System.Text; using TYLDDB.Basic; namespace TYLDDB.Utils { - internal class ReadFile + /// + /// A struct used to read a file
+ /// 用于读取文件的结构体 + ///
+ public struct ReadFile { + /// + /// The earliest reading method based on FileStream + SreamReader.
+ /// 最早的基于 FileStream + SreamReader 的读取方法。 + ///
+ /// File path
文件路径 + /// File content
文件内容
+ /// public static string ReadTylddbFile(string filePath) { try @@ -21,97 +33,191 @@ public static string ReadTylddbFile(string filePath) throw new FileReadingFailException($"Error reading file: {ex.Message}"); } } - } -internal class NewReader -{ -public static string ReadFile(string filePath) -{ -// 获取文件信息 - FileInfo fileInfo = new FileInfo(filePath); - - // 获取文件大小 (单位字节) - long fileSize = fileInfo.Length; - // 根据文件大小区间进行不同的处理 - if (fileSize < 1 * 1024 * 1024) // 小于 1MB + /// + /// Select the desired method based on the file size
+ /// 根据文件大小选择所需的方法 + /// <1MB + /// 1MB~10MB + /// 10MB~15MB + /// 15MB~20MB + /// 20MB~30MB + /// >30MB + ///
+ /// File path
文件路径 + public static string ReadFileAuto(string filePath) { - ReadSmallFile(filePath); + // 获取文件信息 + FileInfo fileInfo = new FileInfo(filePath); + + // 获取文件大小 (单位字节) + long fileSize = fileInfo.Length; + + // 根据文件大小区间进行不同的处理 + if (fileSize < 1 * 1024 * 1024) // 小于 1MB + { + return ReadSmallFile(filePath); + } + else if (fileSize < 10 * 1024 * 1024) // 小于 10MB + { + return ReadMediumFile(filePath); + } + else if(fileSize < 15 * 1024 * 1024) // 小于 15MB + { + return ReadLargeFile_8(filePath); + } + else if(fileSize < 20 * 1024 * 1024) // 小于 20MB + { + return ReadLargeFile_64(filePath); + } + else if (fileSize < 30 * 1024 * 1024) // 小于 30MB + { + return ReadLargeFile_128(filePath); + } + else // 大于 30MB + { + return ReadVeryLargeFile(filePath); + } } - else if (fileSize < 15 * 1024 * 1024) // 小于 15MB + + /// + /// Read small file.
+ /// 读取小文件。 + ///
+ /// File path
文件路径 + /// File content
文件内容
+ public static string ReadSmallFile(string filePath) => File.ReadAllText(filePath); + + /// + /// Read medium file.
+ /// 读取中等大小文件。 + ///
+ /// File path
文件路径 + /// File content
文件内容
+ public static string ReadMediumFile(string filePath) { - ReadMediumFile(filePath); + // 使用 FileStream 和 BufferedStream 进行高效读取 + StringBuilder fileContent = new StringBuilder(); // 用来存储文件内容 + + using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) + using (BufferedStream bs = new BufferedStream(fs)) + using (StreamReader reader = new StreamReader(bs, Encoding.UTF8)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + // 将每一行的内容追加到 fileContent + fileContent.AppendLine(line); + } + } + + return fileContent.ToString(); // 返回文件的所有内容 } - else + + /// + /// Read large file.(8KB buffer)
+ /// 读取大文件。(8KB缓冲区) + ///
+ /// File path
文件路径 + /// File content
文件内容
+ public static string ReadLargeFile_8(string filePath) { - Console.WriteLine("文件较大 (> 10MB 且 <= 25MB),使用缓冲读取方式处理。"); - ReadLargeFile(filePath); - } -} -// 定义委托类型,表示文件处理的方式 - private delegate void FileProcessingStrategy(string filePath); + // 这里采用分块读取文件的方式,避免一次性加载大文件 + const int bufferSize = 8192; // 8 KB缓冲区 + byte[] buffer = new byte[bufferSize]; + StringBuilder fileContent = new StringBuilder(); - // 使用一个字典来映射文件大小区间到处理方法 - private static readonly Dictionary<(long, long), FileProcessingStrategy> FileProcessingStrategies - = new Dictionary<(long, long), FileProcessingStrategy> - { - { (0, 1 * 1024 * 1024), ReadSmallFile }, // 小于 1MB - { (1 * 1024 * 1024, 15 * 1024 * 1024), ReadMediumFile }, // 1MB 到 15MB - { (15 * 1024 * 1024, long.MaxValue), ReadLargeFile } // 大于 15MB - }; + using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) + { + int bytesRead; + while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) + { + // 将每一块数据转换成字符串并累积到 fileContent 中 + string chunkContent = Encoding.UTF8.GetString(buffer, 0, bytesRead); + fileContent.Append(chunkContent); + } + } - public static void ReadFilePlus(string filePath) - { - // 获取文件信息 - FileInfo fileInfo = new FileInfo(filePath); - long fileSize = fileInfo.Length; + // 返回文件的全部内容 + return fileContent.ToString(); + } - // 根据文件大小选择合适的处理方法 - foreach (var entry in FileProcessingStrategies) + /// + /// Read large file.(64KB buffer)
+ /// 读取大文件。(64KB缓冲区) + ///
+ /// File path
文件路径 + /// File content
文件内容
+ public static string ReadLargeFile_64(string filePath) { - var (minSize, maxSize) = entry.Key; - if (fileSize > minSize && fileSize <= maxSize) + // 这里采用分块读取文件的方式,避免一次性加载大文件 + const int bufferSize = 65536; // 64 KB缓冲区 + byte[] buffer = new byte[bufferSize]; + StringBuilder fileContent = new StringBuilder(); + + using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { - entry.Value(filePath); // 调用相应的处理策略 - break; + int bytesRead; + while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) + { + // 将每一块数据转换成字符串并累积到 fileContent 中 + string chunkContent = Encoding.UTF8.GetString(buffer, 0, bytesRead); + fileContent.Append(chunkContent); + } } + + // 返回文件的全部内容 + return fileContent.ToString(); } - } -public static string ReadSmallFile(string filePath) -{return File.ReadAllText(filePath);} -public static string ReadMediumFile(string filePath) - { - // 使用 FileStream 和 BufferedStream 进行高效读取 - using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) - using (BufferedStream bs = new BufferedStream(fs)) + + /// + /// Read large file.(128KB buffer)
+ /// 读取大文件。(128KB缓冲区) + ///
+ /// File path
文件路径 + /// File content
文件内容
+ public static string ReadLargeFile_128(string filePath) { - // 使用 MemoryStream 来动态存储文件内容 - using (MemoryStream ms = new MemoryStream()) + // 这里采用分块读取文件的方式,避免一次性加载大文件 + const int bufferSize = 131072; // 128 KB缓冲区 + byte[] buffer = new byte[bufferSize]; + StringBuilder fileContent = new StringBuilder(); + + using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { - byte[] buffer = new byte[65536]; // 缓冲区大小 int bytesRead; - - // 读取文件并将其内容写入 MemoryStream - while ((bytesRead = bs.Read(buffer, 0, buffer.Length)) > 0) + while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) { - ms.Write(buffer, 0, bytesRead); + // 将每一块数据转换成字符串并累积到 fileContent 中 + string chunkContent = Encoding.UTF8.GetString(buffer, 0, bytesRead); + fileContent.Append(chunkContent); } - - // 返回完整文件内容的字符串 - return Encoding.UTF8.GetString(ms.ToArray()); } + + // 返回文件的全部内容 + return fileContent.ToString(); } - } -public static string ReadLargeFile(string filePath) - { - using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(filePath, FileMode.Open)) + + // 使用 MemoryMappedFile 读取非常大的文件 + /// + /// Read very large file.(Based on MemoryMappedFile)
+ /// 读取很大的文件。(基于MemoryMappedFile) + ///
+ /// File path
文件路径 + /// File content
文件内容
+ public static string ReadVeryLargeFile(string filePath) { - using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor()) + using (System.IO.MemoryMappedFiles.MemoryMappedFile mmf = System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(filePath, FileMode.Open)) { - byte[] buffer = new byte[accessor.Capacity]; - accessor.ReadArray(0, buffer, 0, (int)accessor.Capacity); - return Encoding.UTF8.GetString(buffer); + using (System.IO.MemoryMappedFiles.MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor()) + { + long length = accessor.Capacity; + byte[] buffer = new byte[length]; + accessor.ReadArray(0, buffer, 0, (int)length); + string content = Encoding.UTF8.GetString(buffer); + return content; + } } } } } -} From 692f4090e9b84b785ae85a8eabbd9cec93a833d1 Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Tue, 24 Dec 2024 16:48:03 +0800 Subject: [PATCH 11/18] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TYLDDB.Test/Program.cs | 51 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/TYLDDB.Test/Program.cs b/TYLDDB.Test/Program.cs index d2f6cee..534ec1a 100644 --- a/TYLDDB.Test/Program.cs +++ b/TYLDDB.Test/Program.cs @@ -1,5 +1,10 @@ using TYLDDB; using TYLDDB.Test; +using TYLDDB.Utils; + +string dbFilePath = "./example.lddb"; + +ReadFileMethodTest(); ///////////////////////////////////////////////////////////////////////////////////////////////////////// 实例化 LDDB lddb = new LDDB(); @@ -7,7 +12,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////// 读取文件 HighPrecisionTimer readDbTimer = new(); // 从发起读取文件到成功读取的总时间 readDbTimer.Start(); -lddb.FilePath = "./example.lddb"; +lddb.FilePath = dbFilePath; lddb.ReadingFile(); readDbTimer.Stop(); WriteTime("从发起读取文件指令到成功读取的总时间为: ", readDbTimer.ElapsedMilliseconds()); @@ -50,9 +55,49 @@ Console.ReadLine(); +////////////////////////////////////////////////////////////////////////////////////////////////////////// Test Method - - +void ReadFileMethodTest() +{ + HighPrecisionTimer readSmallFileFuncTime = new(); + HighPrecisionTimer readMediumFileFuncTime = new(); + HighPrecisionTimer readLarge8FileFuncTime = new(); + HighPrecisionTimer readLarge64FileFuncTime = new(); + HighPrecisionTimer readLarge128FileFuncTime = new(); + HighPrecisionTimer readVeryLargeFileFuncTime = new(); + readSmallFileFuncTime.Start(); + ReadFile.ReadSmallFile(dbFilePath); + readSmallFileFuncTime.Stop(); + readMediumFileFuncTime.Start(); + ReadFile.ReadMediumFile(dbFilePath); + readMediumFileFuncTime.Stop(); + readLarge8FileFuncTime.Start(); + ReadFile.ReadLargeFile_8(dbFilePath); + readLarge8FileFuncTime.Stop(); + readLarge64FileFuncTime.Start(); + ReadFile.ReadLargeFile_64(dbFilePath); + readLarge64FileFuncTime.Stop(); + readLarge128FileFuncTime.Start(); + ReadFile.ReadLargeFile_128(dbFilePath); + readLarge128FileFuncTime.Stop(); + readVeryLargeFileFuncTime.Start(); + ReadFile.ReadVeryLargeFile(dbFilePath); + readVeryLargeFileFuncTime.Stop(); + Console.WriteLine("不同读取文件的方法测试:"); + Console.WriteLine($"小文件读取:{readSmallFileFuncTime.ElapsedMilliseconds()}ms"); + Console.WriteLine($"中文件读取:{readMediumFileFuncTime.ElapsedMilliseconds()}ms"); + Console.WriteLine($"大文件读取8kb:{readLarge8FileFuncTime.ElapsedMilliseconds()}ms"); + Console.WriteLine($"大文件读取64kb:{readLarge64FileFuncTime.ElapsedMilliseconds()}ms"); + Console.WriteLine($"大文件读取256kb:{readLarge128FileFuncTime.ElapsedMilliseconds()}ms"); + Console.WriteLine($"特大文件读取:{readVeryLargeFileFuncTime.ElapsedMilliseconds()}ms"); + + // 获取文件信息 + FileInfo fileInfo = new FileInfo(dbFilePath); + // 获取文件大小 (单位字节) + long fileSize = fileInfo.Length; + + Console.WriteLine("使用的测试文件大小为:" + fileSize / 1024); +} ///////////////////////////////////////////////////////////////////////////////////////////////////////// 工具 static void WriteTime(string what, double time) From 41b856e4902f007394d47783f0fc2b8ef0f6cd7f Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Tue, 24 Dec 2024 16:49:10 +0800 Subject: [PATCH 12/18] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=9A=84=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TYLDDB.Test/Program.cs | 45 ------------------------------------------ 1 file changed, 45 deletions(-) diff --git a/TYLDDB.Test/Program.cs b/TYLDDB.Test/Program.cs index 534ec1a..289cb0e 100644 --- a/TYLDDB.Test/Program.cs +++ b/TYLDDB.Test/Program.cs @@ -1,11 +1,8 @@ using TYLDDB; using TYLDDB.Test; -using TYLDDB.Utils; string dbFilePath = "./example.lddb"; -ReadFileMethodTest(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// 实例化 LDDB lddb = new LDDB(); @@ -57,48 +54,6 @@ ////////////////////////////////////////////////////////////////////////////////////////////////////////// Test Method -void ReadFileMethodTest() -{ - HighPrecisionTimer readSmallFileFuncTime = new(); - HighPrecisionTimer readMediumFileFuncTime = new(); - HighPrecisionTimer readLarge8FileFuncTime = new(); - HighPrecisionTimer readLarge64FileFuncTime = new(); - HighPrecisionTimer readLarge128FileFuncTime = new(); - HighPrecisionTimer readVeryLargeFileFuncTime = new(); - readSmallFileFuncTime.Start(); - ReadFile.ReadSmallFile(dbFilePath); - readSmallFileFuncTime.Stop(); - readMediumFileFuncTime.Start(); - ReadFile.ReadMediumFile(dbFilePath); - readMediumFileFuncTime.Stop(); - readLarge8FileFuncTime.Start(); - ReadFile.ReadLargeFile_8(dbFilePath); - readLarge8FileFuncTime.Stop(); - readLarge64FileFuncTime.Start(); - ReadFile.ReadLargeFile_64(dbFilePath); - readLarge64FileFuncTime.Stop(); - readLarge128FileFuncTime.Start(); - ReadFile.ReadLargeFile_128(dbFilePath); - readLarge128FileFuncTime.Stop(); - readVeryLargeFileFuncTime.Start(); - ReadFile.ReadVeryLargeFile(dbFilePath); - readVeryLargeFileFuncTime.Stop(); - Console.WriteLine("不同读取文件的方法测试:"); - Console.WriteLine($"小文件读取:{readSmallFileFuncTime.ElapsedMilliseconds()}ms"); - Console.WriteLine($"中文件读取:{readMediumFileFuncTime.ElapsedMilliseconds()}ms"); - Console.WriteLine($"大文件读取8kb:{readLarge8FileFuncTime.ElapsedMilliseconds()}ms"); - Console.WriteLine($"大文件读取64kb:{readLarge64FileFuncTime.ElapsedMilliseconds()}ms"); - Console.WriteLine($"大文件读取256kb:{readLarge128FileFuncTime.ElapsedMilliseconds()}ms"); - Console.WriteLine($"特大文件读取:{readVeryLargeFileFuncTime.ElapsedMilliseconds()}ms"); - - // 获取文件信息 - FileInfo fileInfo = new FileInfo(dbFilePath); - // 获取文件大小 (单位字节) - long fileSize = fileInfo.Length; - - Console.WriteLine("使用的测试文件大小为:" + fileSize / 1024); -} - ///////////////////////////////////////////////////////////////////////////////////////////////////////// 工具 static void WriteTime(string what, double time) { From 097b1ef7737fdeeb162826e73be45a86a8bc43a5 Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Tue, 24 Dec 2024 16:49:29 +0800 Subject: [PATCH 13/18] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AF=BB=E5=8F=96?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TYLDDB/TYLDDB.cs | 2 +- TYLDDB/Utils/ReadFile.cs | 190 +-------------------------------------- 2 files changed, 5 insertions(+), 187 deletions(-) diff --git a/TYLDDB/TYLDDB.cs b/TYLDDB/TYLDDB.cs index 569a5c9..7741e03 100644 --- a/TYLDDB/TYLDDB.cs +++ b/TYLDDB/TYLDDB.cs @@ -61,7 +61,7 @@ private static void ValidateFilePath(string path) /// public void ReadingFile() { - _fileContent = ReadFile.ReadTylddbFile(FilePath); + _fileContent = Reader.ReadFile(FilePath); _isRead = true; } diff --git a/TYLDDB/Utils/ReadFile.cs b/TYLDDB/Utils/ReadFile.cs index 4695455..31ecbe3 100644 --- a/TYLDDB/Utils/ReadFile.cs +++ b/TYLDDB/Utils/ReadFile.cs @@ -8,147 +8,15 @@ namespace TYLDDB.Utils /// A struct used to read a file
/// 用于读取文件的结构体 /// - public struct ReadFile + public struct Reader { /// - /// The earliest reading method based on FileStream + SreamReader.
- /// 最早的基于 FileStream + SreamReader 的读取方法。 + /// Read file.(64KB buffer)
+ /// 读取文件。(64KB缓冲区) ///
/// File path
文件路径 /// File content
文件内容
- /// - public static string ReadTylddbFile(string filePath) - { - try - { - using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) - using (StreamReader reader = new StreamReader(fs)) - { - string content = reader.ReadToEnd(); - return content; - } - } - catch (TylddbException ex) - { - throw new FileReadingFailException($"Error reading file: {ex.Message}"); - } - } - - /// - /// Select the desired method based on the file size
- /// 根据文件大小选择所需的方法 - /// <1MB - /// 1MB~10MB - /// 10MB~15MB - /// 15MB~20MB - /// 20MB~30MB - /// >30MB - ///
- /// File path
文件路径 - public static string ReadFileAuto(string filePath) - { - // 获取文件信息 - FileInfo fileInfo = new FileInfo(filePath); - - // 获取文件大小 (单位字节) - long fileSize = fileInfo.Length; - - // 根据文件大小区间进行不同的处理 - if (fileSize < 1 * 1024 * 1024) // 小于 1MB - { - return ReadSmallFile(filePath); - } - else if (fileSize < 10 * 1024 * 1024) // 小于 10MB - { - return ReadMediumFile(filePath); - } - else if(fileSize < 15 * 1024 * 1024) // 小于 15MB - { - return ReadLargeFile_8(filePath); - } - else if(fileSize < 20 * 1024 * 1024) // 小于 20MB - { - return ReadLargeFile_64(filePath); - } - else if (fileSize < 30 * 1024 * 1024) // 小于 30MB - { - return ReadLargeFile_128(filePath); - } - else // 大于 30MB - { - return ReadVeryLargeFile(filePath); - } - } - - /// - /// Read small file.
- /// 读取小文件。 - ///
- /// File path
文件路径 - /// File content
文件内容
- public static string ReadSmallFile(string filePath) => File.ReadAllText(filePath); - - /// - /// Read medium file.
- /// 读取中等大小文件。 - ///
- /// File path
文件路径 - /// File content
文件内容
- public static string ReadMediumFile(string filePath) - { - // 使用 FileStream 和 BufferedStream 进行高效读取 - StringBuilder fileContent = new StringBuilder(); // 用来存储文件内容 - - using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) - using (BufferedStream bs = new BufferedStream(fs)) - using (StreamReader reader = new StreamReader(bs, Encoding.UTF8)) - { - string line; - while ((line = reader.ReadLine()) != null) - { - // 将每一行的内容追加到 fileContent - fileContent.AppendLine(line); - } - } - - return fileContent.ToString(); // 返回文件的所有内容 - } - - /// - /// Read large file.(8KB buffer)
- /// 读取大文件。(8KB缓冲区) - ///
- /// File path
文件路径 - /// File content
文件内容
- public static string ReadLargeFile_8(string filePath) - { - // 这里采用分块读取文件的方式,避免一次性加载大文件 - const int bufferSize = 8192; // 8 KB缓冲区 - byte[] buffer = new byte[bufferSize]; - StringBuilder fileContent = new StringBuilder(); - - using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) - { - int bytesRead; - while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) - { - // 将每一块数据转换成字符串并累积到 fileContent 中 - string chunkContent = Encoding.UTF8.GetString(buffer, 0, bytesRead); - fileContent.Append(chunkContent); - } - } - - // 返回文件的全部内容 - return fileContent.ToString(); - } - - /// - /// Read large file.(64KB buffer)
- /// 读取大文件。(64KB缓冲区) - ///
- /// File path
文件路径 - /// File content
文件内容
- public static string ReadLargeFile_64(string filePath) + public static string ReadFile(string filePath) { // 这里采用分块读取文件的方式,避免一次性加载大文件 const int bufferSize = 65536; // 64 KB缓冲区 @@ -169,55 +37,5 @@ public static string ReadLargeFile_64(string filePath) // 返回文件的全部内容 return fileContent.ToString(); } - - /// - /// Read large file.(128KB buffer)
- /// 读取大文件。(128KB缓冲区) - ///
- /// File path
文件路径 - /// File content
文件内容
- public static string ReadLargeFile_128(string filePath) - { - // 这里采用分块读取文件的方式,避免一次性加载大文件 - const int bufferSize = 131072; // 128 KB缓冲区 - byte[] buffer = new byte[bufferSize]; - StringBuilder fileContent = new StringBuilder(); - - using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) - { - int bytesRead; - while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) - { - // 将每一块数据转换成字符串并累积到 fileContent 中 - string chunkContent = Encoding.UTF8.GetString(buffer, 0, bytesRead); - fileContent.Append(chunkContent); - } - } - - // 返回文件的全部内容 - return fileContent.ToString(); - } - - // 使用 MemoryMappedFile 读取非常大的文件 - /// - /// Read very large file.(Based on MemoryMappedFile)
- /// 读取很大的文件。(基于MemoryMappedFile) - ///
- /// File path
文件路径 - /// File content
文件内容
- public static string ReadVeryLargeFile(string filePath) - { - using (System.IO.MemoryMappedFiles.MemoryMappedFile mmf = System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(filePath, FileMode.Open)) - { - using (System.IO.MemoryMappedFiles.MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor()) - { - long length = accessor.Capacity; - byte[] buffer = new byte[length]; - accessor.ReadArray(0, buffer, 0, (int)length); - string content = Encoding.UTF8.GetString(buffer); - return content; - } - } - } } } From 364a659366074de7438d4584d6e530254aea4fdd Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Tue, 24 Dec 2024 17:07:07 +0800 Subject: [PATCH 14/18] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TYLDDB.Test/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TYLDDB.Test/Program.cs b/TYLDDB.Test/Program.cs index 289cb0e..b4583a7 100644 --- a/TYLDDB.Test/Program.cs +++ b/TYLDDB.Test/Program.cs @@ -8,8 +8,8 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////// 读取文件 HighPrecisionTimer readDbTimer = new(); // 从发起读取文件到成功读取的总时间 -readDbTimer.Start(); lddb.FilePath = dbFilePath; +readDbTimer.Start(); lddb.ReadingFile(); readDbTimer.Stop(); WriteTime("从发起读取文件指令到成功读取的总时间为: ", readDbTimer.ElapsedMilliseconds()); From d815c530b3b8998253aac17246521dd370b0ddbb Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Tue, 24 Dec 2024 17:22:07 +0800 Subject: [PATCH 15/18] =?UTF-8?q?=E9=87=8D=E5=91=BD=E5=90=8D=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TYLDDB/TYLDDB.cs | 37 +++++++++++++++++-------- TYLDDB/Utils/{ReadFile.cs => Reader.cs} | 0 TYLDDB/Utils/Writer.cs | 10 +++++++ 3 files changed, 36 insertions(+), 11 deletions(-) rename TYLDDB/Utils/{ReadFile.cs => Reader.cs} (100%) create mode 100644 TYLDDB/Utils/Writer.cs diff --git a/TYLDDB/TYLDDB.cs b/TYLDDB/TYLDDB.cs index 7741e03..6a3baa9 100644 --- a/TYLDDB/TYLDDB.cs +++ b/TYLDDB/TYLDDB.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using TYLDDB.Basic; using TYLDDB.Utils; @@ -9,19 +10,25 @@ namespace TYLDDB /// public class LDDB { - private string _filePath; // 私有字段存储文件路径 - private string _fileContent; // 私有字段存储文件内容 - private string _database; - private string _databaseContent; + /// + /// Instantiate the LDDB class
+ /// 实例化LDDB类 + ///
+ public LDDB() + { + // TODO + } + ///////////////////////////////////////////////////// 私有字段 + private string _filePath; // 存储文件路径 + private string _fileContent; // 存储文件内容 + private string _database; // 存储正在访问的数据库 + private string _databaseContent; // 存储数据库内容 private bool _isRead = false; // 是否已调用读取文件 - -#if NET6_0_OR_GREATER - private Database database = new(); -#else + private event Action OnFileReadComplete; private Database database = new Database(); -#endif + ///////////////////////////////////////////////////// 公开字段 /// /// Set the path where you want to read the file
/// 设置希望读取文件的路径 @@ -35,7 +42,6 @@ public string FilePath _filePath = value; // 只有通过验证后才设置值 } } - /// /// Names of all databases in the current file
/// 当前文件内所有数据库的名称 @@ -97,5 +103,14 @@ public string GetLoadingDatabaseContent() /// 读取全部数据库的名称 ///
public void ReadAllDatabaseName() => AllDatabaseName = database.GetDatabaseList(_fileContent); + + /// + /// Initialize the fast cache
+ /// 初始化快速缓存 + ///
+ public void QuickReadInitialize() + { + // TODO + } } } diff --git a/TYLDDB/Utils/ReadFile.cs b/TYLDDB/Utils/Reader.cs similarity index 100% rename from TYLDDB/Utils/ReadFile.cs rename to TYLDDB/Utils/Reader.cs diff --git a/TYLDDB/Utils/Writer.cs b/TYLDDB/Utils/Writer.cs new file mode 100644 index 0000000..75e8674 --- /dev/null +++ b/TYLDDB/Utils/Writer.cs @@ -0,0 +1,10 @@ +namespace TYLDDB.Utils +{ + /// + /// A class used to write contents into the file
+ /// 用于写入文件的类 + ///
+ public class Writer + { + } +} From a66e61ed081c93c24ac2351b4ec109af18676625 Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Fri, 27 Dec 2024 21:48:29 +0800 Subject: [PATCH 16/18] =?UTF-8?q?=E5=BF=AB=E9=80=9F=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 基于线程锁 --- TYLDDB-CSharp.sln | 12 + .../HighPrecisionTimer.cs | 44 +++ TYLDDB.Utils.FastCache.Test/Program.cs | 76 +++++ .../TYLDDB.Utils.FastCache.Test.csproj | 14 + TYLDDB/TYLDDB.cs | 9 - TYLDDB/TYLDDB.csproj | 4 + TYLDDB/Utils/FastCache/Cache.cs | 286 ++++++++++++++++++ TYLDDB/Utils/Reader.cs | 1 - 8 files changed, 436 insertions(+), 10 deletions(-) create mode 100644 TYLDDB.Utils.FastCache.Test/HighPrecisionTimer.cs create mode 100644 TYLDDB.Utils.FastCache.Test/Program.cs create mode 100644 TYLDDB.Utils.FastCache.Test/TYLDDB.Utils.FastCache.Test.csproj create mode 100644 TYLDDB/Utils/FastCache/Cache.cs diff --git a/TYLDDB-CSharp.sln b/TYLDDB-CSharp.sln index 7d2180e..9ed67ba 100644 --- a/TYLDDB-CSharp.sln +++ b/TYLDDB-CSharp.sln @@ -12,6 +12,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TYLDDB.Test", "TYLDDB.Test\TYLDDB.Test.csproj", "{FDFD566C-CB13-43EB-970E-0EC0A21E36C0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TYLDDB.Utils.FastCache.Test", "TYLDDB.Utils.FastCache.Test\TYLDDB.Utils.FastCache.Test.csproj", "{A58C0A6B-9BD4-4B29-9B5F-5FDFB849D23B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{95BC8FAF-AB03-44A3-A7E7-8E42FA7138E3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -26,10 +30,18 @@ Global {FDFD566C-CB13-43EB-970E-0EC0A21E36C0}.Debug|Any CPU.Build.0 = Debug|Any CPU {FDFD566C-CB13-43EB-970E-0EC0A21E36C0}.Release|Any CPU.ActiveCfg = Release|Any CPU {FDFD566C-CB13-43EB-970E-0EC0A21E36C0}.Release|Any CPU.Build.0 = Release|Any CPU + {A58C0A6B-9BD4-4B29-9B5F-5FDFB849D23B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A58C0A6B-9BD4-4B29-9B5F-5FDFB849D23B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A58C0A6B-9BD4-4B29-9B5F-5FDFB849D23B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A58C0A6B-9BD4-4B29-9B5F-5FDFB849D23B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {FDFD566C-CB13-43EB-970E-0EC0A21E36C0} = {95BC8FAF-AB03-44A3-A7E7-8E42FA7138E3} + {A58C0A6B-9BD4-4B29-9B5F-5FDFB849D23B} = {95BC8FAF-AB03-44A3-A7E7-8E42FA7138E3} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {19390089-354C-41AD-AF7D-9FB3998A88EA} EndGlobalSection diff --git a/TYLDDB.Utils.FastCache.Test/HighPrecisionTimer.cs b/TYLDDB.Utils.FastCache.Test/HighPrecisionTimer.cs new file mode 100644 index 0000000..7856bfe --- /dev/null +++ b/TYLDDB.Utils.FastCache.Test/HighPrecisionTimer.cs @@ -0,0 +1,44 @@ +using System.Diagnostics; + +namespace TYLDDB.Utils.FastCache.Test +{ + internal class HighPrecisionTimer + { + private Stopwatch stopwatch; + + public HighPrecisionTimer() + { + stopwatch = new Stopwatch(); + } + + // 启动计时器 + public void Start() + { + stopwatch.Start(); + } + + // 停止计时器 + public void Stop() + { + stopwatch.Stop(); + } + + // 重置计时器 + public void Reset() + { + stopwatch.Reset(); + } + + // 获取已用时间(毫秒) + public double ElapsedMilliseconds() + { + return stopwatch.Elapsed.TotalMilliseconds; + } + + // 获取已用时间(秒) + public double ElapsedSeconds() + { + return stopwatch.Elapsed.TotalSeconds; + } + } +} diff --git a/TYLDDB.Utils.FastCache.Test/Program.cs b/TYLDDB.Utils.FastCache.Test/Program.cs new file mode 100644 index 0000000..da4dde3 --- /dev/null +++ b/TYLDDB.Utils.FastCache.Test/Program.cs @@ -0,0 +1,76 @@ +using TYLDDB.Utils.FastCache; +using TYLDDB.Utils.FastCache.Test; + +SemaphoreSlimDefault(); + +Console.ReadLine(); + +// 普通线程锁的数据库读写运行 +static async void SemaphoreSlimDefault() +{ + 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(); + + var cache = new Cache(); + + 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"); + Console.WriteLine($"根据值获取键(同步):{getKeysByValueTime.ElapsedMilliseconds()}ms 根据值获取键(异步):{getKeysByValueAsyncTime.ElapsedMilliseconds()}ms"); + Console.WriteLine($"获取所有缓存项(同步):{getAllCacheTime.ElapsedMilliseconds()}ms 获取所有缓存项(异步):{getAllCacheAsyncTime.ElapsedMilliseconds()}ms"); +} diff --git a/TYLDDB.Utils.FastCache.Test/TYLDDB.Utils.FastCache.Test.csproj b/TYLDDB.Utils.FastCache.Test/TYLDDB.Utils.FastCache.Test.csproj new file mode 100644 index 0000000..bb48fc4 --- /dev/null +++ b/TYLDDB.Utils.FastCache.Test/TYLDDB.Utils.FastCache.Test.csproj @@ -0,0 +1,14 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + diff --git a/TYLDDB/TYLDDB.cs b/TYLDDB/TYLDDB.cs index 6a3baa9..0fe14ba 100644 --- a/TYLDDB/TYLDDB.cs +++ b/TYLDDB/TYLDDB.cs @@ -103,14 +103,5 @@ public string GetLoadingDatabaseContent() /// 读取全部数据库的名称 ///
public void ReadAllDatabaseName() => AllDatabaseName = database.GetDatabaseList(_fileContent); - - /// - /// Initialize the fast cache
- /// 初始化快速缓存 - ///
- public void QuickReadInitialize() - { - // TODO - } } } diff --git a/TYLDDB/TYLDDB.csproj b/TYLDDB/TYLDDB.csproj index 55ebde2..2d745c6 100644 --- a/TYLDDB/TYLDDB.csproj +++ b/TYLDDB/TYLDDB.csproj @@ -37,4 +37,8 @@ + + + +
diff --git a/TYLDDB/Utils/FastCache/Cache.cs b/TYLDDB/Utils/FastCache/Cache.cs new file mode 100644 index 0000000..3551198 --- /dev/null +++ b/TYLDDB/Utils/FastCache/Cache.cs @@ -0,0 +1,286 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace TYLDDB.Utils.FastCache +{ + /// + /// Use cached key-value pairs for fast reads and writes.
+ /// 使用缓存的键值对来快速读写。 + ///
+ public class Cache + { + private readonly Dictionary keyValueDict; // 存储键->值映射 + private readonly Dictionary> valueKeyDict; // 存储值->键的映射 + private readonly SemaphoreSlim semaphore; // 控制并发访问 + + /// + /// Use cached key-value pairs for fast reads and writes.
+ /// 使用缓存的键值对来快速读写。 + ///
+ public Cache() + { + 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)) + { + 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; + } + return false; + } + } + + /// + /// 异步方法:移除一个键值对。 + /// + /// + /// + public async Task RemoveByKeyAsync(string key) + { + await semaphore.WaitAsync(); + try + { + if (keyValueDict.ContainsKey(key)) + { + 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; + } + return false; + } + 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(); + } + } + } +} diff --git a/TYLDDB/Utils/Reader.cs b/TYLDDB/Utils/Reader.cs index 31ecbe3..68e9949 100644 --- a/TYLDDB/Utils/Reader.cs +++ b/TYLDDB/Utils/Reader.cs @@ -1,6 +1,5 @@ using System.IO; using System.Text; -using TYLDDB.Basic; namespace TYLDDB.Utils { From 80eeca393b9182011b7091c64acb07156a5d6218 Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Fri, 27 Dec 2024 23:08:07 +0800 Subject: [PATCH 17/18] =?UTF-8?q?=E6=9B=B4=E6=96=B0readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a5d8330..5d82374 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # TYLDDB-C# C# version. + +A strongly typed constrained distributed file system that can act as a database. From 4920f4e40ecd530a16022595fa6bd4fc89c2c8ae Mon Sep 17 00:00:00 2001 From: Grey Wind Date: Fri, 27 Dec 2024 23:08:16 +0800 Subject: [PATCH 18/18] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TYLDDB/TYLDDB.csproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/TYLDDB/TYLDDB.csproj b/TYLDDB/TYLDDB.csproj index 2d745c6..4a1776d 100644 --- a/TYLDDB/TYLDDB.csproj +++ b/TYLDDB/TYLDDB.csproj @@ -4,7 +4,7 @@ netstandard2.0;netstandard2.1;net6.0;net8.0;net9.0 True TTYPDB.NET - 1.0.0-beta.1 + 1.0.0-alpha.1 QingYi-Studio LICENSE True @@ -20,10 +20,12 @@ + + True \