From b0e48211b3cbda845bd18c3283fe0d5f5dcd98c6 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Mon, 15 Mar 2021 22:56:51 -0400 Subject: SERVER-55180 Convert SBE from std::string_view to StringData Remove implicit StringData <=> string_view conversions --- src/mongo/base/string_data.h | 18 ----- src/mongo/db/exec/sbe/expressions/expression.h | 6 +- .../db/exec/sbe/expressions/sbe_concat_test.cpp | 3 +- .../db/exec/sbe/expressions/sbe_regex_test.cpp | 7 +- src/mongo/db/exec/sbe/parser/parser.cpp | 4 +- src/mongo/db/exec/sbe/sbe_filter_test.cpp | 3 +- src/mongo/db/exec/sbe/sbe_hash_agg_test.cpp | 3 +- src/mongo/db/exec/sbe/sbe_hash_join_test.cpp | 1 - src/mongo/db/exec/sbe/sbe_plan_stage_test.cpp | 1 - src/mongo/db/exec/sbe/sbe_sort_test.cpp | 1 - src/mongo/db/exec/sbe/sbe_sorted_merge_test.cpp | 1 - src/mongo/db/exec/sbe/sbe_test.cpp | 25 ++++--- src/mongo/db/exec/sbe/sbe_unique_test.cpp | 1 - src/mongo/db/exec/sbe/stages/ix_scan.cpp | 2 +- src/mongo/db/exec/sbe/stages/ix_scan.h | 2 +- src/mongo/db/exec/sbe/util/debug_print.cpp | 12 ++-- src/mongo/db/exec/sbe/util/debug_print.h | 8 +-- src/mongo/db/exec/sbe/values/bson.cpp | 14 ++-- src/mongo/db/exec/sbe/values/bson.h | 4 +- src/mongo/db/exec/sbe/values/slot.h | 2 +- src/mongo/db/exec/sbe/values/value.cpp | 83 ++++++++++++---------- src/mongo/db/exec/sbe/values/value.h | 53 +++++++------- .../sbe/values/value_serialize_for_sorter_test.cpp | 10 +-- src/mongo/db/exec/sbe/vm/datetime.cpp | 6 +- src/mongo/db/exec/sbe/vm/vm.cpp | 64 +++++++---------- src/mongo/db/exec/sbe/vm/vm.h | 6 +- src/mongo/db/pipeline/expression.cpp | 13 +--- src/mongo/db/query/sbe_stage_builder.cpp | 27 +++---- .../db/query/sbe_stage_builder_expression.cpp | 34 +++++---- src/mongo/db/query/sbe_stage_builder_filter.cpp | 4 +- src/mongo/db/query/sbe_stage_builder_helpers.cpp | 16 ++--- src/mongo/db/query/sbe_stage_builder_helpers.h | 4 +- .../db/query/sbe_stage_builder_index_scan.cpp | 18 ++--- .../db/query/sbe_stage_builder_projection.cpp | 20 +++--- 34 files changed, 207 insertions(+), 269 deletions(-) diff --git a/src/mongo/base/string_data.h b/src/mongo/base/string_data.h index bc2ee4ffc36..eb762771a77 100644 --- a/src/mongo/base/string_data.h +++ b/src/mongo/base/string_data.h @@ -89,12 +89,6 @@ public: */ StringData(const std::string& s) : StringData(s.data(), s.length(), TrustedInitTag()) {} - /** - * Implicitly convert a std::string_view to a StringData. We can use the trusted - * init path because string_view::data() points to length() bytes of data. - */ - StringData(std::string_view s) : StringData(s.data(), s.length(), TrustedInitTag()) {} - /** * Constructs a StringData with an explicit length. 'c' must * either be nullptr (in which case len must be zero), or be a @@ -111,18 +105,6 @@ public: return toString(); } - /** - * Implicitly convert to a std::string_view. - */ - operator std::string_view() const { - // std::string_view produces undefined behaviour if [pointer, pointer + size) is not a valid - // range. To fix this we explicitly use default constructor if StringData contains nullptr. - if (MONGO_unlikely(rawData() == nullptr)) { - return {}; - } - return {rawData(), size()}; - } - /** * Constructs a StringData with begin and end iterators. begin points to the beginning of the * string. end points to the position past the end of the string. In a null-terminated string, diff --git a/src/mongo/db/exec/sbe/expressions/expression.h b/src/mongo/db/exec/sbe/expressions/expression.h index 4e811337cc3..f52acef32ca 100644 --- a/src/mongo/db/exec/sbe/expressions/expression.h +++ b/src/mongo/db/exec/sbe/expressions/expression.h @@ -317,7 +317,7 @@ auto makeSV(Args&&... args) { class EConstant final : public EExpression { public: EConstant(value::TypeTags tag, value::Value val) : _tag(tag), _val(val) {} - EConstant(std::string_view str) { + EConstant(StringData str) { // Views are non-owning so we have to make a copy. std::tie(_tag, _val) = value::makeNewString(str); } @@ -448,7 +448,7 @@ private: */ class EFunction final : public EExpression { public: - EFunction(std::string_view name, std::vector> args) : _name(name) { + EFunction(StringData name, std::vector> args) : _name(name) { _nodes = std::move(args); validateNodes(); } @@ -513,7 +513,7 @@ private: */ class EFail final : public EExpression { public: - EFail(ErrorCodes::Error code, std::string_view message) : _code(code) { + EFail(ErrorCodes::Error code, StringData message) : _code(code) { std::tie(_messageTag, _messageVal) = value::makeNewString(message); } diff --git a/src/mongo/db/exec/sbe/expressions/sbe_concat_test.cpp b/src/mongo/db/exec/sbe/expressions/sbe_concat_test.cpp index 857704fb5b5..4275ae03eee 100644 --- a/src/mongo/db/exec/sbe/expressions/sbe_concat_test.cpp +++ b/src/mongo/db/exec/sbe/expressions/sbe_concat_test.cpp @@ -33,8 +33,7 @@ namespace mongo::sbe { class SBEConcatTest : public EExpressionTestFixture { protected: - void runAndAssertExpression(const vm::CodeFragment* compiledExpr, - std::string_view expectedVal) { + void runAndAssertExpression(const vm::CodeFragment* compiledExpr, StringData expectedVal) { auto [tag, val] = runCompiledExpression(compiledExpr); value::ValueGuard guard(tag, val); diff --git a/src/mongo/db/exec/sbe/expressions/sbe_regex_test.cpp b/src/mongo/db/exec/sbe/expressions/sbe_regex_test.cpp index 2e3c87789cb..8486a7c65f8 100644 --- a/src/mongo/db/exec/sbe/expressions/sbe_regex_test.cpp +++ b/src/mongo/db/exec/sbe/expressions/sbe_regex_test.cpp @@ -32,8 +32,7 @@ namespace mongo::sbe { class SBERegexTest : public EExpressionTestFixture { protected: - void runAndAssertRegexCompile(const vm::CodeFragment* compiledExpr, - std::string_view regexString) { + void runAndAssertRegexCompile(const vm::CodeFragment* compiledExpr, StringData regexString) { auto [tag, val] = runCompiledExpression(compiledExpr); value::ValueGuard guard(tag, val); @@ -53,7 +52,7 @@ protected: } void runAndAssertFindExpression(const vm::CodeFragment* compiledExpr, - std::string_view expectedMatch, + StringData expectedMatch, int idx) { auto [tag, val] = runCompiledExpression(compiledExpr); value::ValueGuard guard(tag, val); @@ -72,7 +71,7 @@ protected: ASSERT_EQUALS(value::numericCast(idxTag, idxVal), idx); } - void addMatchResult(value::Array* arrayPtr, std::string_view matchStr, int32_t idx) { + void addMatchResult(value::Array* arrayPtr, StringData matchStr, int32_t idx) { auto [objTag, objVal] = value::makeNewObject(); value::ValueGuard objGuard{objTag, objVal}; auto obj = value::getObjectView(objVal); diff --git a/src/mongo/db/exec/sbe/parser/parser.cpp b/src/mongo/db/exec/sbe/parser/parser.cpp index 19fe41378ef..a426b9d9a8d 100644 --- a/src/mongo/db/exec/sbe/parser/parser.cpp +++ b/src/mongo/db/exec/sbe/parser/parser.cpp @@ -1161,7 +1161,7 @@ std::unique_ptr Parser::walkPathValue(AstQuery& ast, std::move(inputStage), getCurrentPlanNodeId(), outputSlot, - makeE("getField"sv, + makeE("getField"_sd, makeEs(makeE(inputSlot), makeE(ast.nodes[0]->identifier)))); } @@ -1172,7 +1172,7 @@ std::unique_ptr Parser::walkPathValue(AstQuery& ast, makeProjectStage(std::move(inputStage), getCurrentPlanNodeId(), traverseIn, - makeE("getField"sv, + makeE("getField"_sd, makeEs(makeE(inputSlot), makeE(ast.nodes[0]->identifier)))); auto in = makeS( diff --git a/src/mongo/db/exec/sbe/sbe_filter_test.cpp b/src/mongo/db/exec/sbe/sbe_filter_test.cpp index eb7c7c05214..15a34975c9f 100644 --- a/src/mongo/db/exec/sbe/sbe_filter_test.cpp +++ b/src/mongo/db/exec/sbe/sbe_filter_test.cpp @@ -33,7 +33,6 @@ #include "mongo/platform/basic.h" -#include #include "mongo/db/exec/sbe/sbe_plan_stage_test.h" #include "mongo/db/exec/sbe/stages/filter.h" @@ -148,7 +147,7 @@ TEST_F(FilterStageTest, FilterIsNumberTest) { // Build a FilterStage whose filter expression is "isNumber(scanSlot)". auto filter = makeS>( std::move(scanStage), - makeE("isNumber"sv, makeEs(makeE(scanSlot))), + makeE("isNumber"_sd, makeEs(makeE(scanSlot))), kEmptyPlanNodeId); return std::make_pair(scanSlot, std::move(filter)); diff --git a/src/mongo/db/exec/sbe/sbe_hash_agg_test.cpp b/src/mongo/db/exec/sbe/sbe_hash_agg_test.cpp index 281a7cf0684..2c3bd3d335d 100644 --- a/src/mongo/db/exec/sbe/sbe_hash_agg_test.cpp +++ b/src/mongo/db/exec/sbe/sbe_hash_agg_test.cpp @@ -33,7 +33,6 @@ #include "mongo/platform/basic.h" -#include #include "mongo/db/exec/sbe/sbe_plan_stage_test.h" #include "mongo/db/exec/sbe/stages/hash_agg.h" @@ -115,7 +114,7 @@ TEST_F(HashAggStageTest, HashAggAddToSetTest) { auto [expectedTag, expectedVal] = value::makeNewArray(); value::ValueGuard expectedGuard{expectedTag, expectedVal}; - for (auto&& sv : std::array{"Aa", "BB", "cc", "dD"}) { + for (auto&& sv : std::array{"Aa", "BB", "cc", "dD"}) { auto [tag, val] = value::makeNewString(sv); value::getArrayView(expectedVal)->push_back(tag, val); } diff --git a/src/mongo/db/exec/sbe/sbe_hash_join_test.cpp b/src/mongo/db/exec/sbe/sbe_hash_join_test.cpp index 956831cc8e0..fc9b18a2fdc 100644 --- a/src/mongo/db/exec/sbe/sbe_hash_join_test.cpp +++ b/src/mongo/db/exec/sbe/sbe_hash_join_test.cpp @@ -33,7 +33,6 @@ #include "mongo/platform/basic.h" -#include #include "mongo/db/exec/sbe/sbe_plan_stage_test.h" #include "mongo/db/exec/sbe/stages/hash_join.h" diff --git a/src/mongo/db/exec/sbe/sbe_plan_stage_test.cpp b/src/mongo/db/exec/sbe/sbe_plan_stage_test.cpp index 473ffbe5510..0782f0bdc42 100644 --- a/src/mongo/db/exec/sbe/sbe_plan_stage_test.cpp +++ b/src/mongo/db/exec/sbe/sbe_plan_stage_test.cpp @@ -36,7 +36,6 @@ #include "mongo/db/exec/sbe/sbe_plan_stage_test.h" -#include #include "mongo/logv2/log.h" diff --git a/src/mongo/db/exec/sbe/sbe_sort_test.cpp b/src/mongo/db/exec/sbe/sbe_sort_test.cpp index 1d4574f2d50..83b59daa535 100644 --- a/src/mongo/db/exec/sbe/sbe_sort_test.cpp +++ b/src/mongo/db/exec/sbe/sbe_sort_test.cpp @@ -29,7 +29,6 @@ #include "mongo/platform/basic.h" -#include #include "mongo/db/exec/sbe/sbe_plan_stage_test.h" #include "mongo/db/exec/sbe/stages/sort.h" diff --git a/src/mongo/db/exec/sbe/sbe_sorted_merge_test.cpp b/src/mongo/db/exec/sbe/sbe_sorted_merge_test.cpp index 37cad8d4532..009106f8c59 100644 --- a/src/mongo/db/exec/sbe/sbe_sorted_merge_test.cpp +++ b/src/mongo/db/exec/sbe/sbe_sorted_merge_test.cpp @@ -29,7 +29,6 @@ #include "mongo/platform/basic.h" -#include #include "mongo/db/exec/sbe/sbe_plan_stage_test.h" #include "mongo/db/exec/sbe/stages/sorted_merge.h" diff --git a/src/mongo/db/exec/sbe/sbe_test.cpp b/src/mongo/db/exec/sbe/sbe_test.cpp index 74460db8e2c..ad7529e96bd 100644 --- a/src/mongo/db/exec/sbe/sbe_test.cpp +++ b/src/mongo/db/exec/sbe/sbe_test.cpp @@ -35,16 +35,15 @@ namespace mongo::sbe { TEST(SBEValues, Basic) { - using namespace std::literals; { - const auto [tag, val] = value::makeNewString("small"sv); + const auto [tag, val] = value::makeNewString("small"_sd); ASSERT_EQUALS(tag, value::TypeTags::StringSmall); value::releaseValue(tag, val); } { - const auto [tag, val] = value::makeNewString("not so small string"sv); + const auto [tag, val] = value::makeNewString("not so small string"_sd); ASSERT_EQUALS(tag, value::TypeTags::StringBig); value::releaseValue(tag, val); @@ -53,11 +52,11 @@ TEST(SBEValues, Basic) { const auto [tag, val] = value::makeNewObject(); auto obj = value::getObjectView(val); - const auto [fieldTag, fieldVal] = value::makeNewString("not so small string"sv); - obj->push_back("field"sv, fieldTag, fieldVal); + const auto [fieldTag, fieldVal] = value::makeNewString("not so small string"_sd); + obj->push_back("field"_sd, fieldTag, fieldVal); ASSERT_EQUALS(obj->size(), 1); - const auto [checkTag, checkVal] = obj->getField("field"sv); + const auto [checkTag, checkVal] = obj->getField("field"_sd); ASSERT_EQUALS(fieldTag, checkTag); ASSERT_EQUALS(fieldVal, checkVal); @@ -68,7 +67,7 @@ TEST(SBEValues, Basic) { const auto [tag, val] = value::makeNewArray(); auto obj = value::getArrayView(val); - const auto [fieldTag, fieldVal] = value::makeNewString("not so small string"sv); + const auto [fieldTag, fieldVal] = value::makeNewString("not so small string"_sd); obj->push_back(fieldTag, fieldVal); ASSERT_EQUALS(obj->size(), 1); @@ -198,15 +197,15 @@ TEST(SBEValues, HashCompound) { { auto [tag1, val1] = value::makeNewObject(); auto obj1 = value::getObjectView(val1); - obj1->push_back("a"sv, value::TypeTags::NumberInt32, value::bitcastFrom(-5)); - obj1->push_back("b"sv, value::TypeTags::NumberInt32, value::bitcastFrom(-6)); - obj1->push_back("c"sv, value::TypeTags::NumberInt32, value::bitcastFrom(-7)); + obj1->push_back("a"_sd, value::TypeTags::NumberInt32, value::bitcastFrom(-5)); + obj1->push_back("b"_sd, value::TypeTags::NumberInt32, value::bitcastFrom(-6)); + obj1->push_back("c"_sd, value::TypeTags::NumberInt32, value::bitcastFrom(-7)); auto [tag2, val2] = value::makeNewObject(); auto obj2 = value::getObjectView(val2); - obj2->push_back("a"sv, value::TypeTags::NumberDouble, value::bitcastFrom(-5.0)); - obj2->push_back("b"sv, value::TypeTags::NumberDouble, value::bitcastFrom(-6.0)); - obj2->push_back("c"sv, value::TypeTags::NumberDouble, value::bitcastFrom(-7.0)); + obj2->push_back("a"_sd, value::TypeTags::NumberDouble, value::bitcastFrom(-5.0)); + obj2->push_back("b"_sd, value::TypeTags::NumberDouble, value::bitcastFrom(-6.0)); + obj2->push_back("c"_sd, value::TypeTags::NumberDouble, value::bitcastFrom(-7.0)); ASSERT_EQUALS(value::hashValue(tag1, val1), value::hashValue(tag2, val2)); diff --git a/src/mongo/db/exec/sbe/sbe_unique_test.cpp b/src/mongo/db/exec/sbe/sbe_unique_test.cpp index 08ed98c1723..812b7383b1e 100644 --- a/src/mongo/db/exec/sbe/sbe_unique_test.cpp +++ b/src/mongo/db/exec/sbe/sbe_unique_test.cpp @@ -29,7 +29,6 @@ #include "mongo/platform/basic.h" -#include #include "mongo/db/exec/sbe/sbe_plan_stage_test.h" #include "mongo/db/exec/sbe/stages/unique.h" diff --git a/src/mongo/db/exec/sbe/stages/ix_scan.cpp b/src/mongo/db/exec/sbe/stages/ix_scan.cpp index 854af856cd2..8e70ccd2004 100644 --- a/src/mongo/db/exec/sbe/stages/ix_scan.cpp +++ b/src/mongo/db/exec/sbe/stages/ix_scan.cpp @@ -39,7 +39,7 @@ namespace mongo::sbe { IndexScanStage::IndexScanStage(CollectionUUID collUuid, - std::string_view indexName, + StringData indexName, bool forward, boost::optional recordSlot, boost::optional recordIdSlot, diff --git a/src/mongo/db/exec/sbe/stages/ix_scan.h b/src/mongo/db/exec/sbe/stages/ix_scan.h index da10c9bf126..63c583764ab 100644 --- a/src/mongo/db/exec/sbe/stages/ix_scan.h +++ b/src/mongo/db/exec/sbe/stages/ix_scan.h @@ -60,7 +60,7 @@ namespace mongo::sbe { class IndexScanStage final : public PlanStage { public: IndexScanStage(CollectionUUID collUuid, - std::string_view indexName, + StringData indexName, bool forward, boost::optional recordSlot, boost::optional recordIdSlot, diff --git a/src/mongo/db/exec/sbe/util/debug_print.cpp b/src/mongo/db/exec/sbe/util/debug_print.cpp index 939779be8de..e3d831b5ab5 100644 --- a/src/mongo/db/exec/sbe/util/debug_print.cpp +++ b/src/mongo/db/exec/sbe/util/debug_print.cpp @@ -92,20 +92,20 @@ std::string DebugPrinter::print(const std::vector& blocks) { break; } - std::string_view sv(b.str); + StringData sv(b.str); if (!sv.empty()) { - if (sv.front() == '`') { - sv.remove_prefix(1); + if (*sv.begin() == '`') { + sv = sv.substr(1); if (!ret.empty() && ret.back() == ' ') { ret.resize(ret.size() - 1, 0); } } - if (!sv.empty() && sv.back() == '`') { - sv.remove_suffix(1); + if (!sv.empty() && *(sv.end() - 1) == '`') { + sv = sv.substr(0, sv.size() - 1); addSpace = false; } if (!sv.empty()) { - ret.append(sv); + ret.append(sv.begin(), sv.end()); if (addSpace) { ret.append(" "); } diff --git a/src/mongo/db/exec/sbe/util/debug_print.h b/src/mongo/db/exec/sbe/util/debug_print.h index 19e29d7bdf4..a11bb24c75c 100644 --- a/src/mongo/db/exec/sbe/util/debug_print.h +++ b/src/mongo/db/exec/sbe/util/debug_print.h @@ -60,16 +60,16 @@ public: Command cmd; std::string str; - Block(std::string_view s) : cmd(cmdNone), str(s) {} + Block(StringData s) : cmd(cmdNone), str(s) {} - Block(Command c, std::string_view s) : cmd(c), str(s) {} + Block(Command c, StringData s) : cmd(c), str(s) {} Block(Command c) : cmd(c) {} }; DebugPrinter(bool colorConsole = false) : _colorConsole(colorConsole) {} - static void addKeyword(std::vector& ret, std::string_view k) { + static void addKeyword(std::vector& ret, StringData k) { ret.emplace_back(Block::cmdColorCyan); ret.emplace_back(Block{Block::cmdNoneNoSpace, k}); ret.emplace_back(Block::cmdColorNone); @@ -92,7 +92,7 @@ public: ret.emplace_back(Block{Block::cmdNoneNoSpace, " "}); } - static void addIdentifier(std::vector& ret, std::string_view k) { + static void addIdentifier(std::vector& ret, StringData k) { ret.emplace_back(Block::cmdColorGreen); ret.emplace_back(Block{Block::cmdNoneNoSpace, k}); ret.emplace_back(Block::cmdColorNone); diff --git a/src/mongo/db/exec/sbe/values/bson.cpp b/src/mongo/db/exec/sbe/values/bson.cpp index ea5f50b7e58..6a67127bd6f 100644 --- a/src/mongo/db/exec/sbe/values/bson.cpp +++ b/src/mongo/db/exec/sbe/values/bson.cpp @@ -290,8 +290,7 @@ void convertToBsonObj(ArrayBuilder& builder, value::ArrayEnumerator arr) { case value::TypeTags::StringSmall: case value::TypeTags::StringBig: case value::TypeTags::bsonString: { - auto sv = value::getStringView(tag, val); - builder.append(StringData{sv.data(), sv.size()}); + builder.append(value::getStringView(tag, val)); break; } case value::TypeTags::Array: { @@ -385,11 +384,9 @@ template void convertToBsonObj(UniqueBSONObjBuilder& build template void appendValueToBsonObj(ObjBuilder& builder, - std::string_view nameSV, + StringData name, value::TypeTags tag, value::Value val) { - StringData name{nameSV.data(), nameSV.size()}; - switch (tag) { case value::TypeTags::Nothing: break; @@ -421,8 +418,7 @@ void appendValueToBsonObj(ObjBuilder& builder, case value::TypeTags::StringSmall: case value::TypeTags::StringBig: case value::TypeTags::bsonString: { - auto sv = value::getStringView(tag, val); - builder.append(name, StringData{sv.data(), sv.size()}); + builder.append(name, value::getStringView(tag, val)); break; } case value::TypeTags::Array: { @@ -485,11 +481,11 @@ void appendValueToBsonObj(ObjBuilder& builder, } template void appendValueToBsonObj(BSONObjBuilder& builder, - std::string_view name, + StringData name, value::TypeTags tag, value::Value val); template void appendValueToBsonObj(UniqueBSONObjBuilder& builder, - std::string_view name, + StringData name, value::TypeTags tag, value::Value val); } // namespace bson diff --git a/src/mongo/db/exec/sbe/values/bson.h b/src/mongo/db/exec/sbe/values/bson.h index a8839d511fa..af37f80f76b 100644 --- a/src/mongo/db/exec/sbe/values/bson.h +++ b/src/mongo/db/exec/sbe/values/bson.h @@ -42,7 +42,7 @@ std::pair convertFrom(bool view, const char* advance(const char* be, size_t fieldNameSize); inline auto fieldNameView(const char* be) noexcept { - return std::string_view{be + 1}; + return StringData{be + 1}; } template @@ -53,7 +53,7 @@ void convertToBsonObj(ObjBuilder& builder, value::Object* obj); template void appendValueToBsonObj(ObjBuilder& builder, - std::string_view name, + StringData name, value::TypeTags tag, value::Value val); } // namespace bson diff --git a/src/mongo/db/exec/sbe/values/slot.h b/src/mongo/db/exec/sbe/values/slot.h index fbfc7239d3b..44fcde13d1d 100644 --- a/src/mongo/db/exec/sbe/values/slot.h +++ b/src/mongo/db/exec/sbe/values/slot.h @@ -633,7 +633,7 @@ void readKeyStringValueIntoAccessors( template using SlotMap = absl::flat_hash_map; using SlotAccessorMap = SlotMap; -using FieldAccessorMap = absl::flat_hash_map>; +using FieldAccessorMap = StringMap>; using SlotSet = absl::flat_hash_set; using SlotVector = std::vector; diff --git a/src/mongo/db/exec/sbe/values/value.cpp b/src/mongo/db/exec/sbe/values/value.cpp index 3522679d78f..9fd512ea9d0 100644 --- a/src/mongo/db/exec/sbe/values/value.cpp +++ b/src/mongo/db/exec/sbe/values/value.cpp @@ -44,21 +44,32 @@ namespace mongo { namespace sbe { namespace value { +namespace { +template +auto abslHash(const T& val) { + if constexpr (std::is_same_v) { + return absl::Hash{}(absl::string_view{val.rawData(), val.size()}); + } else { + return absl::Hash{}(val); + } +} +} // namespace + std::pair makeCopyBsonRegex(const BsonRegex& regex) { auto buffer = std::make_unique(regex.byteSize()); memcpy(buffer.get(), regex.data(), regex.byteSize()); return {TypeTags::bsonRegex, bitcastFrom(buffer.release())}; } -std::pair makeNewBsonRegex(std::string_view pattern, std::string_view flags) { +std::pair makeNewBsonRegex(StringData pattern, StringData flags) { // Add 2 to account NULL bytes after pattern and flags. auto totalSize = pattern.size() + flags.size() + 2; auto buffer = std::make_unique(totalSize); auto rawBuffer = buffer.get(); // Copy pattern first and flags after it. - memcpy(rawBuffer, pattern.data(), pattern.size()); - memcpy(rawBuffer + pattern.size() + 1, flags.data(), flags.size()); + memcpy(rawBuffer, pattern.rawData(), pattern.size()); + memcpy(rawBuffer + pattern.size() + 1, flags.rawData(), flags.size()); // Ensure NULL byte is placed after each part. rawBuffer[pattern.size()] = '\0'; @@ -66,7 +77,7 @@ std::pair makeNewBsonRegex(std::string_view pattern, std::strin return {TypeTags::bsonRegex, bitcastFrom(buffer.release())}; } -std::pair makeCopyBsonJavascript(std::string_view code) { +std::pair makeCopyBsonJavascript(StringData code) { auto [_, strVal] = makeBigString(code); return {TypeTags::bsonJavascript, strVal}; } @@ -76,7 +87,7 @@ std::pair makeCopyKeyString(const KeyString::Value& inKey) { return {TypeTags::ksValue, bitcastFrom(k)}; } -std::pair makeNewPcreRegex(std::string_view pattern, std::string_view options) { +std::pair makeNewPcreRegex(StringData pattern, StringData options) { auto regex = std::make_unique(pattern, options); return {TypeTags::pcreRegex, bitcastFrom(regex.release())}; } @@ -94,11 +105,11 @@ void PcreRegex::_compile() { uassert(5073402, str::stream() << "Invalid Regex: " << compile_error, _pcrePtr != nullptr); } -int PcreRegex::execute(std::string_view stringView, int startPos, std::vector& buf) { +int PcreRegex::execute(StringData stringView, int startPos, std::vector& buf) { return pcre_exec(_pcrePtr, nullptr, - stringView.data(), - stringView.length(), + stringView.rawData(), + stringView.size(), startPos, 0, &(buf.front()), @@ -417,11 +428,11 @@ void writeValueToStream(T& stream, TypeTags tag, Value val) { case TypeTags::StringBig: case TypeTags::bsonString: { auto sv = getStringView(tag, val); - if (sv.length() <= kStringMaxDisplayLength) { - stream << '"' << StringData{sv.data(), sv.size()} << '"'; + if (sv.size() <= kStringMaxDisplayLength) { + stream << '"' << sv << '"'; } else { auto sub = sv.substr(0, kStringMaxDisplayLength); - stream << '"' << StringData{sub.data(), sub.size()} << '"' << "..."; + stream << '"' << sub << '"' << "..."; } break; } @@ -595,36 +606,35 @@ BSONType tagToType(TypeTags tag) noexcept { std::size_t hashValue(TypeTags tag, Value val, const CollatorInterface* collator) noexcept { switch (tag) { case TypeTags::NumberInt32: - return absl::Hash{}(bitcastTo(val)); + return abslHash(bitcastTo(val)); case TypeTags::RecordId: case TypeTags::NumberInt64: - return absl::Hash{}(bitcastTo(val)); + return abslHash(bitcastTo(val)); case TypeTags::NumberDouble: { // Force doubles to integers for hashing. auto dbl = bitcastTo(val); if (auto asInt = representAs(dbl); asInt) { - return absl::Hash{}(*asInt); + return abslHash(*asInt); } else { // Doubles not representable as int64_t will hash as doubles. - return absl::Hash{}(dbl); + return abslHash(dbl); } } case TypeTags::NumberDecimal: { // Force decimals to integers for hashing. auto dec = bitcastTo(val); if (auto asInt = representAs(dec); asInt) { - return absl::Hash{}(*asInt); + return abslHash(*asInt); } else if (auto asDbl = representAs(dec); asDbl) { - return absl::Hash{}(*asDbl); + return abslHash(*asDbl); } else { - return absl::Hash{}(dec.getValue().low64) ^ - absl::Hash{}(dec.getValue().high64); + return abslHash(dec.getValue().low64) ^ abslHash(dec.getValue().high64); } } case TypeTags::Date: - return absl::Hash{}(bitcastTo(val)); + return abslHash(bitcastTo(val)); case TypeTags::Timestamp: - return absl::Hash{}(bitcastTo(val)); + return abslHash(bitcastTo(val)); case TypeTags::Boolean: return bitcastTo(val); case TypeTags::Null: @@ -637,18 +647,15 @@ std::size_t hashValue(TypeTags tag, Value val, const CollatorInterface* collator case TypeTags::bsonString: { auto sv = getStringView(tag, val); if (collator) { - auto key = collator->getComparisonKey(StringData{sv.data(), sv.size()}); - auto keyData = key.getKeyData(); - return absl::Hash{}( - std::string_view{keyData.rawData(), keyData.size()}); + return abslHash(collator->getComparisonKey(sv).getKeyData()); } else { - return absl::Hash{}(sv); + return abslHash(sv); } } case TypeTags::ObjectId: { auto id = getObjectIdView(val); - return absl::Hash{}(readFromMemory(id->data())) ^ - absl::Hash{}(readFromMemory(id->data() + 8)); + return abslHash(readFromMemory(id->data())) ^ + abslHash(readFromMemory(id->data() + 8)); } case TypeTags::ksValue: { return getKeyStringView(val)->hash(); @@ -690,19 +697,19 @@ std::size_t hashValue(TypeTags tag, Value val, const CollatorInterface* collator memcpy(buffer, getRawPointerView(val), size); // Hash as if it is 64bit integer. - return absl::Hash{}(readFromMemory(buffer)); + return abslHash(readFromMemory(buffer)); } else { // Hash only the first 8 bytes. It should be enough. - return absl::Hash{}( + return abslHash( readFromMemory(getRawPointerView(val) + sizeof(uint32_t))); } } case TypeTags::bsonRegex: { auto regex = getBsonRegexView(val); - return absl::Hash{}(regex.dataView()); + return abslHash(regex.dataView()); } case TypeTags::bsonJavascript: - return absl::Hash{}(getBsonJavascriptView(val)); + return abslHash(getBsonJavascriptView(val)); default: break; } @@ -715,7 +722,7 @@ std::size_t hashValue(TypeTags tag, Value val, const CollatorInterface* collator * guarantees that the result will be exactlty -1, 0, or 1, which is important, because not all * comparison functions make that guarantee. * - * The std::string_view::compare(basic_string_view s) function, for example, only promises that it + * The StringData::compare(basic_string_view s) function, for example, only promises that it * will return a value less than 0 in the case that 'this' is less than 's,' whereas we want to * return exactly -1. */ @@ -761,9 +768,7 @@ std::pair compareValue(TypeTags lhsTag, auto lhsStr = getStringView(lhsTag, lhsValue); auto rhsStr = getStringView(rhsTag, rhsValue); - auto result = comparator ? comparator->compare(StringData{lhsStr.data(), lhsStr.size()}, - StringData{rhsStr.data(), rhsStr.size()}) - : lhsStr.compare(rhsStr); + auto result = comparator ? comparator->compare(lhsStr, rhsStr) : lhsStr.compare(rhsStr); return {TypeTags::NumberInt32, bitcastFrom(compareHelper(result, 0))}; } else if (lhsTag == TypeTags::Date && rhsTag == TypeTags::Date) { @@ -969,19 +974,19 @@ bool ObjectEnumerator::advance() { } } -std::string_view ObjectEnumerator::getFieldName() const { +StringData ObjectEnumerator::getFieldName() const { using namespace std::literals; if (_object) { if (_index < _object->size()) { return _object->field(_index); } else { - return ""sv; + return ""_sd; } } else { if (*_objectCurrent != 0) { return bson::fieldNameView(_objectCurrent); } else { - return ""sv; + return ""_sd; } } } diff --git a/src/mongo/db/exec/sbe/values/value.h b/src/mongo/db/exec/sbe/values/value.h index 31ade47676d..a70a48bbbee 100644 --- a/src/mongo/db/exec/sbe/values/value.h +++ b/src/mongo/db/exec/sbe/values/value.h @@ -422,7 +422,7 @@ public: } } - void push_back(std::string_view name, TypeTags tag, Value val) { + void push_back(StringData name, TypeTags tag, Value val) { if (tag != TypeTags::Nothing) { ValueGuard guard{tag, val}; // Reserve space in all vectors, they are the same size. We arbitrarily picked _typeTags @@ -437,7 +437,7 @@ public: } } - std::pair getField(std::string_view field) { + std::pair getField(StringData field) { for (size_t idx = 0; idx < _typeTags.size(); ++idx) { if (_names[idx] == field) { return {_typeTags[idx], _values[idx]}; @@ -597,12 +597,11 @@ private: */ class PcreRegex { public: - PcreRegex(std::string_view pattern, std::string_view options) - : _pattern(pattern), _options(options) { + PcreRegex(StringData pattern, StringData options) : _pattern(pattern), _options(options) { _compile(); } - PcreRegex(std::string_view pattern) : PcreRegex(pattern, "") {} + PcreRegex(StringData pattern) : PcreRegex(pattern, "") {} PcreRegex(const PcreRegex& other) : PcreRegex(other._pattern, other._options) {} @@ -639,7 +638,7 @@ public: * = 0 there was a match, but not enough space in the buffer * > 0 the number of matches */ - int execute(std::string_view input, int startPos, std::vector& buf); + int execute(StringData input, int startPos, std::vector& buf); size_t getNumberCaptures() const; @@ -715,7 +714,7 @@ inline size_t getStringLength(TypeTags tag, const Value& val) noexcept { /** * getStringView() should be preferred over getRawStringView() where possible. */ -inline std::string_view getStringView(TypeTags tag, const Value& val) noexcept { +inline StringData getStringView(TypeTags tag, const Value& val) noexcept { return {getRawStringView(tag, val), getStringLength(tag, val)}; } @@ -776,9 +775,9 @@ inline uint8_t* getBSONBinDataCompat(TypeTags tag, Value val) { } } -inline bool canUseSmallString(std::string_view input) { +inline bool canUseSmallString(StringData input) { auto length = input.size(); - auto ptr = input.data(); + auto ptr = input.rawData(); auto end = ptr + length; return length <= kSmallStringMaxLength && std::find(ptr, end, '\0') == end; } @@ -787,18 +786,18 @@ inline bool canUseSmallString(std::string_view input) { * Callers must check that canUseSmallString() returns true before calling this function. * makeNewString() should be preferred over makeSmallString() where possible. */ -inline std::pair makeSmallString(std::string_view input) { +inline std::pair makeSmallString(StringData input) { dassert(canUseSmallString(input)); Value smallString{0}; auto buf = getRawStringView(TypeTags::StringSmall, smallString); - memcpy(buf, input.data(), input.size()); + memcpy(buf, input.rawData(), input.size()); return {TypeTags::StringSmall, smallString}; } -inline std::pair makeBigString(std::string_view input) { +inline std::pair makeBigString(StringData input) { auto len = input.size(); - auto ptr = input.data(); + auto ptr = input.rawData(); invariant(len < static_cast(std::numeric_limits::max())); @@ -810,7 +809,7 @@ inline std::pair makeBigString(std::string_view input) { return {TypeTags::StringBig, reinterpret_cast(buf)}; } -inline std::pair makeNewString(std::string_view input) { +inline std::pair makeNewString(StringData input) { if (canUseSmallString(input)) { return makeSmallString(input); } else { @@ -886,7 +885,7 @@ inline KeyString::Value* getKeyStringView(Value val) noexcept { return reinterpret_cast(val); } -std::pair makeNewPcreRegex(std::string_view pattern, std::string_view options); +std::pair makeNewPcreRegex(StringData pattern, StringData options); std::pair makeCopyPcreRegex(const PcreRegex& regex); @@ -923,13 +922,13 @@ struct BsonRegex { BsonRegex(const char* rawValue) { pattern = rawValue; // We add 1 to account NULL byte after pattern. - flags = pattern.data() + pattern.size() + 1; + flags = pattern.rawData() + pattern.size() + 1; } - BsonRegex(std::string_view pattern, std::string_view flags) : pattern(pattern), flags(flags) { + BsonRegex(StringData pattern, StringData flags) : pattern(pattern), flags(flags) { // Ensure that flags follow right after pattern in memory. Otherwise 'dataView()' may return - // invalid 'std::string_view' object. - invariant(pattern.data() + pattern.size() + 1 == flags.data()); + // invalid 'StringData' object. + invariant(pattern.rawData() + pattern.size() + 1 == flags.rawData()); } size_t byteSize() const { @@ -938,15 +937,15 @@ struct BsonRegex { } const char* data() const { - return pattern.data(); + return pattern.rawData(); } - std::string_view dataView() const { + StringData dataView() const { return {data(), byteSize()}; } - std::string_view pattern; - std::string_view flags; + StringData pattern; + StringData flags; }; inline BsonRegex getBsonRegexView(Value val) noexcept { @@ -955,13 +954,13 @@ inline BsonRegex getBsonRegexView(Value val) noexcept { std::pair makeCopyBsonRegex(const BsonRegex& regex); -std::pair makeNewBsonRegex(std::string_view pattern, std::string_view flags); +std::pair makeNewBsonRegex(StringData pattern, StringData flags); -inline std::string_view getBsonJavascriptView(Value val) noexcept { +inline StringData getBsonJavascriptView(Value val) noexcept { return getStringView(TypeTags::StringBig, val); } -std::pair makeCopyBsonJavascript(std::string_view code); +std::pair makeCopyBsonJavascript(StringData code); std::pair makeCopyKeyString(const KeyString::Value& inKey); @@ -1146,7 +1145,7 @@ public: } } std::pair getViewOfValue() const; - std::string_view getFieldName() const; + StringData getFieldName() const; bool atEnd() const { if (_object) { diff --git a/src/mongo/db/exec/sbe/values/value_serialize_for_sorter_test.cpp b/src/mongo/db/exec/sbe/values/value_serialize_for_sorter_test.cpp index 766bdac983a..3eedbc5dfbb 100644 --- a/src/mongo/db/exec/sbe/values/value_serialize_for_sorter_test.cpp +++ b/src/mongo/db/exec/sbe/values/value_serialize_for_sorter_test.cpp @@ -58,16 +58,16 @@ TEST(ValueSerializeForSorter, Serialize) { testData->push_back(value::TypeTags::MaxKey, 0); testData->push_back(value::TypeTags::bsonUndefined, 0); - std::string_view smallString = "perfect"; + StringData smallString = "perfect"; invariant(sbe::value::canUseSmallString(smallString)); - std::string_view bigString = "too big string to fit into value"; + StringData bigString = "too big string to fit into value"; invariant(!sbe::value::canUseSmallString(bigString)); - std::string_view smallStringWithNull = "a\0b"; + StringData smallStringWithNull = "a\0b"; invariant(smallStringWithNull.size() <= sbe::value::kSmallStringMaxLength); - std::string_view bigStringWithNull = "too big string \0 to fit into value"; + StringData bigStringWithNull = "too big string \0 to fit into value"; invariant(bigStringWithNull.size() > sbe::value::kSmallStringMaxLength); - std::vector stringCases = { + std::vector stringCases = { smallString, smallStringWithNull, bigString, diff --git a/src/mongo/db/exec/sbe/vm/datetime.cpp b/src/mongo/db/exec/sbe/vm/datetime.cpp index 09c4188ea17..84839a4a2d4 100644 --- a/src/mongo/db/exec/sbe/vm/datetime.cpp +++ b/src/mongo/db/exec/sbe/vm/datetime.cpp @@ -45,9 +45,7 @@ bool isValidTimezone(value::TypeTags timezoneTag, return false; } auto timezoneStringView = value::getStringView(timezoneTag, timezoneValue); - return timezoneStringView.empty() || - timezoneDB->isTimeZoneIdentifier( - StringData{timezoneStringView.data(), timezoneStringView.size()}); + return timezoneStringView.empty() || timezoneDB->isTimeZoneIdentifier(timezoneStringView); } TimeZone getTimezone(value::TypeTags timezoneTag, @@ -57,7 +55,7 @@ TimeZone getTimezone(value::TypeTags timezoneTag, if (timezoneStr.empty()) { return timezoneDB->utcZone(); } else { - return timezoneDB->getTimeZone(StringData{timezoneStr.data(), timezoneStr.size()}); + return timezoneDB->getTimeZone(timezoneStr); } } diff --git a/src/mongo/db/exec/sbe/vm/vm.cpp b/src/mongo/db/exec/sbe/vm/vm.cpp index dd207101ee6..09361aaea04 100644 --- a/src/mongo/db/exec/sbe/vm/vm.cpp +++ b/src/mongo/db/exec/sbe/vm/vm.cpp @@ -750,12 +750,9 @@ std::tuple ByteCode::aggLast(value::TypeTag } -bool hasSeparatorAt(size_t idx, std::string_view input, std::string_view separator) { - if (separator.size() + idx > input.size()) { - return false; - } - - return input.compare(idx, separator.size(), separator) == 0; +bool hasSeparatorAt(size_t idx, StringData input, StringData separator) { + return (idx + separator.size() <= input.size()) && + input.substr(idx, separator.size()) == separator; } std::tuple ByteCode::builtinSplit(ArityType arity) { @@ -775,7 +772,7 @@ std::tuple ByteCode::builtinSplit(ArityType size_t splitStart = 0; size_t splitPos; - while ((splitPos = input.find(separator, splitStart)) != std::string_view::npos) { + while ((splitPos = input.find(separator, splitStart)) != std::string::npos) { auto [tag, val] = value::makeNewString(input.substr(splitStart, splitPos - splitStart)); arr->push_back(tag, val); @@ -835,7 +832,7 @@ std::tuple ByteCode::builtinDropFields(Arit } else if (tagInObj == value::TypeTags::Object) { auto objRoot = value::getObjectView(valInObj); for (size_t idx = 0; idx < objRoot->size(); ++idx) { - std::string_view sv(objRoot->field(idx)); + StringData sv(objRoot->field(idx)); if (restrictFieldsSet.count(sv) == 0) { @@ -947,7 +944,7 @@ std::tuple ByteCode::builtinNewKeyString(Ar kb.appendNumberLong(num); } else if (value::isString(tag)) { auto str = value::getStringView(tag, val); - kb.appendString(StringData{str.data(), str.length()}); + kb.appendString(str); } else { uasserted(4822802, "unsuppored key string type"); } @@ -1154,20 +1151,16 @@ std::tuple ByteCode::builtinReplaceOne(Arit return {false, value::TypeTags::Nothing, 0}; } - auto inputStrView = value::getStringView(typeTagInputStr, valueInputStr); - auto findStrView = value::getStringView(typeTagFindStr, valueFindStr); - auto replacementStrView = value::getStringView(typeTagReplacementStr, valueReplacementStr); + auto input = value::getStringView(typeTagInputStr, valueInputStr); + auto find = value::getStringView(typeTagFindStr, valueFindStr); + auto replacement = value::getStringView(typeTagReplacementStr, valueReplacementStr); // If find string is empty, return nothing, since an empty find will match every position in a // string. - if (findStrView.empty()) { + if (find.empty()) { return {false, value::TypeTags::Nothing, 0}; } - auto input = StringData(inputStrView.data(), inputStrView.length()); - auto find = StringData(findStrView.data(), findStrView.length()); - auto replacement = StringData(replacementStrView.data(), replacementStrView.length()); - // If find string is not found, return the original string. size_t startIndex = input.find(find); if (startIndex == std::string::npos) { @@ -1182,8 +1175,7 @@ std::tuple ByteCode::builtinReplaceOne(Arit output << input.substr(endIndex); auto strData = output.stringData(); - auto [outputStrTypeTag, outputStrValue] = - sbe::value::makeNewString({strData.rawData(), strData.size()}); + auto [outputStrTypeTag, outputStrValue] = sbe::value::makeNewString(strData); return {true, outputStrTypeTag, outputStrValue}; } @@ -1321,9 +1313,7 @@ std::tuple builtinDateHelper( invariant(timeZoneDB); auto tzString = value::getStringView(typeTagTz, valueTz); - const auto tz = tzString == "" - ? timeZoneDB->utcZone() - : timeZoneDB->getTimeZone(StringData{tzString.data(), tzString.size()}); + const auto tz = tzString == "" ? timeZoneDB->utcZone() : timeZoneDB->getTimeZone(tzString); auto date = computeDateFn(tz, @@ -1858,8 +1848,7 @@ std::tuple ByteCode::builtinConcat(ArityTyp if (!value::isString(tag)) { return {false, value::TypeTags::Nothing, 0}; } - auto sv = sbe::value::getStringView(tag, value); - result << StringData{sv.data(), sv.size()}; + result << sbe::value::getStringView(tag, value); } auto [strTag, strValue] = sbe::value::makeNewString(result.str()); @@ -1956,7 +1945,7 @@ std::tuple ByteCode::builtinIndexOfBytes(Ar return {false, value::TypeTags::Nothing, 0}; } // Check for valid bounds. - if (static_cast(startIndex) > str.length()) { + if (static_cast(startIndex) > str.size()) { return {false, value::TypeTags::NumberInt32, value::bitcastFrom(-1)}; } } @@ -2003,7 +1992,7 @@ std::tuple ByteCode::builtinIndexOfCP(Arity return {false, value::TypeTags::Nothing, 0}; } // Check for valid bounds. - if (static_cast(startCodePointIndex) > str.length()) { + if (static_cast(startCodePointIndex) > str.size()) { return {false, value::TypeTags::NumberInt32, value::bitcastFrom(-1)}; } } @@ -2044,7 +2033,7 @@ std::tuple ByteCode::builtinIndexOfCP(Arity byteIndex = startByteIndex; for (codePointIndex = startCodePointIndex; codePointIndex < endCodePointIndex; ++codePointIndex) { - if (str.compare(byteIndex, substr.size(), substr) == 0) { + if (str.substr(byteIndex, substr.size()).compare(substr) == 0) { return { false, value::TypeTags::NumberInt32, value::bitcastFrom(codePointIndex)}; } @@ -2088,7 +2077,7 @@ std::tuple ByteCode::builtinIsTimezone(Arit return {false, value::TypeTags::Boolean, false}; } auto timezoneStr = value::getStringView(timezoneTag, timezoneVal); - if (timezoneDB->isTimeZoneIdentifier((StringData{timezoneStr.data(), timezoneStr.size()}))) { + if (timezoneDB->isTimeZoneIdentifier(timezoneStr)) { return {false, value::TypeTags::Boolean, true}; } return {false, value::TypeTags::Boolean, false}; @@ -2322,7 +2311,7 @@ namespace { * ...} from the result of pcre_exec(). */ std::tuple buildRegexMatchResultObject( - std::string_view inputString, + StringData inputString, const std::vector& capturesBuffer, size_t numCaptures, uint32_t& startBytePos, @@ -2419,7 +2408,7 @@ std::tuple buildRegexMatchResultObject( * returned is true/false. */ std::tuple pcreNextMatch(value::PcreRegex* pcre, - std::string_view inputString, + StringData inputString, std::vector& capturesBuffer, uint32_t& startBytePos, uint32_t& codePointPos, @@ -2454,7 +2443,7 @@ std::tuple pcreNextMatch(value::PcreRegex* */ std::tuple pcreFirstMatch( value::PcreRegex* pcre, - std::string_view inputString, + StringData inputString, bool isMatch = false, std::vector* capturesBuffer = nullptr, uint32_t* startBytePos = nullptr, @@ -2507,16 +2496,15 @@ std::pair collComparisonKey(value::TypeTags tag, // For strings, call CollatorInterface::getComparisonKey() to obtain the comparison key. if (value::isString(tag)) { - auto sv = value::getStringView(tag, val); - auto compKey = collator->getComparisonKey(StringData{sv.data(), sv.size()}); + auto compKey = collator->getComparisonKey(value::getStringView(tag, val)); auto keyData = compKey.getKeyData(); - return value::makeNewString(std::string_view{keyData.rawData(), keyData.size()}); + return value::makeNewString(keyData); } // For collatable types other than strings (such as arrays and objects), we take the slow // path and round-trip the value through BSON. BSONObjBuilder input; - bson::appendValueToBsonObj(input, ""sv, tag, val); + bson::appendValueToBsonObj(input, ""_sd, tag, val); BSONObjBuilder output; CollationIndexKey::collationAwareIndexKeyAppend(input.obj().firstElement(), collator, &output); @@ -2625,8 +2613,8 @@ std::tuple ByteCode::builtinRegexFindAll(Ar startBytePos += str::getCodePointLength(inputString[startBytePos]); ++codePointPos; } else { - startBytePos += matchString.length(); - for (size_t byteIdx = 0; byteIdx < matchString.length(); ++codePointPos) { + startBytePos += matchString.size(); + for (size_t byteIdx = 0; byteIdx < matchString.size(); ++codePointPos) { byteIdx += str::getCodePointLength(matchString[byteIdx]); } } @@ -2801,7 +2789,7 @@ std::tuple ByteCode::builtinHasNullBytes(Ar } auto stringView = value::getStringView(strType, strValue); - auto hasNullBytes = stringView.find('\0') != std::string_view::npos; + auto hasNullBytes = stringView.find('\0') != std::string::npos; return {false, value::TypeTags::Boolean, value::bitcastFrom(hasNullBytes)}; } diff --git a/src/mongo/db/exec/sbe/vm/vm.h b/src/mongo/db/exec/sbe/vm/vm.h index b98f3261d12..1d11e835858 100644 --- a/src/mongo/db/exec/sbe/vm/vm.h +++ b/src/mongo/db/exec/sbe/vm/vm.h @@ -79,10 +79,8 @@ std::pair genericCompare( auto lhsStr = getStringView(lhsTag, lhsValue); auto rhsStr = getStringView(rhsTag, rhsValue); - auto result = op(comparator ? comparator->compare(StringData{lhsStr.data(), lhsStr.size()}, - StringData{rhsStr.data(), rhsStr.size()}) - : lhsStr.compare(rhsStr), - 0); + auto result = + op(comparator ? comparator->compare(lhsStr, rhsStr) : lhsStr.compare(rhsStr), 0); return {value::TypeTags::Boolean, value::bitcastFrom(result)}; } else if (lhsTag == value::TypeTags::Date && rhsTag == value::TypeTags::Date) { diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp index 0db59301a5c..f008c6e7b4c 100644 --- a/src/mongo/db/pipeline/expression.cpp +++ b/src/mongo/db/pipeline/expression.cpp @@ -1972,12 +1972,8 @@ TimeUnit ExpressionDateDiff::convertToTimeUnit(const Value& value) { str::stream() << "$dateDiff requires 'unit' to be a string, but got " << typeName(value.getType()), BSONType::String == value.getType()); - auto valueAsString = value.getStringData(); - return addContextToAssertionException( - [&]() { - return parseTimeUnit(std::string_view{valueAsString.rawData(), valueAsString.size()}); - }, - "$dateDiff parameter 'unit' value parsing failed"_sd); + return addContextToAssertionException([&] { return parseTimeUnit(value.getStringData()); }, + "$dateDiff parameter 'unit' value parsing failed"_sd); } DayOfWeek ExpressionDateDiff::parseStartOfWeek(const Value& value) { @@ -1985,11 +1981,8 @@ DayOfWeek ExpressionDateDiff::parseStartOfWeek(const Value& value) { str::stream() << "$dateDiff requires 'startOfWeek' to be a string, but got " << typeName(value.getType()), BSONType::String == value.getType()); - auto valueAsString = value.getStringData(); return addContextToAssertionException( - [&]() { - return parseDayOfWeek(std::string_view{valueAsString.rawData(), valueAsString.size()}); - }, + [&] { return parseDayOfWeek(value.getStringData()); }, "$dateDiff parameter 'startOfWeek' value parsing failed"_sd); } diff --git a/src/mongo/db/query/sbe_stage_builder.cpp b/src/mongo/db/query/sbe_stage_builder.cpp index 6b99a116b3d..dbbb9093759 100644 --- a/src/mongo/db/query/sbe_stage_builder.cpp +++ b/src/mongo/db/query/sbe_stage_builder.cpp @@ -454,11 +454,10 @@ std::pair, PlanStageSlots> SlotBasedStageBuilder for (auto&& field : vsn->indexKeyPattern) { if (reqs.getIndexKeyBitset()->test(indexKeyPos)) { indexKeySlots.push_back(_slotIdGenerator.generate()); - projections.emplace( - indexKeySlots.back(), - makeFunction("getField"sv, - sbe::makeE(resultSlot), - makeConstant(std::string_view{field.fieldName()}))); + projections.emplace(indexKeySlots.back(), + makeFunction("getField"_sd, + sbe::makeE(resultSlot), + makeConstant(field.fieldName()))); } ++indexKeyPos; } @@ -515,10 +514,7 @@ std::pair, PlanStageSlots> SlotBasedStageBuilder size_t i = 0; for (auto&& elem : ixn->index.keyPattern) { - auto fieldName = elem.fieldNameStringData(); - - mkObjArgs.emplace_back(sbe::makeE( - std::string_view{fieldName.rawData(), fieldName.size()})); + mkObjArgs.emplace_back(sbe::makeE(elem.fieldNameStringData())); mkObjArgs.emplace_back(sbe::makeE((*outputs.getIndexKeySlots())[i++])); } @@ -718,20 +714,19 @@ std::pair, PlanStageSlots> SlotBasedStageBuilder // Generate projection to get the value of the sort key. Ideally, this should be // tracked by a 'reference tracker' at higher level. auto fieldName = part.fieldPath->getFieldName(0); - auto fieldNameSV = std::string_view{fieldName.rawData(), fieldName.size()}; - auto getSortFieldExpr = makeFunction("getField"sv, + auto getSortFieldExpr = makeFunction("getField"_sd, sbe::makeE(outputs.get(kResult)), - sbe::makeE(fieldNameSV)); + sbe::makeE(fieldName)); if (auto collatorSlot = _data.env->getSlotIfExists("collator"_sd); collatorSlot) { - getSortFieldExpr = makeFunction("collComparisonKey"sv, + getSortFieldExpr = makeFunction("collComparisonKey"_sd, std::move(getSortFieldExpr), sbe::makeE(*collatorSlot)); } // According to MQL semantics, missing values are treated as nulls during sorting. - getSortFieldExpr = makeFunction("fillEmpty"sv, + getSortFieldExpr = makeFunction("fillEmpty"_sd, std::move(getSortFieldExpr), makeConstant(sbe::value::TypeTags::Null, 0)); @@ -1367,7 +1362,7 @@ SlotBasedStageBuilder::makeUnionForTailableCollScan(const QuerySolutionNode* roo auto&& [anchorBranchSlots, anchorBranch] = makeUnionBranch(false); anchorBranch = sbe::makeS>( std::move(anchorBranch), - makeNot(makeFunction("exists"sv, sbe::makeE(resumeRecordIdSlot))), + makeNot(makeFunction("exists"_sd, sbe::makeE(resumeRecordIdSlot))), root->nodeId()); // Build a resume branch of the union and add a constant filter on op of it, so that it would @@ -1375,7 +1370,7 @@ SlotBasedStageBuilder::makeUnionForTailableCollScan(const QuerySolutionNode* roo auto&& [resumeBranchSlots, resumeBranch] = makeUnionBranch(true); resumeBranch = sbe::makeS>( sbe::makeS(std::move(resumeBranch), boost::none, 1, root->nodeId()), - sbe::makeE("exists"sv, + sbe::makeE("exists"_sd, sbe::makeEs(sbe::makeE(resumeRecordIdSlot))), root->nodeId()); diff --git a/src/mongo/db/query/sbe_stage_builder_expression.cpp b/src/mongo/db/query/sbe_stage_builder_expression.cpp index 4b0de4bdbfd..45ef557b5a5 100644 --- a/src/mongo/db/query/sbe_stage_builder_expression.cpp +++ b/src/mongo/db/query/sbe_stage_builder_expression.cpp @@ -182,15 +182,12 @@ std::pair generateTraverseHelper( // Generate the projection stage to read a sub-field at the current nested level and bind it // to 'fieldSlot'. - inputStage = makeProject( - std::move(inputStage), - planNodeId, - fieldSlot, - makeFunction( - "getField"sv, sbe::makeE(inputSlot), sbe::makeE([&]() { - auto fieldName = fp.getFieldName(level); - return std::string_view{fieldName.rawData(), fieldName.size()}; - }()))); + inputStage = makeProject(std::move(inputStage), + planNodeId, + fieldSlot, + makeFunction("getField"_sd, + sbe::makeE(inputSlot), + sbe::makeE(fp.getFieldName(level)))); EvalStage innerBranch; if (level == fp.getPathLength() - 1) { @@ -1228,7 +1225,7 @@ public: // Get child expressions. auto startOfWeekExpression = expr->isStartOfWeekSpecified() ? _context->popExpr() : nullptr; auto timezoneExpression = - expr->isTimezoneSpecified() ? _context->popExpr() : makeConstant("UTC"sv); + expr->isTimezoneSpecified() ? _context->popExpr() : makeConstant("UTC"_sd); auto unitExpression = _context->popExpr(); auto endDateExpression = _context->popExpr(); auto startDateExpression = _context->popExpr(); @@ -1247,7 +1244,7 @@ public: // "dateDiff" built-in function does not accept non-string type values for this // parameter. arguments.push_back(sbe::makeE( - unitIsWeekRef.clone(), startOfWeekRef.clone(), makeConstant("sun"sv))); + unitIsWeekRef.clone(), startOfWeekRef.clone(), makeConstant("sun"_sd))); } // Set bindings for the frame. @@ -1257,11 +1254,11 @@ public: bindings.push_back(std::move(timezoneExpression)); if (expr->isStartOfWeekSpecified()) { bindings.push_back(std::move(startOfWeekExpression)); - bindings.push_back(generateIsEqualToStringCheck(unitRef, "week"sv)); + bindings.push_back(generateIsEqualToStringCheck(unitRef, "week"_sd)); } // Create an expression to invoke built-in "dateDiff" function. - auto dateDiffFunctionCall = sbe::makeE("dateDiff"sv, std::move(arguments)); + auto dateDiffFunctionCall = sbe::makeE("dateDiff"_sd, std::move(arguments)); // Create expressions to check that each argument to "dateDiff" function exists, is not // null, and is of the correct type. @@ -2853,7 +2850,7 @@ private: * Creates a boolean expression to check if 'variable' is equal to string 'string'. */ static std::unique_ptr generateIsEqualToStringCheck( - const sbe::EVariable& variable, std::string_view string) { + const sbe::EVariable& variable, StringData string) { return sbe::makeE(sbe::EPrimBinary::logicAnd, makeFunction("isString", variable.clone()), sbe::makeE(sbe::EPrimBinary::eq, @@ -3078,14 +3075,15 @@ private: switch (setOp) { case SetOperation::Difference: return std::make_pair("setDifference"_sd, - collatorSlot ? "collSetDifference"sv : "setDifference"sv); + collatorSlot ? "collSetDifference"_sd + : "setDifference"_sd); case SetOperation::Intersection: return std::make_pair("setIntersection"_sd, - collatorSlot ? "collSetIntersection"sv - : "setIntersection"sv); + collatorSlot ? "collSetIntersection"_sd + : "setIntersection"_sd); case SetOperation::Union: return std::make_pair("setUnion"_sd, - collatorSlot ? "collSetUnion"sv : "setUnion"sv); + collatorSlot ? "collSetUnion"_sd : "setUnion"_sd); default: MONGO_UNREACHABLE; } diff --git a/src/mongo/db/query/sbe_stage_builder_filter.cpp b/src/mongo/db/query/sbe_stage_builder_filter.cpp index 1f4d65eb4ba..9d9c8ebaefa 100644 --- a/src/mongo/db/query/sbe_stage_builder_filter.cpp +++ b/src/mongo/db/query/sbe_stage_builder_filter.cpp @@ -332,13 +332,13 @@ EvalExprStagePair generatePathTraversal(EvalStage inputStage, // Generate the projection stage to read a sub-field at the current nested level and bind it // to 'fieldSlot'. - std::string_view fieldName{fp.getPart(level).rawData(), fp.getPart(level).size()}; + auto fieldName = fp.getPart(level); auto fieldSlot{slotIdGenerator->generate()}; auto fromBranch = makeProject(std::move(inputStage), planNodeId, fieldSlot, - sbe::makeE("getField"sv, + sbe::makeE("getField"_sd, sbe::makeEs(sbe::makeE(inputSlot), sbe::makeE(fieldName)))); diff --git a/src/mongo/db/query/sbe_stage_builder_helpers.cpp b/src/mongo/db/query/sbe_stage_builder_helpers.cpp index 86c5bad1eb2..31f214a9521 100644 --- a/src/mongo/db/query/sbe_stage_builder_helpers.cpp +++ b/src/mongo/db/query/sbe_stage_builder_helpers.cpp @@ -197,7 +197,7 @@ std::unique_ptr makeLimitCoScanTree(PlanNodeId planNodeId, long std::unique_ptr makeFillEmptyFalse(std::unique_ptr e) { using namespace std::literals; - return makeFunction("fillEmpty"sv, + return makeFunction("fillEmpty"_sd, std::move(e), sbe::makeE(sbe::value::TypeTags::Boolean, sbe::value::bitcastFrom(false))); @@ -212,13 +212,13 @@ std::unique_ptr makeVariable(sbe::value::SlotId slotId, std::unique_ptr makeFillEmptyNull(std::unique_ptr e) { using namespace std::literals; return makeFunction( - "fillEmpty"sv, std::move(e), sbe::makeE(sbe::value::TypeTags::Null, 0)); + "fillEmpty"_sd, std::move(e), sbe::makeE(sbe::value::TypeTags::Null, 0)); } std::unique_ptr makeNothingArrayCheck( std::unique_ptr isArrayInput, std::unique_ptr otherwise) { using namespace std::literals; - return sbe::makeE(makeFunction("isArray"sv, std::move(isArrayInput)), + return sbe::makeE(makeFunction("isArray"_sd, std::move(isArrayInput)), sbe::makeE(sbe::value::TypeTags::Nothing, 0), std::move(otherwise)); } @@ -228,15 +228,11 @@ std::unique_ptr generateShardKeyBinding( sbe::value::FrameIdGenerator& frameIdGenerator, std::unique_ptr inputExpr, int level) { - using namespace std::literals; invariant(level >= 0); auto makeGetFieldKeyPattern = [&](std::unique_ptr slot) { - return makeFillEmptyNull( - makeFunction("getField"sv, std::move(slot), sbe::makeE([&]() { - const auto fieldName = keyPatternField[level]; - return std::string_view{fieldName.rawData(), fieldName.size()}; - }()))); + return makeFillEmptyNull(makeFunction( + "getField"_sd, std::move(slot), sbe::makeE(keyPatternField[level]))); }; if (level == keyPatternField.numParts() - 1) { @@ -531,7 +527,7 @@ std::pair> generateVirtu projectSlots.emplace_back(slotIdGenerator->generate()); projections.emplace( projectSlots.back(), - makeFunction("getElement"sv, + makeFunction("getElement"_sd, sbe::makeE(scanSlot), sbe::makeE(sbe::value::TypeTags::NumberInt32, sbe::value::bitcastFrom(i)))); diff --git a/src/mongo/db/query/sbe_stage_builder_helpers.h b/src/mongo/db/query/sbe_stage_builder_helpers.h index d5956b0ca8d..65b3371d034 100644 --- a/src/mongo/db/query/sbe_stage_builder_helpers.h +++ b/src/mongo/db/query/sbe_stage_builder_helpers.h @@ -188,7 +188,7 @@ std::unique_ptr makeFillEmptyFalse(std::unique_ptr -inline std::unique_ptr makeFunction(std::string_view name, Args&&... args) { +inline std::unique_ptr makeFunction(StringData name, Args&&... args) { return sbe::makeE(name, sbe::makeEs(std::forward(args)...)); } @@ -197,7 +197,7 @@ inline auto makeConstant(sbe::value::TypeTags tag, T value) { return sbe::makeE(tag, sbe::value::bitcastFrom(value)); } -inline auto makeConstant(std::string_view str) { +inline auto makeConstant(StringData str) { auto [tag, value] = sbe::value::makeNewString(str); return sbe::makeE(tag, value); } diff --git a/src/mongo/db/query/sbe_stage_builder_index_scan.cpp b/src/mongo/db/query/sbe_stage_builder_index_scan.cpp index 1eee1a968f7..84a20dfd9a4 100644 --- a/src/mongo/db/query/sbe_stage_builder_index_scan.cpp +++ b/src/mongo/db/query/sbe_stage_builder_index_scan.cpp @@ -301,10 +301,10 @@ generateOptimizedMultiIntervalIndexScan( for (auto&& [lowKey, highKey] : intervals) { auto [tag, val] = sbe::value::makeNewObject(); auto obj = sbe::value::getObjectView(val); - obj->push_back("l"sv, + obj->push_back("l"_sd, sbe::value::TypeTags::ksValue, sbe::value::bitcastFrom(lowKey.release())); - obj->push_back("h"sv, + obj->push_back("h"_sd, sbe::value::TypeTags::ksValue, sbe::value::bitcastFrom(highKey.release())); arr->push_back(tag, val); @@ -334,13 +334,13 @@ generateOptimizedMultiIntervalIndexScan( std::move(unwind), planNodeId, lowKeySlot, - sbe::makeE( - "getField"sv, - sbe::makeEs(sbe::makeE(unwindSlot), sbe::makeE("l"sv))), + sbe::makeE("getField"_sd, + sbe::makeEs(sbe::makeE(unwindSlot), + sbe::makeE("l"_sd))), highKeySlot, - sbe::makeE("getField"sv, + sbe::makeE("getField"_sd, sbe::makeEs(sbe::makeE(unwindSlot), - sbe::makeE("h"sv)))); + sbe::makeE("h"_sd)))); auto ixscan = sbe::makeS(collection->uuid(), indexName, @@ -609,14 +609,14 @@ generateGenericMultiIntervalIndexScan(const CollectionPtr& collection, std::move(unionStage), spoolId, makeSlotVector(resultSlot, std::move(indexKeySlots)), - makeNot(makeFunction("isRecordId"sv, sbe::makeE(resultSlot))), + makeNot(makeFunction("isRecordId"_sd, sbe::makeE(resultSlot))), ixn->nodeId()); // Finally, add a filter stage on top to filter out seek keys and return only recordIds. return {resultSlot, sbe::makeS>( std::move(spool), - sbe::makeE("isRecordId"sv, + sbe::makeE("isRecordId"_sd, sbe::makeEs(sbe::makeE(resultSlot))), ixn->nodeId())}; } diff --git a/src/mongo/db/query/sbe_stage_builder_projection.cpp b/src/mongo/db/query/sbe_stage_builder_projection.cpp index 896b36fba27..4bba27c9833 100644 --- a/src/mongo/db/query/sbe_stage_builder_projection.cpp +++ b/src/mongo/db/query/sbe_stage_builder_projection.cpp @@ -463,7 +463,7 @@ public: childLevelStage = sbe::makeS>( std::move(mkBsonStage), - makeFunction("isObject"sv, sbe::makeE(childLevelInputSlot)), + makeFunction("isObject"_sd, sbe::makeE(childLevelInputSlot)), _context->planNodeId); } @@ -497,7 +497,7 @@ public: sbe::makeProjectStage(std::move(parentLevelStage), _context->planNodeId, childLevelInputSlot, - makeFunction("getField"sv, + makeFunction("getField"_sd, sbe::makeE(parentLevelInputSlot), makeConstant(_context->topFrontField()))); } @@ -603,8 +603,8 @@ public: auto isObjectOrArrayExpr = makeBinaryOp( sbe::EPrimBinary::logicOr, - makeFunction("isObject"sv, sbe::makeE(inputArraySlot)), - makeFunction("isArray"sv, sbe::makeE(inputArraySlot))); + makeFunction("isObject"_sd, sbe::makeE(inputArraySlot)), + makeFunction("isArray"_sd, sbe::makeE(inputArraySlot))); return sbe::makeS>(std::move(elemMatchPredicateTree), std::move(isObjectOrArrayExpr), _context->planNodeId); @@ -680,7 +680,7 @@ public: std::move(_context->topLevel().evalStage), _context->planNodeId, inputArraySlot, - makeFunction("getField"sv, + makeFunction("getField"_sd, inputDocumentVariable.clone(), sbe::makeE(_context->topFrontField()))); @@ -688,7 +688,7 @@ public: std::move(fromBranch), _context->planNodeId, traversingAnArrayFlagSlot, - makeFunction("isArray"sv, sbe::makeE(inputArraySlot))); + makeFunction("isArray"_sd, sbe::makeE(inputArraySlot))); auto filteredArraySlot = _context->slotIdGenerator->generate(); auto traverseStage = @@ -813,7 +813,7 @@ public: childLevelStage = sbe::makeS( std::move(childLevelStage), makeLimitCoScanTree(_context->planNodeId), - makeFunction("isObject"sv, sbe::makeE(childLevelInputSlot)), + makeFunction("isObject"_sd, sbe::makeE(childLevelInputSlot)), sbe::makeSV(childLevelObjSlot), sbe::makeSV(childLevelInputSlot), sbe::makeSV(childLevelResultSlot), @@ -831,7 +831,7 @@ public: sbe::makeProjectStage(std::move(parentLevelStage), _context->planNodeId, childLevelInputSlot, - makeFunction("getField"sv, + makeFunction("getField"_sd, sbe::makeE(parentLevelInputSlot), makeConstant(_context->topFrontField()))); } else { @@ -869,7 +869,7 @@ public: using namespace std::literals; auto arrayFromField = - makeFunction("getField"sv, + makeFunction("getField"_sd, sbe::makeE(_context->topLevel().inputSlot), makeConstant(_context->topFrontField())); auto binds = sbe::makeEs(std::move(arrayFromField)); @@ -884,7 +884,7 @@ public: } auto extractSubArrayExpr = sbe::makeE( - makeFunction("isArray"sv, arrayVariable.clone()), + makeFunction("isArray"_sd, arrayVariable.clone()), sbe::makeE("extractSubArray", std::move(arguments)), arrayVariable.clone()); -- cgit v1.2.1