private unsafe void WriteReadIndexByScanRes(BinSerializer bs) { bs.Write(Data1.ToInt64()); //error code bs.Write(Data3.ToInt64()); //length if (Data1 == IntPtr.Zero && Data2 != IntPtr.Zero) //不要判断length,可能包含其他如skipped数据 { int dataSize = 4; //初始化4字节for skipped int length = Data3.ToInt32(); //先计算并写入数据部分大小,方便子进程分配内存(另考虑子进程内使用ByteBuffer缓存分块) IteratorKV kv = new IteratorKV(); IntPtr kvPtr = new IntPtr(&kv); for (int i = 0; i < length; i++) //TODO:底层Api实现一次调用计算出总大小 { NativeApi.ScanResponseGetKV(Data2, i, kvPtr); dataSize += 4 + kv.KeySize.ToInt32() + 4 + kv.ValueSize.ToInt32(); } bs.Write(dataSize); //再写入skipped uint skipped = NativeApi.ScanResponseGetSkipped(Data2); var span = new ReadOnlySpan <byte>(&skipped, 4); bs.Stream.Write(span); //最后写入记录数据 int tempSize = 0; for (int i = 0; i < length; i++) { NativeApi.ScanResponseGetKV(Data2, i, kvPtr); tempSize = kv.KeySize.ToInt32(); span = new ReadOnlySpan <byte>(&tempSize, 4); bs.Stream.Write(span); span = new ReadOnlySpan <byte>(kv.KeyPtr.ToPointer(), tempSize); bs.Stream.Write(span); tempSize = kv.ValueSize.ToInt32(); span = new ReadOnlySpan <byte>(&tempSize, 4); bs.Stream.Write(span); span = new ReadOnlySpan <byte>(kv.ValuePtr.ToPointer(), tempSize); bs.Stream.Write(span); } } else { bs.Write(0); //dataSize } }
public void ForEachRow(Action <IntPtr, int, IntPtr, int> action) { if (Length <= 0) { return; } IteratorKV kv = new IteratorKV(); IntPtr kvPtr = IntPtr.Zero; unsafe { kvPtr = new IntPtr(&kv); } for (int i = 0; i < Length; i++) { NativeApi.ScanResponseGetKV(_handle, i, kvPtr); action(kv.KeyPtr, kv.KeySize.ToInt32(), kv.ValuePtr, kv.ValueSize.ToInt32()); } }