diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.cpp | 12 | ||||
-rw-r--r-- | src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp | 34 |
2 files changed, 37 insertions, 9 deletions
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.cpp index 1ad70b3d11b..c3421f81987 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.cpp @@ -91,10 +91,16 @@ WiredTigerBeginTxnBlock::~WiredTigerBeginTxnBlock() { Status WiredTigerBeginTxnBlock::setReadSnapshot(Timestamp readTimestamp) { invariant(_rollback); - std::string readTSConfigString = "read_timestamp={:x}"_format(readTimestamp.asULL()); + // Avoid heap allocation in favour of a stack allocation for the configuration string. + constexpr auto configFmtString = "read_timestamp={:x}"; + constexpr auto numBytesRequired = std::char_traits<char>::length(configFmtString) + + (sizeof(decltype(readTimestamp.asULL())) * 2) + 1; + std::array<char, numBytesRequired> configString; + auto end = + fmt::format_to(configString.begin(), FMT_STRING(configFmtString), readTimestamp.asULL()); + *end = '\0'; - return wtRCToStatus(_session->timestamp_transaction(_session, readTSConfigString.c_str()), - _session); + return wtRCToStatus(_session->timestamp_transaction(_session, configString.begin()), _session); } void WiredTigerBeginTxnBlock::done() { diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp index cf6d0313988..ad930b5c698 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp @@ -45,6 +45,9 @@ #include "mongo/util/stacktrace.h" #include "mongo/util/testing_proctor.h" +#include <fmt/compile.h> +#include <fmt/format.h> + namespace mongo { namespace { @@ -468,27 +471,39 @@ void WiredTigerRecoveryUnit::_txnClose(bool commit) { int wtRet; if (commit) { - StringBuilder conf; + // Avoid heap allocation in favour of a stack allocation for the commit string. + constexpr auto commitTimestampFmtString = "commit_timestamp={:X},"; + constexpr auto durableTimestampFmtString = "durable_timestamp={:X}"; + constexpr auto bytesRequired = std::char_traits<char>::length(commitTimestampFmtString) + + (sizeof(decltype(_commitTimestamp.asULL())) * 2) + + std::char_traits<char>::length(durableTimestampFmtString) + + (sizeof(decltype(_durableTimestamp.asULL())) * 2) + 1; + std::array<char, bytesRequired> conf; + auto end = conf.begin(); if (!_commitTimestamp.isNull()) { // There is currently no scenario where it is intentional to commit before the current // read timestamp. invariant(_readAtTimestamp.isNull() || _commitTimestamp >= _readAtTimestamp); if (MONGO_likely(!doUntimestampedWritesForIdempotencyTests.shouldFail())) { - conf << "commit_timestamp=" << unsignedHex(_commitTimestamp.asULL()) << ","; + end = fmt::format_to( + conf.begin(), FMT_STRING(commitTimestampFmtString), _commitTimestamp.asULL()); } _isTimestamped = true; } if (!_durableTimestamp.isNull()) { - conf << "durable_timestamp=" << unsignedHex(_durableTimestamp.asULL()); + end = fmt::format_to( + end, FMT_STRING(durableTimestampFmtString), _durableTimestamp.asULL()); } if (_mustBeTimestamped) { invariant(_isTimestamped); } - wtRet = s->commit_transaction(s, conf.str().c_str()); + *end = '\0'; + + wtRet = s->commit_transaction(s, conf.begin()); LOGV2_DEBUG( 22412, 3, "WT commit_transaction", "snapshotId"_attr = getSnapshotId().toNumber()); @@ -834,8 +849,15 @@ Status WiredTigerRecoveryUnit::setTimestamp(Timestamp timestamp) { return Status::OK(); } - const std::string conf = "commit_timestamp=" + unsignedHex(timestamp.asULL()); - auto rc = session->timestamp_transaction(session, conf.c_str()); + // Avoid heap allocation in favour of a stack allocation. + constexpr auto formatString = "commit_timestamp={:X}"; + constexpr auto bytesToAllocate = std::char_traits<char>::length(formatString) + + (sizeof(decltype(timestamp.asULL())) * 2) + 1; + std::array<char, bytesToAllocate> conf; + auto end = fmt::format_to(conf.begin(), FMT_COMPILE(formatString), timestamp.asULL()); + // Manual null-termination + *end = '\0'; + auto rc = session->timestamp_transaction(session, conf.begin()); if (rc == 0) { _isTimestamped = true; } |