using System;
using System.Buffers;
using System.Runtime.CompilerServices;
/*https://github.com/sidristij/memory-pools*/
namespace MemoryPools.Memory
{
///
/// Encapsulates manual memory management mechanism. Holds
/// IMemoryOwner instance goes to GC (link = null) only when
/// all owning entities called Dispose() method. This means,
/// that only this mechanism should be used for covering
/// managed instances.
///
public sealed class CountdownMemoryOwner : IMemoryOwner
{
private int _length;
private int _offset;
private int _owners;
private T[] _arr;
private CountdownMemoryOwner _parent;
private Memory _memory;
public Memory Memory
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _memory;
private set => _memory = value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal CountdownMemoryOwner Init(CountdownMemoryOwner parent, int offset, int length, bool defaultOwner = true)
{
_owners = defaultOwner ? 1 : 0;
_offset = offset;
_length = length;
_parent = parent;
_parent.AddOwner();
Memory = _parent.Memory.Slice(_offset, _length);
return this;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal CountdownMemoryOwner Init(T[] array, int length)
{
_owners = 1;
_offset = 0;
_length = length;
_parent = default;
_arr = array;
Memory = _arr.AsMemory(0, _length);
return this;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AddOwner() => _owners++;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dispose()
{
_owners--;
if (_owners > 0)
{
return;
}
if (_parent != default)
{
_parent.Dispose();
_parent = null;
}
else
{
ArrayPool.Shared.Return(_arr);
}
Pool>.Return(this);
}
}
}