diff --git a/RocksDbSharp/Native.Marshaled.cs b/RocksDbSharp/Native.Marshaled.cs index 532d19c..cb5895b 100644 --- a/RocksDbSharp/Native.Marshaled.cs +++ b/RocksDbSharp/Native.Marshaled.cs @@ -1,10 +1,11 @@ -/* +/* The functions in this file provide some wrappers around the lowest level C API to aid in marshalling. This is kept separate so that the lowest level imports can be kept as close as possible to c.h from rocksdb. See Native.Raw.cs for more information. */ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using Transitional; @@ -155,7 +156,37 @@ public byte[] rocksdb_get( rocksdb_free(resultPtr); return result; } - + + public unsafe Span rocksdb_get_span( + IntPtr db, + IntPtr read_options, + byte[] key, + long keyLength, + out IntPtr errptr, + ColumnFamilyHandle cf = null) + { + UIntPtr skLength = (UIntPtr)keyLength; + var resultPtr = cf == null + ? rocksdb_get(db, read_options, key, skLength, out UIntPtr valueLength, out errptr) + : rocksdb_get_cf(db, read_options, cf.Handle, key, skLength, out valueLength, out errptr); + if (errptr != IntPtr.Zero) + return null; + if (resultPtr == IntPtr.Zero) + return null; + Span span = new Span((void*)resultPtr, (int)valueLength); + //MemoryMarshal.GetReference(span); + + + return span; + } + + public unsafe void rocksdb_release_span(in Span span) + { + ref byte ptr = ref MemoryMarshal.GetReference(span); + IntPtr intPtr = new IntPtr(Unsafe.AsPointer(ref ptr)); + rocksdb_free(intPtr); + } + /// /// Executes a multi_get with automatic marshalling /// diff --git a/RocksDbSharp/Native.Wrap.cs b/RocksDbSharp/Native.Wrap.cs index f79390a..b8cfcd8 100644 --- a/RocksDbSharp/Native.Wrap.cs +++ b/RocksDbSharp/Native.Wrap.cs @@ -182,6 +182,19 @@ public byte[] rocksdb_get( throw new RocksDbException(errptr); return result; } + + public Span rocksdb_get_span( + IntPtr db, + IntPtr read_options, + byte[] key, + long keyLength = 0, + ColumnFamilyHandle cf = null) + { + var result = rocksdb_get_span(db, read_options, key, keyLength == 0 ? key.Length : keyLength, out IntPtr errptr, cf); + if (errptr != IntPtr.Zero) + throw new RocksDbException(errptr); + return result; + } public KeyValuePair[] rocksdb_multi_get( IntPtr db, diff --git a/RocksDbSharp/RocksDb.cs b/RocksDbSharp/RocksDb.cs index 9468188..d4fbf4e 100644 --- a/RocksDbSharp/RocksDb.cs +++ b/RocksDbSharp/RocksDb.cs @@ -119,12 +119,22 @@ public byte[] Get(byte[] key, ColumnFamilyHandle cf = null, ReadOptions readOpti { return Get(key, key.GetLongLength(0), cf, readOptions); } - + public byte[] Get(byte[] key, long keyLength, ColumnFamilyHandle cf = null, ReadOptions readOptions = null) { return Native.Instance.rocksdb_get(Handle, (readOptions ?? DefaultReadOptions).Handle, key, keyLength, cf); } + public Span GetSpan(byte[] key, ColumnFamilyHandle cf = null, ReadOptions readOptions = null) + { + return GetSpan(key, key.GetLongLength(0), cf, readOptions); + } + + public Span GetSpan(byte[] key, long keyLength, ColumnFamilyHandle cf = null, ReadOptions readOptions = null) + { + return Native.Instance.rocksdb_get_span(Handle, (readOptions ?? DefaultReadOptions).Handle, key, keyLength, cf); + } + /// /// Reads the contents of the database value associated with , if present, into the supplied /// at up to bytes, returning the @@ -306,5 +316,10 @@ public void CompactRange(string start, string limit, ColumnFamilyHandle cf = nul encoding = Encoding.UTF8; CompactRange(encoding.GetBytes(start), encoding.GetBytes(limit), cf); } + + public void DangerousReleaseMemory(in Span span) + { + Native.Instance.rocksdb_release_span(in span); + } } } diff --git a/RocksDbSharp/RocksDbSharp.csproj b/RocksDbSharp/RocksDbSharp.csproj index c2ff931..8dfec5a 100644 --- a/RocksDbSharp/RocksDbSharp.csproj +++ b/RocksDbSharp/RocksDbSharp.csproj @@ -1,5 +1,5 @@  - + RocksDbSharp True @@ -40,5 +40,6 @@ + \ No newline at end of file