Skip to content

Commit 7919499

Browse files
committed
Fix parsing of incomplete VersionStamps, using the highest bit to distinguish between cases
1 parent da593a6 commit 7919499

File tree

3 files changed

+9
-34
lines changed

3 files changed

+9
-34
lines changed

FoundationDB.Client/Native/FdbNative.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -848,10 +848,8 @@ public static FdbError FutureGetVersionStamp(FutureHandle future, out VersionSta
848848
stamp = default;
849849
return err;
850850
}
851-
//note: we assume that this is a complete stamp read from the database.
852-
//BUGBUG: if the code serialize an incomplete stamp into a tuple, and unpacks it (logging?) it MAY be changed into a complete one!
853-
// => we could check for the 'all FF' signature, but this only works for default incomplete tokens, not custom incomplete tokens !
854-
VersionStamp.ReadUnsafe(ptr, 10, /*FLAGS_NONE*/0, out stamp);
851+
852+
VersionStamp.ReadUnsafe(ptr, 10, out stamp);
855853
return err;
856854
}
857855

FoundationDB.Client/VersionStamp.cs

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ namespace FoundationDB.Client
5252
private const ulong PLACEHOLDER_VERSION = ulong.MaxValue;
5353
private const ushort PLACEHOLDER_ORDER = ushort.MaxValue;
5454
private const ushort NO_USER_VERSION = 0;
55+
private const ulong HSB_VERSION = 0x8000000000000000UL;
5556

5657
private const ushort FLAGS_NONE = 0x0;
5758
private const ushort FLAGS_HAS_VERSION = 0x1; // unset: 80-bits, set: 96-bits
@@ -262,46 +263,22 @@ public static bool TryParse(Slice data, out VersionStamp vs)
262263
{
263264
fixed (byte* ptr = &data.DangerousGetPinnableReference())
264265
{
265-
ReadUnsafe(ptr, data.Count, FLAGS_NONE, out vs);
266+
ReadUnsafe(ptr, data.Count, out vs);
266267
return true;
267268
}
268269
}
269270
}
270271

271-
/// <summary>Parse a VersionStamp from a sequence of 10 bytes</summary>
272-
/// <exception cref="FormatException">If the buffer length is not exactly 12 bytes</exception>
273-
[Pure]
274-
public static VersionStamp ParseIncomplete(Slice data)
275-
{
276-
return TryParseIncomplete(data, out var vs) ? vs : throw new FormatException("A VersionStamp is either 10 or 12 bytes.");
277-
}
278-
279-
/// <summary>Try parsing a VersionStamp from a sequence of bytes</summary>
280-
public static bool TryParseIncomplete(Slice data, out VersionStamp vs)
281-
{
282-
if (data.Count != 10 && data.Count != 12)
283-
{
284-
vs = default;
285-
return false;
286-
}
287-
unsafe
288-
{
289-
fixed (byte* ptr = &data.DangerousGetPinnableReference())
290-
{
291-
ReadUnsafe(ptr, data.Count, FLAGS_IS_INCOMPLETE, out vs);
292-
return true;
293-
}
294-
}
295-
}
296-
297-
internal static unsafe void ReadUnsafe(byte* ptr, int len, ushort flags, out VersionStamp vs)
272+
internal static unsafe void ReadUnsafe(byte* ptr, int len, out VersionStamp vs)
298273
{
299274
Contract.Debug.Assert(len == 10 || len == 12);
300275
// reads a complete 12 bytes Versionstamp
301276
ulong ver = UnsafeHelpers.LoadUInt64BE(ptr);
302277
ushort order = UnsafeHelpers.LoadUInt16BE(ptr + 8);
303278
ushort idx = len == 10 ? NO_USER_VERSION : UnsafeHelpers.LoadUInt16BE(ptr + 10);
304-
flags |= len == 12 ? FLAGS_HAS_VERSION : FLAGS_NONE;
279+
ushort flags = FLAGS_NONE;
280+
if (len == 12) flags |= FLAGS_HAS_VERSION;
281+
if ((ver & HSB_VERSION) != 0) flags |= FLAGS_IS_INCOMPLETE;
305282
vs = new VersionStamp(ver, order, idx, flags);
306283
}
307284

FoundationDB.Tests/VersionStampFacts.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public void Test_Incomplete_VersionStamp()
109109
Assert.That(vs.TransactionVersion, Is.EqualTo(ulong.MaxValue));
110110
Assert.That(vs.TransactionOrder, Is.EqualTo(ushort.MaxValue));
111111
Assert.That(vs.UserVersion, Is.EqualTo(123));
112-
Assert.That(vs.IsIncomplete, Is.False, "NOTE: reading stamps is only supposed to happen for stamps already in the database!");
112+
Assert.That(vs.IsIncomplete, Is.True);
113113
}
114114

115115
{

0 commit comments

Comments
 (0)