Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 74 additions & 12 deletions src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.Buffers.Binary;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.IO.Abstractions;
using System.Linq;
Expand Down Expand Up @@ -619,22 +621,14 @@ public byte[]? this[ReadOnlySpan<byte> key]
{
if (_readAheadReadOptions is not null && (flags & ReadFlags.HintReadAhead) != 0)
{
using IteratorManager.RentWrapper wrapper = iteratorManager.Rent(flags);
Iterator iterator = wrapper.Iterator;

if (iterator.Valid() && TryCloseReadAhead(iterator, key, out byte[]? closeRes))
byte[]? result = GetWithIterator(key, cf, iteratorManager, flags, out bool success);
if (success)
{
return closeRes;
}

iterator.Seek(key);
if (iterator.Valid() && Bytes.AreEqual(iterator.GetKeySpan(), key))
{
return iterator.Value();
return result;
}
}

return _db.Get(key, cf, (flags & ReadFlags.HintCacheMiss) != 0 ? _hintCacheMissOptions : _defaultReadOptions);
return Get(key, cf, flags);
}
catch (RocksDbSharpException e)
{
Expand All @@ -643,6 +637,74 @@ public byte[]? this[ReadOnlySpan<byte> key]
}
}

private unsafe byte[]? GetWithIterator(ReadOnlySpan<byte> key, ColumnFamilyHandle? cf, IteratorManager iteratorManager, ReadFlags flags, out bool success)
{
success = true;

using IteratorManager.RentWrapper wrapper = iteratorManager.Rent(flags);
Iterator iterator = wrapper.Iterator;

if (iterator.Valid() && TryCloseReadAhead(iterator, key, out byte[]? closeRes))
{
return closeRes;
}

iterator.Seek(key);
if (iterator.Valid() && Bytes.AreEqual(iterator.GetKeySpan(), key))
{
return iterator.Value();
}

success = false;
return null;
}

private unsafe byte[]? Get(ReadOnlySpan<byte> key, ColumnFamilyHandle? cf, ReadFlags flags)
{
// TODO: update when merged upstream: https://github.com/curiosity-ai/rocksdb-sharp/pull/61
// return _db.Get(key, cf, (flags & ReadFlags.HintCacheMiss) != 0 ? _hintCacheMissOptions : _defaultReadOptions);

nint db = _db.Handle;
nint read_options = ((flags & ReadFlags.HintCacheMiss) != 0 ? _hintCacheMissOptions : _defaultReadOptions).Handle;
UIntPtr skLength = (UIntPtr)key.Length;
IntPtr handle;
IntPtr errPtr;
fixed (byte* ptr = &MemoryMarshal.GetReference(key))
{
handle = cf is null
? Native.Instance.rocksdb_get_pinned(db, read_options, ptr, skLength, out errPtr)
: Native.Instance.rocksdb_get_pinned_cf(db, read_options, cf.Handle, ptr, skLength, out errPtr);
}

if (errPtr != IntPtr.Zero) ThrowRocksDbException(errPtr);
if (handle == IntPtr.Zero) return null;

try
{
IntPtr valuePtr = Native.Instance.rocksdb_pinnableslice_value(handle, out UIntPtr valueLength);
if (valuePtr == IntPtr.Zero)
{
return null;
}

int length = (int)valueLength;
byte[] result = new byte[length];
new ReadOnlySpan<byte>((void*)valuePtr, length).CopyTo(new Span<byte>(result));
return result;
}
finally
{
Native.Instance.rocksdb_pinnableslice_destroy(handle);
}

[DoesNotReturn]
[StackTraceHidden]
static unsafe void ThrowRocksDbException(nint errPtr)
{
throw new RocksDbException(errPtr);
}
}

/// <summary>
/// iterator.Next() is about 10 to 20 times faster than iterator.Seek().
/// Here we attempt to do that first. To prevent futile attempt some logic is added to approximately detect
Expand Down