Support versionstamps in key backed object properties

This commit is contained in:
A.J. Beamon 2022-10-05 12:48:40 -07:00
parent dc917453c1
commit cfb36bd9c3
8 changed files with 69 additions and 26 deletions

View File

@ -1001,7 +1001,7 @@ GetMappedRangeResult getMappedIndexEntries(int beginId,
TEST_CASE("versionstamp_unit_test") {
// a random 12 bytes long StringRef as a versionstamp
StringRef str = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12"_sr;
Versionstamp vs(str), vs2(str);
TupleVersionstamp vs(str), vs2(str);
ASSERT(vs == vs2);
ASSERT(vs.begin() != vs2.begin());
@ -1031,7 +1031,7 @@ TEST_CASE("versionstamp_unit_test") {
TEST_CASE("tuple_support_versionstamp") {
// a random 12 bytes long StringRef as a versionstamp
StringRef str = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12"_sr;
Versionstamp vs(str);
TupleVersionstamp vs(str);
const Tuple t = Tuple::makeTuple(prefix, RECORD, vs, "{K[3]}"_sr, "{...}"_sr);
ASSERT(t.getVersionstamp(2) == vs);
@ -1047,7 +1047,7 @@ TEST_CASE("tuple_fail_to_append_truncated_versionstamp") {
// a truncated 11 bytes long StringRef as a versionstamp
StringRef str = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11"_sr;
try {
Versionstamp truncatedVersionstamp(str);
TupleVersionstamp truncatedVersionstamp(str);
} catch (Error& e) {
return;
}
@ -1058,7 +1058,7 @@ TEST_CASE("tuple_fail_to_append_longer_versionstamp") {
// a longer than expected 13 bytes long StringRef as a versionstamp
StringRef str = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11"_sr;
try {
Versionstamp longerVersionstamp(str);
TupleVersionstamp longerVersionstamp(str);
} catch (Error& e) {
return;
}

View File

@ -24,7 +24,9 @@
#pragma once
#include "bindings/flow/fdb_flow.h"
#include "fdbclient/Versionstamp.h"
#include "fdbclient/TupleVersionstamp.h"
typedef TupleVersionstamp Versionstamp;
namespace FDB {
struct Uuid {

View File

@ -117,7 +117,7 @@ Tuple& Tuple::append(Tuple const& tuple) {
return *this;
}
Tuple& Tuple::append(Versionstamp const& vs) {
Tuple& Tuple::append(TupleVersionstamp const& vs) {
offsets.push_back(data.size());
data.push_back(data.arena(), VERSIONSTAMP_96_CODE);
@ -413,7 +413,7 @@ double Tuple::getDouble(size_t index) const {
return bigEndianDouble(swap);
}
Versionstamp Tuple::getVersionstamp(size_t index) const {
TupleVersionstamp Tuple::getVersionstamp(size_t index) const {
if (index >= offsets.size()) {
throw invalid_tuple_index();
}
@ -422,7 +422,7 @@ Versionstamp Tuple::getVersionstamp(size_t index) const {
if (code != VERSIONSTAMP_96_CODE) {
throw invalid_tuple_data_type();
}
return Versionstamp(StringRef(data.begin() + offsets[index] + 1, VERSIONSTAMP_TUPLE_SIZE));
return TupleVersionstamp(StringRef(data.begin() + offsets[index] + 1, VERSIONSTAMP_TUPLE_SIZE));
}
Tuple::UserTypeStr Tuple::getUserType(size_t index) const {
@ -495,7 +495,7 @@ TEST_CASE("/fdbclient/Tuple/makeTuple") {
"byteStr"_sr,
Tuple::UnicodeStr("str"_sr),
nullptr,
Versionstamp("000000000000"_sr),
TupleVersionstamp("000000000000"_sr),
Tuple::UserTypeStr(0x41, "12345678"_sr));
Tuple t2 = Tuple()
.append(1)
@ -505,7 +505,7 @@ TEST_CASE("/fdbclient/Tuple/makeTuple") {
.append("byteStr"_sr)
.append(Tuple::UnicodeStr("str"_sr))
.append(nullptr)
.append(Versionstamp("000000000000"_sr))
.append(TupleVersionstamp("000000000000"_sr))
.append(Tuple::UserTypeStr(0x41, "12345678"_sr));
ASSERT(t1.pack() == t2.pack());
@ -531,7 +531,7 @@ TEST_CASE("/fdbclient/Tuple/unpack") {
"byteStr"_sr,
Tuple::UnicodeStr("str"_sr),
nullptr,
Versionstamp("000000000000"_sr),
TupleVersionstamp("000000000000"_sr),
Tuple::UserTypeStr(0x41, "12345678"_sr));
Standalone<StringRef> packed = t1.pack();

View File

@ -1,13 +1,13 @@
#include "fdbclient/Versionstamp.h"
#include "fdbclient/TupleVersionstamp.h"
Versionstamp::Versionstamp(StringRef str) {
TupleVersionstamp::TupleVersionstamp(StringRef str) {
if (str.size() != VERSIONSTAMP_TUPLE_SIZE) {
throw invalid_versionstamp_size();
}
data = str;
}
int16_t Versionstamp::getBatchNumber() const {
int16_t TupleVersionstamp::getBatchNumber() const {
const uint8_t* begin = data.begin();
begin += 8;
int16_t batchNumber = *(int16_t*)(begin);
@ -15,7 +15,7 @@ int16_t Versionstamp::getBatchNumber() const {
return batchNumber;
}
int16_t Versionstamp::getUserVersion() const {
int16_t TupleVersionstamp::getUserVersion() const {
const uint8_t* begin = data.begin();
begin += 10;
int16_t userVersion = *(int16_t*)(begin);
@ -23,22 +23,22 @@ int16_t Versionstamp::getUserVersion() const {
return userVersion;
}
const uint8_t* Versionstamp::begin() const {
const uint8_t* TupleVersionstamp::begin() const {
return data.begin();
}
int64_t Versionstamp::getVersion() const {
int64_t TupleVersionstamp::getVersion() const {
const uint8_t* begin = data.begin();
int64_t version = *(int64_t*)begin;
version = bigEndian64(version);
return version;
}
size_t Versionstamp::size() const {
size_t TupleVersionstamp::size() const {
return VERSIONSTAMP_TUPLE_SIZE;
}
bool Versionstamp::operator==(const Versionstamp& other) const {
bool TupleVersionstamp::operator==(const TupleVersionstamp& other) const {
return getVersion() == other.getVersion() && getBatchNumber() == other.getBatchNumber() &&
getUserVersion() == other.getUserVersion();
}

View File

@ -1654,4 +1654,36 @@ struct transaction_creator_traits<T, std::void_t<typename T::TransactionT>> : st
template <typename T>
constexpr bool is_transaction_creator = transaction_creator_traits<T>::value;
struct Versionstamp {
Version version = invalidVersion;
uint16_t batchNumber = 0;
bool operator==(const Versionstamp& r) const { return version == r.version && batchNumber == r.batchNumber; }
bool operator!=(const Versionstamp& r) const { return !(*this == r); }
bool operator<(const Versionstamp& r) const {
return version < r.version || (version == r.version && batchNumber < r.batchNumber);
}
bool operator>(const Versionstamp& r) const { return r < *this; }
bool operator<=(const Versionstamp& r) const { return !(*this > r); }
bool operator>=(const Versionstamp& r) const { return !(*this < r); }
template <class Ar>
void serialize(Ar& ar) {
int64_t beVersion;
int16_t beBatch;
if constexpr (!Ar::isDeserializing) {
beVersion = bigEndian64(version);
beBatch = bigEndian16(batchNumber);
}
serializer(ar, beVersion, beBatch);
if constexpr (Ar::isDeserializing) {
version = bigEndian64(version);
batchNumber = bigEndian16(beBatch);
}
}
};
#endif

View File

@ -29,6 +29,7 @@
#include "fdbclient/GenericTransactionHelper.h"
#include "fdbclient/Subspace.h"
#include "flow/ObjectSerializer.h"
#include "flow/Platform.h"
#include "flow/genericactors.actor.h"
#include "flow/serialize.h"
@ -305,6 +306,14 @@ public:
tr->atomicOp(key, BinaryWriter::toValue<T>(val, Unversioned()), type);
}
template <class Transaction>
void setVersionstamp(Transaction tr, T const& val, int offset) {
tr->atomicOp(
key,
BinaryWriter::toValue<T>(val, Unversioned()).withSuffix(StringRef(reinterpret_cast<uint8_t*>(offset), 4)),
MutationRef::SetVersionstampedValue);
}
template <class Transaction>
void clear(Transaction tr) {
tr->clear(key);

View File

@ -25,7 +25,7 @@
#include "flow/flow.h"
#include "fdbclient/FDBTypes.h"
#include "fdbclient/Versionstamp.h"
#include "fdbclient/TupleVersionstamp.h"
struct Tuple {
struct UnicodeStr {
@ -63,7 +63,7 @@ struct Tuple {
Tuple& append(double);
Tuple& append(std::nullptr_t);
Tuple& appendNull();
Tuple& append(Versionstamp const&);
Tuple& append(TupleVersionstamp const&);
Tuple& append(UserTypeStr const&);
Standalone<StringRef> pack() const {
@ -92,7 +92,7 @@ struct Tuple {
StringRef subTupleRawString(size_t index) const;
ElementType getType(size_t index) const;
Standalone<StringRef> getString(size_t index) const;
Versionstamp getVersionstamp(size_t index) const;
TupleVersionstamp getVersionstamp(size_t index) const;
int64_t getInt(size_t index, bool allow_incomplete = false) const;
bool getBool(size_t index) const;
float getFloat(size_t index) const;

View File

@ -1,5 +1,5 @@
/*
* Versionstamp.h
* TupleVersionstamp.h
*
* This source file is part of the FoundationDB open source project
*
@ -27,15 +27,15 @@
const size_t VERSIONSTAMP_TUPLE_SIZE = 12;
struct Versionstamp {
Versionstamp(StringRef);
struct TupleVersionstamp {
TupleVersionstamp(StringRef);
int64_t getVersion() const;
int16_t getBatchNumber() const;
int16_t getUserVersion() const;
size_t size() const;
const uint8_t* begin() const;
bool operator==(const Versionstamp&) const;
bool operator==(const TupleVersionstamp&) const;
private:
Standalone<StringRef> data;