|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
namespace Microsoft.Data.Analysis
{
/// <summary>
/// A basic immutable store to hold values in a DataFrame column. Supports wrapping with an ArrowBuffer
/// </summary>
/// <typeparam name="T"></typeparam>
internal class ReadOnlyDataFrameBuffer<T>
where T : unmanaged
{
private readonly ReadOnlyMemory<byte> _readOnlyBuffer;
public virtual ReadOnlyMemory<byte> ReadOnlyBuffer => _readOnlyBuffer;
public ReadOnlyMemory<T> ReadOnlyMemory => RawReadOnlyMemory.Slice(0, Length);
public ReadOnlyMemory<T> RawReadOnlyMemory
{
get
{
ReadOnlyMemory<byte> memory = ReadOnlyBuffer;
return Unsafe.As<ReadOnlyMemory<byte>, ReadOnlyMemory<T>>(ref memory);
}
}
protected static int Size = Unsafe.SizeOf<T>();
protected int Capacity => ReadOnlyBuffer.Length / Size;
public static int MaxCapacity => ArrayUtility.ArrayMaxSize / Size;
public ReadOnlySpan<T> ReadOnlySpan
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => (MemoryMarshal.Cast<byte, T>(ReadOnlyBuffer.Span)).Slice(0, Length);
}
public int Length { get; protected set; }
public ReadOnlyDataFrameBuffer(int length = 0)
{
if ((long)length * Size > MaxCapacity)
{
throw new ArgumentException($"{length} exceeds buffer capacity", nameof(length));
}
_readOnlyBuffer = new byte[length * Size];
Length = length;
}
public ReadOnlyDataFrameBuffer(ReadOnlyMemory<byte> buffer, int length)
{
_readOnlyBuffer = buffer;
Length = length;
}
internal virtual T this[int index]
{
get
{
if (index >= Length)
throw new ArgumentOutOfRangeException(nameof(index));
return ReadOnlySpan[index];
}
set => throw new NotSupportedException();
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
ReadOnlySpan<T> span = ReadOnlySpan;
for (int i = 0; i < Length; i++)
{
sb.Append(span[i]).Append(" ");
}
return sb.ToString();
}
}
}
|