diff --git a/MareSynchronos/FileCache/CacheMonitor.cs b/MareSynchronos/FileCache/CacheMonitor.cs index 34d8713..38947f6 100644 --- a/MareSynchronos/FileCache/CacheMonitor.cs +++ b/MareSynchronos/FileCache/CacheMonitor.cs @@ -408,7 +408,9 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase Logger.LogWarning(ex, "Could not determine drive size for Storage Folder {folder}", _configService.Current.CacheFolder); } - FileCacheSize = Directory.EnumerateFiles(_configService.Current.CacheFolder) + var files = Directory.EnumerateFiles(_configService.Current.CacheFolder).Select(f => new FileInfo(f)) + .OrderBy(f => f.LastAccessTime).ToList(); + FileCacheSize = files .Sum(f => { token.ThrowIfCancellationRequested(); @@ -427,15 +429,13 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase if (FileCacheSize < maxCacheInBytes) return; - var allFiles = Directory.EnumerateFiles(_configService.Current.CacheFolder) - .Select(f => new FileInfo(f)).OrderBy(f => f.LastAccessTime).ToList(); var maxCacheBuffer = maxCacheInBytes * 0.05d; while (FileCacheSize > maxCacheInBytes - (long)maxCacheBuffer) { - var oldestFile = allFiles[0]; - FileCacheSize -= _fileCompactor.GetFileSizeOnDisk(oldestFile.FullName); + var oldestFile = files[0]; + FileCacheSize -= _fileCompactor.GetFileSizeOnDisk(oldestFile); File.Delete(oldestFile.FullName); - allFiles.Remove(oldestFile); + files.Remove(oldestFile); } } diff --git a/MareSynchronos/FileCache/FileCompactor.cs b/MareSynchronos/FileCache/FileCompactor.cs index 7fea1a0..daa018c 100644 --- a/MareSynchronos/FileCache/FileCompactor.cs +++ b/MareSynchronos/FileCache/FileCompactor.cs @@ -65,15 +65,15 @@ public sealed class FileCompactor MassCompactRunning = false; } - public long GetFileSizeOnDisk(string filePath, bool? isNTFS = null) + public long GetFileSizeOnDisk(FileInfo fileInfo, bool? isNTFS = null) { - bool ntfs = isNTFS ?? string.Equals(new DriveInfo(new FileInfo(filePath).Directory!.Root.FullName).DriveFormat, "NTFS", StringComparison.OrdinalIgnoreCase); + bool ntfs = isNTFS ?? string.Equals(new DriveInfo(fileInfo.Directory!.Root.FullName).DriveFormat, "NTFS", StringComparison.OrdinalIgnoreCase); - if (_dalamudUtilService.IsWine || !ntfs) return new FileInfo(filePath).Length; + if (_dalamudUtilService.IsWine || !ntfs) return fileInfo.Length; - var clusterSize = GetClusterSize(filePath); - if (clusterSize == -1) return new FileInfo(filePath).Length; - var losize = GetCompressedFileSizeW(filePath, out uint hosize); + var clusterSize = GetClusterSize(fileInfo); + if (clusterSize == -1) return fileInfo.Length; + var losize = GetCompressedFileSizeW(fileInfo.FullName, out uint hosize); var size = (long)hosize << 32 | losize; return ((size + clusterSize - 1) / clusterSize) * clusterSize; } @@ -118,8 +118,9 @@ public sealed class FileCompactor return; } - var oldSize = new FileInfo(filePath).Length; - var clusterSize = GetClusterSize(filePath); + var fi = new FileInfo(filePath); + var oldSize = fi.Length; + var clusterSize = GetClusterSize(fi); if (oldSize < Math.Max(clusterSize, 8 * 1024)) { @@ -133,7 +134,7 @@ public sealed class FileCompactor WOFCompressFile(filePath); - var newSize = GetFileSizeOnDisk(filePath); + var newSize = GetFileSizeOnDisk(fi); _logger.LogDebug("Compressed {file} from {orig}b to {comp}b", filePath, oldSize, newSize); } @@ -162,14 +163,13 @@ public sealed class FileCompactor } } - private int GetClusterSize(string filePath) + private int GetClusterSize(FileInfo fi) { - FileInfo fi = new(filePath); if (!fi.Exists) return -1; var root = fi.Directory?.Root.FullName.ToLower() ?? string.Empty; if (string.IsNullOrEmpty(root)) return -1; if (_clusterSizes.TryGetValue(root, out int value)) return value; - _logger.LogDebug("Getting Cluster Size for {path}, root {root}", filePath, root); + _logger.LogDebug("Getting Cluster Size for {path}, root {root}", fi.FullName, root); int result = GetDiskFreeSpaceW(root, out uint sectorsPerCluster, out uint bytesPerSector, out _, out _); if (result == 0) return -1; _clusterSizes[root] = (int)(sectorsPerCluster * bytesPerSector); diff --git a/MareSynchronos/Services/Mediator/MareMediator.cs b/MareSynchronos/Services/Mediator/MareMediator.cs index 4433833..3625c4b 100644 --- a/MareSynchronos/Services/Mediator/MareMediator.cs +++ b/MareSynchronos/Services/Mediator/MareMediator.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System.Collections.Concurrent; +using System.Reflection; using System.Text; namespace MareSynchronos.Services.Mediator; @@ -15,7 +16,7 @@ public sealed class MareMediator : IHostedService private readonly PerformanceCollectorService _performanceCollector; private readonly Dictionary> _subscriberDict = []; private bool _processQueue = false; - + private readonly Dictionary _genericExecuteMethods = new(); public MareMediator(ILogger logger, PerformanceCollectorService performanceCollector) { _logger = logger; @@ -143,10 +144,15 @@ public sealed class MareMediator : IHostedService } #pragma warning disable S3011 // Reflection should not be used to increase accessibility of classes, methods, or fields - GetType() - .GetMethod(nameof(ExecuteReflected), System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)? - .MakeGenericMethod(message.GetType())? - .Invoke(this, [subscribersCopy, message]); + var msgType = message.GetType(); + if (!_genericExecuteMethods.TryGetValue(msgType, out var methodInfo)) + { + _genericExecuteMethods[message.GetType()] = methodInfo = GetType() + .GetMethod(nameof(ExecuteReflected), System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)? + .MakeGenericMethod(msgType); + } + + methodInfo!.Invoke(this, [subscribersCopy, message]); #pragma warning restore S3011 // Reflection should not be used to increase accessibility of classes, methods, or fields }