Consolidate the 2 separate Buffer types

This commit is contained in:
Alex Barney 2021-11-23 15:51:47 -07:00
parent f526860599
commit 280fe14b5f
13 changed files with 78 additions and 87 deletions

View File

@ -1,27 +0,0 @@
using System;
using System.ComponentModel;
// ReSharper disable once CheckNamespace
namespace LibHac.Fs;
public readonly struct Buffer : IEquatable<Buffer>
{
public static Buffer Empty => default;
public Memory<byte> Memory { get; }
public Span<byte> Span => Memory.Span;
public int Length => Memory.Length;
public bool IsNull => Memory.IsEmpty;
public Buffer(Memory<byte> buffer)
{
Memory = buffer;
}
public static bool operator ==(Buffer left, Buffer right) => left.Memory.Equals(right.Memory);
public static bool operator !=(Buffer left, Buffer right) => !(left == right);
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj) => obj is Buffer other && Equals(other);
public bool Equals(Buffer other) => Memory.Equals(other.Memory);
public override int GetHashCode() => Memory.GetHashCode();
}

View File

@ -1,5 +1,5 @@
using System;
using Buffer = LibHac.Mem.Buffer;
using CacheHandle = System.Int64;
// ReSharper disable once CheckNamespace

View File

@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
using System.Threading;
using LibHac.Diag;
using LibHac.Fs;
using Buffer = LibHac.Fs.Buffer;
using Buffer = LibHac.Mem.Buffer;
namespace LibHac.FsSystem.Buffers;

View File

@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
using LibHac.Diag;
using LibHac.Fs;
using LibHac.Util;
using Buffer = LibHac.Fs.Buffer;
using Buffer = LibHac.Mem.Buffer;
// ReSharper disable once CheckNamespace
namespace LibHac.FsSystem;

View File

@ -6,7 +6,7 @@ using LibHac.Common;
using LibHac.Diag;
using LibHac.Fs;
using LibHac.Util;
using Buffer = LibHac.Fs.Buffer;
using Buffer = LibHac.Mem.Buffer;
using CacheHandle = System.Int64;
// ReSharper disable once CheckNamespace

View File

@ -192,7 +192,7 @@ internal class RomFsDictionary<T> where T : unmanaged
if (value != _capacity)
{
byte[] newBuffer = new byte[value];
System.Buffer.BlockCopy(Entries, 0, newBuffer, 0, _length);
Buffer.BlockCopy(Entries, 0, newBuffer, 0, _length);
Entries = newBuffer;
_capacity = value;

View File

@ -7,7 +7,7 @@ using LibHac.Diag;
using LibHac.Fs;
using LibHac.FsSystem.Buffers;
using LibHac.Util;
using Buffer = LibHac.Fs.Buffer;
using Buffer = LibHac.Mem.Buffer;
using CacheHandle = System.Int64;
namespace LibHac.FsSystem.Save;

View File

@ -1,4 +1,5 @@
using System;
using Buffer = LibHac.Mem.Buffer;
namespace LibHac.Kvdb;
@ -7,15 +8,15 @@ internal struct AutoBuffer : IDisposable
private const int Alignment = 0x10;
private MemoryResource _memoryResource;
private MemoryResource.Buffer _buffer;
private Buffer _buffer;
public Span<byte> Get() => _buffer.Get();
public Span<byte> Get() => _buffer.Span;
public int GetSize() => _buffer.Length;
public Result Initialize(long size, MemoryResource memoryResource)
{
MemoryResource.Buffer buffer = memoryResource.Allocate(size, Alignment);
if (!buffer.IsValid)
Buffer buffer = memoryResource.Allocate(size, Alignment);
if (buffer.IsNull)
return ResultKvdb.AllocationFailed.Log();
_memoryResource = memoryResource;
@ -26,7 +27,7 @@ internal struct AutoBuffer : IDisposable
public void Dispose()
{
if (_buffer.IsValid)
if (!_buffer.IsNull)
{
_memoryResource.Deallocate(ref _buffer, Alignment);
}

View File

@ -5,6 +5,7 @@ using LibHac.Common;
using LibHac.Diag;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using Buffer = LibHac.Mem.Buffer;
namespace LibHac.Kvdb;
@ -284,8 +285,8 @@ public class FlatMapKeyValueStore<TKey> : IDisposable where TKey : unmanaged, IE
if (rc.IsFailure()) return rc;
// Allocate memory for value.
MemoryResource.Buffer newValue = _memoryResource.Allocate(valueSize, Alignment);
if (!newValue.IsValid)
Buffer newValue = _memoryResource.Allocate(valueSize, Alignment);
if (newValue.IsNull)
return ResultKvdb.AllocationFailed.Log();
bool success = false;
@ -294,7 +295,7 @@ public class FlatMapKeyValueStore<TKey> : IDisposable where TKey : unmanaged, IE
// Read key and value.
Unsafe.SkipInit(out TKey key);
rc = reader.ReadKeyValue(SpanHelpers.AsByteSpan(ref key), newValue.Get());
rc = reader.ReadKeyValue(SpanHelpers.AsByteSpan(ref key), newValue.Span);
if (rc.IsFailure()) return rc;
rc = _index.AppendUnsafe(in key, newValue);
@ -376,9 +377,9 @@ public class FlatMapKeyValueStore<TKey> : IDisposable where TKey : unmanaged, IE
public struct KeyValue
{
public TKey Key;
public MemoryResource.Buffer Value;
public Buffer Value;
public KeyValue(in TKey key, MemoryResource.Buffer value)
public KeyValue(in TKey key, Buffer value)
{
Key = key;
Value = value;
@ -459,11 +460,11 @@ public class FlatMapKeyValueStore<TKey> : IDisposable where TKey : unmanaged, IE
}
// Allocate new value.
MemoryResource.Buffer newValue = _memoryResource.Allocate(value.Length, Alignment);
if (!newValue.IsValid)
Buffer newValue = _memoryResource.Allocate(value.Length, Alignment);
if (newValue.IsNull)
return ResultKvdb.AllocationFailed.Log();
value.CopyTo(newValue.Get());
value.CopyTo(newValue.Span);
// Add the new entry to the list.
_entries[index] = new KeyValue(in key, newValue);
@ -479,7 +480,7 @@ public class FlatMapKeyValueStore<TKey> : IDisposable where TKey : unmanaged, IE
/// <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(in TKey key, MemoryResource.Buffer value)
public Result AppendUnsafe(in TKey key, Buffer value)
{
if (_count >= _capacity)
return ResultKvdb.OutOfKeyResource.Log();
@ -647,11 +648,11 @@ public class FlatMapKeyValueStore<TKey> : IDisposable where TKey : unmanaged, IE
}
public ref KeyValue Get() => ref _entries[_index];
public Span<byte> GetValue() => _entries[_index].Value.Get();
public Span<byte> GetValue() => _entries[_index].Value.Span;
public ref T GetValue<T>() where T : unmanaged
{
return ref SpanHelpers.AsStruct<T>(_entries[_index].Value.Get());
return ref SpanHelpers.AsStruct<T>(_entries[_index].Value.Span);
}
public void Next() => _index++;
@ -720,7 +721,7 @@ public class FlatMapKeyValueStore<TKey> : IDisposable where TKey : unmanaged, IE
}
public ref readonly KeyValue Get() => ref _entries[_index];
public ReadOnlySpan<byte> GetValue() => _entries[_index].Value.Get();
public ReadOnlySpan<byte> GetValue() => _entries[_index].Value.Span;
public void Next() => _index++;
public bool IsEnd() => _index == _length;

48
src/LibHac/Mem/Buffer.cs Normal file
View File

@ -0,0 +1,48 @@
using System;
using System.ComponentModel;
namespace LibHac.Mem;
/// <summary>
/// Represents a region of memory allocated by a <see cref="MemoryResource"/>.
/// </summary>
public struct Buffer : IEquatable<Buffer>
{
private Memory<byte> _memory;
public static Buffer Empty => default;
/// <summary>
/// A field where <see cref="MemoryResource"/> implementers can store info about the <see cref="Buffer"/>.
/// </summary>
internal object Extra { get; }
/// <summary>
/// The length of the buffer in bytes.
/// </summary>
public readonly int Length => _memory.Length;
/// <summary>
/// Gets a <see cref="Span{T}"/> from the <see cref="Buffer"/>.
/// </summary>
public readonly Span<byte> Span => _memory.Span;
/// <summary>
/// Returns <see langword="true"/> if the <see cref="Buffer"/> is not valid.
/// </summary>
public readonly bool IsNull => _memory.IsEmpty;
internal Buffer(Memory<byte> memory, object extra = null)
{
_memory = memory;
Extra = extra;
}
public static bool operator ==(Buffer left, Buffer right) => left._memory.Equals(right._memory);
public static bool operator !=(Buffer left, Buffer right) => !(left == right);
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj) => obj is Buffer other && Equals(other);
public bool Equals(Buffer other) => _memory.Equals(other._memory);
public override int GetHashCode() => _memory.GetHashCode();
}

View File

@ -1,6 +1,7 @@
using System;
using System.Buffers;
using System.Runtime.CompilerServices;
using Buffer = LibHac.Mem.Buffer;
namespace LibHac;
@ -28,40 +29,6 @@ public abstract class MemoryResource
protected abstract Buffer DoAllocate(long size, int alignment);
protected abstract void DoDeallocate(Buffer buffer, int alignment);
protected abstract bool DoIsEqual(MemoryResource other);
/// <summary>
/// Represents a region of memory allocated by a <see cref="MemoryResource"/>.
/// </summary>
public struct Buffer
{
private Memory<byte> _memory;
/// <summary>
/// A field where <see cref="MemoryResource"/> implementers can store info about the <see cref="Buffer"/>.
/// </summary>
internal object Extra { get; }
/// <summary>
/// The length of the buffer in bytes.
/// </summary>
public readonly int Length => _memory.Length;
/// <summary>
/// Gets a span from the <see cref="Buffer"/>.
/// </summary>
public readonly Span<byte> Get() => _memory.Span;
/// <summary>
/// Returns <see langword="true"/> if the <see cref="Buffer"/> is valid.
/// </summary>
public readonly bool IsValid => !_memory.Equals(default);
internal Buffer(Memory<byte> memory, object extra = null)
{
_memory = memory;
Extra = extra;
}
}
}
public class ArrayPoolMemoryResource : MemoryResource

View File

@ -1,5 +1,6 @@
using LibHac.Fs;
using LibHac.FsSystem;
using LibHac.Mem;
using Xunit;
namespace LibHac.Tests.FsSystem;

View File

@ -142,7 +142,7 @@ public class FlatMapKeyValueStoreTests
ref FlatMapKeyValueStore<TTest>.KeyValue kv = ref iterator.Get();
Assert.Equal(expectedKey, kv.Key);
Assert.Equal(expectedValue, kv.Value.Get().ToArray());
Assert.Equal(expectedValue, kv.Value.Span.ToArray());
iterator.Next();
}
@ -299,7 +299,7 @@ public class FlatMapKeyValueStoreTests
ref FlatMapKeyValueStore<TTest>.KeyValue kv = ref iterator.Get();
Assert.Equal(expectedKey, kv.Key);
Assert.Equal(expectedValue, kv.Value.Get().ToArray());
Assert.Equal(expectedValue, kv.Value.Span.ToArray());
iterator.Next();
}
@ -576,7 +576,7 @@ public class FlatMapKeyValueStoreTests
ref FlatMapKeyValueStore<TTest>.KeyValue kv = ref iterator.Get();
Assert.Equal(expectedKey, kv.Key);
Assert.Equal(expectedValue, kv.Value.Get().ToArray());
Assert.Equal(expectedValue, kv.Value.Span.ToArray());
iterator.Next();
}