Adjust opened SaveDataInfoReaders if the collection is modified

This commit is contained in:
Alex Barney 2019-10-23 15:44:00 -05:00
parent f0aac13fab
commit 04b123f16e
4 changed files with 67 additions and 3 deletions

View file

@ -227,7 +227,7 @@ namespace LibHac.Fs.Shim
} }
} }
public struct SaveDataIterator public struct SaveDataIterator : IDisposable
{ {
private FileSystemClient FsClient { get; } private FileSystemClient FsClient { get; }
private ISaveDataInfoReader Reader { get; } private ISaveDataInfoReader Reader { get; }
@ -259,5 +259,10 @@ namespace LibHac.Fs.Shim
return rc; return rc;
} }
public void Dispose()
{
Reader?.Dispose();
}
} }
} }

View file

@ -2,7 +2,7 @@
namespace LibHac.FsService namespace LibHac.FsService
{ {
public interface ISaveDataInfoReader public interface ISaveDataInfoReader : IDisposable
{ {
Result ReadSaveDataInfo(out long readCount, Span<byte> saveDataInfoBuffer); Result ReadSaveDataInfo(out long readCount, Span<byte> saveDataInfoBuffer);
} }

View file

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using LibHac.Common; using LibHac.Common;
@ -26,6 +27,7 @@ namespace LibHac.FsService
private bool IsKvdbLoaded { get; set; } private bool IsKvdbLoaded { get; set; }
private ulong LastPublishedId { get; set; } private ulong LastPublishedId { get; set; }
private int Version { get; set; } private int Version { get; set; }
private List<SaveDataInfoReader> OpenedReaders { get; } = new List<SaveDataInfoReader>();
public SaveDataIndexer(FileSystemClient fsClient, string mountName, SaveDataSpaceId spaceId, ulong saveDataId) public SaveDataIndexer(FileSystemClient fsClient, string mountName, SaveDataSpaceId spaceId, ulong saveDataId)
{ {
@ -356,6 +358,8 @@ namespace LibHac.FsService
var reader = new SaveDataInfoReader(this); var reader = new SaveDataInfoReader(this);
OpenedReaders.Add(reader);
infoReader = reader; infoReader = reader;
return Result.Success; return Result.Success;
@ -490,10 +494,55 @@ namespace LibHac.FsService
private Result AdjustOpenedInfoReaders(ref SaveDataAttribute key) private Result AdjustOpenedInfoReaders(ref SaveDataAttribute key)
{ {
// todo // If a new key is added or removed during iteration of the list,
// make sure the current item of the iterator remains the same
// Todo: A more efficient way of doing this
List<SaveDataAttribute> list = KvDatabase.ToList().Select(x => x.key).ToList();
int index = list.BinarySearch(key);
bool keyWasAdded = index >= 0;
if (!keyWasAdded)
{
// If the item was not found, List<T>.BinarySearch returns a negative number that
// is the bitwise complement of the index of the next element that is larger than the item
index = ~index;
}
foreach (SaveDataInfoReader reader in OpenedReaders)
{
if (keyWasAdded)
{
// New key was inserted before the iterator's position
// increment the position to compensate
if(reader.Position >= index)
{
reader.Position++;
}
}
else
{
// The position should be decremented if the iterator's position is
// after the key that came directly after the deleted key
if (reader.Position > index)
{
reader.Position--;
}
}
}
return Result.Success; return Result.Success;
} }
private void CloseReader(SaveDataInfoReader reader)
{
bool wasRemoved = OpenedReaders.Remove(reader);
Debug.Assert(wasRemoved);
}
private ref struct Mounter private ref struct Mounter
{ {
private FileSystemClient FsClient { get; set; } private FileSystemClient FsClient { get; set; }
@ -602,6 +651,11 @@ namespace LibHac.FsService
return Result.Success; return Result.Success;
} }
} }
public void Dispose()
{
Indexer?.CloseReader(this);
}
} }
} }
} }

View file

@ -48,6 +48,11 @@ namespace LibHac.FsService
return Result.Success; return Result.Success;
} }
public void Dispose()
{
Reader?.Dispose();
}
} }
[StructLayout(LayoutKind.Explicit, Size = 0x50)] [StructLayout(LayoutKind.Explicit, Size = 0x50)]