aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAc_K <Acoustik666@gmail.com>2024-01-29 16:32:34 +0100
committerGitHub <noreply@github.com>2024-01-29 16:32:34 +0100
commit7795b662a9b6054343195db9fc221a920509c1be (patch)
treecc2189229bc4d82296f53a5ad340690b47ad4a75
parent30bdc4544e5270ba0676e3a288b947b685aa1cab (diff)
Mod: Do LayeredFs loading Parallel to improve speed (#6180)1.1.1143
* Mod: Do LayeredFs loading Parallel to improve speed This fixes and superseed #5672 due to inactivity, nothing more. (See original PR for description) Testing are welcome. Close #5661 * Addresses gdkchan's feedback * commit to test mako change * Revert "commit to test mako change" This reverts commit 8b0caa8a21db298db3dfcbe5b7e9029c4f066c46.
-rw-r--r--src/Ryujinx.HLE/HOS/ModLoader.cs13
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/LazyFile.cs65
2 files changed, 72 insertions, 6 deletions
diff --git a/src/Ryujinx.HLE/HOS/ModLoader.cs b/src/Ryujinx.HLE/HOS/ModLoader.cs
index 322c8afd..8ae52965 100644
--- a/src/Ryujinx.HLE/HOS/ModLoader.cs
+++ b/src/Ryujinx.HLE/HOS/ModLoader.cs
@@ -18,6 +18,7 @@ using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Linq;
+using LazyFile = Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.LazyFile;
using Path = System.IO.Path;
namespace Ryujinx.HLE.HOS
@@ -512,7 +513,7 @@ namespace Ryujinx.HLE.HOS
using (IFileSystem fs = new LocalFileSystem(mod.Path.FullName))
{
- AddFiles(fs, mod.Name, fileSet, builder);
+ AddFiles(fs, mod.Name, mod.Path.FullName, fileSet, builder);
}
count++;
}
@@ -528,7 +529,7 @@ namespace Ryujinx.HLE.HOS
Logger.Info?.Print(LogClass.ModLoader, $"Found 'romfs.bin' for Application {applicationId:X16}");
using (IFileSystem fs = new RomFsFileSystem(mod.Path.OpenRead().AsStorage()))
{
- AddFiles(fs, mod.Name, fileSet, builder);
+ AddFiles(fs, mod.Name, mod.Path.FullName, fileSet, builder);
}
count++;
}
@@ -561,18 +562,18 @@ namespace Ryujinx.HLE.HOS
return newStorage;
}
- private static void AddFiles(IFileSystem fs, string modName, ISet<string> fileSet, RomFsBuilder builder)
+ private static void AddFiles(IFileSystem fs, string modName, string rootPath, ISet<string> fileSet, RomFsBuilder builder)
{
foreach (var entry in fs.EnumerateEntries()
+ .AsParallel()
.Where(f => f.Type == DirectoryEntryType.File)
.OrderBy(f => f.FullPath, StringComparer.Ordinal))
{
- using var file = new UniqueRef<IFile>();
+ var file = new LazyFile(entry.FullPath, rootPath, fs);
- fs.OpenFile(ref file.Ref, entry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
if (fileSet.Add(entry.FullPath))
{
- builder.AddFile(entry.FullPath, file.Release());
+ builder.AddFile(entry.FullPath, file);
}
else
{
diff --git a/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/LazyFile.cs b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/LazyFile.cs
new file mode 100644
index 00000000..a179e8e3
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/LazyFile.cs
@@ -0,0 +1,65 @@
+using LibHac;
+using LibHac.Common;
+using LibHac.Fs;
+using System;
+using System.IO;
+
+namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
+{
+ class LazyFile : LibHac.Fs.Fsa.IFile
+ {
+ private readonly LibHac.Fs.Fsa.IFileSystem _fs;
+ private readonly string _filePath;
+ private readonly UniqueRef<LibHac.Fs.Fsa.IFile> _fileReference = new();
+ private readonly FileInfo _fileInfo;
+
+ public LazyFile(string filePath, string prefix, LibHac.Fs.Fsa.IFileSystem fs)
+ {
+ _fs = fs;
+ _filePath = filePath;
+ _fileInfo = new FileInfo(prefix + "/" + filePath);
+ }
+
+ private void PrepareFile()
+ {
+ if (_fileReference.Get == null)
+ {
+ _fs.OpenFile(ref _fileReference.Ref, _filePath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
+ }
+ }
+
+ protected override Result DoRead(out long bytesRead, long offset, Span<byte> destination, in ReadOption option)
+ {
+ PrepareFile();
+
+ return _fileReference.Get!.Read(out bytesRead, offset, destination);
+ }
+
+ protected override Result DoWrite(long offset, ReadOnlySpan<byte> source, in WriteOption option)
+ {
+ throw new NotSupportedException();
+ }
+
+ protected override Result DoFlush()
+ {
+ throw new NotSupportedException();
+ }
+
+ protected override Result DoSetSize(long size)
+ {
+ throw new NotSupportedException();
+ }
+
+ protected override Result DoGetSize(out long size)
+ {
+ size = _fileInfo.Length;
+
+ return Result.Success;
+ }
+
+ protected override Result DoOperateRange(Span<byte> outBuffer, OperationId operationId, long offset, long size, ReadOnlySpan<byte> inBuffer)
+ {
+ throw new NotSupportedException();
+ }
+ }
+}