Move getting machines to VFS.

This commit is contained in:
2020-09-03 01:25:06 +01:00
parent 0c0b519072
commit ff9c5cac19
2 changed files with 131 additions and 275 deletions

View File

@@ -19,22 +19,18 @@ namespace RomRepoMgr.Core.Filesystem
// TODO: Last handle goes negative // TODO: Last handle goes negative
public sealed class Fuse : FileSystem public sealed class Fuse : FileSystem
{ {
readonly ConcurrentDictionary<long, List<DirectoryEntry>> _directoryCache; readonly ConcurrentDictionary<long, List<DirectoryEntry>> _directoryCache;
readonly ConcurrentDictionary<long, Stat> _fileStatHandleCache; readonly ConcurrentDictionary<long, Stat> _fileStatHandleCache;
readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedFile>> _machineFilesCache; readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedFile>> _machineFilesCache;
readonly ConcurrentDictionary<long, ConcurrentDictionary<string, CachedMachine>> _machinesStatCache; readonly ConcurrentDictionary<long, Stream> _streamsCache;
readonly ConcurrentDictionary<long, RomSet> _romSetsCache; readonly Vfs _vfs;
readonly ConcurrentDictionary<long, Stream> _streamsCache; long _lastHandle;
readonly Vfs _vfs; string _umountToken;
long _lastHandle;
string _umountToken;
public Fuse(Vfs vfs) public Fuse(Vfs vfs)
{ {
_directoryCache = new ConcurrentDictionary<long, List<DirectoryEntry>>(); _directoryCache = new ConcurrentDictionary<long, List<DirectoryEntry>>();
_lastHandle = 0; _lastHandle = 0;
_machinesStatCache = new ConcurrentDictionary<long, ConcurrentDictionary<string, CachedMachine>>();
_romSetsCache = new ConcurrentDictionary<long, RomSet>();
_machineFilesCache = new ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedFile>>(); _machineFilesCache = new ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedFile>>();
_streamsCache = new ConcurrentDictionary<long, Stream>(); _streamsCache = new ConcurrentDictionary<long, Stream>();
_fileStatHandleCache = new ConcurrentDictionary<long, Stat>(); _fileStatHandleCache = new ConcurrentDictionary<long, Stat>();
@@ -127,13 +123,7 @@ namespace RomRepoMgr.Core.Filesystem
return 0; return 0;
} }
if(!_romSetsCache.TryGetValue(romSetId, out RomSet romSet)) RomSet romSet = _vfs.GetRomSet(romSetId);
{
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
romSet = ctx.RomSets.Find(romSetId);
_romSetsCache[romSetId] = romSet;
}
if(romSet == null) if(romSet == null)
return Errno.ENOENT; return Errno.ENOENT;
@@ -148,44 +138,25 @@ namespace RomRepoMgr.Core.Filesystem
return 0; return 0;
} }
_machinesStatCache.TryGetValue(romSetId, out ConcurrentDictionary<string, CachedMachine> cachedMachines); CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);
if(cachedMachines == null) if(machine == null)
{
cachedMachines = new ConcurrentDictionary<string, CachedMachine>();
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
foreach(Machine mach in ctx.Machines.Where(m => m.RomSet.Id == romSetId))
{
cachedMachines[mach.Name] = new CachedMachine
{
Id = mach.Id,
Stat = new Stat
{
st_mode = FilePermissions.S_IFDIR | NativeConvert.FromOctalPermissionString("0555"),
st_nlink = 2,
st_ctime = NativeConvert.ToTimeT(mach.CreatedOn.ToUniversalTime()),
st_mtime = NativeConvert.ToTimeT(mach.UpdatedOn.ToUniversalTime())
}
};
}
_machinesStatCache[romSetId] = cachedMachines;
}
if(!cachedMachines.TryGetValue(pieces[1], out CachedMachine machineStat))
return Errno.ENOENT; return Errno.ENOENT;
if(pieces.Length == 2) if(pieces.Length == 2)
{ {
stat = machineStat.Stat; stat = new Stat
{
st_mode = FilePermissions.S_IFDIR | NativeConvert.FromOctalPermissionString("0555"),
st_nlink = 2,
st_ctime = NativeConvert.ToTimeT(machine.CreationDate.ToUniversalTime()),
st_mtime = NativeConvert.ToTimeT(machine.ModificationDate.ToUniversalTime())
};
return 0; return 0;
} }
_machineFilesCache.TryGetValue(machineStat.Id, _machineFilesCache.TryGetValue(machine.Id, out ConcurrentDictionary<string, CachedFile> cachedMachineFiles);
out ConcurrentDictionary<string, CachedFile> cachedMachineFiles);
if(cachedMachineFiles == null) if(cachedMachineFiles == null)
{ {
@@ -193,8 +164,8 @@ namespace RomRepoMgr.Core.Filesystem
cachedMachineFiles = new ConcurrentDictionary<string, CachedFile>(); cachedMachineFiles = new ConcurrentDictionary<string, CachedFile>();
foreach(FileByMachine machineFile in foreach(FileByMachine machineFile in ctx.FilesByMachines.Where(fbm => fbm.Machine.Id == machine.Id &&
ctx.FilesByMachines.Where(fbm => fbm.Machine.Id == machineStat.Id && fbm.File.IsInRepo)) fbm.File.IsInRepo))
{ {
var cachedFile = new CachedFile var cachedFile = new CachedFile
{ {
@@ -213,7 +184,7 @@ namespace RomRepoMgr.Core.Filesystem
cachedMachineFiles[machineFile.Name] = cachedFile; cachedMachineFiles[machineFile.Name] = cachedFile;
} }
_machineFilesCache[machineStat.Id] = cachedMachineFiles; _machineFilesCache[machine.Id] = cachedMachineFiles;
} }
if(!cachedMachineFiles.TryGetValue(pieces[2], out CachedFile file)) if(!cachedMachineFiles.TryGetValue(pieces[2], out CachedFile file))
@@ -275,16 +246,12 @@ namespace RomRepoMgr.Core.Filesystem
if(pieces.Length == 0) if(pieces.Length == 0)
return Errno.EISDIR; return Errno.EISDIR;
if(!_rootDirectoryCache.TryGetValue(pieces[0], out long romSetId)) long romSetId = _vfs.GetRomSetId(pieces[0]);
if(romSetId <= 0)
return Errno.ENOENT; return Errno.ENOENT;
if(!_romSetsCache.TryGetValue(romSetId, out RomSet romSet)) RomSet romSet = _vfs.GetRomSet(romSetId);
{
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
romSet = ctx.RomSets.Find(romSetId);
_romSetsCache[romSetId] = romSet;
}
if(romSet == null) if(romSet == null)
return Errno.ENOENT; return Errno.ENOENT;
@@ -292,40 +259,15 @@ namespace RomRepoMgr.Core.Filesystem
if(pieces.Length == 1) if(pieces.Length == 1)
return Errno.EISDIR; return Errno.EISDIR;
_machinesStatCache.TryGetValue(romSetId, out ConcurrentDictionary<string, CachedMachine> cachedMachines); CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);
if(cachedMachines == null) if(machine == null)
{
cachedMachines = new ConcurrentDictionary<string, CachedMachine>();
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
foreach(Machine mach in ctx.Machines.Where(m => m.RomSet.Id == romSetId))
{
cachedMachines[mach.Name] = new CachedMachine
{
Id = mach.Id,
Stat = new Stat
{
st_mode = FilePermissions.S_IFDIR | NativeConvert.FromOctalPermissionString("0555"),
st_nlink = 2,
st_ctime = NativeConvert.ToTimeT(mach.CreatedOn.ToUniversalTime()),
st_mtime = NativeConvert.ToTimeT(mach.UpdatedOn.ToUniversalTime())
}
};
}
_machinesStatCache[romSetId] = cachedMachines;
}
if(!cachedMachines.TryGetValue(pieces[1], out CachedMachine machineStat))
return Errno.ENOENT; return Errno.ENOENT;
if(pieces.Length == 2) if(pieces.Length == 2)
return Errno.EISDIR; return Errno.EISDIR;
_machineFilesCache.TryGetValue(machineStat.Id, _machineFilesCache.TryGetValue(machine.Id, out ConcurrentDictionary<string, CachedFile> cachedMachineFiles);
out ConcurrentDictionary<string, CachedFile> cachedMachineFiles);
if(cachedMachineFiles == null) if(cachedMachineFiles == null)
{ {
@@ -333,8 +275,8 @@ namespace RomRepoMgr.Core.Filesystem
cachedMachineFiles = new ConcurrentDictionary<string, CachedFile>(); cachedMachineFiles = new ConcurrentDictionary<string, CachedFile>();
foreach(FileByMachine machineFile in foreach(FileByMachine machineFile in ctx.FilesByMachines.Where(fbm => fbm.Machine.Id == machine.Id &&
ctx.FilesByMachines.Where(fbm => fbm.Machine.Id == machineStat.Id && fbm.File.IsInRepo)) fbm.File.IsInRepo))
{ {
var cachedFile = new CachedFile var cachedFile = new CachedFile
{ {
@@ -353,7 +295,7 @@ namespace RomRepoMgr.Core.Filesystem
cachedMachineFiles[machineFile.Name] = cachedFile; cachedMachineFiles[machineFile.Name] = cachedFile;
} }
_machineFilesCache[machineStat.Id] = cachedMachineFiles; _machineFilesCache[machine.Id] = cachedMachineFiles;
} }
if(!cachedMachineFiles.TryGetValue(pieces[2], out CachedFile file)) if(!cachedMachineFiles.TryGetValue(pieces[2], out CachedFile file))
@@ -520,16 +462,12 @@ namespace RomRepoMgr.Core.Filesystem
if(pieces.Length == 0) if(pieces.Length == 0)
return Errno.ENODATA; return Errno.ENODATA;
if(!_rootDirectoryCache.TryGetValue(pieces[0], out long romSetId)) long romSetId = _vfs.GetRomSetId(pieces[0]);
if(romSetId <= 0)
return Errno.ENOENT; return Errno.ENOENT;
if(!_romSetsCache.TryGetValue(romSetId, out RomSet romSet)) RomSet romSet = _vfs.GetRomSet(romSetId);
{
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
romSet = ctx.RomSets.Find(romSetId);
_romSetsCache[romSetId] = romSet;
}
if(romSet == null) if(romSet == null)
return Errno.ENOENT; return Errno.ENOENT;
@@ -537,40 +475,15 @@ namespace RomRepoMgr.Core.Filesystem
if(pieces.Length == 1) if(pieces.Length == 1)
return Errno.ENODATA; return Errno.ENODATA;
_machinesStatCache.TryGetValue(romSetId, out ConcurrentDictionary<string, CachedMachine> cachedMachines); CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);
if(cachedMachines == null) if(machine == null)
{
cachedMachines = new ConcurrentDictionary<string, CachedMachine>();
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
foreach(Machine mach in ctx.Machines.Where(m => m.RomSet.Id == romSetId))
{
cachedMachines[mach.Name] = new CachedMachine
{
Id = mach.Id,
Stat = new Stat
{
st_mode = FilePermissions.S_IFDIR | NativeConvert.FromOctalPermissionString("0555"),
st_nlink = 2,
st_ctime = NativeConvert.ToTimeT(mach.CreatedOn.ToUniversalTime()),
st_mtime = NativeConvert.ToTimeT(mach.UpdatedOn.ToUniversalTime())
}
};
}
_machinesStatCache[romSetId] = cachedMachines;
}
if(!cachedMachines.TryGetValue(pieces[1], out CachedMachine machineStat))
return Errno.ENOENT; return Errno.ENOENT;
if(pieces.Length == 2) if(pieces.Length == 2)
return Errno.ENODATA; return Errno.ENODATA;
_machineFilesCache.TryGetValue(machineStat.Id, _machineFilesCache.TryGetValue(machine.Id, out ConcurrentDictionary<string, CachedFile> cachedMachineFiles);
out ConcurrentDictionary<string, CachedFile> cachedMachineFiles);
if(cachedMachineFiles == null) if(cachedMachineFiles == null)
{ {
@@ -578,8 +491,8 @@ namespace RomRepoMgr.Core.Filesystem
cachedMachineFiles = new ConcurrentDictionary<string, CachedFile>(); cachedMachineFiles = new ConcurrentDictionary<string, CachedFile>();
foreach(FileByMachine machineFile in foreach(FileByMachine machineFile in ctx.FilesByMachines.Where(fbm => fbm.Machine.Id == machine.Id &&
ctx.FilesByMachines.Where(fbm => fbm.Machine.Id == machineStat.Id && fbm.File.IsInRepo)) fbm.File.IsInRepo))
{ {
var cachedFile = new CachedFile var cachedFile = new CachedFile
{ {
@@ -598,7 +511,7 @@ namespace RomRepoMgr.Core.Filesystem
cachedMachineFiles[machineFile.Name] = cachedFile; cachedMachineFiles[machineFile.Name] = cachedFile;
} }
_machineFilesCache[machineStat.Id] = cachedMachineFiles; _machineFilesCache[machine.Id] = cachedMachineFiles;
} }
if(!cachedMachineFiles.TryGetValue(pieces[2], out CachedFile file)) if(!cachedMachineFiles.TryGetValue(pieces[2], out CachedFile file))
@@ -689,16 +602,12 @@ namespace RomRepoMgr.Core.Filesystem
if(pieces.Length == 0) if(pieces.Length == 0)
return 0; return 0;
if(!_rootDirectoryCache.TryGetValue(pieces[0], out long romSetId)) long romSetId = _vfs.GetRomSetId(pieces[0]);
if(romSetId <= 0)
return Errno.ENOENT; return Errno.ENOENT;
if(!_romSetsCache.TryGetValue(romSetId, out RomSet romSet)) RomSet romSet = _vfs.GetRomSet(romSetId);
{
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
romSet = ctx.RomSets.Find(romSetId);
_romSetsCache[romSetId] = romSet;
}
if(romSet == null) if(romSet == null)
return Errno.ENOENT; return Errno.ENOENT;
@@ -706,40 +615,15 @@ namespace RomRepoMgr.Core.Filesystem
if(pieces.Length == 1) if(pieces.Length == 1)
return 0; return 0;
_machinesStatCache.TryGetValue(romSetId, out ConcurrentDictionary<string, CachedMachine> cachedMachines); CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);
if(cachedMachines == null) if(machine == null)
{
cachedMachines = new ConcurrentDictionary<string, CachedMachine>();
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
foreach(Machine mach in ctx.Machines.Where(m => m.RomSet.Id == romSetId))
{
cachedMachines[mach.Name] = new CachedMachine
{
Id = mach.Id,
Stat = new Stat
{
st_mode = FilePermissions.S_IFDIR | NativeConvert.FromOctalPermissionString("0555"),
st_nlink = 2,
st_ctime = NativeConvert.ToTimeT(mach.CreatedOn.ToUniversalTime()),
st_mtime = NativeConvert.ToTimeT(mach.UpdatedOn.ToUniversalTime())
}
};
}
_machinesStatCache[romSetId] = cachedMachines;
}
if(!cachedMachines.TryGetValue(pieces[1], out CachedMachine machineStat))
return Errno.ENOENT; return Errno.ENOENT;
if(pieces.Length == 2) if(pieces.Length == 2)
return 0; return 0;
_machineFilesCache.TryGetValue(machineStat.Id, _machineFilesCache.TryGetValue(machine.Id, out ConcurrentDictionary<string, CachedFile> cachedMachineFiles);
out ConcurrentDictionary<string, CachedFile> cachedMachineFiles);
if(cachedMachineFiles == null) if(cachedMachineFiles == null)
{ {
@@ -747,8 +631,8 @@ namespace RomRepoMgr.Core.Filesystem
cachedMachineFiles = new ConcurrentDictionary<string, CachedFile>(); cachedMachineFiles = new ConcurrentDictionary<string, CachedFile>();
foreach(FileByMachine machineFile in foreach(FileByMachine machineFile in ctx.FilesByMachines.Where(fbm => fbm.Machine.Id == machine.Id &&
ctx.FilesByMachines.Where(fbm => fbm.Machine.Id == machineStat.Id && fbm.File.IsInRepo)) fbm.File.IsInRepo))
{ {
var cachedFile = new CachedFile var cachedFile = new CachedFile
{ {
@@ -767,7 +651,7 @@ namespace RomRepoMgr.Core.Filesystem
cachedMachineFiles[machineFile.Name] = cachedFile; cachedMachineFiles[machineFile.Name] = cachedFile;
} }
_machineFilesCache[machineStat.Id] = cachedMachineFiles; _machineFilesCache[machine.Id] = cachedMachineFiles;
} }
if(!cachedMachineFiles.TryGetValue(pieces[2], out CachedFile file)) if(!cachedMachineFiles.TryGetValue(pieces[2], out CachedFile file))
@@ -834,8 +718,7 @@ namespace RomRepoMgr.Core.Filesystem
continue; continue;
entries.Add(new DirectoryEntry(name)); entries.Add(new DirectoryEntry(name));
rootCache[name] = set.Id; rootCache[name] = set.Id;
_romSetsCache[set.Id] = set;
} }
_lastHandle++; _lastHandle++;
@@ -856,43 +739,12 @@ namespace RomRepoMgr.Core.Filesystem
if(romSetId <= 0) if(romSetId <= 0)
return Errno.ENOENT; return Errno.ENOENT;
if(!_romSetsCache.TryGetValue(romSetId, out RomSet romSet)) RomSet romSet = _vfs.GetRomSet(romSetId);
{
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
romSet = ctx.RomSets.Find(romSetId);
_romSetsCache[romSetId] = romSet;
}
if(romSet == null) if(romSet == null)
return Errno.ENOENT; return Errno.ENOENT;
_machinesStatCache.TryGetValue(romSetId, ConcurrentDictionary<string, CachedMachine> machines = _vfs.GetMachinesFromRomSet(romSetId);
out ConcurrentDictionary<string, CachedMachine> cachedMachines);
if(cachedMachines == null)
{
cachedMachines = new ConcurrentDictionary<string, CachedMachine>();
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
foreach(Machine mach in ctx.Machines.Where(m => m.RomSet.Id == romSetId))
{
cachedMachines[mach.Name] = new CachedMachine
{
Id = mach.Id,
Stat = new Stat
{
st_mode = FilePermissions.S_IFDIR | NativeConvert.FromOctalPermissionString("0755"),
st_nlink = 2,
st_ctime = NativeConvert.ToTimeT(mach.CreatedOn.ToUniversalTime()),
st_mtime = NativeConvert.ToTimeT(mach.UpdatedOn.ToUniversalTime())
}
};
}
_machinesStatCache[romSetId] = cachedMachines;
}
if(pieces.Length == 1) if(pieces.Length == 1)
{ {
@@ -902,7 +754,7 @@ namespace RomRepoMgr.Core.Filesystem
new DirectoryEntry("..") new DirectoryEntry("..")
}; };
entries.AddRange(cachedMachines.Select(mach => new DirectoryEntry(mach.Key))); entries.AddRange(machines.Select(mach => new DirectoryEntry(mach.Key)));
_lastHandle++; _lastHandle++;
info.Handle = new IntPtr(_lastHandle); info.Handle = new IntPtr(_lastHandle);
@@ -912,31 +764,10 @@ namespace RomRepoMgr.Core.Filesystem
return 0; return 0;
} }
cachedMachines.TryGetValue(pieces[1], out CachedMachine machine); CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);
if(machine == null) if(machine == null)
{ return Errno.ENOENT;
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
Machine mach = ctx.Machines.FirstOrDefault(m => m.RomSet.Id == romSetId && m.Name == pieces[1]);
if(mach == null)
return Errno.ENOENT;
cachedMachines[mach.Name] = new CachedMachine
{
Id = mach.Id,
Stat = new Stat
{
st_mode = FilePermissions.S_IFDIR | NativeConvert.FromOctalPermissionString("0755"),
st_nlink = 2,
st_ctime = NativeConvert.ToTimeT(mach.CreatedOn.ToUniversalTime()),
st_mtime = NativeConvert.ToTimeT(mach.UpdatedOn.ToUniversalTime())
}
};
machine = cachedMachines[mach.Name];
}
_machineFilesCache.TryGetValue(machine.Id, _machineFilesCache.TryGetValue(machine.Id,
out ConcurrentDictionary<string, CachedFile> cachedMachineFiles); out ConcurrentDictionary<string, CachedFile> cachedMachineFiles);
@@ -1040,13 +871,7 @@ namespace RomRepoMgr.Core.Filesystem
if(romSetId <= 0) if(romSetId <= 0)
return Errno.ENOENT; return Errno.ENOENT;
if(!_romSetsCache.TryGetValue(romSetId, out RomSet romSet)) RomSet romSet = _vfs.GetRomSet(romSetId);
{
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
romSet = ctx.RomSets.Find(romSetId);
_romSetsCache[romSetId] = romSet;
}
if(romSet == null) if(romSet == null)
return Errno.ENOENT; return Errno.ENOENT;
@@ -1054,40 +879,15 @@ namespace RomRepoMgr.Core.Filesystem
if(pieces.Length == 1) if(pieces.Length == 1)
return mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0; return mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0;
_machinesStatCache.TryGetValue(romSetId, out ConcurrentDictionary<string, CachedMachine> cachedMachines); CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);
if(cachedMachines == null) if(machine == null)
{
cachedMachines = new ConcurrentDictionary<string, CachedMachine>();
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
foreach(Machine mach in ctx.Machines.Where(m => m.RomSet.Id == romSetId))
{
cachedMachines[mach.Name] = new CachedMachine
{
Id = mach.Id,
Stat = new Stat
{
st_mode = FilePermissions.S_IFDIR | NativeConvert.FromOctalPermissionString("0555"),
st_nlink = 2,
st_ctime = NativeConvert.ToTimeT(mach.CreatedOn.ToUniversalTime()),
st_mtime = NativeConvert.ToTimeT(mach.UpdatedOn.ToUniversalTime())
}
};
}
_machinesStatCache[romSetId] = cachedMachines;
}
if(!cachedMachines.TryGetValue(pieces[1], out CachedMachine machineStat))
return Errno.ENOENT; return Errno.ENOENT;
if(pieces.Length == 2) if(pieces.Length == 2)
return mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0; return mode.HasFlag(AccessModes.W_OK) ? Errno.EROFS : 0;
_machineFilesCache.TryGetValue(machineStat.Id, _machineFilesCache.TryGetValue(machine.Id, out ConcurrentDictionary<string, CachedFile> cachedMachineFiles);
out ConcurrentDictionary<string, CachedFile> cachedMachineFiles);
if(cachedMachineFiles == null) if(cachedMachineFiles == null)
{ {
@@ -1095,8 +895,8 @@ namespace RomRepoMgr.Core.Filesystem
cachedMachineFiles = new ConcurrentDictionary<string, CachedFile>(); cachedMachineFiles = new ConcurrentDictionary<string, CachedFile>();
foreach(FileByMachine machineFile in foreach(FileByMachine machineFile in ctx.FilesByMachines.Where(fbm => fbm.Machine.Id == machine.Id &&
ctx.FilesByMachines.Where(fbm => fbm.Machine.Id == machineStat.Id && fbm.File.IsInRepo)) fbm.File.IsInRepo))
{ {
var cachedFile = new CachedFile var cachedFile = new CachedFile
{ {
@@ -1115,7 +915,7 @@ namespace RomRepoMgr.Core.Filesystem
cachedMachineFiles[machineFile.Name] = cachedFile; cachedMachineFiles[machineFile.Name] = cachedFile;
} }
_machineFilesCache[machineStat.Id] = cachedMachineFiles; _machineFilesCache[machine.Id] = cachedMachineFiles;
} }
if(!cachedMachineFiles.TryGetValue(pieces[2], out CachedFile _)) if(!cachedMachineFiles.TryGetValue(pieces[2], out CachedFile _))
@@ -1165,12 +965,6 @@ namespace RomRepoMgr.Core.Filesystem
setxattr(Path.Combine(MountPoint, ".fuse_umount"), _umountToken, IntPtr.Zero, 0, 0); setxattr(Path.Combine(MountPoint, ".fuse_umount"), _umountToken, IntPtr.Zero, 0, 0);
} }
sealed class CachedMachine
{
public ulong Id { get; set; }
public Stat Stat { get; set; }
}
sealed class CachedFile sealed class CachedFile
{ {
public ulong Id { get; set; } public ulong Id { get; set; }

View File

@@ -11,16 +11,17 @@ namespace RomRepoMgr.Core.Filesystem
{ {
public class Vfs : IDisposable public class Vfs : IDisposable
{ {
readonly ConcurrentDictionary<long, RomSet> _romSetsCache; readonly ConcurrentDictionary<long, ConcurrentDictionary<string, CachedMachine>> _machinesStatCache;
Fuse _fuse; readonly ConcurrentDictionary<long, RomSet> _romSetsCache;
Fuse _fuse;
ConcurrentDictionary<string, long> _rootDirectoryCache; ConcurrentDictionary<string, long> _rootDirectoryCache;
Winfsp _winfsp; Winfsp _winfsp;
public Vfs() public Vfs()
{ {
_rootDirectoryCache = new ConcurrentDictionary<string, long>(); _rootDirectoryCache = new ConcurrentDictionary<string, long>();
_romSetsCache = new ConcurrentDictionary<long, RomSet>(); _romSetsCache = new ConcurrentDictionary<long, RomSet>();
_machinesStatCache = new ConcurrentDictionary<long, ConcurrentDictionary<string, CachedMachine>>();
} }
public static bool IsAvailable => Winfsp.IsAvailable || Fuse.IsAvailable; public static bool IsAvailable => Winfsp.IsAvailable || Fuse.IsAvailable;
@@ -135,5 +136,66 @@ namespace RomRepoMgr.Core.Filesystem
return romSetId; return romSetId;
} }
internal RomSet GetRomSet(long id)
{
if(_romSetsCache.TryGetValue(id, out RomSet romSet))
return romSet;
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
romSet = ctx.RomSets.Find(id);
if(romSet == null)
return null;
_romSetsCache[id] = romSet;
return romSet;
}
internal ConcurrentDictionary<string, CachedMachine> GetMachinesFromRomSet(long id)
{
_machinesStatCache.TryGetValue(id, out ConcurrentDictionary<string, CachedMachine> cachedMachines);
if(cachedMachines != null)
return cachedMachines;
cachedMachines = new ConcurrentDictionary<string, CachedMachine>();
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
foreach(Machine mach in ctx.Machines.Where(m => m.RomSet.Id == id))
{
cachedMachines[mach.Name] = new CachedMachine
{
Id = mach.Id,
CreationDate = mach.CreatedOn,
ModificationDate = mach.UpdatedOn
};
}
_machinesStatCache[id] = cachedMachines;
return cachedMachines;
}
internal CachedMachine GetMachine(long romSetId, string name)
{
ConcurrentDictionary<string, CachedMachine> cachedMachines = GetMachinesFromRomSet(romSetId);
if(cachedMachines == null ||
!cachedMachines.TryGetValue(name, out CachedMachine machine))
return null;
return machine;
}
}
internal sealed class CachedMachine
{
public ulong Id { get; set; }
public DateTime CreationDate { get; set; }
public DateTime ModificationDate { get; set; }
} }
} }