summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/query/plan_ranker.cpp16
-rw-r--r--src/mongo/util/str.cpp7
-rw-r--r--src/mongo/util/str.h6
-rw-r--r--src/mongo/util/str_test.cpp10
4 files changed, 32 insertions, 7 deletions
diff --git a/src/mongo/db/query/plan_ranker.cpp b/src/mongo/db/query/plan_ranker.cpp
index 4d3069fb47a..ff2e636a28a 100644
--- a/src/mongo/db/query/plan_ranker.cpp
+++ b/src/mongo/db/query/plan_ranker.cpp
@@ -242,14 +242,16 @@ double PlanRanker::scoreTree(const PlanStageStats* stats) {
double tieBreakers = noFetchBonus + noSortBonus + noIxisectBonus;
double score = baseScore + productivity + tieBreakers;
- str::stream ss;
- ss << "score(" << score << ") = baseScore(" << baseScore << ")"
+ StringBuilder sb;
+ sb << "score(" << str::convertDoubleToString(score) << ") = baseScore("
+ << str::convertDoubleToString(baseScore) << ")"
<< " + productivity((" << stats->common.advanced << " advanced)/(" << stats->common.works
- << " works) = " << productivity << ")"
- << " + tieBreakers(" << noFetchBonus << " noFetchBonus + " << noSortBonus
- << " noSortBonus + " << noIxisectBonus << " noIxisectBonus = " << tieBreakers << ")";
- std::string scoreStr = ss;
- LOG(2) << scoreStr;
+ << " works) = " << str::convertDoubleToString(productivity) << ")"
+ << " + tieBreakers(" << str::convertDoubleToString(noFetchBonus) << " noFetchBonus + "
+ << str::convertDoubleToString(noSortBonus) << " noSortBonus + "
+ << str::convertDoubleToString(noIxisectBonus)
+ << " noIxisectBonus = " << str::convertDoubleToString(tieBreakers) << ")";
+ LOG(2) << sb.str();
if (internalQueryForceIntersectionPlans.load()) {
if (hasStage(STAGE_AND_HASH, stats) || hasStage(STAGE_AND_SORTED, stats)) {
diff --git a/src/mongo/util/str.cpp b/src/mongo/util/str.cpp
index 7209fd90e2e..0f04497f95f 100644
--- a/src/mongo/util/str.cpp
+++ b/src/mongo/util/str.cpp
@@ -236,4 +236,11 @@ boost::optional<size_t> parseUnsignedBase10Integer(StringData fieldName) {
return boost::none;
}
+std::string convertDoubleToString(double d, int prec) {
+ char buffer[StringBuilder::MONGO_DBL_SIZE];
+ int z = snprintf(buffer, sizeof(buffer), "%.*g", prec, d);
+ invariant(z >= 0);
+ return std::string(buffer);
+}
+
} // namespace mongo::str
diff --git a/src/mongo/util/str.h b/src/mongo/util/str.h
index bddfff282b2..b2ee26dbbdb 100644
--- a/src/mongo/util/str.h
+++ b/src/mongo/util/str.h
@@ -344,4 +344,10 @@ std::string escape(StringData s, bool escape_slash = false);
*/
boost::optional<size_t> parseUnsignedBase10Integer(StringData integer);
+/**
+ * Converts a double to a string with specified precision. If unspecified, default to 17, which is
+ * the maximum decimal precision possible from a standard double.
+ */
+std::string convertDoubleToString(double d, int prec = 17);
+
} // namespace mongo::str
diff --git a/src/mongo/util/str_test.cpp b/src/mongo/util/str_test.cpp
index 68d06b7535c..66ee0f77196 100644
--- a/src/mongo/util/str_test.cpp
+++ b/src/mongo/util/str_test.cpp
@@ -270,4 +270,14 @@ TEST(StringUtilsTest, WhitespaceWithinNumberFailsToParse) {
boost::optional<size_t> result = parseUnsignedBase10Integer(" 10");
ASSERT(!result);
}
+
+TEST(StringUtilsTest, ConvertDoubleToStringWithProperPrecision) {
+ ASSERT_EQUALS(std::string("1.9876543219876543"), convertDoubleToString(1.98765432198765432));
+ ASSERT_EQUALS(std::string("1.987654321"), convertDoubleToString(1.987654321, 10));
+ ASSERT_EQUALS(std::string("1.988"), convertDoubleToString(1.987654321, 4));
+ ASSERT_EQUALS(std::string("6e-07"), convertDoubleToString(6E-7, 10));
+ ASSERT_EQUALS(std::string("6e-07"), convertDoubleToString(6E-7, 6));
+ ASSERT_EQUALS(std::string("0.1000000006"), convertDoubleToString(0.1 + 6E-10, 10));
+ ASSERT_EQUALS(std::string("0.1"), convertDoubleToString(0.1 + 6E-8, 6));
+}
} // namespace mongo::str