Unfortunately, it seems that we diverged slightly after that, since my embedded tuples (with 00 FF encoding) are still using the old 03/04 prefix/suffix, while it seems they are now using 05.
Yeah, that’s right. We went with 05/00
instead of 03/04
because the 05/00
sorts prefixes correctly. For example, (("hello",),)
would serialize to \x03\x02hello\x00\x04
and then (("hello", "world"),)
would serialize to \x03\x02hello\x00\x02world\x00\x04
, which means (("hello", "world"),)
would sort before (("hello",),)
when serialized. Using \x00
as the terminator fixes that problem.
I also see that false/true are mapped to 0x26/0x27 while at the time they were encoded as integer 0 or 1. Is this a “recent” change as well?
Yeah, that was introduced in release 5.0. In principle, an application can choose to use 1 and 0 to mean true and false, and everything would still work. The extra type lets them specify boolean-ness in a type safe way (and saves a byte on “true”, for what that’s worth).
Is the only difference between the 80 bits and 96 bits version the two additional bytes at the end?
Yep, that’s the only difference. The extra 16 bits let the user specify an order of operations within a transaction, and the first 80 bits are set by the database to enforce an order between transactions. So the 96 bit versionstamp can be used to globally order things across all transactions in a way that is consistent with a valid serialization order.
I’ll probably need to create a custom struct to represent this type in .NET because 80 bits is somewhat in between two chairs
Sure. As I’m sure you’ll find digging through the source, there is also some work needed to be done on the binding implementor’s part to handle cases where the versionstamp hasn’t been set and will be passed into a versionstamp mutation. I believe we refer to those versionstamps as “unset” in our API.