Encode conflicting keys using base64.

This commit is contained in:
chaoguang 2019-12-04 00:19:36 -08:00
parent eacfdf6da3
commit b376b947d5
5 changed files with 32 additions and 18 deletions

View File

@ -2674,7 +2674,7 @@ ACTOR static Future<Void> tryCommit( Database cx, Reference<TransactionLogInfo>
return Void();
} else {
if (ci.conflictingKeyRanges.present()){
tr->info.conflictingKeyRanges.push_back_deep(tr->info.conflictingKeyRanges.arena(), ci.conflictingKeyRanges.get());
tr->info.conflictingKeyRanges = ci.conflictingKeyRanges.get();
}
if (info.debugID.present())

View File

@ -144,7 +144,7 @@ struct TransactionInfo {
Optional<UID> debugID;
TaskPriority taskID;
bool useProvisionalProxies;
Standalone<VectorRef<VectorRef<KeyRangeRef>>> conflictingKeyRanges;
Optional<Standalone<VectorRef<KeyRangeRef>>> conflictingKeyRanges;
explicit TransactionInfo( TaskPriority taskID ) : taskID(taskID), useProvisionalProxies(false) {}
};

View File

@ -23,6 +23,7 @@
#include "fdbclient/DatabaseContext.h"
#include "fdbclient/StatusClient.h"
#include "fdbclient/MonitorLeader.h"
#include "fdbclient/libb64/encode.h"
#include "flow/Util.h"
#include "flow/actorcompiler.h" // This must be the last #include.
@ -1230,21 +1231,16 @@ Future< Optional<Value> > ReadYourWritesTransaction::get( const Key& key, bool s
// Add conflicting keys to special key space
if (key == LiteralStringRef("\xff\xff/conflicting_keys/json")){
if (!tr.info.conflictingKeyRanges.empty()){
if (tr.info.conflictingKeyRanges.present()){
json_spirit::mArray root;
json_spirit::mArray keyranges;
json_spirit::mObject keyrange;
for (int i = 0; i < tr.info.conflictingKeyRanges.size(); ++i) {
for (const auto & kr : tr.info.conflictingKeyRanges[i]) {
keyrange["begin"] = kr.begin.toString();
keyrange["end"] = kr.end.toString();
keyranges.push_back(keyrange);
keyrange.clear();
}
root.push_back(keyranges);
keyranges.clear();
for (const auto & kr : tr.info.conflictingKeyRanges.get()) {
keyrange["begin"] = base64::encoder::from_string(kr.begin.toString());
keyrange["end"] = base64::encoder::from_string(kr.end.toString());
root.push_back(keyrange);
keyrange.clear();
}
Optional<Value> output = StringRef(json_spirit::write_string(json_spirit::mValue(root), json_spirit::Output_options::raw_utf8).c_str());
Optional<Value> output = StringRef(json_spirit::write_string(json_spirit::mValue(root), json_spirit::Output_options::raw_utf8));
return output;
} else {
return Optional<Value>();

View File

@ -9,6 +9,9 @@ For details, see http://sourceforge.net/projects/libb64
#define BASE64_DECODE_H
#include <iostream>
#include <sstream>
#define BUFFERSIZE 8192
namespace base64
{
@ -60,6 +63,15 @@ namespace base64
delete [] code;
delete [] plaintext;
}
static std::string from_string(std::string s)
{
std::stringstream in(s);
std::stringstream out;
decoder dec;
dec.decode(in, out);
return out.str();
}
};
} // namespace base64

View File

@ -23,6 +23,7 @@
#include "fdbserver/workloads/workloads.actor.h"
#include "fdbserver/workloads/BulkSetup.actor.h"
#include "fdbclient/ReadYourWrites.h"
#include "fdbclient/libb64/decode.h"
#include "flow/actorcompiler.h" // This must be the last #include.
struct ReportConflictingKeysWorkload : TestWorkload {
@ -161,9 +162,11 @@ struct ReportConflictingKeysWorkload : TestWorkload {
ASSERT(root.size() > 0);
// Only use the last entry which contains the read_conflict_ranges corresponding to current
// conflicts
for (const auto& pair : root.back().get_array()) {
for (const auto& pair : root) {
json_spirit::mObject kr_obj = pair.get_obj();
KeyRange kr = KeyRangeRef(kr_obj["begin"].get_str(), kr_obj["end"].get_str());
std::string start_key = base64::decoder::from_string(kr_obj["begin"].get_str());
std::string end_key = base64::decoder::from_string(kr_obj["end"].get_str());
KeyRange kr = KeyRangeRef(start_key, end_key);
if (!std::any_of(readConflictRanges.begin(), readConflictRanges.end(), [&kr](KeyRange rCR) {
// Read_conflict_range remains same in the resolver.
// Thus, the returned keyrange is either the original read_conflict_range or merged
@ -175,7 +178,10 @@ struct ReportConflictingKeysWorkload : TestWorkload {
TraceEvent(SevError, "TestFailure").detail("Reason", "InvalidKeyRangeReturned");
}
}
}
} else {
++self->invalidReports;
TraceEvent(SevError, "TestFailure").detail("Reason", "FailedToParseJson");
}
}
++self->retries;
}
@ -185,4 +191,4 @@ struct ReportConflictingKeysWorkload : TestWorkload {
}
};
WorkloadFactory<ReportConflictingKeysWorkload> ReportConflictingKeysWorkload("ReportConflictingKeys");
WorkloadFactory<ReportConflictingKeysWorkload> ReportConflictingKeysWorkload("ReportConflictingKeys");