From 67a134435338db83ddbbd110327002e910f4e2ed Mon Sep 17 00:00:00 2001 From: Evan Tschannen Date: Fri, 3 Jan 2020 17:46:24 -0800 Subject: [PATCH 1/3] do not serialize the begin key for single key ranges --- fdbclient/CommitTransaction.h | 13 ++++++++++++- fdbclient/FDBTypes.h | 14 +++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/fdbclient/CommitTransaction.h b/fdbclient/CommitTransaction.h index 540157e5c9..6349b9bcb5 100644 --- a/fdbclient/CommitTransaction.h +++ b/fdbclient/CommitTransaction.h @@ -96,7 +96,18 @@ struct MutationRef { template void serialize( Ar& ar ) { - serializer(ar, type, param1, param2); + if (!ar.isDeserializing && type == ClearRange && equalsKeyAfter(param1, param2)) { + StringRef hold = param1; + param1 = StringRef(); + serializer(ar, type, param2, param1); + param1 = hold; + } else { + serializer(ar, type, param1, param2); + } + if (ar.isDeserializing && type == ClearRange && param2 == StringRef() && param1[param1.size()-1] == '\x00') { + param2 = param1; + param1 = param2.substr(0, param2.size()-1); + } } // These masks define which mutation types have particular properties (they are used to implement isSingleKeyMutation() etc) diff --git a/fdbclient/FDBTypes.h b/fdbclient/FDBTypes.h index 4358e83887..d3e22dd196 100644 --- a/fdbclient/FDBTypes.h +++ b/fdbclient/FDBTypes.h @@ -277,7 +277,19 @@ struct KeyRangeRef { template force_inline void serialize(Ar& ar) { - serializer(ar, const_cast(begin), const_cast(end)); + if (!ar.isDeserializing && equalsKeyAfter(begin, end)) { + KeyRef hold = begin; + const_cast(begin) = KeyRef(); + serializer(ar, const_cast(end), const_cast(begin)); + const_cast(begin) = hold; + } else { + serializer(ar, const_cast(begin), const_cast(end)); + } + if (ar.isDeserializing && end == StringRef() && begin[begin.size()-1] == '\x00') { + const_cast(end) = begin; + const_cast(begin) = end.substr(0, end.size()-1); + } + if( begin > end ) { throw inverted_range(); }; From 335774b53df2155191d4e0352091f15c0eaca6b5 Mon Sep 17 00:00:00 2001 From: Evan Tschannen Date: Mon, 6 Jan 2020 14:15:38 -0800 Subject: [PATCH 2/3] added asserts to avoid invalid memory access. fixed the serialization of an empty KeyRangeRef (begin=StringRef(), end=StringRef()). --- fdbclient/CommitTransaction.h | 3 ++- fdbclient/FDBTypes.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/fdbclient/CommitTransaction.h b/fdbclient/CommitTransaction.h index 6349b9bcb5..a520465d75 100644 --- a/fdbclient/CommitTransaction.h +++ b/fdbclient/CommitTransaction.h @@ -104,7 +104,8 @@ struct MutationRef { } else { serializer(ar, type, param1, param2); } - if (ar.isDeserializing && type == ClearRange && param2 == StringRef() && param1[param1.size()-1] == '\x00') { + if (ar.isDeserializing && type == ClearRange && param2 == StringRef()) { + ASSERT(param1.size() > 0 && param1[param1.size()-1] == '\x00'); param2 = param1; param1 = param2.substr(0, param2.size()-1); } diff --git a/fdbclient/FDBTypes.h b/fdbclient/FDBTypes.h index d3e22dd196..d6c1930c2b 100644 --- a/fdbclient/FDBTypes.h +++ b/fdbclient/FDBTypes.h @@ -285,7 +285,8 @@ struct KeyRangeRef { } else { serializer(ar, const_cast(begin), const_cast(end)); } - if (ar.isDeserializing && end == StringRef() && begin[begin.size()-1] == '\x00') { + if (ar.isDeserializing && end == StringRef() && begin != StringRef()) { + ASSERT(begin[begin.size()-1] == '\x00'); const_cast(end) = begin; const_cast(begin) = end.substr(0, end.size()-1); } From c14133a4eca0c71b55b790bfef4a00bb42b7ee41 Mon Sep 17 00:00:00 2001 From: Evan Tschannen Date: Thu, 30 Apr 2020 11:13:59 -0700 Subject: [PATCH 3/3] better serialization of empty StringRef --- fdbclient/CommitTransaction.h | 10 ++++------ fdbclient/FDBTypes.h | 6 ++---- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/fdbclient/CommitTransaction.h b/fdbclient/CommitTransaction.h index 02ab3bb23a..234a869731 100644 --- a/fdbclient/CommitTransaction.h +++ b/fdbclient/CommitTransaction.h @@ -111,15 +111,13 @@ struct MutationRef { template void serialize( Ar& ar ) { if (!ar.isDeserializing && type == ClearRange && equalsKeyAfter(param1, param2)) { - StringRef hold = param1; - param1 = StringRef(); - serializer(ar, type, param2, param1); - param1 = hold; + StringRef empty; + serializer(ar, type, param2, empty); } else { serializer(ar, type, param1, param2); } - if (ar.isDeserializing && type == ClearRange && param2 == StringRef()) { - ASSERT(param1.size() > 0 && param1[param1.size()-1] == '\x00'); + if (ar.isDeserializing && type == ClearRange && param2 == StringRef() && param1 != StringRef()) { + ASSERT(param1[param1.size()-1] == '\x00'); param2 = param1; param1 = param2.substr(0, param2.size()-1); } diff --git a/fdbclient/FDBTypes.h b/fdbclient/FDBTypes.h index 95f5b6602d..21b5d00dc5 100644 --- a/fdbclient/FDBTypes.h +++ b/fdbclient/FDBTypes.h @@ -283,10 +283,8 @@ struct KeyRangeRef { template force_inline void serialize(Ar& ar) { if (!ar.isDeserializing && equalsKeyAfter(begin, end)) { - KeyRef hold = begin; - const_cast(begin) = KeyRef(); - serializer(ar, const_cast(end), const_cast(begin)); - const_cast(begin) = hold; + StringRef empty; + serializer(ar, const_cast(end), empty); } else { serializer(ar, const_cast(begin), const_cast(end)); }