From 7e8e42d07c2af83306e96a5ac0b50413486460ed Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Tue, 8 Jul 2025 01:18:07 +0100 Subject: [PATCH] [Refactor] Simplify constructor parameters and initialization in multiple classes --- RomRepoMgr.Core/Filesystem/Vfs.cs | 33 ++++----- RomRepoMgr.Core/Filesystem/Winfsp.cs | 75 ++++++++++----------- RomRepoMgr.Core/StreamWithLength.cs | 24 +++---- RomRepoMgr.Core/Workers/FileExporter.cs | 22 ++---- RomRepoMgr.Core/Workers/FileImporter.cs | 59 ++++++---------- RomRepoMgr.Database/Context.cs | 4 +- RomRepoMgr/ViewModels/RemoveDatViewModel.cs | 16 ++--- 7 files changed, 90 insertions(+), 143 deletions(-) diff --git a/RomRepoMgr.Core/Filesystem/Vfs.cs b/RomRepoMgr.Core/Filesystem/Vfs.cs index 9fa5d26..9513e71 100644 --- a/RomRepoMgr.Core/Filesystem/Vfs.cs +++ b/RomRepoMgr.Core/Filesystem/Vfs.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics.Contracts; using System.IO; using System.Linq; using System.Threading; @@ -19,29 +20,17 @@ namespace RomRepoMgr.Core.Filesystem; // TODO: Do not show machines or romsets with no ROMs in repo public class Vfs : IDisposable { - readonly ConcurrentDictionary> _machineDisksCache; - readonly ConcurrentDictionary> _machineFilesCache; - readonly ConcurrentDictionary> _machineMediasCache; - readonly ConcurrentDictionary> _machinesStatCache; - readonly ConcurrentDictionary _romSetsCache; - readonly ConcurrentDictionary _streamsCache; + readonly ConcurrentDictionary> _machineDisksCache = []; + readonly ConcurrentDictionary> _machineFilesCache = []; + readonly ConcurrentDictionary> _machineMediasCache = []; + readonly ConcurrentDictionary> _machinesStatCache = []; + readonly ConcurrentDictionary _romSetsCache = []; + readonly ConcurrentDictionary _streamsCache = []; Fuse _fuse; long _lastHandle; - ConcurrentDictionary _rootDirectoryCache; + ConcurrentDictionary _rootDirectoryCache = []; Winfsp _winfsp; - public Vfs() - { - _rootDirectoryCache = new ConcurrentDictionary(); - _romSetsCache = new ConcurrentDictionary(); - _machinesStatCache = new ConcurrentDictionary>(); - _machineFilesCache = new ConcurrentDictionary>(); - _machineDisksCache = new ConcurrentDictionary>(); - _machineMediasCache = new ConcurrentDictionary>(); - _streamsCache = new ConcurrentDictionary(); - _lastHandle = 0; - } - public static bool IsAvailable => OperatingSystem.IsMacOS() || OperatingSystem.IsLinux() ? Fuse.IsAvailable : OperatingSystem.IsWindows() && Winfsp.IsAvailable; @@ -667,6 +656,12 @@ public class Vfs : IDisposable return handle; } + + [ContractInvariantMethod] + void ObjectInvariant() + { + Contract.Invariant(_machineMediasCache.All(pair => pair.Value != null)); + } } internal sealed class CachedMachine diff --git a/RomRepoMgr.Core/Filesystem/Winfsp.cs b/RomRepoMgr.Core/Filesystem/Winfsp.cs index 940615e..7377136 100644 --- a/RomRepoMgr.Core/Filesystem/Winfsp.cs +++ b/RomRepoMgr.Core/Filesystem/Winfsp.cs @@ -14,13 +14,10 @@ using FileInfo = Fsp.Interop.FileInfo; namespace RomRepoMgr.Core.Filesystem; [SupportedOSPlatform("windows")] -public class Winfsp : FileSystemBase +public class Winfsp(Vfs vfs) : FileSystemBase { - readonly Vfs _vfs; FileSystemHost _host; - public Winfsp(Vfs vfs) => _vfs = vfs; - public static bool IsAvailable { get @@ -128,7 +125,7 @@ public class Winfsp : FileSystemBase { volumeInfo = new VolumeInfo(); - _vfs.GetInfo(out _, out ulong totalSize); + vfs.GetInfo(out _, out ulong totalSize); volumeInfo.FreeSize = 0; volumeInfo.TotalSize = totalSize; @@ -144,7 +141,7 @@ public class Winfsp : FileSystemBase fileInfo = default(FileInfo); normalizedName = default(string); - string[] pieces = _vfs.SplitPath(fileName); + string[] pieces = vfs.SplitPath(fileName); // Root directory if(pieces.Length == 0) @@ -169,11 +166,11 @@ public class Winfsp : FileSystemBase return STATUS_SUCCESS; } - long romSetId = _vfs.GetRomSetId(pieces[0]); + long romSetId = vfs.GetRomSetId(pieces[0]); if(romSetId <= 0) return STATUS_OBJECT_NAME_NOT_FOUND; - RomSet romSet = _vfs.GetRomSet(romSetId); + RomSet romSet = vfs.GetRomSet(romSetId); if(romSet == null) return STATUS_OBJECT_NAME_NOT_FOUND; @@ -207,7 +204,7 @@ public class Winfsp : FileSystemBase return STATUS_SUCCESS; } - CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]); + CachedMachine machine = vfs.GetMachine(romSetId, pieces[1]); if(machine == null) return STATUS_OBJECT_NAME_NOT_FOUND; @@ -242,7 +239,7 @@ public class Winfsp : FileSystemBase } long handle = 0; - CachedFile file = _vfs.GetFile(machine.Id, pieces[2]); + CachedFile file = vfs.GetFile(machine.Id, pieces[2]); if(file != null) { @@ -250,7 +247,7 @@ public class Winfsp : FileSystemBase if(file.Sha384 == null) return STATUS_OBJECT_NAME_NOT_FOUND; - handle = _vfs.Open(file.Sha384, (long)file.Size); + handle = vfs.Open(file.Sha384, (long)file.Size); if(handle <= 0) return STATUS_OBJECT_NAME_NOT_FOUND; @@ -280,7 +277,7 @@ public class Winfsp : FileSystemBase return STATUS_SUCCESS; } - CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]); + CachedDisk disk = vfs.GetDisk(machine.Id, pieces[2]); if(disk != null) { @@ -288,7 +285,7 @@ public class Winfsp : FileSystemBase if(disk.Sha1 == null && disk.Md5 == null) return STATUS_OBJECT_NAME_NOT_FOUND; - handle = _vfs.OpenDisk(disk.Sha1, disk.Md5); + handle = vfs.OpenDisk(disk.Sha1, disk.Md5); if(handle <= 0) return STATUS_OBJECT_NAME_NOT_FOUND; @@ -318,7 +315,7 @@ public class Winfsp : FileSystemBase return STATUS_SUCCESS; } - CachedMedia media = _vfs.GetMedia(machine.Id, pieces[2]); + CachedMedia media = vfs.GetMedia(machine.Id, pieces[2]); if(media == null) return STATUS_OBJECT_NAME_NOT_FOUND; @@ -326,7 +323,7 @@ public class Winfsp : FileSystemBase if(media.Sha256 == null && media.Sha1 == null && media.Md5 == null) return STATUS_OBJECT_NAME_NOT_FOUND; - handle = _vfs.OpenMedia(media.Sha256, media.Sha1, media.Md5); + handle = vfs.OpenMedia(media.Sha256, media.Sha1, media.Md5); if(handle <= 0) return STATUS_OBJECT_NAME_NOT_FOUND; @@ -362,7 +359,7 @@ public class Winfsp : FileSystemBase if(node.Handle <= 0) return; - _vfs.Close(node.Handle); + vfs.Close(node.Handle); } public override int Read(object fileNode, object fileDesc, IntPtr buffer, ulong offset, uint length, @@ -374,7 +371,7 @@ public class Winfsp : FileSystemBase var buf = new byte[length]; - int ret = _vfs.Read(node.Handle, buf, (long)offset); + int ret = vfs.Read(node.Handle, buf, (long)offset); if(ret < 0) return STATUS_INVALID_HANDLE; @@ -408,12 +405,12 @@ public class Winfsp : FileSystemBase { if(node.MachineId > 0) { - ConcurrentDictionary cachedMachineFiles = _vfs.GetFilesFromMachine(node.MachineId); + ConcurrentDictionary cachedMachineFiles = vfs.GetFilesFromMachine(node.MachineId); - ConcurrentDictionary cachedMachineDisks = _vfs.GetDisksFromMachine(node.MachineId); + ConcurrentDictionary cachedMachineDisks = vfs.GetDisksFromMachine(node.MachineId); ConcurrentDictionary cachedMachineMedias = - _vfs.GetMediasFromMachine(node.MachineId); + vfs.GetMediasFromMachine(node.MachineId); node.Children = [ @@ -483,7 +480,7 @@ public class Winfsp : FileSystemBase } else if(node.RomSetId > 0) { - ConcurrentDictionary machines = _vfs.GetMachinesFromRomSet(node.RomSetId); + ConcurrentDictionary machines = vfs.GetMachinesFromRomSet(node.RomSetId); node.Children = [ @@ -514,12 +511,12 @@ public class Winfsp : FileSystemBase { node.Children = []; - node.Children.AddRange(_vfs.GetRootEntries() - .Select(e => new FileEntry - { - FileName = e, - IsRomSet = true - })); + node.Children.AddRange(vfs.GetRootEntries() + .Select(e => new FileEntry + { + FileName = e, + IsRomSet = true + })); } if(marker != null) @@ -540,11 +537,11 @@ public class Winfsp : FileSystemBase if(entry.IsRomSet) { - long romSetId = _vfs.GetRomSetId(entry.FileName); + long romSetId = vfs.GetRomSetId(entry.FileName); if(romSetId <= 0) continue; - RomSet romSet = _vfs.GetRomSet(romSetId); + RomSet romSet = vfs.GetRomSet(romSetId); if(romSet is null) continue; @@ -569,7 +566,7 @@ public class Winfsp : FileSystemBase { fileAttributes = 0; - string[] pieces = _vfs.SplitPath(fileName); + string[] pieces = vfs.SplitPath(fileName); // Root directory if(pieces.Length == 0) @@ -588,11 +585,11 @@ public class Winfsp : FileSystemBase return STATUS_SUCCESS; } - long romSetId = _vfs.GetRomSetId(pieces[0]); + long romSetId = vfs.GetRomSetId(pieces[0]); if(romSetId <= 0) return STATUS_OBJECT_NAME_NOT_FOUND; - RomSet romSet = _vfs.GetRomSet(romSetId); + RomSet romSet = vfs.GetRomSet(romSetId); if(romSet == null) return STATUS_OBJECT_NAME_NOT_FOUND; @@ -604,7 +601,7 @@ public class Winfsp : FileSystemBase return STATUS_SUCCESS; } - CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]); + CachedMachine machine = vfs.GetMachine(romSetId, pieces[1]); if(machine == null) return STATUS_OBJECT_NAME_NOT_FOUND; @@ -617,7 +614,7 @@ public class Winfsp : FileSystemBase } long handle = 0; - CachedFile file = _vfs.GetFile(machine.Id, pieces[2]); + CachedFile file = vfs.GetFile(machine.Id, pieces[2]); if(file != null) { @@ -625,7 +622,7 @@ public class Winfsp : FileSystemBase if(file.Sha384 == null) return STATUS_OBJECT_NAME_NOT_FOUND; - handle = _vfs.Open(file.Sha384, (long)file.Size); + handle = vfs.Open(file.Sha384, (long)file.Size); if(handle <= 0) return STATUS_OBJECT_NAME_NOT_FOUND; @@ -634,7 +631,7 @@ public class Winfsp : FileSystemBase return STATUS_SUCCESS; } - CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]); + CachedDisk disk = vfs.GetDisk(machine.Id, pieces[2]); if(disk != null) { @@ -642,7 +639,7 @@ public class Winfsp : FileSystemBase if(disk.Sha1 == null && disk.Md5 == null) return STATUS_OBJECT_NAME_NOT_FOUND; - handle = _vfs.OpenDisk(disk.Sha1, disk.Md5); + handle = vfs.OpenDisk(disk.Sha1, disk.Md5); if(handle <= 0) return STATUS_OBJECT_NAME_NOT_FOUND; @@ -651,7 +648,7 @@ public class Winfsp : FileSystemBase return STATUS_SUCCESS; } - CachedMedia media = _vfs.GetMedia(machine.Id, pieces[2]); + CachedMedia media = vfs.GetMedia(machine.Id, pieces[2]); if(media == null) return STATUS_OBJECT_NAME_NOT_FOUND; @@ -659,7 +656,7 @@ public class Winfsp : FileSystemBase if(media.Sha256 == null && media.Sha1 == null && media.Md5 == null) return STATUS_OBJECT_NAME_NOT_FOUND; - handle = _vfs.OpenMedia(media.Sha256, media.Sha1, media.Md5); + handle = vfs.OpenMedia(media.Sha256, media.Sha1, media.Md5); if(handle <= 0) return STATUS_OBJECT_NAME_NOT_FOUND; diff --git a/RomRepoMgr.Core/StreamWithLength.cs b/RomRepoMgr.Core/StreamWithLength.cs index 232f9eb..d849959 100644 --- a/RomRepoMgr.Core/StreamWithLength.cs +++ b/RomRepoMgr.Core/StreamWithLength.cs @@ -3,20 +3,12 @@ using System.IO; namespace RomRepoMgr.Core; -internal sealed class StreamWithLength : Stream +internal sealed class StreamWithLength(Stream baseStream, long length) : Stream { - readonly Stream _baseStream; - - public StreamWithLength(Stream baseStream, long length) - { - _baseStream = baseStream; - Length = length; - } - - public override bool CanRead => _baseStream.CanRead; - public override bool CanSeek => _baseStream.CanSeek; - public override bool CanWrite => _baseStream.CanWrite; - public override long Length { get; } + public override bool CanRead => baseStream.CanRead; + public override bool CanSeek => baseStream.CanSeek; + public override bool CanWrite => baseStream.CanWrite; + public override long Length { get; } = length; public override long Position { @@ -24,9 +16,9 @@ internal sealed class StreamWithLength : Stream set => throw new NotSupportedException(); } - public override void Flush() => _baseStream.Flush(); + public override void Flush() => baseStream.Flush(); - public override int Read(byte[] buffer, int offset, int count) => _baseStream.Read(buffer, offset, count); + public override int Read(byte[] buffer, int offset, int count) => baseStream.Read(buffer, offset, count); public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException(); @@ -36,7 +28,7 @@ internal sealed class StreamWithLength : Stream public override void Close() { - _baseStream.Close(); + baseStream.Close(); base.Close(); } } \ No newline at end of file diff --git a/RomRepoMgr.Core/Workers/FileExporter.cs b/RomRepoMgr.Core/Workers/FileExporter.cs index d19b831..0a1a316 100644 --- a/RomRepoMgr.Core/Workers/FileExporter.cs +++ b/RomRepoMgr.Core/Workers/FileExporter.cs @@ -15,23 +15,15 @@ using CompressionMode = SharpCompress.Compressors.CompressionMode; namespace RomRepoMgr.Core.Workers; -public class FileExporter +public class FileExporter(long romSetId, string outPath) { - const long BUFFER_SIZE = 131072; - readonly string _outPath; - readonly long _romSetId; + const long BUFFER_SIZE = 131072; long _filePosition; Dictionary _filesByMachine; long _machinePosition; Machine[] _machines; string _zipCurrentEntryName; - public FileExporter(long romSetId, string outPath) - { - _romSetId = romSetId; - _outPath = outPath; - } - public event EventHandler WorkFinished; public event EventHandler SetProgressBounds; public event EventHandler SetProgress; @@ -53,7 +45,7 @@ public class FileExporter using var ctx = Context.Create(Settings.Settings.Current.DatabasePath); - RomSet romSet = ctx.RomSets.Find(_romSetId); + RomSet romSet = ctx.RomSets.Find(romSetId); if(romSet == null) { @@ -74,7 +66,7 @@ public class FileExporter Message = Localization.ExportingRoms }); - _machines = ctx.Machines.Where(m => m.RomSet.Id == _romSetId).ToArray(); + _machines = ctx.Machines.Where(m => m.RomSet.Id == romSetId).ToArray(); SetProgressBounds?.Invoke(this, new ProgressBoundsEventArgs @@ -135,7 +127,7 @@ public class FileExporter if(machineName.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) machineName = machineName[..^4]; - string machinePath = Path.Combine(_outPath, machineName); + string machinePath = Path.Combine(outPath, machineName); if(!Directory.Exists(machinePath)) Directory.CreateDirectory(machinePath); @@ -340,7 +332,7 @@ public class FileExporter if(machineName.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) machineName = machineName[..^4]; - string machinePath = Path.Combine(_outPath, machineName); + string machinePath = Path.Combine(outPath, machineName); if(!Directory.Exists(machinePath)) Directory.CreateDirectory(machinePath); @@ -512,7 +504,7 @@ public class FileExporter if(!machineName.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) machineName += ".zip"; - var zf = new ZipFile(Path.Combine(_outPath, machineName), Encoding.UTF8) + var zf = new ZipFile(Path.Combine(outPath, machineName), Encoding.UTF8) { CompressionLevel = CompressionLevel.BestCompression, CompressionMethod = CompressionMethod.Deflate, diff --git a/RomRepoMgr.Core/Workers/FileImporter.cs b/RomRepoMgr.Core/Workers/FileImporter.cs index 9b4e3cf..a6fd9c8 100644 --- a/RomRepoMgr.Core/Workers/FileImporter.cs +++ b/RomRepoMgr.Core/Workers/FileImporter.cs @@ -18,42 +18,23 @@ using SharpCompress.Compressors.LZMA; namespace RomRepoMgr.Core.Workers; -public class FileImporter +public class FileImporter(bool onlyKnown, bool deleteAfterImport) { const long BUFFER_SIZE = 131072; - readonly Context _ctx; - readonly bool _deleteAfterImport; - readonly List _newDisks; - readonly List _newFiles; - readonly List _newMedias; - readonly bool _onlyKnown; - readonly Dictionary _pendingDisksByMd5; - readonly Dictionary _pendingDisksBySha1; - readonly Dictionary _pendingFiles; - readonly Dictionary _pendingMediasByMd5; - readonly Dictionary _pendingMediasBySha1; - readonly Dictionary _pendingMediasBySha256; + readonly Context _ctx = Context.Create(Settings.Settings.Current.DatabasePath); + readonly List _newDisks = []; + readonly List _newFiles = []; + readonly List _newMedias = []; + readonly Dictionary _pendingDisksByMd5 = []; + readonly Dictionary _pendingDisksBySha1 = []; + readonly Dictionary _pendingFiles = []; + readonly Dictionary _pendingMediasByMd5 = []; + readonly Dictionary _pendingMediasBySha1 = []; + readonly Dictionary _pendingMediasBySha256 = []; string _lastMessage; long _position; long _totalFiles; - public FileImporter(bool onlyKnown, bool deleteAfterImport) - { - _pendingFiles = new Dictionary(); - _pendingDisksByMd5 = new Dictionary(); - _pendingDisksBySha1 = new Dictionary(); - _pendingMediasBySha256 = new Dictionary(); - _pendingMediasBySha1 = new Dictionary(); - _pendingMediasByMd5 = new Dictionary(); - _newFiles = []; - _newDisks = []; - _newMedias = []; - _onlyKnown = onlyKnown; - _deleteAfterImport = deleteAfterImport; - _position = 0; - _ctx = Context.Create(Settings.Settings.Current.DatabasePath); - } - public event EventHandler SetIndeterminateProgress2; public event EventHandler SetProgressBounds2; public event EventHandler SetProgress2; @@ -388,7 +369,7 @@ public class FileImporter if(dbFile == null) { - if(_onlyKnown) + if(onlyKnown) { _lastMessage = Localization.UnknownFile; @@ -493,7 +474,7 @@ public class FileImporter inFs.Close(); - if(_deleteAfterImport) File.Delete(path); + if(deleteAfterImport) File.Delete(path); return true; } @@ -559,7 +540,7 @@ public class FileImporter if(!fileInDb) _newFiles.Add(dbFile); - if(_deleteAfterImport) File.Delete(path); + if(deleteAfterImport) File.Delete(path); return true; } @@ -655,7 +636,7 @@ public class FileImporter if(dbDisk == null) { - if(_onlyKnown) + if(onlyKnown) { _lastMessage = Localization.UnknownFile; @@ -770,7 +751,7 @@ public class FileImporter inFs.Close(); - if(_deleteAfterImport) File.Delete(path); + if(deleteAfterImport) File.Delete(path); return true; } @@ -833,7 +814,7 @@ public class FileImporter if(!diskInDb) _newDisks.Add(dbDisk); - if(_deleteAfterImport) File.Delete(path); + if(deleteAfterImport) File.Delete(path); if(knownDiskWasBigger) File.Delete(repoPath + ".bak"); @@ -954,7 +935,7 @@ public class FileImporter if(dbMedia == null) { - if(_onlyKnown) + if(onlyKnown) { _lastMessage = Localization.UnknownFile; @@ -1107,7 +1088,7 @@ public class FileImporter inFs.Close(); - if(_deleteAfterImport) File.Delete(path); + if(deleteAfterImport) File.Delete(path); return true; } @@ -1170,7 +1151,7 @@ public class FileImporter if(!mediaInDb) _newMedias.Add(dbMedia); - if(_deleteAfterImport) File.Delete(path); + if(deleteAfterImport) File.Delete(path); if(knownMediaWasBigger) File.Delete(repoPath + ".bak"); diff --git a/RomRepoMgr.Database/Context.cs b/RomRepoMgr.Database/Context.cs index e705920..40db50c 100644 --- a/RomRepoMgr.Database/Context.cs +++ b/RomRepoMgr.Database/Context.cs @@ -29,10 +29,8 @@ using RomRepoMgr.Database.Models; namespace RomRepoMgr.Database; -public sealed class Context : DbContext +public sealed class Context(DbContextOptions options) : DbContext(options) { - public Context(DbContextOptions options) : base(options) {} - public DbSet Files { get; set; } public DbSet RomSets { get; set; } public DbSet Machines { get; set; } diff --git a/RomRepoMgr/ViewModels/RemoveDatViewModel.cs b/RomRepoMgr/ViewModels/RemoveDatViewModel.cs index ef5682d..a41d4df 100644 --- a/RomRepoMgr/ViewModels/RemoveDatViewModel.cs +++ b/RomRepoMgr/ViewModels/RemoveDatViewModel.cs @@ -35,17 +35,9 @@ using RomRepoMgr.Views; namespace RomRepoMgr.ViewModels; -public sealed class RemoveDatViewModel : ViewModelBase +public sealed class RemoveDatViewModel(RemoveDat view, long romSetId) : ViewModelBase { - readonly long _romSetId; - readonly RemoveDat _view; - string _statusMessage; - - public RemoveDatViewModel(RemoveDat view, long romSetId) - { - _view = view; - _romSetId = romSetId; - } + string _statusMessage; public string Title => Localization.RemoveDatTitle; @@ -63,7 +55,7 @@ public sealed class RemoveDatViewModel : ViewModelBase Dispatcher.UIThread.Post(() => StatusMessage = Localization.RetrievingRomSetFromDatabase); - RomSet romSet = ctx.RomSets.Find(_romSetId); + RomSet romSet = ctx.RomSets.Find(romSetId); if(romSet == null) return; @@ -103,7 +95,7 @@ public sealed class RemoveDatViewModel : ViewModelBase if(File.Exists(compressedDatPath)) File.Delete(compressedDatPath); - Dispatcher.UIThread.Post(_view.Close); + Dispatcher.UIThread.Post(view.Close); }); } } \ No newline at end of file