It looks like this native call doesn't return a key-value pair but only positions the cursor. (or I am calling this in a wrong way)
When I add operation check in the middle of the following methods, it works as expected, but without it
keyStruct.ToByteArray(res) throws because the returned ValueStructures are empty.
private KeyValuePair<byte[], byte[]>? Get(CursorOperation operation, ValueStructure? key = null, ValueStructure? value = null)
{
var keyStruct = key.GetValueOrDefault();
var valueStruct = value.GetValueOrDefault();
var res = NativeMethods.Read(lib => lib.mdb_cursor_get(_handle, ref keyStruct, ref valueStruct, operation));
// HERE need to check and provide current values
if (operation == CursorOperation.FirstDuplicate) {
res = NativeMethods.Read(lib => lib.mdb_cursor_get(_handle, ref keyStruct, ref valueStruct, CursorOperation.GetCurrent));
}
return res == NativeMethods.MDB_NOTFOUND
? (KeyValuePair<byte[], byte[]>?) null
: new KeyValuePair<byte[], byte[]>(keyStruct.ToByteArray(res), valueStruct.ToByteArray(res));
}
The whole test below. Note the expected behavior right before the last loop:
[Test]
public void CursorShouldPutDupValues() {
var db2 = _txn.OpenDatabase("dup",
DBFlags.Create | DBFlags.DuplicatesSort
| DBFlags.DuplicatesFixed | DBFlags.IntegerDuplicates);
using (var cur = _txn.CreateCursor(db2)) {
var keys = Enumerable.Range(1, 50000).ToArray();
foreach (var k in keys) {
cur.Put(Encoding.UTF8.GetBytes("key"), k, CursorPutOptions.None);
}
// overwrite
foreach (var k in keys) {
cur.Put(Encoding.UTF8.GetBytes("key"), k, CursorPutOptions.None);
}
var kvp = cur.MoveToFirst();
kvp = cur.MoveNextDuplicate();
kvp = cur.MoveNextDuplicate();
kvp = cur.MoveToFirstDuplicate(); // cancel the moves above and start from the beginning
foreach (var k in keys) {
//var kvp = cur.GetCurrent();
Assert.AreEqual(k, BitConverter.ToInt32(kvp.Value.Value, 0));
kvp = cur.MoveNextDuplicate();
}
}
}
It looks like this native call doesn't return a key-value pair but only positions the cursor. (or I am calling this in a wrong way)
When I add operation check in the middle of the following methods, it works as expected, but without it
keyStruct.ToByteArray(res)
throws because the returnedValueStructure
s are empty.The whole test below. Note the expected behavior right before the last loop: