From e95c1625acdaed28ddb9ebda5c293e307e8ee284 Mon Sep 17 00:00:00 2001 From: Ian Boros Date: Wed, 1 Apr 2020 22:02:17 -0400 Subject: SERVER-47328 optimize MR by avoiding repeated creation of RuntimeConstants --- src/mongo/db/pipeline/expression_context.h | 4 ++-- src/mongo/db/pipeline/variables.cpp | 32 ++++++++++-------------------- src/mongo/db/pipeline/variables.h | 13 ++++++++---- 3 files changed, 21 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/mongo/db/pipeline/expression_context.h b/src/mongo/db/pipeline/expression_context.h index 96f9f538837..cbb0aab0c4b 100644 --- a/src/mongo/db/pipeline/expression_context.h +++ b/src/mongo/db/pipeline/expression_context.h @@ -257,7 +257,7 @@ public: _resolvedNamespaces = std::move(resolvedNamespaces); } - auto getRuntimeConstants() const { + const RuntimeConstants& getRuntimeConstants() const { return variables.getRuntimeConstants(); } @@ -273,7 +273,7 @@ public: uassert(31264, "Cannot run server-side javascript without the javascript engine enabled", getGlobalScriptEngine()); - RuntimeConstants runtimeConstants = getRuntimeConstants(); + const auto& runtimeConstants = getRuntimeConstants(); const boost::optional isMapReduceCommand = runtimeConstants.getIsMapReduce(); if (inMongos) { invariant(!forceLoadOfStoredProcedures); diff --git a/src/mongo/db/pipeline/variables.cpp b/src/mongo/db/pipeline/variables.cpp index 8a79c23f7ca..c76b12cabef 100644 --- a/src/mongo/db/pipeline/variables.cpp +++ b/src/mongo/db/pipeline/variables.cpp @@ -136,7 +136,7 @@ Value Variables::getValue(Id id, const Document& root) const { return Value(); case Variables::kNowId: case Variables::kClusterTimeId: - if (auto it = _runtimeConstants.find(id); it != _runtimeConstants.end()) { + if (auto it = _runtimeConstantsMap.find(id); it != _runtimeConstantsMap.end()) { return it->second; } @@ -169,40 +169,28 @@ Document Variables::getDocument(Id id, const Document& root) const { return Document(); } -RuntimeConstants Variables::getRuntimeConstants() const { - RuntimeConstants constants; - - if (auto it = _runtimeConstants.find(kNowId); it != _runtimeConstants.end()) { - constants.setLocalNow(it->second.getDate()); - } - if (auto it = _runtimeConstants.find(kClusterTimeId); it != _runtimeConstants.end()) { - constants.setClusterTime(it->second.getTimestamp()); - } - if (auto it = _runtimeConstants.find(kJsScopeId); it != _runtimeConstants.end()) { - constants.setJsScope(it->second.getDocument().toBson()); - } - if (auto it = _runtimeConstants.find(kIsMapReduceId); it != _runtimeConstants.end()) { - constants.setIsMapReduce(it->second.getBool()); - } - - return constants; +const RuntimeConstants& Variables::getRuntimeConstants() const { + invariant(_runtimeConstants); + return *_runtimeConstants; } void Variables::setRuntimeConstants(const RuntimeConstants& constants) { - _runtimeConstants[kNowId] = Value(constants.getLocalNow()); + invariant(!_runtimeConstants); + _runtimeConstantsMap[kNowId] = Value(constants.getLocalNow()); // We use a null Timestamp to indicate that the clusterTime is not available; this can happen if // the logical clock is not running. We do not use boost::optional because this would allow the // IDL to serialize a RuntimConstants without clusterTime, which should always be an error. if (!constants.getClusterTime().isNull()) { - _runtimeConstants[kClusterTimeId] = Value(constants.getClusterTime()); + _runtimeConstantsMap[kClusterTimeId] = Value(constants.getClusterTime()); } if (constants.getJsScope()) { - _runtimeConstants[kJsScopeId] = Value(constants.getJsScope().get()); + _runtimeConstantsMap[kJsScopeId] = Value(constants.getJsScope().get()); } if (constants.getIsMapReduce()) { - _runtimeConstants[kIsMapReduceId] = Value(constants.getIsMapReduce().get()); + _runtimeConstantsMap[kIsMapReduceId] = Value(constants.getIsMapReduce().get()); } + _runtimeConstants = constants; } void Variables::setDefaultRuntimeConstants(OperationContext* opCtx) { diff --git a/src/mongo/db/pipeline/variables.h b/src/mongo/db/pipeline/variables.h index b0035054c52..da9d6100518 100644 --- a/src/mongo/db/pipeline/variables.h +++ b/src/mongo/db/pipeline/variables.h @@ -136,12 +136,14 @@ public: } /** - * Serializes runtime constants. This is used to send the constants to shards. + * Return a reference to an object which represents the variables which are considered "runtime + * constants." It is a programming error to call this function without having called + * setRuntimeConstants(). */ - RuntimeConstants getRuntimeConstants() const; + const RuntimeConstants& getRuntimeConstants() const; /** - * Deserialize runtime constants. + * Set the runtime constants. It is a programming error to call this more than once. */ void setRuntimeConstants(const RuntimeConstants& constants); @@ -184,7 +186,10 @@ private: IdGenerator _idGenerator; stdx::unordered_map _values; - stdx::unordered_map _runtimeConstants; + stdx::unordered_map _runtimeConstantsMap; + + // Populated after construction. Should not be set more than once. + boost::optional _runtimeConstants; }; /** -- cgit v1.2.1