Mod: Do LayeredFs loading Parallel to improve speed (#6180)
* 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 8b0caa8a21
.
This commit is contained in:
parent
30bdc4544e
commit
7795b662a9
2 changed files with 72 additions and 6 deletions
|
@ -18,6 +18,7 @@ using System.Collections.Specialized;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using LazyFile = Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.LazyFile;
|
||||||
using Path = System.IO.Path;
|
using Path = System.IO.Path;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS
|
namespace Ryujinx.HLE.HOS
|
||||||
|
@ -512,7 +513,7 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
using (IFileSystem fs = new LocalFileSystem(mod.Path.FullName))
|
using (IFileSystem fs = new LocalFileSystem(mod.Path.FullName))
|
||||||
{
|
{
|
||||||
AddFiles(fs, mod.Name, fileSet, builder);
|
AddFiles(fs, mod.Name, mod.Path.FullName, fileSet, builder);
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
@ -528,7 +529,7 @@ namespace Ryujinx.HLE.HOS
|
||||||
Logger.Info?.Print(LogClass.ModLoader, $"Found 'romfs.bin' for Application {applicationId:X16}");
|
Logger.Info?.Print(LogClass.ModLoader, $"Found 'romfs.bin' for Application {applicationId:X16}");
|
||||||
using (IFileSystem fs = new RomFsFileSystem(mod.Path.OpenRead().AsStorage()))
|
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++;
|
count++;
|
||||||
}
|
}
|
||||||
|
@ -561,18 +562,18 @@ namespace Ryujinx.HLE.HOS
|
||||||
return newStorage;
|
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()
|
foreach (var entry in fs.EnumerateEntries()
|
||||||
|
.AsParallel()
|
||||||
.Where(f => f.Type == DirectoryEntryType.File)
|
.Where(f => f.Type == DirectoryEntryType.File)
|
||||||
.OrderBy(f => f.FullPath, StringComparer.Ordinal))
|
.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))
|
if (fileSet.Add(entry.FullPath))
|
||||||
{
|
{
|
||||||
builder.AddFile(entry.FullPath, file.Release());
|
builder.AddFile(entry.FullPath, file);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
65
src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/LazyFile.cs
Normal file
65
src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/LazyFile.cs
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue