rocksdb-sharp
rocksdb-sharp copied to clipboard
PinnableSlice support
Only for netstandard2.1 and up
Potential Implementation:
public sealed class PinnableSlice : IDisposable
{
public IntPtr Handle { get; internal set; }
public PinnableSlice(IntPtr handle)
{
Handle = handle;
}
public bool Valid => Handle != IntPtr.Zero;
public ReadOnlySpan<byte> GetValue()
{
if (Handle == IntPtr.Zero) return default;
var valuePtr = Native.Instance.rocksdb_pinnableslice_value(Handle, out var valueLength);
if (valuePtr == IntPtr.Zero) return default;
unsafe
{
return new ReadOnlySpan<byte>((byte*)valuePtr, (int)valueLength);
}
}
public void Dispose()
{
if (Handle != IntPtr.Zero)
{
var handle = Handle;
Handle = IntPtr.Zero;
Native.Instance.rocksdb_pinnableslice_destroy(handle);
}
}
}
// Added to RocksDb class
public static PinnableSlice GetSlice(this RocksDb db, byte[]? key, ReadOptions? readOptions = null)
=> db.GetSlice(key, null, readOptions);
public unsafe static PinnableSlice GetSlice(this RocksDb db, byte[]? key, ColumnFamilyHandle? columnFamily, ReadOptions? readOptions = null)
{
key ??= Array.Empty<byte>();
readOptions ??= DefaultReadOptions;
fixed (byte* keyPtr = key)
{
var slice = columnFamily is null
? Instance.rocksdb_get_pinned(db.Handle, readOptions.Handle, (IntPtr)keyPtr, (UIntPtr)key.Length)
: Instance.rocksdb_get_pinned_cf(db.Handle, readOptions.Handle, columnFamily.Handle, (IntPtr)keyPtr, (UIntPtr)key.Length);
return new PinnableSlice(slice);
}
}
Note, key should probably be ReadOnlyMemory or ReadOnlySpan. And PinnableSlice should probably be a struct like MemoryHandle