private static unsafe void FindFieldFromMvccRaw(ushort id, IntPtr vp, int vs, ulong ts, ref KVField found) { ushort *countPtr = (ushort *)vp.ToPointer(); ushort count = (ushort)(*countPtr >> 1); uint offsetToEnd = 0; int to = GetVersionLessOrEqual(vp, count, ts, &offsetToEnd); int from = GetNearestFullVersionIndex(to); byte * dataPtr = (byte *)vp + vs - offsetToEnd; uint dataSize = GetDataSizeAt(vp, to); KVField temp = new KVField(); for (int i = to; i >= from; i--) //注意倒序 { FindField(id, dataPtr, dataSize, ref temp); if (temp.Id == id) { found = temp; break; //因为倒序找到即是最新版本 } if (i > from) { dataSize = GetDataSizeAt(vp, i - 1); dataPtr -= dataSize; } } }
/// <summary> /// Only for test /// </summary> public static unsafe bool CompareRaw(ushort id, IntPtr vp, int vs, byte[] target) { KVField found = KVField.Invalid; FindFieldFromMvccRaw(id, vp, vs, ulong.MaxValue, ref found); var span = new ReadOnlySpan <byte>(found.DataPtr.ToPointer(), found.DataSize); return(span.SequenceEqual(target)); }
static KVField GetField(Type type) { KVField kvField; if (!_typeToField.TryGetValue(type, out kvField)) { _typeToField[type] = kvField = new KVField() { keyField = type.GetField("key"), valueField = type.GetField("_value") }; } return kvField; }
public static unsafe byte?GetByte(ushort id, IntPtr vp, int vs, bool mv, ulong ts) { KVField found = KVField.Invalid; if (mv) { FindFieldFromMvccRaw(id, vp, vs, ts, ref found); } else { FindField(id, (byte *)vp.ToPointer(), (uint)vs, ref found); } return(found.IsInvalid() ? null : found.GetByte()); }
private static unsafe void FindField(ushort id, byte *dataPtr, uint dataSize, ref KVField found) { byte *cur = dataPtr; byte *end = cur + dataSize; while (cur < end) { found.ReadFrom(&cur); if (found.Id == id) { break; } cur += found.DataSize; } }