diff --git a/src/LibHac/Fs/SaveDataStructs.cs b/src/LibHac/Fs/SaveDataStructs.cs index 8ac01c43..ed13769a 100644 --- a/src/LibHac/Fs/SaveDataStructs.cs +++ b/src/LibHac/Fs/SaveDataStructs.cs @@ -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); } diff --git a/src/LibHac/Fs/Shim/BcatSaveData.cs b/src/LibHac/Fs/Shim/BcatSaveData.cs index c89cf6d2..95c27611 100644 --- a/src/LibHac/Fs/Shim/BcatSaveData.cs +++ b/src/LibHac/Fs/Shim/BcatSaveData.cs @@ -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; diff --git a/src/LibHac/Fs/Shim/SaveData.cs b/src/LibHac/Fs/Shim/SaveData.cs index b7e8eecb..b641906c 100644 --- a/src/LibHac/Fs/Shim/SaveData.cs +++ b/src/LibHac/Fs/Shim/SaveData.cs @@ -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; diff --git a/src/LibHac/Fs/Shim/SaveDataManagement.cs b/src/LibHac/Fs/Shim/SaveDataManagement.cs index 59602fbd..9e972867 100644 --- a/src/LibHac/Fs/Shim/SaveDataManagement.cs +++ b/src/LibHac/Fs/Shim/SaveDataManagement.cs @@ -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 { diff --git a/src/LibHac/Fs/Shim/SystemSaveData.cs b/src/LibHac/Fs/Shim/SystemSaveData.cs index 838db618..b817ad07 100644 --- a/src/LibHac/Fs/Shim/SystemSaveData.cs +++ b/src/LibHac/Fs/Shim/SystemSaveData.cs @@ -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; diff --git a/src/LibHac/FsService/FileSystemProxy.cs b/src/LibHac/FsService/FileSystemProxy.cs index bec3acfd..3f3eaf95 100644 --- a/src/LibHac/FsService/FileSystemProxy.cs +++ b/src/LibHac/FsService/FileSystemProxy.cs @@ -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); diff --git a/src/LibHac/FsService/ISaveDataIndexer.cs b/src/LibHac/FsService/ISaveDataIndexer.cs index ea618a87..f98eb759 100644 --- a/src/LibHac/FsService/ISaveDataIndexer.cs +++ b/src/LibHac/FsService/ISaveDataIndexer.cs @@ -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 infoReader); } diff --git a/src/LibHac/FsService/SaveDataIndexer.cs b/src/LibHac/FsService/SaveDataIndexer.cs index b1dd3913..fc24b9f4 100644 --- a/src/LibHac/FsService/SaveDataIndexer.cs +++ b/src/LibHac/FsService/SaveDataIndexer.cs @@ -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.Iterator iterator = KvDatabase.GetLowerBoundIterator(ref key); + FlatMapKeyValueStore.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.Iterator iterator, - ref SaveDataAttribute key) + in SaveDataAttribute key) { - KvDatabase.FixIterator(ref iterator, ref key); + KvDatabase.FixIterator(ref iterator, in key); } /// @@ -688,13 +688,13 @@ namespace LibHac.FsService /// /// The key of the element that was removed or added. /// The of the operation. - private Result FixReader(ref SaveDataAttribute key) + private Result FixReader(in SaveDataAttribute key) { foreach (ReaderAccessor accessor in OpenReaders) { using (ReferenceCountedDisposable 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() diff --git a/src/LibHac/FsService/SaveDataIndexerLite.cs b/src/LibHac/FsService/SaveDataIndexerLite.cs index 040ccedb..855526c2 100644 --- a/src/LibHac/FsService/SaveDataIndexerLite.cs +++ b/src/LibHac/FsService/SaveDataIndexerLite.cs @@ -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 outInfo = MemoryMarshal.Cast(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; diff --git a/src/LibHac/Kvdb/FlatMapKeyValueStore.cs b/src/LibHac/Kvdb/FlatMapKeyValueStore.cs index dbeb2211..6c92b7b7 100644 --- a/src/LibHac/Kvdb/FlatMapKeyValueStore.cs +++ b/src/LibHac/Kvdb/FlatMapKeyValueStore.cs @@ -154,12 +154,12 @@ namespace LibHac.Kvdb /// Possible s:
/// /// The specified key was not found in the .
- public Result Get(out int valueSize, ref TKey key, Span valueBuffer) + public Result Get(out int valueSize, in TKey key, Span 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 /// The key to add. /// The value to add. /// The of the operation. - public Result Set(ref TKey key, ReadOnlySpan value) + public Result Set(in TKey key, ReadOnlySpan value) { - return _index.Set(ref key, value); + return _index.Set(in key, value); } /// @@ -195,9 +195,9 @@ namespace LibHac.Kvdb /// Possible s:
/// /// The specified key was not found in the .
- 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 ///
/// The key at which to begin iteration. /// The created iterator. - public Iterator GetLowerBoundIterator(ref TKey key) + public Iterator GetLowerBoundIterator(in TKey key) { - return _index.GetLowerBoundIterator(ref key); + return _index.GetLowerBoundIterator(in key); } /// @@ -229,9 +229,9 @@ namespace LibHac.Kvdb /// /// The iterator to fix. /// The key that was added or removed. - 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); } /// @@ -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 /// The key to add. /// The value to add. /// The of the operation. - public Result Set(ref TKey key, ReadOnlySpan value) + public Result Set(in TKey key, ReadOnlySpan 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 /// The key to add. /// The value to add. /// The of the operation. - 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 /// The key of the element to delete. /// if the item was found and deleted. /// if the key was not in the store. - 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 /// /// The key at which to begin iteration. /// The created iterator. - 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 /// /// The key at which to begin iteration. /// The created iterator. - 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 /// /// The iterator to fix. /// The key that was added or removed. - 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 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; diff --git a/tests/LibHac.Tests/Kvdb/FlatMapKeyValueStoreTests.cs b/tests/LibHac.Tests/Kvdb/FlatMapKeyValueStoreTests.cs index 455d5dda..62b4b4c1 100644 --- a/tests/LibHac.Tests/Kvdb/FlatMapKeyValueStoreTests.cs +++ b/tests/LibHac.Tests/Kvdb/FlatMapKeyValueStoreTests.cs @@ -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 kvStore, FileSystemClient _) = Create(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 kvStore, FileSystemClient _) = Create(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.Iterator iterator = kvStore.GetBeginIterator(); @@ -414,7 +414,7 @@ namespace LibHac.Tests.Kvdb Assert.Success(PopulateKvStore(kvStore, out _, count)); TTest startingKey = startEntry; - FlatMapKeyValueStore.Iterator iterator = kvStore.GetLowerBoundIterator(ref startingKey); + FlatMapKeyValueStore.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.Iterator iterator = kvStore.GetLowerBoundIterator(ref startingKey); + FlatMapKeyValueStore.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.Iterator iterator = kvStore.GetLowerBoundIterator(ref key); + FlatMapKeyValueStore.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.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);