[Refactor] Simplify constructor parameters and initialization in multiple classes

This commit is contained in:
2025-07-08 01:18:07 +01:00
parent 63a16cb19e
commit 7e8e42d07c
7 changed files with 90 additions and 143 deletions

View File

@@ -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<ulong, ConcurrentDictionary<string, CachedDisk>> _machineDisksCache;
readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedFile>> _machineFilesCache;
readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedMedia>> _machineMediasCache;
readonly ConcurrentDictionary<long, ConcurrentDictionary<string, CachedMachine>> _machinesStatCache;
readonly ConcurrentDictionary<long, RomSet> _romSetsCache;
readonly ConcurrentDictionary<long, Stream> _streamsCache;
readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedDisk>> _machineDisksCache = [];
readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedFile>> _machineFilesCache = [];
readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedMedia>> _machineMediasCache = [];
readonly ConcurrentDictionary<long, ConcurrentDictionary<string, CachedMachine>> _machinesStatCache = [];
readonly ConcurrentDictionary<long, RomSet> _romSetsCache = [];
readonly ConcurrentDictionary<long, Stream> _streamsCache = [];
Fuse _fuse;
long _lastHandle;
ConcurrentDictionary<string, long> _rootDirectoryCache;
ConcurrentDictionary<string, long> _rootDirectoryCache = [];
Winfsp _winfsp;
public Vfs()
{
_rootDirectoryCache = new ConcurrentDictionary<string, long>();
_romSetsCache = new ConcurrentDictionary<long, RomSet>();
_machinesStatCache = new ConcurrentDictionary<long, ConcurrentDictionary<string, CachedMachine>>();
_machineFilesCache = new ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedFile>>();
_machineDisksCache = new ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedDisk>>();
_machineMediasCache = new ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedMedia>>();
_streamsCache = new ConcurrentDictionary<long, Stream>();
_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

View File

@@ -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<string, CachedFile> cachedMachineFiles = _vfs.GetFilesFromMachine(node.MachineId);
ConcurrentDictionary<string, CachedFile> cachedMachineFiles = vfs.GetFilesFromMachine(node.MachineId);
ConcurrentDictionary<string, CachedDisk> cachedMachineDisks = _vfs.GetDisksFromMachine(node.MachineId);
ConcurrentDictionary<string, CachedDisk> cachedMachineDisks = vfs.GetDisksFromMachine(node.MachineId);
ConcurrentDictionary<string, CachedMedia> 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<string, CachedMachine> machines = _vfs.GetMachinesFromRomSet(node.RomSetId);
ConcurrentDictionary<string, CachedMachine> 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;

View File

@@ -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();
}
}

View File

@@ -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<string, FileByMachine> _filesByMachine;
long _machinePosition;
Machine[] _machines;
string _zipCurrentEntryName;
public FileExporter(long romSetId, string outPath)
{
_romSetId = romSetId;
_outPath = outPath;
}
public event EventHandler WorkFinished;
public event EventHandler<ProgressBoundsEventArgs> SetProgressBounds;
public event EventHandler<ProgressEventArgs> 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,

View File

@@ -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<DbDisk> _newDisks;
readonly List<DbFile> _newFiles;
readonly List<DbMedia> _newMedias;
readonly bool _onlyKnown;
readonly Dictionary<string, DbDisk> _pendingDisksByMd5;
readonly Dictionary<string, DbDisk> _pendingDisksBySha1;
readonly Dictionary<string, DbFile> _pendingFiles;
readonly Dictionary<string, DbMedia> _pendingMediasByMd5;
readonly Dictionary<string, DbMedia> _pendingMediasBySha1;
readonly Dictionary<string, DbMedia> _pendingMediasBySha256;
readonly Context _ctx = Context.Create(Settings.Settings.Current.DatabasePath);
readonly List<DbDisk> _newDisks = [];
readonly List<DbFile> _newFiles = [];
readonly List<DbMedia> _newMedias = [];
readonly Dictionary<string, DbDisk> _pendingDisksByMd5 = [];
readonly Dictionary<string, DbDisk> _pendingDisksBySha1 = [];
readonly Dictionary<string, DbFile> _pendingFiles = [];
readonly Dictionary<string, DbMedia> _pendingMediasByMd5 = [];
readonly Dictionary<string, DbMedia> _pendingMediasBySha1 = [];
readonly Dictionary<string, DbMedia> _pendingMediasBySha256 = [];
string _lastMessage;
long _position;
long _totalFiles;
public FileImporter(bool onlyKnown, bool deleteAfterImport)
{
_pendingFiles = new Dictionary<string, DbFile>();
_pendingDisksByMd5 = new Dictionary<string, DbDisk>();
_pendingDisksBySha1 = new Dictionary<string, DbDisk>();
_pendingMediasBySha256 = new Dictionary<string, DbMedia>();
_pendingMediasBySha1 = new Dictionary<string, DbMedia>();
_pendingMediasByMd5 = new Dictionary<string, DbMedia>();
_newFiles = [];
_newDisks = [];
_newMedias = [];
_onlyKnown = onlyKnown;
_deleteAfterImport = deleteAfterImport;
_position = 0;
_ctx = Context.Create(Settings.Settings.Current.DatabasePath);
}
public event EventHandler SetIndeterminateProgress2;
public event EventHandler<ProgressBoundsEventArgs> SetProgressBounds2;
public event EventHandler<ProgressEventArgs> 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");