Change ref to in where possible in SaveDataIndexer and kvdb

This commit is contained in:
Alex Barney 2020-08-04 22:01:17 -07:00
parent d575415b0e
commit c1b9eb8903
11 changed files with 127 additions and 145 deletions

View File

@ -15,12 +15,31 @@ namespace LibHac.Fs
[FieldOffset(0x21)] public SaveDataRank Rank;
[FieldOffset(0x22)] public short Index;
public override bool Equals(object obj)
public SaveDataAttribute(ProgramId programId, SaveDataType type, UserId userId, ulong saveDataId) : this(
programId, type, userId, saveDataId, 0, SaveDataRank.Primary)
{ }
public SaveDataAttribute(ProgramId programId, SaveDataType type, UserId userId, ulong saveDataId,
short index) : this(programId, type, userId, saveDataId, index, SaveDataRank.Primary)
{ }
public SaveDataAttribute(ProgramId programId, SaveDataType type, UserId userId, ulong saveDataId, short index,
SaveDataRank rank)
{
ProgramId = programId;
Type = type;
UserId = userId;
StaticSaveDataId = saveDataId;
Index = index;
Rank = rank;
}
public override readonly bool Equals(object obj)
{
return obj is SaveDataAttribute attribute && Equals(attribute);
}
public bool Equals(SaveDataAttribute other)
public readonly bool Equals(SaveDataAttribute other)
{
return ProgramId == other.ProgramId &&
Type == other.Type &&
@ -33,24 +52,24 @@ namespace LibHac.Fs
public static bool operator ==(SaveDataAttribute left, SaveDataAttribute right) => left.Equals(right);
public static bool operator !=(SaveDataAttribute left, SaveDataAttribute right) => !(left == right);
public override int GetHashCode()
public override readonly int GetHashCode()
{
// ReSharper disable NonReadonlyMemberInGetHashCode
return HashCode.Combine(ProgramId, Type, UserId, StaticSaveDataId, Rank, Index);
// ReSharper restore NonReadonlyMemberInGetHashCode
}
public int CompareTo(SaveDataAttribute other)
public readonly int CompareTo(SaveDataAttribute other)
{
int titleIdComparison = ProgramId.CompareTo(other.ProgramId);
if (titleIdComparison != 0) return titleIdComparison;
int typeComparison = Type.CompareTo(other.Type);
int typeComparison = ((int)Type).CompareTo((int)other.Type);
if (typeComparison != 0) return typeComparison;
int userIdComparison = UserId.CompareTo(other.UserId);
if (userIdComparison != 0) return userIdComparison;
int saveDataIdComparison = StaticSaveDataId.CompareTo(other.StaticSaveDataId);
if (saveDataIdComparison != 0) return saveDataIdComparison;
int rankComparison = Rank.CompareTo(other.Rank);
int rankComparison = ((int)Rank).CompareTo((int)other.Rank);
if (rankComparison != 0) return rankComparison;
return Index.CompareTo(other.Index);
}

View File

@ -43,9 +43,7 @@ namespace LibHac.Fs.Shim
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
SaveDataAttribute attribute = default;
attribute.ProgramId = applicationId;
attribute.Type = SaveDataType.Bcat;
var attribute = new SaveDataAttribute(applicationId, SaveDataType.Bcat, UserId.Zero, 0);
rc = fsProxy.OpenSaveDataFileSystem(out IFileSystem fileSystem, SaveDataSpaceId.User, ref attribute);
if (rc.IsFailure()) return rc;

View File

@ -191,11 +191,7 @@ namespace LibHac.Fs.Shim
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
SaveDataAttribute attribute = default;
attribute.ProgramId = programId;
attribute.UserId = userId;
attribute.Type = type;
attribute.Index = index;
var attribute = new SaveDataAttribute(programId, type, userId, 0, index);
IFileSystem saveFs;

View File

@ -17,12 +17,7 @@ namespace LibHac.Fs.Shim
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute
{
ProgramId = applicationId,
UserId = userId,
Type = SaveDataType.Account
};
var attribute = new SaveDataAttribute(applicationId, SaveDataType.Account, userId, 0);
var createInfo = new SaveDataCreationInfo
{
@ -54,12 +49,7 @@ namespace LibHac.Fs.Shim
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute
{
ProgramId = applicationId,
UserId = userId,
Type = SaveDataType.Account
};
var attribute = new SaveDataAttribute(applicationId, SaveDataType.Account, userId, 0);
var createInfo = new SaveDataCreationInfo
{
@ -91,11 +81,7 @@ namespace LibHac.Fs.Shim
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute
{
ProgramId = applicationId,
Type = SaveDataType.Bcat
};
var attribute = new SaveDataAttribute(applicationId, SaveDataType.Bcat, UserId.Zero, 0);
var createInfo = new SaveDataCreationInfo
{
@ -122,11 +108,7 @@ namespace LibHac.Fs.Shim
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute
{
ProgramId = applicationId,
Type = SaveDataType.Device
};
var attribute = new SaveDataAttribute(applicationId, SaveDataType.Device, UserId.Zero, 0);
var createInfo = new SaveDataCreationInfo
{
@ -152,11 +134,7 @@ namespace LibHac.Fs.Shim
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute
{
ProgramId = applicationId,
Type = SaveDataType.Temporary
};
var attribute = new SaveDataAttribute(applicationId, SaveDataType.Temporary, UserId.Zero, 0);
var createInfo = new SaveDataCreationInfo
{
@ -182,12 +160,7 @@ namespace LibHac.Fs.Shim
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute
{
ProgramId = applicationId,
Type = SaveDataType.Cache,
Index = index
};
var attribute = new SaveDataAttribute(applicationId, SaveDataType.Cache, UserId.Zero, 0, index);
var creationInfo = new SaveDataCreationInfo
{
@ -226,11 +199,7 @@ namespace LibHac.Fs.Shim
{
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
var attribute = new SaveDataAttribute
{
UserId = userId,
StaticSaveDataId = saveDataId
};
var attribute = new SaveDataAttribute(ProgramId.InvalidId, SaveDataType.System, userId, saveDataId);
var createInfo = new SaveDataCreationInfo
{

View File

@ -1,6 +1,7 @@
using LibHac.Common;
using LibHac.Fs.Fsa;
using LibHac.FsService;
using LibHac.Ncm;
namespace LibHac.Fs.Shim
{
@ -19,9 +20,7 @@ namespace LibHac.Fs.Shim
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
SaveDataAttribute attribute = default;
attribute.UserId = userId;
attribute.StaticSaveDataId = saveDataId;
var attribute = new SaveDataAttribute(ProgramId.InvalidId, SaveDataType.System, userId, saveDataId);
rc = fsProxy.OpenSaveDataFileSystemBySystemSaveDataId(out IFileSystem fileSystem, spaceId, ref attribute);
if (rc.IsFailure()) return rc;

View File

@ -227,7 +227,7 @@ namespace LibHac.FsService
return DeleteSaveDataFileSystemImpl(spaceId, saveDataId);
}
private Result GetSaveDataInfo(out SaveDataInfo info, SaveDataSpaceId spaceId, ref SaveDataAttribute attribute)
private Result GetSaveDataInfo(out SaveDataInfo info, SaveDataSpaceId spaceId, in SaveDataAttribute attribute)
{
Unsafe.SkipInit(out info);
@ -236,7 +236,7 @@ namespace LibHac.FsService
using (accessor)
{
rc = accessor.Indexer.Get(out SaveDataIndexerValue value, ref attribute);
rc = accessor.Indexer.Get(out SaveDataIndexerValue value, in attribute);
if (rc.IsFailure()) return rc;
SaveDataIndexer.GenerateSaveDataInfo(out info, in attribute, in value);
@ -246,7 +246,7 @@ namespace LibHac.FsService
public Result DeleteSaveDataFileSystemBySaveDataAttribute(SaveDataSpaceId spaceId, ref SaveDataAttribute attribute)
{
Result rs = GetSaveDataInfo(out SaveDataInfo info, spaceId, ref attribute);
Result rs = GetSaveDataInfo(out SaveDataInfo info, spaceId, in attribute);
if (rs.IsFailure()) return rs;
return DeleteSaveDataFileSystemBySaveDataSpaceIdImpl(spaceId, info.SaveDataId);
@ -291,7 +291,7 @@ namespace LibHac.FsService
{
saveDataId = attribute.StaticSaveDataId;
rc = accessor.Indexer.PutStaticSaveDataIdIndex(ref indexerKey);
rc = accessor.Indexer.PutStaticSaveDataIdIndex(in indexerKey);
}
else
{
@ -304,7 +304,7 @@ namespace LibHac.FsService
}
}
rc = accessor.Indexer.Publish(out saveDataId, ref indexerKey);
rc = accessor.Indexer.Publish(out saveDataId, in indexerKey);
}
if (ResultFs.SaveDataPathAlreadyExists.Includes(rc))
@ -491,7 +491,7 @@ namespace LibHac.FsService
using SaveDataIndexerAccessor accessor = tempAccessor;
if (rc.IsFailure()) return rc;
rc = accessor.Indexer.Get(out SaveDataIndexerValue indexerValue, ref indexerKey);
rc = accessor.Indexer.Get(out SaveDataIndexerValue indexerValue, in indexerKey);
if (rc.IsFailure()) return rc;
SaveDataSpaceId indexerSpaceId = GetSpaceIdForIndexer(spaceId);
@ -1143,9 +1143,8 @@ namespace LibHac.FsService
{
fileSystem = default;
SaveDataAttribute attribute = default;
attribute.ProgramId = new ProgramId(MultiCommitManager.ProgramId);
attribute.StaticSaveDataId = MultiCommitManager.SaveDataId;
var attribute = new SaveDataAttribute(new ProgramId(MultiCommitManager.ProgramId), SaveDataType.System,
UserId.Zero, MultiCommitManager.SaveDataId);
Result rc = OpenSaveDataFileSystemImpl(out IFileSystem saveFs, out _, SaveDataSpaceId.System, ref attribute,
false, true);

View File

@ -8,9 +8,9 @@ namespace LibHac.FsService
Result Commit();
Result Rollback();
Result Reset();
Result Publish(out ulong saveDataId, ref SaveDataAttribute key);
Result Get(out SaveDataIndexerValue value, ref SaveDataAttribute key);
Result PutStaticSaveDataIdIndex(ref SaveDataAttribute key);
Result Publish(out ulong saveDataId, in SaveDataAttribute key);
Result Get(out SaveDataIndexerValue value, in SaveDataAttribute key);
Result PutStaticSaveDataIdIndex(in SaveDataAttribute key);
bool IsRemainedReservedOnly();
Result Delete(ulong saveDataId);
Result SetSpaceId(ulong saveDataId, SaveDataSpaceId spaceId);
@ -18,7 +18,7 @@ namespace LibHac.FsService
Result SetState(ulong saveDataId, SaveDataState state);
Result GetKey(out SaveDataAttribute key, ulong saveDataId);
Result GetValue(out SaveDataIndexerValue value, ulong saveDataId);
Result SetValue(ref SaveDataAttribute key, ref SaveDataIndexerValue value);
Result SetValue(in SaveDataAttribute key, in SaveDataIndexerValue value);
int GetIndexCount();
Result OpenSaveDataInfoReader(out ReferenceCountedDisposable<ISaveDataInfoReader> infoReader);
}

View File

@ -197,7 +197,7 @@ namespace LibHac.FsService
}
}
public Result Publish(out ulong saveDataId, ref SaveDataAttribute key)
public Result Publish(out ulong saveDataId, in SaveDataAttribute key)
{
saveDataId = default;
@ -212,7 +212,7 @@ namespace LibHac.FsService
Unsafe.SkipInit(out SaveDataIndexerValue value);
// Make sure the key isn't in the database already.
rc = KvDatabase.Get(out _, ref key, SpanHelpers.AsByteSpan(ref value));
rc = KvDatabase.Get(out _, in key, SpanHelpers.AsByteSpan(ref value));
if (rc.IsSuccess())
{
@ -224,7 +224,7 @@ namespace LibHac.FsService
value = new SaveDataIndexerValue { SaveDataId = newSaveDataId };
rc = KvDatabase.Set(ref key, SpanHelpers.AsByteSpan(ref value));
rc = KvDatabase.Set(in key, SpanHelpers.AsByteSpan(ref value));
if (rc.IsFailure())
{
@ -232,7 +232,7 @@ namespace LibHac.FsService
return rc;
}
rc = FixReader(ref key);
rc = FixReader(in key);
if (rc.IsFailure()) return rc;
saveDataId = newSaveDataId;
@ -240,7 +240,7 @@ namespace LibHac.FsService
}
}
public Result Get(out SaveDataIndexerValue value, ref SaveDataAttribute key)
public Result Get(out SaveDataIndexerValue value, in SaveDataAttribute key)
{
Unsafe.SkipInit(out value);
@ -252,7 +252,7 @@ namespace LibHac.FsService
rc = TryLoadDatabase(false);
if (rc.IsFailure()) return rc;
rc = KvDatabase.Get(out _, ref key, SpanHelpers.AsByteSpan(ref value));
rc = KvDatabase.Get(out _, in key, SpanHelpers.AsByteSpan(ref value));
if (rc.IsFailure())
{
@ -263,7 +263,7 @@ namespace LibHac.FsService
}
}
public Result PutStaticSaveDataIdIndex(ref SaveDataAttribute key)
public Result PutStaticSaveDataIdIndex(in SaveDataAttribute key)
{
lock (Locker)
{
@ -290,10 +290,10 @@ namespace LibHac.FsService
SaveDataId = key.StaticSaveDataId
};
rc = KvDatabase.Set(ref key, SpanHelpers.AsReadOnlyByteSpan(in newValue));
rc = KvDatabase.Set(in key, SpanHelpers.AsReadOnlyByteSpan(in newValue));
if (rc.IsFailure()) return rc;
rc = FixReader(ref key);
rc = FixReader(in key);
if (rc.IsFailure()) return rc;
return Result.Success;
@ -330,10 +330,10 @@ namespace LibHac.FsService
SaveDataAttribute key = iterator.Get().Key;
rc = KvDatabase.Delete(ref key);
rc = KvDatabase.Delete(in key);
if (rc.IsFailure()) return rc;
rc = FixReader(ref key);
rc = FixReader(in key);
if (rc.IsFailure()) return rc;
return Result.Success;
@ -371,7 +371,7 @@ namespace LibHac.FsService
func(ref value, data);
rc = KvDatabase.Set(ref iterator.Get().Key, SpanHelpers.AsReadOnlyByteSpan(in value));
rc = KvDatabase.Set(in iterator.Get().Key, SpanHelpers.AsReadOnlyByteSpan(in value));
if (rc.IsFailure()) return rc;
return Result.Success;
@ -462,7 +462,7 @@ namespace LibHac.FsService
return ResultFs.TargetNotFound.Log();
}
public Result SetValue(ref SaveDataAttribute key, ref SaveDataIndexerValue value)
public Result SetValue(in SaveDataAttribute key, in SaveDataIndexerValue value)
{
Result rc = TryInitializeDatabase();
if (rc.IsFailure()) return rc;
@ -470,7 +470,7 @@ namespace LibHac.FsService
rc = TryLoadDatabase(false);
if (rc.IsFailure()) return rc;
FlatMapKeyValueStore<SaveDataAttribute>.Iterator iterator = KvDatabase.GetLowerBoundIterator(ref key);
FlatMapKeyValueStore<SaveDataAttribute>.Iterator iterator = KvDatabase.GetLowerBoundIterator(in key);
// Key was not found
if (iterator.IsEnd())
@ -520,9 +520,9 @@ namespace LibHac.FsService
}
private void FixIterator(ref FlatMapKeyValueStore<SaveDataAttribute>.Iterator iterator,
ref SaveDataAttribute key)
in SaveDataAttribute key)
{
KvDatabase.FixIterator(ref iterator, ref key);
KvDatabase.FixIterator(ref iterator, in key);
}
/// <summary>
@ -688,13 +688,13 @@ namespace LibHac.FsService
/// </summary>
/// <param name="key">The key of the element that was removed or added.</param>
/// <returns>The <see cref="Result"/> of the operation.</returns>
private Result FixReader(ref SaveDataAttribute key)
private Result FixReader(in SaveDataAttribute key)
{
foreach (ReaderAccessor accessor in OpenReaders)
{
using (ReferenceCountedDisposable<Reader> reader = accessor.Lock())
{
reader?.Target.Fix(ref key);
reader?.Target.Fix(in key);
}
}
@ -826,9 +826,9 @@ namespace LibHac.FsService
}
}
public void Fix(ref SaveDataAttribute attribute)
public void Fix(in SaveDataAttribute attribute)
{
_indexer.FixIterator(ref _iterator, ref attribute);
_indexer.FixIterator(ref _iterator, in attribute);
}
public void Dispose()

View File

@ -32,7 +32,7 @@ namespace LibHac.FsService
}
}
public Result Publish(out ulong saveDataId, ref SaveDataAttribute key)
public Result Publish(out ulong saveDataId, in SaveDataAttribute key)
{
lock (Locker)
{
@ -53,7 +53,7 @@ namespace LibHac.FsService
}
}
public Result Get(out SaveDataIndexerValue value, ref SaveDataAttribute key)
public Result Get(out SaveDataIndexerValue value, in SaveDataAttribute key)
{
lock (Locker)
{
@ -68,7 +68,7 @@ namespace LibHac.FsService
}
}
public Result PutStaticSaveDataIdIndex(ref SaveDataAttribute key)
public Result PutStaticSaveDataIdIndex(in SaveDataAttribute key)
{
lock (Locker)
{
@ -179,7 +179,7 @@ namespace LibHac.FsService
}
}
public Result SetValue(ref SaveDataAttribute key, ref SaveDataIndexerValue value)
public Result SetValue(in SaveDataAttribute key, in SaveDataIndexerValue value)
{
lock (Locker)
{
@ -235,7 +235,7 @@ namespace LibHac.FsService
{
Span<SaveDataInfo> outInfo = MemoryMarshal.Cast<byte, SaveDataInfo>(saveDataInfoBuffer);
// Note: Nintendo doesn't check if the buffer is too small here
// Note: Nintendo doesn't check if the buffer is large enough here
if (_finishedIterating || outInfo.IsEmpty)
{
readCount = 0;

View File

@ -154,12 +154,12 @@ namespace LibHac.Kvdb
/// <remarks>Possible <see cref="Result"/>s:<br/>
/// <see cref="ResultKvdb.KeyNotFound"/>
/// The specified key was not found in the <see cref="FlatMapKeyValueStore{T}"/>.</remarks>
public Result Get(out int valueSize, ref TKey key, Span<byte> valueBuffer)
public Result Get(out int valueSize, in TKey key, Span<byte> valueBuffer)
{
Unsafe.SkipInit(out valueSize);
// Find entry.
ConstIterator iterator = _index.GetLowerBoundConstIterator(ref key);
ConstIterator iterator = _index.GetLowerBoundConstIterator(in key);
if (iterator.IsEnd())
return ResultKvdb.KeyNotFound.Log();
@ -182,9 +182,9 @@ namespace LibHac.Kvdb
/// <param name="key">The key to add.</param>
/// <param name="value">The value to add.</param>
/// <returns>The <see cref="Result"/> of the operation.</returns>
public Result Set(ref TKey key, ReadOnlySpan<byte> value)
public Result Set(in TKey key, ReadOnlySpan<byte> value)
{
return _index.Set(ref key, value);
return _index.Set(in key, value);
}
/// <summary>
@ -195,9 +195,9 @@ namespace LibHac.Kvdb
/// <remarks>Possible <see cref="Result"/>s:<br/>
/// <see cref="ResultKvdb.KeyNotFound"/>
/// The specified key was not found in the <see cref="FlatMapKeyValueStore{T}"/>.</remarks>
public Result Delete(ref TKey key)
public Result Delete(in TKey key)
{
if (!_index.Delete(ref key))
if (!_index.Delete(in key))
return ResultKvdb.KeyNotFound.Log();
return Result.Success;
@ -218,9 +218,9 @@ namespace LibHac.Kvdb
/// </summary>
/// <param name="key">The key at which to begin iteration.</param>
/// <returns>The created iterator.</returns>
public Iterator GetLowerBoundIterator(ref TKey key)
public Iterator GetLowerBoundIterator(in TKey key)
{
return _index.GetLowerBoundIterator(ref key);
return _index.GetLowerBoundIterator(in key);
}
/// <summary>
@ -229,9 +229,9 @@ namespace LibHac.Kvdb
/// </summary>
/// <param name="iterator">The iterator to fix.</param>
/// <param name="key">The key that was added or removed.</param>
public void FixIterator(ref Iterator iterator, ref TKey key)
public void FixIterator(ref Iterator iterator, in TKey key)
{
_index.FixIterator(ref iterator, ref key);
_index.FixIterator(ref iterator, in key);
}
/// <summary>
@ -296,7 +296,7 @@ namespace LibHac.Kvdb
rc = reader.ReadKeyValue(SpanHelpers.AsByteSpan(ref key), newValue.Get());
if (rc.IsFailure()) return rc;
rc = _index.AppendUnsafe(ref key, newValue);
rc = _index.AppendUnsafe(in key, newValue);
if (rc.IsFailure()) return rc;
success = true;
@ -377,7 +377,7 @@ namespace LibHac.Kvdb
public TKey Key;
public MemoryResource.Buffer Value;
public KeyValue(ref TKey key, MemoryResource.Buffer value)
public KeyValue(in TKey key, MemoryResource.Buffer value)
{
Key = key;
Value = value;
@ -437,10 +437,10 @@ namespace LibHac.Kvdb
/// <param name="key">The key to add.</param>
/// <param name="value">The value to add.</param>
/// <returns>The <see cref="Result"/> of the operation.</returns>
public Result Set(ref TKey key, ReadOnlySpan<byte> value)
public Result Set(in TKey key, ReadOnlySpan<byte> value)
{
// The list is sorted by key. Find the index to insert at.
int index = GetLowerBoundIndex(ref key);
int index = GetLowerBoundIndex(in key);
if (index != _count && _entries[index].Key.Equals(key))
{
@ -465,7 +465,7 @@ namespace LibHac.Kvdb
value.CopyTo(newValue.Get());
// Add the new entry to the list.
_entries[index] = new KeyValue(ref key, newValue);
_entries[index] = new KeyValue(in key, newValue);
return Result.Success;
}
@ -478,7 +478,7 @@ namespace LibHac.Kvdb
/// <param name="key">The key to add.</param>
/// <param name="value">The value to add.</param>
/// <returns>The <see cref="Result"/> of the operation.</returns>
public Result AppendUnsafe(ref TKey key, MemoryResource.Buffer value)
public Result AppendUnsafe(in TKey key, MemoryResource.Buffer value)
{
if (_count >= _capacity)
return ResultKvdb.OutOfKeyResource.Log();
@ -489,7 +489,7 @@ namespace LibHac.Kvdb
Assert.AssertTrue(key.CompareTo(_entries[_count - 1].Key) > 0);
}
_entries[_count] = new KeyValue(ref key, value);
_entries[_count] = new KeyValue(in key, value);
_count++;
return Result.Success;
@ -516,9 +516,9 @@ namespace LibHac.Kvdb
/// <param name="key">The key of the element to delete.</param>
/// <returns><see langword="true"/> if the item was found and deleted.
/// <see langword="false"/> if the key was not in the store.</returns>
public bool Delete(ref TKey key)
public bool Delete(in TKey key)
{
int index = GetLowerBoundIndex(ref key);
int index = GetLowerBoundIndex(in key);
// Make sure the key was found.
if (index == _count || !_entries[index].Key.Equals(key))
@ -558,9 +558,9 @@ namespace LibHac.Kvdb
/// </summary>
/// <param name="key">The key at which to begin iteration.</param>
/// <returns>The created iterator.</returns>
public Iterator GetLowerBoundIterator(ref TKey key)
public Iterator GetLowerBoundIterator(in TKey key)
{
int index = GetLowerBoundIndex(ref key);
int index = GetLowerBoundIndex(in key);
return new Iterator(_entries, index, _count);
}
@ -570,9 +570,9 @@ namespace LibHac.Kvdb
/// </summary>
/// <param name="key">The key at which to begin iteration.</param>
/// <returns>The created iterator.</returns>
public ConstIterator GetLowerBoundConstIterator(ref TKey key)
public ConstIterator GetLowerBoundConstIterator(in TKey key)
{
int index = GetLowerBoundIndex(ref key);
int index = GetLowerBoundIndex(in key);
return new ConstIterator(_entries, index, _count);
}
@ -583,31 +583,33 @@ namespace LibHac.Kvdb
/// </summary>
/// <param name="iterator">The iterator to fix.</param>
/// <param name="key">The key that was added or removed.</param>
public void FixIterator(ref Iterator iterator, ref TKey key)
public void FixIterator(ref Iterator iterator, in TKey key)
{
int keyIndex = GetLowerBoundIndex(ref key);
int keyIndex = GetLowerBoundIndex(in key);
iterator.Fix(keyIndex, _count);
}
private int GetLowerBoundIndex(ref TKey key)
private int GetLowerBoundIndex(in TKey key)
{
// The AsSpan takes care of any bounds checking
ReadOnlySpan<KeyValue> entries = _entries.AsSpan(0, _count);
return BinarySearch(ref MemoryMarshal.GetReference(entries), entries.Length, ref key);
return BinarySearch(ref MemoryMarshal.GetReference(entries), entries.Length, in key);
}
private static int BinarySearch(ref KeyValue spanStart, int length, ref TKey item)
private static int BinarySearch(ref KeyValue spanStart, int length, in TKey item)
{
// A tweaked version of .NET's SpanHelpers.BinarySearch
int lo = 0;
int hi = length - 1;
TKey tempItem = item;
while (lo <= hi)
{
int i = (int)(((uint)hi + (uint)lo) >> 1);
int c = item.CompareTo(Unsafe.Add(ref spanStart, i).Key);
int c = tempItem.CompareTo(Unsafe.Add(ref spanStart, i).Key);
if (c == 0)
{
return i;

View File

@ -63,7 +63,7 @@ namespace LibHac.Tests.Kvdb
{
for (TTest i = 0; i < count; i++)
{
Result rc = kvStore.Set(ref i, values[i]);
Result rc = kvStore.Set(in i, values[i]);
if (rc.IsFailure()) return rc;
}
}
@ -74,7 +74,7 @@ namespace LibHac.Tests.Kvdb
for (int i = 0; i < count; i++)
{
TTest index = rng.Next();
Result rc = kvStore.Set(ref index, values[index]);
Result rc = kvStore.Set(in index, values[index]);
if (rc.IsFailure()) return rc;
}
}
@ -191,7 +191,7 @@ namespace LibHac.Tests.Kvdb
TTest key = 20;
var value = new byte[20];
Result rc = kvStore.Get(out int _, ref key, value);
Result rc = kvStore.Get(out int _, in key, value);
Assert.Result(ResultKvdb.KeyNotFound, rc);
}
@ -210,7 +210,7 @@ namespace LibHac.Tests.Kvdb
for (TTest i = 0; i < count; i++)
{
Assert.Success(kvStore.Get(out int valueSize, ref i, value));
Assert.Success(kvStore.Get(out int valueSize, in i, value));
Assert.Equal(startingValueSize + i, valueSize);
}
}
@ -231,7 +231,7 @@ namespace LibHac.Tests.Kvdb
for (int i = 0; i < count; i++)
{
TTest key = i;
Assert.Success(kvStore.Get(out int _, ref key, value));
Assert.Success(kvStore.Get(out int _, in key, value));
Assert.Equal(values[i], value.AsSpan(0, startingValueSize + i).ToArray());
}
}
@ -246,7 +246,7 @@ namespace LibHac.Tests.Kvdb
Assert.Success(PopulateKvStore(kvStore, out byte[][] values, count));
TTest key = count;
Result rc = kvStore.Set(ref key, values[0]);
Result rc = kvStore.Set(in key, values[0]);
Assert.Result(ResultKvdb.OutOfKeyResource, rc);
}
@ -266,11 +266,11 @@ namespace LibHac.Tests.Kvdb
var value = new byte[15];
value.AsSpan().Fill(0xFF);
Assert.Success(kvStore.Set(ref key, value));
Assert.Success(kvStore.Set(in key, value));
// Read back the value
var readValue = new byte[20];
Assert.Success(kvStore.Get(out int valueSize, ref key, readValue));
Assert.Success(kvStore.Get(out int valueSize, in key, readValue));
// Check the value contents and size
Assert.Equal(value.Length, valueSize);
@ -314,7 +314,7 @@ namespace LibHac.Tests.Kvdb
(FlatMapKeyValueStore<TTest> kvStore, FileSystemClient _) = Create<TTest>(count);
Result rc = kvStore.Delete(ref keyToDelete);
Result rc = kvStore.Delete(in keyToDelete);
Assert.Result(ResultKvdb.KeyNotFound, rc);
}
@ -327,7 +327,7 @@ namespace LibHac.Tests.Kvdb
(FlatMapKeyValueStore<TTest> kvStore, FileSystemClient _) = Create<TTest>(count);
Assert.Success(PopulateKvStore(kvStore, out _, count));
Result rc = kvStore.Delete(ref keyToDelete);
Result rc = kvStore.Delete(in keyToDelete);
Assert.Result(ResultKvdb.KeyNotFound, rc);
}
@ -345,11 +345,11 @@ namespace LibHac.Tests.Kvdb
Assert.Success(PopulateKvStore(kvStore, out _, count, startingValueSize, rngSeed));
TTest keyToDelete = entryToDelete;
Assert.Success(kvStore.Delete(ref keyToDelete));
Assert.Success(kvStore.Delete(in keyToDelete));
var value = new byte[20];
Result rc = kvStore.Get(out int _, ref keyToDelete, value);
Result rc = kvStore.Get(out int _, in keyToDelete, value);
Assert.Result(ResultKvdb.KeyNotFound, rc);
}
@ -365,7 +365,7 @@ namespace LibHac.Tests.Kvdb
Assert.Success(PopulateKvStore(kvStore, out _, count));
TTest keyToDelete = entryToDelete;
Assert.Success(kvStore.Delete(ref keyToDelete));
Assert.Success(kvStore.Delete(in keyToDelete));
Assert.Equal(count - 1, kvStore.Count);
}
@ -382,7 +382,7 @@ namespace LibHac.Tests.Kvdb
Assert.Success(PopulateKvStore(kvStore, out _, count));
TTest keyToDelete = entryToDelete;
Assert.Success(kvStore.Delete(ref keyToDelete));
Assert.Success(kvStore.Delete(in keyToDelete));
FlatMapKeyValueStore<TTest>.Iterator iterator = kvStore.GetBeginIterator();
@ -414,7 +414,7 @@ namespace LibHac.Tests.Kvdb
Assert.Success(PopulateKvStore(kvStore, out _, count));
TTest startingKey = startEntry;
FlatMapKeyValueStore<TTest>.Iterator iterator = kvStore.GetLowerBoundIterator(ref startingKey);
FlatMapKeyValueStore<TTest>.Iterator iterator = kvStore.GetLowerBoundIterator(in startingKey);
Assert.False(iterator.IsEnd());
Assert.Equal(startingKey, iterator.Get().Key);
@ -436,12 +436,12 @@ namespace LibHac.Tests.Kvdb
for (int i = 0; i < count; i++)
{
TTest key = i * 2;
Assert.Success(kvStore.Set(ref key, values[i]));
Assert.Success(kvStore.Set(in key, values[i]));
}
TTest startingKey = startIndex;
TTest nextLargestKey = startIndex + 1;
FlatMapKeyValueStore<TTest>.Iterator iterator = kvStore.GetLowerBoundIterator(ref startingKey);
FlatMapKeyValueStore<TTest>.Iterator iterator = kvStore.GetLowerBoundIterator(in startingKey);
Assert.False(iterator.IsEnd());
Assert.Equal(nextLargestKey, iterator.Get().Key);
@ -457,7 +457,7 @@ namespace LibHac.Tests.Kvdb
Assert.Success(PopulateKvStore(kvStore, out _, count));
TTest key = startIndex;
FlatMapKeyValueStore<TTest>.Iterator iterator = kvStore.GetLowerBoundIterator(ref key);
FlatMapKeyValueStore<TTest>.Iterator iterator = kvStore.GetLowerBoundIterator(in key);
Assert.True(iterator.IsEnd());
}
@ -481,9 +481,9 @@ namespace LibHac.Tests.Kvdb
}
TTest keyToRemove = entryToRemove;
Assert.Success(kvStore.Delete(ref keyToRemove));
Assert.Success(kvStore.Delete(in keyToRemove));
kvStore.FixIterator(ref iterator, ref keyToRemove);
kvStore.FixIterator(ref iterator, in keyToRemove);
TTest expectedKey = expectedNewPosition;
Assert.Equal(expectedKey, iterator.Get().Key);
@ -504,7 +504,7 @@ namespace LibHac.Tests.Kvdb
for (int i = 0; i < count; i++)
{
TTest key = i * 2;
Assert.Success(kvStore.Set(ref key, values[i]));
Assert.Success(kvStore.Set(in key, values[i]));
}
FlatMapKeyValueStore<TTest>.Iterator iterator = kvStore.GetBeginIterator();
@ -517,9 +517,9 @@ namespace LibHac.Tests.Kvdb
TTest keyToAdd = entryToAdd;
var valueToAdd = new byte[10];
Assert.Success(kvStore.Set(ref keyToAdd, valueToAdd));
Assert.Success(kvStore.Set(in keyToAdd, valueToAdd));
kvStore.FixIterator(ref iterator, ref keyToAdd);
kvStore.FixIterator(ref iterator, in keyToAdd);
TTest expectedKey = expectedNewPosition;
Assert.Equal(expectedKey, iterator.Get().Key);