From 19e8c9b64fca099fd6619bcef0f5513a81c6327d Mon Sep 17 00:00:00 2001 From: jsteemann Date: Thu, 5 Sep 2019 13:57:59 -0700 Subject: [PATCH] use c++17's try_emplace if available (#5696) Summary: This avoids rehashing the key in TrackKey() in case the key is not already in the map of tracked keys, which will happen at least once per key used in a transaction. Additionally fix two typos. Pull Request resolved: https://github.com/facebook/rocksdb/pull/5696 Differential Revision: D17210178 Pulled By: lth fbshipit-source-id: 7e2c28e9e505c1d1c1535d435250cf2b191a6fdf --- utilities/transactions/transaction_base.cc | 16 ++++++++++++++-- utilities/transactions/transaction_util.cc | 4 ++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/utilities/transactions/transaction_base.cc b/utilities/transactions/transaction_base.cc index 81f398124..1f4723e54 100644 --- a/utilities/transactions/transaction_base.cc +++ b/utilities/transactions/transaction_base.cc @@ -633,18 +633,30 @@ void TransactionBaseImpl::TrackKey(TransactionKeyMap* key_map, uint32_t cfh_id, const std::string& key, SequenceNumber seq, bool read_only, bool exclusive) { auto& cf_key_map = (*key_map)[cfh_id]; +#ifdef __cpp_lib_unordered_map_try_emplace + // use c++17's try_emplace if available, to avoid rehashing the key + // in case it is not already in the map + auto result = cf_key_map.try_emplace(key, seq); + auto iter = result.first; + if (!result.second && + seq < iter->second.seq) { + // Now tracking this key with an earlier sequence number + iter->second.seq = seq; + } +#else auto iter = cf_key_map.find(key); if (iter == cf_key_map.end()) { - auto result = cf_key_map.emplace(key, TransactionKeyMapInfo(seq)); + auto result = cf_key_map.emplace(key, seq); iter = result.first; } else if (seq < iter->second.seq) { // Now tracking this key with an earlier sequence number iter->second.seq = seq; } +#endif // else we do not update the seq. The smaller the tracked seq, the stronger it // the guarantee since it implies from the seq onward there has not been a // concurrent update to the key. So we update the seq if it implies stronger - // guarantees, i.e., if it is smaller than the existing trakced seq. + // guarantees, i.e., if it is smaller than the existing tracked seq. if (read_only) { iter->second.num_reads++; diff --git a/utilities/transactions/transaction_util.cc b/utilities/transactions/transaction_util.cc index 371448503..5e3c27f09 100644 --- a/utilities/transactions/transaction_util.cc +++ b/utilities/transactions/transaction_util.cc @@ -75,8 +75,8 @@ Status TransactionUtil::CheckKey(DBImpl* db_impl, SuperVersion* sv, if (cache_only) { result = Status::TryAgain( - "Transaction ould not check for conflicts as the MemTable does not " - "countain a long enough history to check write at SequenceNumber: ", + "Transaction could not check for conflicts as the MemTable does not " + "contain a long enough history to check write at SequenceNumber: ", ToString(snap_seq)); } } else if (snap_seq < earliest_seq || min_uncommitted <= earliest_seq) {