From ee217e1a3223a2a48643967116b8e81887006aa8 Mon Sep 17 00:00:00 2001 From: walon Date: Wed, 9 Jun 2021 19:29:26 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90cfg=E3=80=91=20=E8=A7=A3=E5=86=B3FileR?= =?UTF-8?q?ecordCacheManager=E4=B8=8D=E6=B8=85=E9=99=A4=E7=BC=93=E5=AD=98?= =?UTF-8?q?=EF=BC=8C=E5=AF=BC=E8=87=B4=E5=86=85=E5=AD=98=E5=8D=A0=E7=94=A8?= =?UTF-8?q?=E7=BC=93=E6=85=A2=E6=97=A0=E9=99=90=E5=A2=9E=E5=A4=A7=E7=9A=84?= =?UTF-8?q?bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Luban.Client/Source/Program.cs | 4 +- .../Source/Cache/FileRecordCacheManager.cs | 54 +++++++++++++++++-- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/Luban.Client/Source/Program.cs b/src/Luban.Client/Source/Program.cs index 7a9ab75..09b650e 100644 --- a/src/Luban.Client/Source/Program.cs +++ b/src/Luban.Client/Source/Program.cs @@ -33,8 +33,6 @@ namespace Luban.Client private static NLog.Logger s_logger; - private static MultiFileWatcher s_watcher; - private static void PrintUsage(string err) { Console.WriteLine("ERRORS:"); @@ -166,7 +164,7 @@ Options: { GenOnce(options, profile); - s_watcher = new MultiFileWatcher(options.WatchDir, () => GenOnce(options, profile)); + new MultiFileWatcher(options.WatchDir, () => GenOnce(options, profile)); } } diff --git a/src/Luban.Job.Cfg/Source/Cache/FileRecordCacheManager.cs b/src/Luban.Job.Cfg/Source/Cache/FileRecordCacheManager.cs index d21f1fc..456c641 100644 --- a/src/Luban.Job.Cfg/Source/Cache/FileRecordCacheManager.cs +++ b/src/Luban.Job.Cfg/Source/Cache/FileRecordCacheManager.cs @@ -2,6 +2,7 @@ using Luban.Job.Cfg.Datas; using Luban.Job.Cfg.Defs; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; namespace Luban.Job.Cfg.Cache { @@ -13,9 +14,30 @@ namespace Luban.Job.Cfg.Cache { private static readonly NLog.Logger s_logger = NLog.LogManager.GetCurrentClassLogger(); + private const int CACHE_FILE_LOW_WATER_MARK = 5000; + private const int CACHE_FILE_HIGH_WATER_MARK = 8000; + public static FileRecordCacheManager Ins { get; } = new FileRecordCacheManager(); - private readonly ConcurrentDictionary<(string, string, string, bool), (DefTable, List)> _caches = new ConcurrentDictionary<(string, string, string, bool), (DefTable, List)>(); + class FileRecordCache + { + public DefTable Table { get; } + + public List Records { get; } + + public volatile int LastAccessTime; + + public FileRecordCache(DefTable table, List records) + { + Table = table; + Records = records; + LastAccessTime = Bright.Time.TimeUtil.Now; + } + } + + private readonly ConcurrentDictionary<(string, string, string, bool), FileRecordCache> _caches = new ConcurrentDictionary<(string, string, string, bool), FileRecordCache>(); + + private readonly object _shrinkLocker = new object(); public bool TryGetCacheLoadedRecords(DefTable table, string md5, string originFile, string sheetName, bool exportTestData, out List cacheRecords) { @@ -25,9 +47,10 @@ namespace Luban.Job.Cfg.Cache { return false; } - if (r.Item1.ValueTType.GetBeanAs().IsDefineEquals(table.ValueTType.GetBeanAs())) + r.LastAccessTime = Bright.Time.TimeUtil.Now; + if (r.Table.ValueTType.GetBeanAs().IsDefineEquals(table.ValueTType.GetBeanAs())) { - cacheRecords = r.Item2; + cacheRecords = r.Records; s_logger.Trace("hit cache. table:{table} file:{file} md5:{md5}", table.FullName, originFile, md5); return true; } @@ -39,7 +62,30 @@ namespace Luban.Job.Cfg.Cache public void AddCacheLoadedRecords(DefTable table, string md5, string sheetName, bool exportTestData, List cacheRecords) { - _caches[(table.Assembly.TimeZone.Id, md5, sheetName, exportTestData)] = (table, cacheRecords); + lock (_shrinkLocker) + { + _caches[(table.Assembly.TimeZone.Id, md5, sheetName, exportTestData)] = new FileRecordCache(table, cacheRecords); + if (_caches.Count > CACHE_FILE_HIGH_WATER_MARK) + { + s_logger.Info("ShrinkCaches. cache count > high CACHE_FILE_HIGH_WATER_MARK:{}", CACHE_FILE_HIGH_WATER_MARK); + ShrinkCaches(); + } + } + } + + private void ShrinkCaches() + { + if (_caches.Count < CACHE_FILE_HIGH_WATER_MARK) + { + return; + } + var cacheList = _caches.ToList(); + cacheList.Sort((a, b) => a.Value.LastAccessTime - b.Value.LastAccessTime); + for (int i = 0; i < CACHE_FILE_HIGH_WATER_MARK - CACHE_FILE_LOW_WATER_MARK; i++) + { + _caches.Remove(cacheList[i].Key, out _); + } + s_logger.Info("ShrinkCaches. after shrink, cache file num:{}", _caches.Count); } } }