mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-08-19 21:52:22 +00:00
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
This commit is contained in:
parent
cea204d48e
commit
8854c0c25c
|
@ -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 ILazyFile = Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.ILazyFile;
|
||||||
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 ILazyFile(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/ILazyFile.cs
Normal file
65
src/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/ILazyFile.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
|
||||||
|
{
|
||||||
|
public class ILazyFile : 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 ILazyFile(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 new Result(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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