summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/storage/key_string_test.cpp198
1 files changed, 108 insertions, 90 deletions
diff --git a/src/mongo/db/storage/key_string_test.cpp b/src/mongo/db/storage/key_string_test.cpp
index b29d1b01da8..01432714ce0 100644
--- a/src/mongo/db/storage/key_string_test.cpp
+++ b/src/mongo/db/storage/key_string_test.cpp
@@ -47,6 +47,7 @@
#include "mongo/db/storage/key_string.h"
#include "mongo/platform/decimal128.h"
#include "mongo/stdx/functional.h"
+#include "mongo/stdx/future.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/hex.h"
#include "mongo/util/log.h"
@@ -382,39 +383,47 @@ TEST_F(KeyStringTest, LotsOfNumbers2) {
}
TEST_F(KeyStringTest, LotsOfNumbers3) {
- const auto V1 = KeyString::Version::V1;
- Decimal128::RoundingPrecision roundingPrecisions[]{Decimal128::kRoundTo15Digits,
- Decimal128::kRoundTo34Digits};
- Decimal128::RoundingMode roundingModes[]{Decimal128::kRoundTowardNegative,
- Decimal128::kRoundTowardPositive};
-
- for (double i = -1100; i < 1100; i++) {
- for (double j = 0; j < 52; j++) {
- for (double k = 0; k < 8; k++) {
- double x = pow(2, i);
- double y = pow(2, i - j);
- double z = pow(2, i - 53 + k);
- double bin = x + y - z;
-
- // In general NaNs don't roundtrip as we only store a single NaN, see the NaNs test.
- if (std::isnan(bin))
- continue;
-
- ROUNDTRIP(version, BSON("" << bin));
- ROUNDTRIP(version, BSON("" << -bin));
-
- if (version < V1)
- continue;
-
- for (auto precision : roundingPrecisions) {
- for (auto mode : roundingModes) {
- Decimal128 rounded = Decimal128(bin, precision, mode);
- ROUNDTRIP(V1, BSON("" << rounded));
- ROUNDTRIP(V1, BSON("" << rounded.negate()));
+ std::vector<stdx::future<void>> futures;
+
+ for (double k = 0; k < 8; k++) {
+ futures.push_back(stdx::async(stdx::launch::async, [k, this] {
+
+ for (double i = -1100; i < 1100; i++) {
+ for (double j = 0; j < 52; j++) {
+ const auto V1 = KeyString::Version::V1;
+ Decimal128::RoundingPrecision roundingPrecisions[]{
+ Decimal128::kRoundTo15Digits, Decimal128::kRoundTo34Digits};
+ Decimal128::RoundingMode roundingModes[]{Decimal128::kRoundTowardNegative,
+ Decimal128::kRoundTowardPositive};
+ double x = pow(2, i);
+ double y = pow(2, i - j);
+ double z = pow(2, i - 53 + k);
+ double bin = x + y - z;
+
+ // In general NaNs don't roundtrip as we only store a single NaN, see the NaNs
+ // test.
+ if (std::isnan(bin))
+ continue;
+
+ ROUNDTRIP(version, BSON("" << bin));
+ ROUNDTRIP(version, BSON("" << -bin));
+
+ if (version < V1)
+ continue;
+
+ for (auto precision : roundingPrecisions) {
+ for (auto mode : roundingModes) {
+ Decimal128 rounded = Decimal128(bin, precision, mode);
+ ROUNDTRIP(V1, BSON("" << rounded));
+ ROUNDTRIP(V1, BSON("" << rounded.negate()));
+ }
}
}
}
- }
+ }));
+ }
+ for (auto&& future : futures) {
+ future.get();
}
}
@@ -757,69 +766,78 @@ void testPermutation(KeyString::Version version,
// Since KeyStrings are compared using memcmp we can assume it provides a total ordering such
// that there won't be cases where (a < b && b < c && !(a < c)). This test still needs to ensure
// that it provides the *correct* total ordering.
+ std::vector<stdx::future<void>> futures;
for (size_t k = 0; k < orderings.size(); k++) {
- BSONObj orderObj = orderings[k];
- Ordering ordering = Ordering::make(orderObj);
- if (debug)
- log() << "ordering: " << orderObj;
-
- std::vector<BSONObj> elements = elementsOrig;
- BSONObjComparator bsonCmp(orderObj,
- BSONObjComparator::FieldNamesMode::kConsider,
- &SimpleStringDataComparator::kInstance);
- std::stable_sort(elements.begin(), elements.end(), bsonCmp.makeLessThan());
-
- for (size_t i = 0; i < elements.size(); i++) {
- const BSONObj& o1 = elements[i];
- if (debug)
- log() << "\to1: " << o1;
- ROUNDTRIP_ORDER(version, o1, ordering);
-
- KeyString k1(version, o1, ordering);
-
- KeyString l1(version, BSON("l" << o1.firstElement()), ordering); // kLess
- KeyString g1(version, BSON("g" << o1.firstElement()), ordering); // kGreater
- ASSERT_LT(l1, k1);
- ASSERT_GT(g1, k1);
-
- if (i + 1 < elements.size()) {
- const BSONObj& o2 = elements[i + 1];
+ futures.push_back(
+ stdx::async(stdx::launch::async, [k, version, elementsOrig, orderings, debug] {
+ BSONObj orderObj = orderings[k];
+ Ordering ordering = Ordering::make(orderObj);
if (debug)
- log() << "\t\t o2: " << o2;
- KeyString k2(version, o2, ordering);
- KeyString g2(version, BSON("g" << o2.firstElement()), ordering);
- KeyString l2(version, BSON("l" << o2.firstElement()), ordering);
-
- int bsonCmp = o1.woCompare(o2, ordering);
- invariant(bsonCmp <= 0); // We should be sorted...
-
- if (bsonCmp == 0) {
- ASSERT_EQ(k1, k2);
- } else {
- ASSERT_LT(k1, k2);
- }
-
- // Test the query encodings using kLess and kGreater
- int firstElementComp = o1.firstElement().woCompare(o2.firstElement());
- if (ordering.descending(1))
- firstElementComp = -firstElementComp;
-
- invariant(firstElementComp <= 0);
-
- if (firstElementComp == 0) {
- // If they share a first element then l1/g1 should equal l2/g2 and l1 should be
- // less than both and g1 should be greater than both.
- ASSERT_EQ(l1, l2);
- ASSERT_EQ(g1, g2);
- ASSERT_LT(l1, k2);
- ASSERT_GT(g1, k2);
- } else {
- // k1 is less than k2. Less(k2) and Greater(k1) should be between them.
- ASSERT_LT(g1, k2);
- ASSERT_GT(l2, k1);
+ log() << "ordering: " << orderObj;
+
+ std::vector<BSONObj> elements = elementsOrig;
+ BSONObjComparator bsonCmp(orderObj,
+ BSONObjComparator::FieldNamesMode::kConsider,
+ &SimpleStringDataComparator::kInstance);
+ std::stable_sort(elements.begin(), elements.end(), bsonCmp.makeLessThan());
+
+ for (size_t i = 0; i < elements.size(); i++) {
+ const BSONObj& o1 = elements[i];
+ if (debug)
+ log() << "\to1: " << o1;
+ ROUNDTRIP_ORDER(version, o1, ordering);
+
+ KeyString k1(version, o1, ordering);
+
+ KeyString l1(version, BSON("l" << o1.firstElement()), ordering); // kLess
+ KeyString g1(version, BSON("g" << o1.firstElement()), ordering); // kGreater
+ ASSERT_LT(l1, k1);
+ ASSERT_GT(g1, k1);
+
+ if (i + 1 < elements.size()) {
+ const BSONObj& o2 = elements[i + 1];
+ if (debug)
+ log() << "\t\t o2: " << o2;
+ KeyString k2(version, o2, ordering);
+ KeyString g2(version, BSON("g" << o2.firstElement()), ordering);
+ KeyString l2(version, BSON("l" << o2.firstElement()), ordering);
+
+ int bsonCmp = o1.woCompare(o2, ordering);
+ invariant(bsonCmp <= 0); // We should be sorted...
+
+ if (bsonCmp == 0) {
+ ASSERT_EQ(k1, k2);
+ } else {
+ ASSERT_LT(k1, k2);
+ }
+
+ // Test the query encodings using kLess and kGreater
+ int firstElementComp = o1.firstElement().woCompare(o2.firstElement());
+ if (ordering.descending(1))
+ firstElementComp = -firstElementComp;
+
+ invariant(firstElementComp <= 0);
+
+ if (firstElementComp == 0) {
+ // If they share a first element then l1/g1 should equal l2/g2 and l1
+ // should
+ // be
+ // less than both and g1 should be greater than both.
+ ASSERT_EQ(l1, l2);
+ ASSERT_EQ(g1, g2);
+ ASSERT_LT(l1, k2);
+ ASSERT_GT(g1, k2);
+ } else {
+ // k1 is less than k2. Less(k2) and Greater(k1) should be between them.
+ ASSERT_LT(g1, k2);
+ ASSERT_GT(l2, k1);
+ }
+ }
}
- }
- }
+ }));
+ }
+ for (auto&& future : futures) {
+ future.get();
}
}