diff --git a/fdbclient/DatabaseContext.h b/fdbclient/DatabaseContext.h index 916ab2997f..69a7a926d9 100644 --- a/fdbclient/DatabaseContext.h +++ b/fdbclient/DatabaseContext.h @@ -46,6 +46,7 @@ typedef MultiInterface> LocationInfo typedef MultiInterface ProxyInfo; class SpecialKeySpace; //forward declaration +class ConflictingKeysImpl; class DatabaseContext : public ReferenceCounted, public FastAllocated, NonCopyable { public: static DatabaseContext* allocateOnForeignThread() { @@ -230,6 +231,7 @@ public: UniqueOrderedOptionList transactionDefaults; std::shared_ptr specialKeySpace; + std::shared_ptr cKImpl; }; #endif diff --git a/fdbclient/NativeAPI.actor.cpp b/fdbclient/NativeAPI.actor.cpp index 1143217e4a..b65764e2a8 100644 --- a/fdbclient/NativeAPI.actor.cpp +++ b/fdbclient/NativeAPI.actor.cpp @@ -541,6 +541,8 @@ DatabaseContext::DatabaseContext( monitorMasterProxiesInfoChange = monitorMasterProxiesChange(clientInfo, &masterProxiesChangeTrigger); clientStatusUpdater.actor = clientStatusUpdateActor(this); specialKeySpace = std::make_shared(normalKeys.begin, normalKeys.end); + cKImpl = std::make_shared(conflictingKeys.begin, conflictingKeys.end); + specialKeySpace->registerKeyRange(conflictingKeys, cKImpl.get()); } DatabaseContext::DatabaseContext( const Error &err ) : deferredError(err), cc("TransactionMetrics"), transactionReadVersions("ReadVersions", cc), diff --git a/fdbclient/ReadYourWrites.actor.cpp b/fdbclient/ReadYourWrites.actor.cpp index dea11a5653..96458afc57 100644 --- a/fdbclient/ReadYourWrites.actor.cpp +++ b/fdbclient/ReadYourWrites.actor.cpp @@ -1281,8 +1281,12 @@ Future< Standalone > ReadYourWritesTransaction::getRange( } // start with simplest point, special key space are only allowed to query if both begin and end start with \xff\xff - if (begin.getKey().startsWith(specialKeys.begin) && end.getKey().startsWith(specialKeys.begin)) - return getDatabase()->specialKeySpace->getRange(Reference(this), begin, end, limits, snapshot, reverse); + if (begin.getKey().startsWith(specialKeys.begin) && end.getKey().startsWith(specialKeys.begin)) { + Reference self = Reference(this); + auto result = getDatabase()->specialKeySpace->getRange(self, begin, end, limits, snapshot, reverse); + self.extractPtr(); + return result; + } // Use special key prefix "\xff\xff/transaction/conflicting_keys/", // to retrieve keys which caused latest not_committed(conflicting with another transaction) error. diff --git a/fdbclient/ReadYourWrites.h b/fdbclient/ReadYourWrites.h index f4ebd92e4b..4783bb29a2 100644 --- a/fdbclient/ReadYourWrites.h +++ b/fdbclient/ReadYourWrites.h @@ -131,6 +131,10 @@ public: Database getDatabase() const { return tr.getDatabase(); } + + const Transaction& getTransaction() const { + return tr; + } private: friend class RYWImpl; diff --git a/fdbclient/SpecialKeySpace.actor.h b/fdbclient/SpecialKeySpace.actor.h index 8327c4356e..dccec9f5c7 100644 --- a/fdbclient/SpecialKeySpace.actor.h +++ b/fdbclient/SpecialKeySpace.actor.h @@ -69,5 +69,17 @@ private: KeyRange range; }; +class ConflictingKeysImpl : public SpecialKeyRangeBaseImpl { +public: + explicit ConflictingKeysImpl(KeyRef start, KeyRef end) : SpecialKeyRangeBaseImpl(start, end) {} + virtual Future> getRange(Reference ryw, + KeyRangeRef kr) const { + auto resultFuture = ryw->getTransaction().info.conflictingKeysRYW->getRange(kr, CLIENT_KNOBS->TOO_MANY); + // all keys are written to RYW, since GRV is set, the read should happen locally + ASSERT(resultFuture.isReady()); + return resultFuture.getValue(); + } +}; + #include "flow/unactorcompiler.h" #endif