curiosity-ai / rocksdb-sharp

.net bindings for the rocksdb by facebook
BSD 2-Clause "Simplified" License
158 stars 38 forks source link

Add support for Get without allocations #3

Closed theolivenbaum closed 3 years ago

theolivenbaum commented 3 years ago

The current Get method always allocate a new byte array to copy the data from RocksDB managed memory to C#-managed memory:

public byte[] rocksdb_get(
            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;
            var result = new byte[(ulong)valueLength];
            Marshal.Copy(resultPtr, result, 0, (int)valueLength);
            rocksdb_free(resultPtr);
            return result;
        }

We should add a new method that receives a byte array to copy to, and returns the copied length instead. This will allow using an ArrayPool instead of allocating on each call

theolivenbaum commented 3 years ago

was already in the API 🤦‍♂️ https://github.com/curiosity-ai/rocksdb-sharp/blob/935501cf8bb636e3196aab017cafe17b7c33ba15/csharp/src/RocksDb.cs#L148