From c4bca20e65afbb77834559247bdda8f541cda16b Mon Sep 17 00:00:00 2001 From: Ian Boros Date: Tue, 7 Apr 2020 21:36:41 -0400 Subject: SERVER-47405 improve performance of sort key generation by avoiding creation of non-OK Status --- src/mongo/db/index/sort_key_generator.cpp | 35 ++++++++++++++----------------- src/mongo/db/index/sort_key_generator.h | 16 +++++++------- 2 files changed, 24 insertions(+), 27 deletions(-) (limited to 'src/mongo') diff --git a/src/mongo/db/index/sort_key_generator.cpp b/src/mongo/db/index/sort_key_generator.cpp index a9415f1100e..152f7dc7886 100644 --- a/src/mongo/db/index/sort_key_generator.cpp +++ b/src/mongo/db/index/sort_key_generator.cpp @@ -214,7 +214,7 @@ Value SortKeyGenerator::getCollationComparisonKey(const Value& val) const { return Value(output.obj().firstElement()); } -StatusWith SortKeyGenerator::extractKeyPart( +boost::optional SortKeyGenerator::extractKeyPart( const Document& doc, const DocumentMetadataFields& metadata, const SortPattern::SortPatternPart& patternPart) const { @@ -223,38 +223,35 @@ StatusWith SortKeyGenerator::extractKeyPart( invariant(!patternPart.expression); auto keyVariant = doc.getNestedFieldNonCaching(*patternPart.fieldPath); - const Status arrayError{ErrorCodes::InternalError, "array along path"}; auto key = stdx::visit( visit_helper::Overloaded{ // In this case, the document has an array along the path given. This means the // document is ineligible for taking the fast path for index key generation. - [&arrayError](Document::TraversesArrayTag) -> StatusWith { - return arrayError; - }, + [](Document::TraversesArrayTag) -> boost::optional { return boost::none; }, // In this case the field was already in the cache (or may not have existed). - [&arrayError](const Value& val) -> StatusWith { + [](const Value& val) -> boost::optional { // The document may have an array at the given path. if (val.getType() == BSONType::Array) { - return arrayError; + return boost::none; } return val; }, // In this case the field was in the backing BSON, and not in the cache. - [&arrayError](BSONElement elt) -> StatusWith { + [](BSONElement elt) -> boost::optional { // The document may have an array at the given path. if (elt.type() == BSONType::Array) { - return arrayError; + return boost::none; } return Value(elt); }, - [](stdx::monostate none) -> StatusWith { return Value(); }, + [](stdx::monostate none) -> boost::optional { return Value(); }, }, keyVariant); - if (!key.isOK()) { - return key; + if (!key) { + return boost::none; } - plainKey = key.getValue(); + plainKey = std::move(*key); } else { invariant(patternPart.expression); // ExpressionMeta expects metadata to be attached to the document. @@ -269,8 +266,8 @@ StatusWith SortKeyGenerator::extractKeyPart( return plainKey.missing() ? Value{BSONNULL} : getCollationComparisonKey(plainKey); } -StatusWith SortKeyGenerator::extractKeyFast(const Document& doc, - const DocumentMetadataFields& metadata) const { +boost::optional SortKeyGenerator::extractKeyFast( + const Document& doc, const DocumentMetadataFields& metadata) const { if (_sortPattern.isSingleElementKey()) { return extractKeyPart(doc, metadata, _sortPattern[0]); } @@ -279,12 +276,12 @@ StatusWith SortKeyGenerator::extractKeyFast(const Document& doc, keys.reserve(_sortPattern.size()); for (auto&& keyPart : _sortPattern) { auto extractedKey = extractKeyPart(doc, metadata, keyPart); - if (!extractedKey.isOK()) { + if (!extractedKey) { // We can't use the fast path, so bail out. return extractedKey; } - keys.push_back(std::move(extractedKey.getValue())); + keys.push_back(std::move(*extractedKey)); } return Value{std::move(keys)}; } @@ -307,8 +304,8 @@ Value SortKeyGenerator::computeSortKeyFromDocument(const Document& doc, const DocumentMetadataFields& metadata) const { // This fast pass directly generates a Value. auto fastKey = extractKeyFast(doc, metadata); - if (fastKey.isOK()) { - return std::move(fastKey.getValue()); + if (fastKey) { + return std::move(*fastKey); } // Compute the key through the slow path, which generates a serialized BSON sort key (taking a diff --git a/src/mongo/db/index/sort_key_generator.h b/src/mongo/db/index/sort_key_generator.h index dd4b5031d05..d9b73c75c38 100644 --- a/src/mongo/db/index/sort_key_generator.h +++ b/src/mongo/db/index/sort_key_generator.h @@ -103,22 +103,22 @@ private: // the appropriate metadata if '_sortHasMeta' is true. StatusWith computeSortKeyFromDocumentWithoutMetadata(const BSONObj& obj) const; - // Returns the sort key for 'doc' based on the SortPattern, or ErrorCodes::InternalError if an - // array is encountered during sort key generation. + // Returns the sort key for 'doc' based on the SortPattern, or boost::none if an array is + // encountered during sort key generation. // // Note that this function will ignore any metadata (e.g., textScore, randVal), in 'doc' but // will instead read from the 'metadata' variable. - StatusWith extractKeyFast(const Document& doc, - const DocumentMetadataFields& metadata) const; + boost::optional extractKeyFast(const Document& doc, + const DocumentMetadataFields& metadata) const; // Extracts the sort key component described by 'keyPart' from 'doc' and returns it. Returns - // ErrorCodes::InternalError if the path for 'keyPart' contains an array in 'doc'. + // boost::none if the path for 'keyPart' contains an array in 'doc'. // // Note that this function will ignore any metadata (e.g., textScore, randVal), in 'doc' but // will instead read from the 'metadata' variable. - StatusWith extractKeyPart(const Document& doc, - const DocumentMetadataFields& metadata, - const SortPattern::SortPatternPart& keyPart) const; + boost::optional extractKeyPart(const Document& doc, + const DocumentMetadataFields& metadata, + const SortPattern::SortPatternPart& keyPart) const; // Returns the sort key for 'doc' based on the SortPattern. Note this is in the BSONObj format - // with empty field names. -- cgit v1.2.1