Merge pull request #8405 from sfc-gh-ajbeamon/versionstamp-in-key-backed-object-property
Support versionstamps in KeyBackedBinaryValue
This commit is contained in:
commit
09050c0b87
|
@ -1001,7 +1001,7 @@ GetMappedRangeResult getMappedIndexEntries(int beginId,
|
||||||
TEST_CASE("versionstamp_unit_test") {
|
TEST_CASE("versionstamp_unit_test") {
|
||||||
// a random 12 bytes long StringRef as a 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;
|
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 == vs2);
|
||||||
ASSERT(vs.begin() != vs2.begin());
|
ASSERT(vs.begin() != vs2.begin());
|
||||||
|
|
||||||
|
@ -1031,7 +1031,7 @@ TEST_CASE("versionstamp_unit_test") {
|
||||||
TEST_CASE("tuple_support_versionstamp") {
|
TEST_CASE("tuple_support_versionstamp") {
|
||||||
// a random 12 bytes long StringRef as a 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;
|
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);
|
const Tuple t = Tuple::makeTuple(prefix, RECORD, vs, "{K[3]}"_sr, "{...}"_sr);
|
||||||
ASSERT(t.getVersionstamp(2) == vs);
|
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
|
// a truncated 11 bytes long StringRef as a versionstamp
|
||||||
StringRef str = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11"_sr;
|
StringRef str = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11"_sr;
|
||||||
try {
|
try {
|
||||||
Versionstamp truncatedVersionstamp(str);
|
TupleVersionstamp truncatedVersionstamp(str);
|
||||||
} catch (Error& e) {
|
} catch (Error& e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1058,7 +1058,7 @@ TEST_CASE("tuple_fail_to_append_longer_versionstamp") {
|
||||||
// a longer than expected 13 bytes long StringRef as a 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;
|
StringRef str = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11"_sr;
|
||||||
try {
|
try {
|
||||||
Versionstamp longerVersionstamp(str);
|
TupleVersionstamp longerVersionstamp(str);
|
||||||
} catch (Error& e) {
|
} catch (Error& e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "bindings/flow/fdb_flow.h"
|
#include "bindings/flow/fdb_flow.h"
|
||||||
#include "fdbclient/Versionstamp.h"
|
#include "fdbclient/TupleVersionstamp.h"
|
||||||
|
|
||||||
|
typedef TupleVersionstamp Versionstamp;
|
||||||
|
|
||||||
namespace FDB {
|
namespace FDB {
|
||||||
struct Uuid {
|
struct Uuid {
|
||||||
|
|
|
@ -117,7 +117,7 @@ Tuple& Tuple::append(Tuple const& tuple) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tuple& Tuple::append(Versionstamp const& vs) {
|
Tuple& Tuple::append(TupleVersionstamp const& vs) {
|
||||||
offsets.push_back(data.size());
|
offsets.push_back(data.size());
|
||||||
|
|
||||||
data.push_back(data.arena(), VERSIONSTAMP_96_CODE);
|
data.push_back(data.arena(), VERSIONSTAMP_96_CODE);
|
||||||
|
@ -413,7 +413,7 @@ double Tuple::getDouble(size_t index) const {
|
||||||
return bigEndianDouble(swap);
|
return bigEndianDouble(swap);
|
||||||
}
|
}
|
||||||
|
|
||||||
Versionstamp Tuple::getVersionstamp(size_t index) const {
|
TupleVersionstamp Tuple::getVersionstamp(size_t index) const {
|
||||||
if (index >= offsets.size()) {
|
if (index >= offsets.size()) {
|
||||||
throw invalid_tuple_index();
|
throw invalid_tuple_index();
|
||||||
}
|
}
|
||||||
|
@ -422,7 +422,7 @@ Versionstamp Tuple::getVersionstamp(size_t index) const {
|
||||||
if (code != VERSIONSTAMP_96_CODE) {
|
if (code != VERSIONSTAMP_96_CODE) {
|
||||||
throw invalid_tuple_data_type();
|
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 {
|
Tuple::UserTypeStr Tuple::getUserType(size_t index) const {
|
||||||
|
@ -495,7 +495,7 @@ TEST_CASE("/fdbclient/Tuple/makeTuple") {
|
||||||
"byteStr"_sr,
|
"byteStr"_sr,
|
||||||
Tuple::UnicodeStr("str"_sr),
|
Tuple::UnicodeStr("str"_sr),
|
||||||
nullptr,
|
nullptr,
|
||||||
Versionstamp("000000000000"_sr),
|
TupleVersionstamp("000000000000"_sr),
|
||||||
Tuple::UserTypeStr(0x41, "12345678"_sr));
|
Tuple::UserTypeStr(0x41, "12345678"_sr));
|
||||||
Tuple t2 = Tuple()
|
Tuple t2 = Tuple()
|
||||||
.append(1)
|
.append(1)
|
||||||
|
@ -505,7 +505,7 @@ TEST_CASE("/fdbclient/Tuple/makeTuple") {
|
||||||
.append("byteStr"_sr)
|
.append("byteStr"_sr)
|
||||||
.append(Tuple::UnicodeStr("str"_sr))
|
.append(Tuple::UnicodeStr("str"_sr))
|
||||||
.append(nullptr)
|
.append(nullptr)
|
||||||
.append(Versionstamp("000000000000"_sr))
|
.append(TupleVersionstamp("000000000000"_sr))
|
||||||
.append(Tuple::UserTypeStr(0x41, "12345678"_sr));
|
.append(Tuple::UserTypeStr(0x41, "12345678"_sr));
|
||||||
|
|
||||||
ASSERT(t1.pack() == t2.pack());
|
ASSERT(t1.pack() == t2.pack());
|
||||||
|
@ -531,7 +531,7 @@ TEST_CASE("/fdbclient/Tuple/unpack") {
|
||||||
"byteStr"_sr,
|
"byteStr"_sr,
|
||||||
Tuple::UnicodeStr("str"_sr),
|
Tuple::UnicodeStr("str"_sr),
|
||||||
nullptr,
|
nullptr,
|
||||||
Versionstamp("000000000000"_sr),
|
TupleVersionstamp("000000000000"_sr),
|
||||||
Tuple::UserTypeStr(0x41, "12345678"_sr));
|
Tuple::UserTypeStr(0x41, "12345678"_sr));
|
||||||
|
|
||||||
Standalone<StringRef> packed = t1.pack();
|
Standalone<StringRef> packed = t1.pack();
|
||||||
|
|
|
@ -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) {
|
if (str.size() != VERSIONSTAMP_TUPLE_SIZE) {
|
||||||
throw invalid_versionstamp_size();
|
throw invalid_versionstamp_size();
|
||||||
}
|
}
|
||||||
data = str;
|
data = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t Versionstamp::getBatchNumber() const {
|
int16_t TupleVersionstamp::getBatchNumber() const {
|
||||||
const uint8_t* begin = data.begin();
|
const uint8_t* begin = data.begin();
|
||||||
begin += 8;
|
begin += 8;
|
||||||
int16_t batchNumber = *(int16_t*)(begin);
|
int16_t batchNumber = *(int16_t*)(begin);
|
||||||
|
@ -15,7 +15,7 @@ int16_t Versionstamp::getBatchNumber() const {
|
||||||
return batchNumber;
|
return batchNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t Versionstamp::getUserVersion() const {
|
int16_t TupleVersionstamp::getUserVersion() const {
|
||||||
const uint8_t* begin = data.begin();
|
const uint8_t* begin = data.begin();
|
||||||
begin += 10;
|
begin += 10;
|
||||||
int16_t userVersion = *(int16_t*)(begin);
|
int16_t userVersion = *(int16_t*)(begin);
|
||||||
|
@ -23,22 +23,22 @@ int16_t Versionstamp::getUserVersion() const {
|
||||||
return userVersion;
|
return userVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t* Versionstamp::begin() const {
|
const uint8_t* TupleVersionstamp::begin() const {
|
||||||
return data.begin();
|
return data.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t Versionstamp::getVersion() const {
|
int64_t TupleVersionstamp::getVersion() const {
|
||||||
const uint8_t* begin = data.begin();
|
const uint8_t* begin = data.begin();
|
||||||
int64_t version = *(int64_t*)begin;
|
int64_t version = *(int64_t*)begin;
|
||||||
version = bigEndian64(version);
|
version = bigEndian64(version);
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Versionstamp::size() const {
|
size_t TupleVersionstamp::size() const {
|
||||||
return VERSIONSTAMP_TUPLE_SIZE;
|
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() &&
|
return getVersion() == other.getVersion() && getBatchNumber() == other.getBatchNumber() &&
|
||||||
getUserVersion() == other.getUserVersion();
|
getUserVersion() == other.getUserVersion();
|
||||||
}
|
}
|
|
@ -1654,4 +1654,36 @@ struct transaction_creator_traits<T, std::void_t<typename T::TransactionT>> : st
|
||||||
template <typename T>
|
template <typename T>
|
||||||
constexpr bool is_transaction_creator = transaction_creator_traits<T>::value;
|
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
|
#endif
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "fdbclient/GenericTransactionHelper.h"
|
#include "fdbclient/GenericTransactionHelper.h"
|
||||||
#include "fdbclient/Subspace.h"
|
#include "fdbclient/Subspace.h"
|
||||||
#include "flow/ObjectSerializer.h"
|
#include "flow/ObjectSerializer.h"
|
||||||
|
#include "flow/Platform.h"
|
||||||
#include "flow/genericactors.actor.h"
|
#include "flow/genericactors.actor.h"
|
||||||
#include "flow/serialize.h"
|
#include "flow/serialize.h"
|
||||||
|
|
||||||
|
@ -305,6 +306,14 @@ public:
|
||||||
tr->atomicOp(key, BinaryWriter::toValue<T>(val, Unversioned()), type);
|
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>
|
template <class Transaction>
|
||||||
void clear(Transaction tr) {
|
void clear(Transaction tr) {
|
||||||
tr->clear(key);
|
tr->clear(key);
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
#include "flow/flow.h"
|
#include "flow/flow.h"
|
||||||
#include "fdbclient/FDBTypes.h"
|
#include "fdbclient/FDBTypes.h"
|
||||||
#include "fdbclient/Versionstamp.h"
|
#include "fdbclient/TupleVersionstamp.h"
|
||||||
|
|
||||||
struct Tuple {
|
struct Tuple {
|
||||||
struct UnicodeStr {
|
struct UnicodeStr {
|
||||||
|
@ -63,7 +63,7 @@ struct Tuple {
|
||||||
Tuple& append(double);
|
Tuple& append(double);
|
||||||
Tuple& append(std::nullptr_t);
|
Tuple& append(std::nullptr_t);
|
||||||
Tuple& appendNull();
|
Tuple& appendNull();
|
||||||
Tuple& append(Versionstamp const&);
|
Tuple& append(TupleVersionstamp const&);
|
||||||
Tuple& append(UserTypeStr const&);
|
Tuple& append(UserTypeStr const&);
|
||||||
|
|
||||||
Standalone<StringRef> pack() const {
|
Standalone<StringRef> pack() const {
|
||||||
|
@ -92,7 +92,7 @@ struct Tuple {
|
||||||
StringRef subTupleRawString(size_t index) const;
|
StringRef subTupleRawString(size_t index) const;
|
||||||
ElementType getType(size_t index) const;
|
ElementType getType(size_t index) const;
|
||||||
Standalone<StringRef> getString(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;
|
int64_t getInt(size_t index, bool allow_incomplete = false) const;
|
||||||
bool getBool(size_t index) const;
|
bool getBool(size_t index) const;
|
||||||
float getFloat(size_t index) const;
|
float getFloat(size_t index) const;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Versionstamp.h
|
* TupleVersionstamp.h
|
||||||
*
|
*
|
||||||
* This source file is part of the FoundationDB open source project
|
* This source file is part of the FoundationDB open source project
|
||||||
*
|
*
|
||||||
|
@ -27,15 +27,15 @@
|
||||||
|
|
||||||
const size_t VERSIONSTAMP_TUPLE_SIZE = 12;
|
const size_t VERSIONSTAMP_TUPLE_SIZE = 12;
|
||||||
|
|
||||||
struct Versionstamp {
|
struct TupleVersionstamp {
|
||||||
Versionstamp(StringRef);
|
TupleVersionstamp(StringRef);
|
||||||
|
|
||||||
int64_t getVersion() const;
|
int64_t getVersion() const;
|
||||||
int16_t getBatchNumber() const;
|
int16_t getBatchNumber() const;
|
||||||
int16_t getUserVersion() const;
|
int16_t getUserVersion() const;
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
const uint8_t* begin() const;
|
const uint8_t* begin() const;
|
||||||
bool operator==(const Versionstamp&) const;
|
bool operator==(const TupleVersionstamp&) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Standalone<StringRef> data;
|
Standalone<StringRef> data;
|
Loading…
Reference in New Issue