diff options
author | Xiangyu Yao <xiangyu.yao@mongodb.com> | 2019-08-29 05:15:39 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-08-29 05:15:39 +0000 |
commit | ffd486c3ff049abc9f8a2c76b3e2b9dea970c19b (patch) | |
tree | 8e030dff77ff90c04aad143e14d1e2d924a92dcb /src | |
parent | 98413549db019381b09c85299cee53c31e284f17 (diff) | |
download | mongo-ffd486c3ff049abc9f8a2c76b3e2b9dea970c19b.tar.gz |
SERVER-42248 Remove SortedDataInterface::seek() which accepts a BSONObj
Diffstat (limited to 'src')
26 files changed, 444 insertions, 262 deletions
diff --git a/src/mongo/db/catalog/throttle_cursor.cpp b/src/mongo/db/catalog/throttle_cursor.cpp index e6dcb9e4f77..8e2fb2f9745 100644 --- a/src/mongo/db/catalog/throttle_cursor.cpp +++ b/src/mongo/db/catalog/throttle_cursor.cpp @@ -76,9 +76,9 @@ SortedDataInterfaceThrottleCursor::SortedDataInterfaceThrottleCursor( _dataThrottle = dataThrottle; } -boost::optional<IndexKeyEntry> SortedDataInterfaceThrottleCursor::seek(OperationContext* opCtx, - const BSONObj& key) { - boost::optional<IndexKeyEntry> entry = _cursor->seek(key, /*inclusive=*/true); +boost::optional<IndexKeyEntry> SortedDataInterfaceThrottleCursor::seek( + OperationContext* opCtx, const KeyString::Value& key) { + boost::optional<IndexKeyEntry> entry = _cursor->seek(key); if (entry) { const int64_t dataSize = entry->key.objsize() + sizeof(entry->loc.repr()); _dataThrottle->awaitIfNeeded(opCtx, dataSize); diff --git a/src/mongo/db/catalog/throttle_cursor.h b/src/mongo/db/catalog/throttle_cursor.h index 3d41a1f410b..1f67b24b520 100644 --- a/src/mongo/db/catalog/throttle_cursor.h +++ b/src/mongo/db/catalog/throttle_cursor.h @@ -72,7 +72,7 @@ public: const IndexAccessMethod* iam, std::shared_ptr<DataThrottle> dataThrottle); - boost::optional<IndexKeyEntry> seek(OperationContext* opCtx, const BSONObj& key); + boost::optional<IndexKeyEntry> seek(OperationContext* opCtx, const KeyString::Value& key); boost::optional<IndexKeyEntry> next(OperationContext* opCtx); diff --git a/src/mongo/db/catalog/throttle_cursor_test.cpp b/src/mongo/db/catalog/throttle_cursor_test.cpp index 14491efacdc..606e7856b23 100644 --- a/src/mongo/db/catalog/throttle_cursor_test.cpp +++ b/src/mongo/db/catalog/throttle_cursor_test.cpp @@ -46,6 +46,7 @@ namespace mongo { namespace { const NamespaceString kNss = NamespaceString("test.throttleCursor"); +const KeyString::Value kMinKeyString = KeyString::Value(); class ThrottleCursorTest : public CatalogTestFixture { private: @@ -219,7 +220,7 @@ TEST_F(ThrottleCursorTest, TestSortedDataInterfaceThrottleCursorOff) { setMaxMbPerSec(0); Date_t start = getTime(); - ASSERT_TRUE(cursor.seek(opCtx, BSONObj())); + ASSERT_TRUE(cursor.seek(opCtx, kMinKeyString)); int numRecords = 1; while (cursor.next(opCtx)) { @@ -249,7 +250,7 @@ TEST_F(ThrottleCursorTest, TestSortedDataInterfaceThrottleCursorOn) { setMaxMbPerSec(1); Date_t start = getTime(); - ASSERT_TRUE(cursor.seek(opCtx, BSONObj())); + ASSERT_TRUE(cursor.seek(opCtx, kMinKeyString)); int numRecords = 1; while (cursor.next(opCtx)) { @@ -269,7 +270,7 @@ TEST_F(ThrottleCursorTest, TestSortedDataInterfaceThrottleCursorOn) { setMaxMbPerSec(5); Date_t start = getTime(); - ASSERT_TRUE(cursor.seek(opCtx, BSONObj())); + ASSERT_TRUE(cursor.seek(opCtx, kMinKeyString)); int numRecords = 1; while (cursor.next(opCtx)) { @@ -302,7 +303,7 @@ TEST_F(ThrottleCursorTest, TestMixedCursorsWithSharedThrottleOff) { setMaxMbPerSec(10); Date_t start = getTime(); - ASSERT_TRUE(indexCursor.seek(opCtx, BSONObj())); + ASSERT_TRUE(indexCursor.seek(opCtx, kMinKeyString)); int numRecords = 1; while (indexCursor.next(opCtx)) { @@ -345,7 +346,7 @@ TEST_F(ThrottleCursorTest, TestMixedCursorsWithSharedThrottleOn) { setMaxMbPerSec(2); Date_t start = getTime(); - ASSERT_TRUE(indexCursor.seek(opCtx, BSONObj())); + ASSERT_TRUE(indexCursor.seek(opCtx, kMinKeyString)); ASSERT_TRUE(recordCursor.seekExact(opCtx, RecordId(1))); int numRecords = 2; @@ -367,7 +368,7 @@ TEST_F(ThrottleCursorTest, TestMixedCursorsWithSharedThrottleOn) { setMaxMbPerSec(5); Date_t start = getTime(); - ASSERT_TRUE(indexCursor.seek(opCtx, BSONObj())); + ASSERT_TRUE(indexCursor.seek(opCtx, kMinKeyString)); ASSERT_TRUE(recordCursor.seekExact(opCtx, RecordId(1))); int numRecords = 2; diff --git a/src/mongo/db/catalog/validate_adaptor.cpp b/src/mongo/db/catalog/validate_adaptor.cpp index 8f3d690ee76..36bd6a1aff5 100644 --- a/src/mongo/db/catalog/validate_adaptor.cpp +++ b/src/mongo/db/catalog/validate_adaptor.cpp @@ -177,8 +177,10 @@ void ValidateAdaptor::traverseIndex( int interruptInterval = 4096; - // Seeking to BSONObj() is equivalent to seeking to the first entry of an index. - for (auto indexEntry = indexCursor->seek(opCtx, BSONObj()); indexEntry; + KeyString::Builder firstKeyString( + version, BSONObj(), ord, KeyString::Discriminator::kExclusiveBefore); + + for (auto indexEntry = indexCursor->seek(opCtx, firstKeyString.getValueCopy()); indexEntry; indexEntry = indexCursor->next(opCtx)) { if (!(numKeys % interruptInterval)) { opCtx->checkForInterrupt(); diff --git a/src/mongo/db/exec/count_scan.cpp b/src/mongo/db/exec/count_scan.cpp index 55379bd5550..c24f3ef1343 100644 --- a/src/mongo/db/exec/count_scan.cpp +++ b/src/mongo/db/exec/count_scan.cpp @@ -115,7 +115,13 @@ PlanStage::StageState CountScan::doWork(WorkingSetID* out) { _cursor = indexAccessMethod()->newCursor(getOpCtx()); _cursor->setEndPosition(_endKey, _endKeyInclusive); - entry = _cursor->seek(_startKey, _startKeyInclusive, kWantLoc); + auto keyStringForSeek = IndexEntryComparison::makeKeyStringFromBSONKeyForSeek( + _startKey, + indexAccessMethod()->getSortedDataInterface()->getKeyStringVersion(), + indexAccessMethod()->getSortedDataInterface()->getOrdering(), + true, /* forward */ + _startKeyInclusive); + entry = _cursor->seek(keyStringForSeek); } else { entry = _cursor->next(kWantLoc); } diff --git a/src/mongo/db/exec/distinct_scan.cpp b/src/mongo/db/exec/distinct_scan.cpp index 3b18a3e6bbd..3f8c3342e80 100644 --- a/src/mongo/db/exec/distinct_scan.cpp +++ b/src/mongo/db/exec/distinct_scan.cpp @@ -79,7 +79,7 @@ PlanStage::StageState DistinctScan::doWork(WorkingSetID* out) { try { if (!_cursor) _cursor = indexAccessMethod()->newCursor(getOpCtx(), _scanDirection == 1); - kv = _cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + kv = _cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( _seekPoint, indexAccessMethod()->getSortedDataInterface()->getKeyStringVersion(), indexAccessMethod()->getSortedDataInterface()->getOrdering(), diff --git a/src/mongo/db/exec/index_scan.cpp b/src/mongo/db/exec/index_scan.cpp index 4fee1efa50d..cd32deb7c0d 100644 --- a/src/mongo/db/exec/index_scan.cpp +++ b/src/mongo/db/exec/index_scan.cpp @@ -100,7 +100,14 @@ boost::optional<IndexKeyEntry> IndexScan::initIndexScan() { _startKey = _bounds.startKey; _endKey = _bounds.endKey; _indexCursor->setEndPosition(_endKey, _endKeyInclusive); - return _indexCursor->seek(_startKey, _startKeyInclusive); + + KeyString::Value keyStringForSeek = IndexEntryComparison::makeKeyStringFromBSONKeyForSeek( + _startKey, + indexAccessMethod()->getSortedDataInterface()->getKeyStringVersion(), + indexAccessMethod()->getSortedDataInterface()->getOrdering(), + _forward, + _startKeyInclusive); + return _indexCursor->seek(keyStringForSeek); } else { // For single intervals, we can use an optimized scan which checks against the position // of an end cursor. For all other index scans, we fall back on using @@ -108,13 +115,20 @@ boost::optional<IndexKeyEntry> IndexScan::initIndexScan() { if (IndexBoundsBuilder::isSingleInterval( _bounds, &_startKey, &_startKeyInclusive, &_endKey, &_endKeyInclusive)) { _indexCursor->setEndPosition(_endKey, _endKeyInclusive); - return _indexCursor->seek(_startKey, _startKeyInclusive); + + auto keyStringForSeek = IndexEntryComparison::makeKeyStringFromBSONKeyForSeek( + _startKey, + indexAccessMethod()->getSortedDataInterface()->getKeyStringVersion(), + indexAccessMethod()->getSortedDataInterface()->getOrdering(), + _forward, + _startKeyInclusive); + return _indexCursor->seek(keyStringForSeek); } else { _checker.reset(new IndexBoundsChecker(&_bounds, _keyPattern, _direction)); if (!_checker->getStartSeekPoint(&_seekPoint)) return boost::none; - return _indexCursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + return _indexCursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( _seekPoint, indexAccessMethod()->getSortedDataInterface()->getKeyStringVersion(), indexAccessMethod()->getSortedDataInterface()->getOrdering(), @@ -136,7 +150,7 @@ PlanStage::StageState IndexScan::doWork(WorkingSetID* out) { break; case NEED_SEEK: ++_specificStats.seeks; - kv = _indexCursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + kv = _indexCursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( _seekPoint, indexAccessMethod()->getSortedDataInterface()->getKeyStringVersion(), indexAccessMethod()->getSortedDataInterface()->getOrdering(), diff --git a/src/mongo/db/index/wildcard_access_method.cpp b/src/mongo/db/index/wildcard_access_method.cpp index cabf81df2c6..0f483710727 100644 --- a/src/mongo/db/index/wildcard_access_method.cpp +++ b/src/mongo/db/index/wildcard_access_method.cpp @@ -108,7 +108,7 @@ std::set<FieldRef> WildcardAccessMethod::_getMultikeyPathSet( } std::set<FieldRef> multikeyPaths{}; - auto entry = cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + auto entry = cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, getSortedDataInterface()->getKeyStringVersion(), getSortedDataInterface()->getOrdering(), @@ -127,11 +127,12 @@ std::set<FieldRef> WildcardAccessMethod::_getMultikeyPathSet( case IndexBoundsChecker::MUST_ADVANCE: ++stats->numSeeks; - entry = cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( - seekPoint, - getSortedDataInterface()->getKeyStringVersion(), - getSortedDataInterface()->getOrdering(), - kForward)); + entry = + cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( + seekPoint, + getSortedDataInterface()->getKeyStringVersion(), + getSortedDataInterface()->getOrdering(), + kForward)); break; @@ -237,7 +238,14 @@ std::set<FieldRef> WildcardAccessMethod::getMultikeyPathSet( constexpr bool inclusive = true; cursor->setEndPosition(metadataKeyRangeEnd, inclusive); - auto entry = cursor->seek(metadataKeyRangeBegin, inclusive); + + auto keyStringForSeek = IndexEntryComparison::makeKeyStringFromBSONKeyForSeek( + metadataKeyRangeBegin, + getSortedDataInterface()->getKeyStringVersion(), + getSortedDataInterface()->getOrdering(), + true, /* forward */ + inclusive); + auto entry = cursor->seek(keyStringForSeek); ++stats->numSeeks; // Iterate the cursor, copying the multikey paths into an in-memory set. diff --git a/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp b/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp index eba274f6c62..43208813a4c 100644 --- a/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp +++ b/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp @@ -830,16 +830,6 @@ boost::optional<KeyStringEntry> SortedDataInterface::Cursor::seekAfterProcessing return keyStringToKeyStringEntry(_reverseIt->first, _reverseIt->second, _order); } -boost::optional<IndexKeyEntry> SortedDataInterface::Cursor::seek(const BSONObj& key, - bool inclusive, - RequestedInfo) { - BSONObj finalKey = BSONObj::stripFieldNames(key); - const auto discriminator = _forward == inclusive ? KeyString::Discriminator::kExclusiveBefore - : KeyString::Discriminator::kExclusiveAfter; - KeyString::Builder keyString(KeyString::Version::V1, finalKey, _order, discriminator); - return seek(keyString.getValueCopy()); -} - boost::optional<IndexKeyEntry> SortedDataInterface::Cursor::seek(const KeyString::Value& keyString, RequestedInfo parts) { boost::optional<KeyStringEntry> ksValue = seekForKeyString(keyString); diff --git a/src/mongo/db/storage/biggie/biggie_sorted_impl.h b/src/mongo/db/storage/biggie/biggie_sorted_impl.h index 5e208c039e3..36ac080ea04 100644 --- a/src/mongo/db/storage/biggie/biggie_sorted_impl.h +++ b/src/mongo/db/storage/biggie/biggie_sorted_impl.h @@ -120,9 +120,6 @@ public: std::string KSForIdentEnd); virtual void setEndPosition(const BSONObj& key, bool inclusive) override; virtual boost::optional<IndexKeyEntry> next(RequestedInfo parts = kKeyAndLoc) override; - virtual boost::optional<IndexKeyEntry> seek(const BSONObj& key, - bool inclusive, - RequestedInfo parts = kKeyAndLoc) override; virtual boost::optional<IndexKeyEntry> seek(const KeyString::Value& keyString, RequestedInfo parts = kKeyAndLoc) override; virtual boost::optional<KeyStringEntry> seekForKeyString( diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.cpp b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.cpp index 7e5f213a0c9..7f1982a4602 100644 --- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.cpp +++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.cpp @@ -302,9 +302,7 @@ public: seekEndCursor(); } - boost::optional<IndexKeyEntry> seek(const BSONObj& key, - bool inclusive, - RequestedInfo) override { + boost::optional<IndexKeyEntry> _seek(const BSONObj& key, bool inclusive, RequestedInfo) { if (key.isEmpty()) { _it = inclusive ? _data.begin() : _data.end(); _isEOF = (_it == _data.end()); @@ -349,7 +347,7 @@ public: } boost::optional<IndexKeyEntry> seekExact(const BSONObj& key, RequestedInfo) { - auto kv = seek(key, true, kKeyAndLoc); + auto kv = _seek(key, true, kKeyAndLoc); if (kv && kv->key.woCompare(key, BSONObj(), /*considerFieldNames*/ false) == 0) return kv; return {}; diff --git a/src/mongo/db/storage/index_entry_comparison.cpp b/src/mongo/db/storage/index_entry_comparison.cpp index 14823066fba..b0d3ae2da56 100644 --- a/src/mongo/db/storage/index_entry_comparison.cpp +++ b/src/mongo/db/storage/index_entry_comparison.cpp @@ -169,10 +169,8 @@ BSONObj IndexEntryComparison::makeQueryObject(const BSONObj& keyPrefix, return bb.obj(); } -KeyString::Value IndexEntryComparison::makeKeyStringForSeekPoint(const IndexSeekPoint& seekPoint, - KeyString::Version version, - Ordering ord, - bool isForward) { +KeyString::Value IndexEntryComparison::makeKeyStringFromSeekPointForSeek( + const IndexSeekPoint& seekPoint, KeyString::Version version, Ordering ord, bool isForward) { BSONObj key = IndexEntryComparison::makeQueryObject(seekPoint, isForward); const auto discriminator = isForward ? KeyString::Discriminator::kExclusiveBefore @@ -182,6 +180,20 @@ KeyString::Value IndexEntryComparison::makeKeyStringForSeekPoint(const IndexSeek return builder.getValueCopy(); } +KeyString::Value IndexEntryComparison::makeKeyStringFromBSONKeyForSeek(const BSONObj& bsonKey, + KeyString::Version version, + Ordering ord, + bool isForward, + bool inclusive) { + BSONObj finalKey = BSONObj::stripFieldNames(bsonKey); + KeyString::Builder builder(version, + finalKey, + ord, + isForward == inclusive ? KeyString::Discriminator::kExclusiveBefore + : KeyString::Discriminator::kExclusiveAfter); + return builder.getValueCopy(); +} + Status buildDupKeyErrorStatus(const BSONObj& key, const NamespaceString& collectionNamespace, const std::string& indexName, diff --git a/src/mongo/db/storage/index_entry_comparison.h b/src/mongo/db/storage/index_entry_comparison.h index 35dc1def735..8d2d60ad99e 100644 --- a/src/mongo/db/storage/index_entry_comparison.h +++ b/src/mongo/db/storage/index_entry_comparison.h @@ -233,7 +233,7 @@ public: } /** - * Encodes the SeekPoint into a Keystring object suitable to pass in to compare(). + * Encodes the SeekPoint into a KeyString object suitable to pass in to compare(). * * A KeyString is used for seeking an iterator to a position in a sorted index. The difference * between a query KeyString and the KeyStrings inserted into indexes is that query KeyString @@ -243,10 +243,41 @@ public: * Returned KeyString are for use in lookups only and should never be inserted into the * database. */ - static KeyString::Value makeKeyStringForSeekPoint(const IndexSeekPoint& seekPoint, - KeyString::Version version, - Ordering ord, - bool isForward); + static KeyString::Value makeKeyStringFromSeekPointForSeek(const IndexSeekPoint& seekPoint, + KeyString::Version version, + Ordering ord, + bool isForward); + + /** + * Encodes the BSON Key into a KeyString object to pass in to SortedDataInterface::seek(). + * + * `isForward` and `inclusive` together decide which discriminator we will put into the + * KeyString. This logic is closely related to how WiredTiger uses its API + * (search_near/prev/next) to do the seek. Other storage engines' SortedDataInterface should use + * the discriminator to deduce the `inclusive` and the use their own ways to seek to the right + * position. + * + * 1. When isForward == true, inclusive == true, bsonKey will be encoded with kExclusiveBefore + * (which is less than bsonKey). WT's search_near() could land either on the previous key or + * bsonKey. WT will selectively call next() if it's on the previous key. + * + * 2. When isForward == true, inclusive == false, bsonKey will be encoded with kExclusiveAfter + * (which is greater than bsonKey). WT's search_near() could land either on bsonKey or the next + * key. WT will selectively call next() if it's on bsonKey. + * + * 3. When isForward == false, inclusive == true, bsonKey will be encoded with kExclusiveAfter + * (which is greater than bsonKey). WT's search_near() could land either on bsonKey or the next + * key. WT will selectively call prev() if it's on the next key. + * + * 4. When isForward == false, inclusive == false, bsonKey will be encoded with kExclusiveBefore + * (which is less than bsonKey). WT's search_near() could land either on the previous key or the + * bsonKey. WT will selectively call prev() if it's on bsonKey. + */ + static KeyString::Value makeKeyStringFromBSONKeyForSeek(const BSONObj& bsonKey, + KeyString::Version version, + Ordering ord, + bool isForward, + bool inclusive); private: // Ordering is used in comparison() to compare BSONElements diff --git a/src/mongo/db/storage/mobile/mobile_index.cpp b/src/mongo/db/storage/mobile/mobile_index.cpp index 0ed2e365e47..19bb34ad77c 100644 --- a/src/mongo/db/storage/mobile/mobile_index.cpp +++ b/src/mongo/db/storage/mobile/mobile_index.cpp @@ -405,21 +405,6 @@ public: BSONObj::stripFieldNames(key), _index.getOrdering(), discriminator); } - boost::optional<IndexKeyEntry> seek(const BSONObj& key, - bool inclusive, - RequestedInfo parts) override { - const auto discriminator = _isForward == inclusive - ? KeyString::Discriminator::kExclusiveBefore - : KeyString::Discriminator::kExclusiveAfter; - _startPosition.resetToKey( - BSONObj::stripFieldNames(key), _index.getOrdering(), discriminator); - seekForKeyString(_startPosition.getValueCopy()); - if (_isEOF) { - return {}; - } - return getCurrentEntry(parts); - } - boost::optional<IndexKeyEntry> seek(const KeyString::Value& keyString, RequestedInfo parts) override { seekForKeyString(keyString); diff --git a/src/mongo/db/storage/sorted_data_interface.h b/src/mongo/db/storage/sorted_data_interface.h index 004ab479fd6..28326398ee1 100644 --- a/src/mongo/db/storage/sorted_data_interface.h +++ b/src/mongo/db/storage/sorted_data_interface.h @@ -271,18 +271,6 @@ public: // /** - * Seeks to the provided key and returns current position. - * - * TODO consider removing once IndexSeekPoint has been cleaned up a bit. In particular, - * need a way to specify use whole keyPrefix and nothing else and to support the - * combination of empty and exclusive. Should also make it easier to construct for the - * common cases. - */ - virtual boost::optional<IndexKeyEntry> seek(const BSONObj& key, - bool inclusive, - RequestedInfo parts = kKeyAndLoc) = 0; - - /** * Seeks to the provided keyString and returns the KeyStringEntry. * The provided keyString has discriminator information encoded. */ diff --git a/src/mongo/db/storage/sorted_data_interface_test_cursor.cpp b/src/mongo/db/storage/sorted_data_interface_test_cursor.cpp index 9d3ae65350e..070622633f9 100644 --- a/src/mongo/db/storage/sorted_data_interface_test_cursor.cpp +++ b/src/mongo/db/storage/sorted_data_interface_test_cursor.cpp @@ -55,7 +55,7 @@ TEST(SortedDataInterface, CursorIsEOFWhenEmpty) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT(!cursor->seek(kMinBSONKey, true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), kMinBSONKey, true, true))); // Cursor at EOF should remain at EOF when advanced ASSERT(!cursor->next()); @@ -78,7 +78,7 @@ TEST(SortedDataInterface, CursorIsEOFWhenEmptyReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT(!cursor->seek(kMaxBSONKey, true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), kMaxBSONKey, false, true))); // Cursor at EOF should remain at EOF when advanced ASSERT(!cursor->next()); @@ -119,7 +119,9 @@ TEST(SortedDataInterface, ExhaustCursor) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); for (int i = 0; i < nToInsert; i++) { - auto entry = i == 0 ? cursor->seek(kMinBSONKey, true) : cursor->next(); + auto entry = i == 0 + ? cursor->seek(makeKeyStringForSeek(sorted.get(), kMinBSONKey, true, true)) + : cursor->next(); ASSERT_EQ(entry, IndexKeyEntry(BSON("" << i), RecordId(42, i * 2))); } ASSERT(!cursor->next()); @@ -164,7 +166,9 @@ TEST(SortedDataInterface, ExhaustCursorReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); for (int i = nToInsert - 1; i >= 0; i--) { - auto entry = (i == nToInsert - 1) ? cursor->seek(kMaxBSONKey, true) : cursor->next(); + auto entry = (i == nToInsert - 1) + ? cursor->seek(makeKeyStringForSeek(sorted.get(), kMaxBSONKey, false, true)) + : cursor->next(); ASSERT_EQ(entry, IndexKeyEntry(BSON("" << i), RecordId(42, i * 2))); } ASSERT(!cursor->next()); @@ -203,7 +207,7 @@ void testBoundaries(bool unique, bool forward, bool inclusive) { auto endKey = BSON("" << endVal); cursor->setEndPosition(endKey, inclusive); - auto entry = cursor->seek(startKey, inclusive); + auto entry = cursor->seek(makeKeyStringForSeek(sorted.get(), startKey, forward, inclusive)); // Check that the cursor returns the expected values in range. int step = forward ? 1 : -1; diff --git a/src/mongo/db/storage/sorted_data_interface_test_cursor_advanceto.cpp b/src/mongo/db/storage/sorted_data_interface_test_cursor_advanceto.cpp index 084242d145b..dedcd266c05 100644 --- a/src/mongo/db/storage/sorted_data_interface_test_cursor_advanceto.cpp +++ b/src/mongo/db/storage/sorted_data_interface_test_cursor_advanceto.cpp @@ -83,28 +83,29 @@ TEST(SortedDataInterface, AdvanceTo) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); IndexSeekPoint seekPoint; seekPoint.keyPrefix = key1; seekPoint.prefixLen = 1; seekPoint.prefixExclusive = false; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key1, loc1)); seekPoint.keyPrefix = key2; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key2, loc4)); seekPoint.keyPrefix = key3; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key3, loc5)); seekPoint.keyPrefix = key4; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), boost::none); } @@ -158,28 +159,29 @@ TEST(SortedDataInterface, AdvanceToReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), isForward)); - ASSERT_EQ(cursor->seek(key3, true), IndexKeyEntry(key3, loc5)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key3, isForward, true)), + IndexKeyEntry(key3, loc5)); IndexSeekPoint seekPoint; seekPoint.keyPrefix = key3; seekPoint.prefixLen = 1; seekPoint.prefixExclusive = false; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), IndexKeyEntry(key3, loc5)); seekPoint.keyPrefix = key2; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), IndexKeyEntry(key2, loc2)); seekPoint.keyPrefix = key1; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), IndexKeyEntry(key1, loc1)); seekPoint.keyPrefix = key0; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), boost::none); } @@ -219,18 +221,19 @@ TEST(SortedDataInterface, AdvanceToKeyBeforeCursorPosition) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); IndexSeekPoint seekPoint; seekPoint.keyPrefix = key0; seekPoint.prefixLen = 1; seekPoint.prefixExclusive = false; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key1, loc1)); seekPoint.prefixExclusive = true; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key1, loc1)); } @@ -272,18 +275,19 @@ TEST(SortedDataInterface, AdvanceToKeyAfterCursorPositionReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), isForward)); - ASSERT_EQ(cursor->seek(key2, true), IndexKeyEntry(key2, loc2)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, isForward, true)), + IndexKeyEntry(key2, loc2)); IndexSeekPoint seekPoint; seekPoint.keyPrefix = key3; seekPoint.prefixLen = 1; seekPoint.prefixExclusive = false; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), IndexKeyEntry(key2, loc2)); seekPoint.prefixExclusive = true; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), IndexKeyEntry(key2, loc2)); } @@ -323,18 +327,19 @@ TEST(SortedDataInterface, AdvanceToKeyAtCursorPosition) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); IndexSeekPoint seekPoint; seekPoint.keyPrefix = key1; seekPoint.prefixLen = 1; seekPoint.prefixExclusive = false; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key1, loc1)); seekPoint.prefixExclusive = true; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), boost::none); } @@ -376,18 +381,19 @@ TEST(SortedDataInterface, AdvanceToKeyAtCursorPositionReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), isForward)); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, isForward, true)), + IndexKeyEntry(key1, loc1)); IndexSeekPoint seekPoint; seekPoint.keyPrefix = key1; seekPoint.prefixLen = 1; seekPoint.prefixExclusive = false; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), IndexKeyEntry(key1, loc1)); seekPoint.prefixExclusive = true; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), boost::none); } @@ -438,28 +444,29 @@ TEST(SortedDataInterface, AdvanceToExclusive) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); IndexSeekPoint seekPoint; seekPoint.keyPrefix = key1; seekPoint.prefixLen = 1; seekPoint.prefixExclusive = true; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key2, loc4)); seekPoint.keyPrefix = key2; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key3, loc5)); seekPoint.keyPrefix = key3; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), boost::none); seekPoint.keyPrefix = key4; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), boost::none); } @@ -512,28 +519,29 @@ TEST(SortedDataInterface, AdvanceToExclusiveReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), isForward)); - ASSERT_EQ(cursor->seek(key3, true), IndexKeyEntry(key3, loc5)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key3, isForward, true)), + IndexKeyEntry(key3, loc5)); IndexSeekPoint seekPoint; seekPoint.keyPrefix = key3; seekPoint.prefixLen = 1; seekPoint.prefixExclusive = true; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), IndexKeyEntry(key2, loc2)); seekPoint.keyPrefix = key2; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), IndexKeyEntry(key1, loc1)); seekPoint.keyPrefix = key1; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), boost::none); seekPoint.keyPrefix = key0; - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), boost::none); } @@ -577,7 +585,8 @@ TEST(SortedDataInterface, AdvanceToIndirect) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); IndexSeekPoint seekPoint; seekPoint.prefixLen = 0; @@ -586,12 +595,12 @@ TEST(SortedDataInterface, AdvanceToIndirect) { seekPoint.suffixInclusive = {true}; suffix0 = key2.firstElement(); - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key3, loc2)); suffix0 = key4.firstElement(); - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key5, loc3)); } @@ -636,7 +645,8 @@ TEST(SortedDataInterface, AdvanceToIndirectReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT_EQ(cursor->seek(key5, true), IndexKeyEntry(key5, loc3)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key5, false, true)), + IndexKeyEntry(key5, loc3)); IndexSeekPoint seekPoint; seekPoint.prefixLen = 0; @@ -645,12 +655,12 @@ TEST(SortedDataInterface, AdvanceToIndirectReversed) { seekPoint.suffixInclusive = {true}; suffix0 = key4.firstElement(); - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key3, loc2)); suffix0 = key2.firstElement(); - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key1, loc1)); } @@ -696,7 +706,8 @@ TEST(SortedDataInterface, AdvanceToIndirectExclusive) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); IndexSeekPoint seekPoint; seekPoint.prefixLen = 0; @@ -705,19 +716,20 @@ TEST(SortedDataInterface, AdvanceToIndirectExclusive) { seekPoint.suffixInclusive = {false}; suffix0 = key2.firstElement(); - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key3, loc2)); suffix0 = key4.firstElement(); - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key5, loc3)); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); suffix0 = key3.firstElement(); - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)), IndexKeyEntry(key5, loc3)); } @@ -765,7 +777,8 @@ TEST(SortedDataInterface, AdvanceToIndirectExclusiveReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), isForward)); - ASSERT_EQ(cursor->seek(key5, true), IndexKeyEntry(key5, loc3)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key5, isForward, true)), + IndexKeyEntry(key5, loc3)); IndexSeekPoint seekPoint; seekPoint.prefixLen = 0; @@ -774,19 +787,20 @@ TEST(SortedDataInterface, AdvanceToIndirectExclusiveReversed) { seekPoint.suffixInclusive = {false}; suffix0 = key4.firstElement(); - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), IndexKeyEntry(key3, loc2)); suffix0 = key2.firstElement(); - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), IndexKeyEntry(key1, loc1)); - ASSERT_EQ(cursor->seek(key5, true), IndexKeyEntry(key5, loc3)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key5, isForward, true)), + IndexKeyEntry(key5, loc3)); suffix0 = key3.firstElement(); - ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint( + ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringFromSeekPointForSeek( seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)), IndexKeyEntry(key1, loc1)); } diff --git a/src/mongo/db/storage/sorted_data_interface_test_cursor_end_position.cpp b/src/mongo/db/storage/sorted_data_interface_test_cursor_end_position.cpp index 20aba3337b3..129657e4912 100644 --- a/src/mongo/db/storage/sorted_data_interface_test_cursor_end_position.cpp +++ b/src/mongo/db/storage/sorted_data_interface_test_cursor_end_position.cpp @@ -57,7 +57,8 @@ void testSetEndPosition_Next_Forward(bool unique, bool inclusive) { auto cursor = sorted->newCursor(opCtx.get()); cursor->setEndPosition(key3, inclusive); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key2, loc1)); if (inclusive) { ASSERT_EQ(cursor->next(), IndexKeyEntry(key3, loc1)); @@ -100,7 +101,8 @@ void testSetEndPosition_Next_Reverse(bool unique, bool inclusive) { auto cursor = sorted->newCursor(opCtx.get(), false); cursor->setEndPosition(key3, inclusive); - ASSERT_EQ(cursor->seek(key5, true), IndexKeyEntry(key5, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key5, false, true)), + IndexKeyEntry(key5, loc1)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key4, loc1)); if (inclusive) { if (!unique) @@ -140,25 +142,25 @@ void testSetEndPosition_Seek_Forward(bool unique, bool inclusive) { cursor->setEndPosition(key3, inclusive); // Directly seeking past end is considered out of range. - ASSERT_EQ(cursor->seek(key4, true), boost::none); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key4, true, true)), boost::none); ASSERT_EQ(cursor->seekExact(key4), boost::none); // Seeking to key3 directly or indirectly is only returned if endPosition is inclusive. auto maybeKey3 = inclusive ? boost::make_optional(IndexKeyEntry(key3, loc1)) : boost::none; // direct - ASSERT_EQ(cursor->seek(key3, true), maybeKey3); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key3, true, true)), maybeKey3); ASSERT_EQ(cursor->seekExact(key3), maybeKey3); // indirect - ASSERT_EQ(cursor->seek(key2, true), maybeKey3); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, true, true)), maybeKey3); cursor->saveUnpositioned(); removeFromIndex(opCtx, sorted, {{key3, loc1}}); cursor->restore(); - ASSERT_EQ(cursor->seek(key2, true), boost::none); - ASSERT_EQ(cursor->seek(key3, true), boost::none); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, true, true)), boost::none); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key3, true, true)), boost::none); } TEST(SortedDataInterface, SetEndPosition_Seek_Forward_Unique_Inclusive) { testSetEndPosition_Seek_Forward(true, true); @@ -189,25 +191,25 @@ void testSetEndPosition_Seek_Reverse(bool unique, bool inclusive) { cursor->setEndPosition(key2, inclusive); // Directly seeking past end is considered out of range. - ASSERT_EQ(cursor->seek(key1, true), boost::none); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, false, true)), boost::none); ASSERT_EQ(cursor->seekExact(key1), boost::none); // Seeking to key2 directly or indirectly is only returned if endPosition is inclusive. auto maybeKey2 = inclusive ? boost::make_optional(IndexKeyEntry(key2, loc1)) : boost::none; // direct - ASSERT_EQ(cursor->seek(key2, true), maybeKey2); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, false, true)), maybeKey2); ASSERT_EQ(cursor->seekExact(key2), maybeKey2); // indirect - ASSERT_EQ(cursor->seek(key3, true), maybeKey2); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key3, false, true)), maybeKey2); cursor->saveUnpositioned(); removeFromIndex(opCtx, sorted, {{key2, loc1}}); cursor->restore(); - ASSERT_EQ(cursor->seek(key3, true), boost::none); - ASSERT_EQ(cursor->seek(key2, true), boost::none); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key3, false, true)), boost::none); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, false, true)), boost::none); } TEST(SortedDataInterface, SetEndPosition_Seek_Reverse_Unique_Inclusive) { testSetEndPosition_Seek_Reverse(true, true); @@ -238,7 +240,8 @@ void testSetEndPosition_Restore_Forward(bool unique) { auto cursor = sorted->newCursor(opCtx.get()); cursor->setEndPosition(key3, false); // Should never see key3 or key4. - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); cursor->save(); cursor->restore(); @@ -278,7 +281,8 @@ void testSetEndPosition_Restore_Reverse(bool unique) { auto cursor = sorted->newCursor(opCtx.get(), false); cursor->setEndPosition(key2, false); // Should never see key1 or key2. - ASSERT_EQ(cursor->seek(key4, true), IndexKeyEntry(key4, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key4, false, true)), + IndexKeyEntry(key4, loc1)); cursor->save(); cursor->restore(); @@ -321,7 +325,8 @@ void testSetEndPosition_RestoreEndCursor_Forward(bool unique) { auto cursor = sorted->newCursor(opCtx.get()); cursor->setEndPosition(key2, true); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); // A potential source of bugs is not restoring end cursor with saveUnpositioned(). cursor->saveUnpositioned(); @@ -333,7 +338,8 @@ void testSetEndPosition_RestoreEndCursor_Forward(bool unique) { }); cursor->restore(); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key2, loc1)); ASSERT_EQ(cursor->next(), boost::none); } @@ -357,7 +363,8 @@ void testSetEndPosition_RestoreEndCursor_Reverse(bool unique) { auto cursor = sorted->newCursor(opCtx.get(), false); cursor->setEndPosition(key3, true); - ASSERT_EQ(cursor->seek(key4, true), IndexKeyEntry(key4, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key4, false, true)), + IndexKeyEntry(key4, loc1)); cursor->saveUnpositioned(); insertToIndex(opCtx, @@ -368,7 +375,8 @@ void testSetEndPosition_RestoreEndCursor_Reverse(bool unique) { }); cursor->restore(); // must restore end cursor even with saveUnpositioned(). - ASSERT_EQ(cursor->seek(key4, true), IndexKeyEntry(key4, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key4, false, true)), + IndexKeyEntry(key4, loc1)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key3, loc1)); ASSERT_EQ(cursor->next(), boost::none); } @@ -395,7 +403,8 @@ void testSetEndPosition_Empty_Forward(bool unique, bool inclusive) { auto cursor = sorted->newCursor(opCtx.get()); cursor->setEndPosition(BSONObj(), inclusive); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key2, loc1)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key3, loc1)); ASSERT_EQ(cursor->next(), boost::none); @@ -427,7 +436,8 @@ void testSetEndPosition_Empty_Reverse(bool unique, bool inclusive) { auto cursor = sorted->newCursor(opCtx.get(), false); cursor->setEndPosition(BSONObj(), inclusive); - ASSERT_EQ(cursor->seek(key3, true), IndexKeyEntry(key3, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key3, false, true)), + IndexKeyEntry(key3, loc1)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key2, loc1)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key1, loc1)); ASSERT_EQ(cursor->next(), boost::none); @@ -455,21 +465,24 @@ void testSetEndPosition_Character_Limits(bool unique, bool inclusive) { cursor->setEndPosition(key7, inclusive); if (inclusive) { - ASSERT_EQ(cursor->seek(key7, true), IndexKeyEntry(key7, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key7, true, true)), + IndexKeyEntry(key7, loc1)); ASSERT_EQ(cursor->next(), boost::none); } else { - ASSERT_EQ(cursor->seek(key7, true), boost::none); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key7, true, true)), boost::none); } cursor = sorted->newCursor(opCtx.get()); cursor->setEndPosition(key8, inclusive); if (inclusive) { - ASSERT_EQ(cursor->seek(key7, true), IndexKeyEntry(key7, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key7, true, true)), + IndexKeyEntry(key7, loc1)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key8, loc1)); ASSERT_EQ(cursor->next(), boost::none); } else { - ASSERT_EQ(cursor->seek(key7, true), IndexKeyEntry(key7, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key7, true, true)), + IndexKeyEntry(key7, loc1)); ASSERT_EQ(cursor->next(), boost::none); } } diff --git a/src/mongo/db/storage/sorted_data_interface_test_cursor_locate.cpp b/src/mongo/db/storage/sorted_data_interface_test_cursor_locate.cpp index 9ebb509d0c6..fe444b2e81a 100644 --- a/src/mongo/db/storage/sorted_data_interface_test_cursor_locate.cpp +++ b/src/mongo/db/storage/sorted_data_interface_test_cursor_locate.cpp @@ -47,7 +47,8 @@ TEST(SortedDataInterface, Locate) { { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT(!cursor->seek(key1, true)); + + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true))); } { @@ -64,7 +65,8 @@ TEST(SortedDataInterface, Locate) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); ASSERT_EQ(cursor->next(), boost::none); } } @@ -80,7 +82,7 @@ TEST(SortedDataInterface, LocateReversed) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT(!cursor->seek(key1, true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), key1, false, true))); } { @@ -98,7 +100,8 @@ TEST(SortedDataInterface, LocateReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, false, true)), + IndexKeyEntry(key1, loc1)); ASSERT_EQ(cursor->next(), boost::none); } } @@ -113,7 +116,7 @@ TEST(SortedDataInterface, LocateCompoundKey) { { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT(!cursor->seek(compoundKey1a, true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey1a, true, true))); } { @@ -130,7 +133,8 @@ TEST(SortedDataInterface, LocateCompoundKey) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(compoundKey1a, true), IndexKeyEntry(compoundKey1a, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey1a, true, true)), + IndexKeyEntry(compoundKey1a, loc1)); ASSERT_EQ(cursor->next(), boost::none); } } @@ -146,7 +150,7 @@ TEST(SortedDataInterface, LocateCompoundKeyReversed) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT(!cursor->seek(compoundKey1a, true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey1a, false, true))); } { @@ -164,7 +168,8 @@ TEST(SortedDataInterface, LocateCompoundKeyReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT_EQ(cursor->seek(compoundKey1a, true), IndexKeyEntry(compoundKey1a, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey1a, false, true)), + IndexKeyEntry(compoundKey1a, loc1)); ASSERT_EQ(cursor->next(), boost::none); } } @@ -179,7 +184,7 @@ TEST(SortedDataInterface, LocateMultiple) { { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT(!cursor->seek(key1, true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true))); } { @@ -198,7 +203,8 @@ TEST(SortedDataInterface, LocateMultiple) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key2, loc2)); ASSERT_EQ(cursor->next(), boost::none); } @@ -217,11 +223,13 @@ TEST(SortedDataInterface, LocateMultiple) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key2, true), IndexKeyEntry(key2, loc2)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, true, true)), + IndexKeyEntry(key2, loc2)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key3, loc3)); ASSERT_EQ(cursor->next(), boost::none); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key2, loc2)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key3, loc3)); ASSERT_EQ(cursor->next(), boost::none); @@ -239,7 +247,7 @@ TEST(SortedDataInterface, LocateMultipleReversed) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT(!cursor->seek(key3, true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), key3, true, true))); } { @@ -259,7 +267,8 @@ TEST(SortedDataInterface, LocateMultipleReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT_EQ(cursor->seek(key2, true), IndexKeyEntry(key2, loc2)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, false, true)), + IndexKeyEntry(key2, loc2)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key1, loc1)); ASSERT_EQ(cursor->next(), boost::none); } @@ -279,11 +288,13 @@ TEST(SortedDataInterface, LocateMultipleReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT_EQ(cursor->seek(key2, true), IndexKeyEntry(key2, loc2)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, false, true)), + IndexKeyEntry(key2, loc2)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key1, loc1)); ASSERT_EQ(cursor->next(), boost::none); - ASSERT_EQ(cursor->seek(key3, true), IndexKeyEntry(key3, loc3)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key3, false, true)), + IndexKeyEntry(key3, loc3)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key2, loc2)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key1, loc1)); ASSERT_EQ(cursor->next(), boost::none); @@ -300,7 +311,7 @@ TEST(SortedDataInterface, LocateMultipleCompoundKeys) { { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT(!cursor->seek(compoundKey1a, true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey1a, true, true))); } { @@ -321,7 +332,8 @@ TEST(SortedDataInterface, LocateMultipleCompoundKeys) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(compoundKey1a, true), IndexKeyEntry(compoundKey1a, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey1a, true, true)), + IndexKeyEntry(compoundKey1a, loc1)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey1b, loc2)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey2b, loc3)); ASSERT_EQ(cursor->next(), boost::none); @@ -343,7 +355,8 @@ TEST(SortedDataInterface, LocateMultipleCompoundKeys) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(compoundKey1a, true), IndexKeyEntry(compoundKey1a, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey1a, true, true)), + IndexKeyEntry(compoundKey1a, loc1)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey1b, loc2)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey1c, loc4)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey2b, loc3)); @@ -363,7 +376,7 @@ TEST(SortedDataInterface, LocateMultipleCompoundKeysReversed) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT(!cursor->seek(compoundKey3a, true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey3a, false, true))); } { @@ -385,7 +398,8 @@ TEST(SortedDataInterface, LocateMultipleCompoundKeysReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT_EQ(cursor->seek(compoundKey2b, true), IndexKeyEntry(compoundKey2b, loc3)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey2b, false, true)), + IndexKeyEntry(compoundKey2b, loc3)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey1b, loc2)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey1a, loc1)); ASSERT_EQ(cursor->next(), boost::none); @@ -408,7 +422,8 @@ TEST(SortedDataInterface, LocateMultipleCompoundKeysReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT_EQ(cursor->seek(compoundKey3a, true), IndexKeyEntry(compoundKey3a, loc5)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey3a, false, true)), + IndexKeyEntry(compoundKey3a, loc5)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey2b, loc3)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey1c, loc4)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey1b, loc2)); @@ -427,7 +442,7 @@ TEST(SortedDataInterface, LocateIndirect) { { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT(!cursor->seek(key1, true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true))); } { @@ -446,7 +461,8 @@ TEST(SortedDataInterface, LocateIndirect) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, false), IndexKeyEntry(key2, loc2)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, false)), + IndexKeyEntry(key2, loc2)); ASSERT_EQ(cursor->next(), boost::none); } @@ -464,7 +480,8 @@ TEST(SortedDataInterface, LocateIndirect) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key2, loc2)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key3, loc3)); ASSERT_EQ(cursor->next(), boost::none); @@ -482,7 +499,7 @@ TEST(SortedDataInterface, LocateIndirectReversed) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT(!cursor->seek(key3, true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), key3, false, true))); } { @@ -502,7 +519,8 @@ TEST(SortedDataInterface, LocateIndirectReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT_EQ(cursor->seek(key2, false), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, false, false)), + IndexKeyEntry(key1, loc1)); ASSERT_EQ(cursor->next(), boost::none); } @@ -521,7 +539,8 @@ TEST(SortedDataInterface, LocateIndirectReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT_EQ(cursor->seek(key3, true), IndexKeyEntry(key3, loc3)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key3, false, true)), + IndexKeyEntry(key3, loc3)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key2, loc2)); ASSERT_EQ(cursor->next(), IndexKeyEntry(key1, loc1)); ASSERT_EQ(cursor->next(), boost::none); @@ -538,7 +557,7 @@ TEST(SortedDataInterface, LocateIndirectCompoundKeys) { { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT(!cursor->seek(compoundKey1a, true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey1a, true, true))); } { @@ -559,7 +578,8 @@ TEST(SortedDataInterface, LocateIndirectCompoundKeys) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(compoundKey1a, false), IndexKeyEntry(compoundKey1b, loc2)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey1a, true, false)), + IndexKeyEntry(compoundKey1b, loc2)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey2b, loc3)); ASSERT_EQ(cursor->next(), boost::none); } @@ -580,7 +600,8 @@ TEST(SortedDataInterface, LocateIndirectCompoundKeys) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(compoundKey2a, true), IndexKeyEntry(compoundKey2b, loc3)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey2a, true, true)), + IndexKeyEntry(compoundKey2b, loc3)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey3a, loc5)); ASSERT_EQ(cursor->next(), boost::none); } @@ -597,7 +618,7 @@ TEST(SortedDataInterface, LocateIndirectCompoundKeysReversed) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT(!cursor->seek(compoundKey3a, true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey3a, false, true))); } { @@ -619,7 +640,8 @@ TEST(SortedDataInterface, LocateIndirectCompoundKeysReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT_EQ(cursor->seek(compoundKey2b, false), IndexKeyEntry(compoundKey1b, loc2)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey2b, true, true)), + IndexKeyEntry(compoundKey1b, loc2)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey1a, loc1)); ASSERT_EQ(cursor->next(), boost::none); } @@ -641,7 +663,8 @@ TEST(SortedDataInterface, LocateIndirectCompoundKeysReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT_EQ(cursor->seek(compoundKey1d, true), IndexKeyEntry(compoundKey1c, loc4)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), compoundKey1d, true, true)), + IndexKeyEntry(compoundKey1c, loc4)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey1b, loc2)); ASSERT_EQ(cursor->next(), IndexKeyEntry(compoundKey1a, loc1)); ASSERT_EQ(cursor->next(), boost::none); @@ -664,7 +687,7 @@ TEST(SortedDataInterface, LocateEmpty) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT(!cursor->seek(BSONObj(), true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), BSONObj(), true, true))); ASSERT(!cursor->next()); } } @@ -686,7 +709,7 @@ TEST(SortedDataInterface, LocateEmptyReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT(!cursor->seek(BSONObj(), true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), BSONObj(), false, true))); ASSERT(!cursor->next()); } } diff --git a/src/mongo/db/storage/sorted_data_interface_test_cursor_saverestore.cpp b/src/mongo/db/storage/sorted_data_interface_test_cursor_saverestore.cpp index 912b7b87367..03e8378dd81 100644 --- a/src/mongo/db/storage/sorted_data_interface_test_cursor_saverestore.cpp +++ b/src/mongo/db/storage/sorted_data_interface_test_cursor_saverestore.cpp @@ -74,7 +74,9 @@ TEST(SortedDataInterface, SaveAndRestorePositionWhileIterateCursor) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); int i = 0; - for (auto entry = cursor->seek(kMinBSONKey, true); entry; i++, entry = cursor->next()) { + for (auto entry = cursor->seek(makeKeyStringForSeek(sorted.get(), kMinBSONKey, true, true)); + entry; + i++, entry = cursor->next()) { ASSERT_LT(i, nToInsert); ASSERT_EQ(entry, IndexKeyEntry(BSON("" << i), RecordId(42, i * 2))); @@ -122,7 +124,10 @@ TEST(SortedDataInterface, SaveAndRestorePositionWhileIterateCursorReversed) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); int i = nToInsert - 1; - for (auto entry = cursor->seek(kMaxBSONKey, true); entry; i--, entry = cursor->next()) { + for (auto entry = + cursor->seek(makeKeyStringForSeek(sorted.get(), kMaxBSONKey, false, true)); + entry; + i--, entry = cursor->next()) { ASSERT_GTE(i, 0); ASSERT_EQ(entry, IndexKeyEntry(BSON("" << i), RecordId(42, i * 2))); @@ -169,7 +174,10 @@ TEST(SortedDataInterface, SaveAndRestorePositionWhileIterateCursorOnIdIndex) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); int i = nToInsert - 1; - for (auto entry = cursor->seek(kMaxBSONKey, true); entry; i--, entry = cursor->next()) { + for (auto entry = + cursor->seek(makeKeyStringForSeek(sorted.get(), kMaxBSONKey, false, true)); + entry; + i--, entry = cursor->next()) { ASSERT_GTE(i, 0); ASSERT_EQ(entry, IndexKeyEntry(BSON("" << i), RecordId(42, i * 2))); @@ -216,7 +224,10 @@ TEST(SortedDataInterface, SaveAndRestorePositionWhileIterateCursorReversedOnIdIn const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); int i = nToInsert - 1; - for (auto entry = cursor->seek(kMaxBSONKey, true); entry; i--, entry = cursor->next()) { + for (auto entry = + cursor->seek(makeKeyStringForSeek(sorted.get(), kMaxBSONKey, false, true)); + entry; + i--, entry = cursor->next()) { ASSERT_GTE(i, 0); ASSERT_EQ(entry, IndexKeyEntry(BSON("" << i), RecordId(42, i * 2))); @@ -265,7 +276,9 @@ TEST(SortedDataInterface, SaveAndRestorePositionWhileIterateCursorWithDupKeys) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); int i = 0; - for (auto entry = cursor->seek(kMinBSONKey, true); entry; i++, entry = cursor->next()) { + for (auto entry = cursor->seek(makeKeyStringForSeek(sorted.get(), kMinBSONKey, true, true)); + entry; + i++, entry = cursor->next()) { ASSERT_LT(i, nToInsert); ASSERT_EQ(entry, IndexKeyEntry(key1, RecordId(42, i * 2))); @@ -315,7 +328,10 @@ TEST(SortedDataInterface, SaveAndRestorePositionWhileIterateCursorWithDupKeysRev const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); int i = nToInsert - 1; - for (auto entry = cursor->seek(kMaxBSONKey, true); entry; i--, entry = cursor->next()) { + for (auto entry = + cursor->seek(makeKeyStringForSeek(sorted.get(), kMaxBSONKey, false, true)); + entry; + i--, entry = cursor->next()) { ASSERT_GTE(i, 0); ASSERT_EQ(entry, IndexKeyEntry(key1, RecordId(42, i * 2))); @@ -411,7 +427,8 @@ void testSaveAndRestorePositionSeesNewInserts(bool forward, bool unique) { auto cursor = sorted->newCursor(opCtx.get(), forward); const auto seekPoint = forward ? key1 : key3; - ASSERT_EQ(cursor->seek(seekPoint, true), IndexKeyEntry(seekPoint, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), seekPoint, forward, true)), + IndexKeyEntry(seekPoint, loc1)); cursor->save(); insertToIndex(opCtx, sorted, {{key2, loc1}}); @@ -447,7 +464,8 @@ void testSaveAndRestorePositionSeesNewInsertsAfterRemove(bool forward, bool uniq auto cursor = sorted->newCursor(opCtx.get(), forward); const auto seekPoint = forward ? key1 : key3; - ASSERT_EQ(cursor->seek(seekPoint, true), IndexKeyEntry(seekPoint, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), seekPoint, forward, true)), + IndexKeyEntry(seekPoint, loc1)); cursor->save(); removeFromIndex(opCtx, sorted, {{key1, loc1}}); @@ -487,7 +505,8 @@ void testSaveAndRestorePositionSeesNewInsertsAfterEOF(bool forward, bool unique) auto cursor = sorted->newCursor(opCtx.get(), forward); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, forward, true)), + IndexKeyEntry(key1, loc1)); // next() would return EOF now. cursor->save(); @@ -530,7 +549,8 @@ TEST(SortedDataInterface, SaveAndRestorePositionStandardIndexConsidersRecordId_F auto cursor = sorted->newCursor(opCtx.get()); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); cursor->save(); removeFromIndex(opCtx, sorted, {{key1, loc1}}); @@ -569,7 +589,8 @@ TEST(SortedDataInterface, SaveAndRestorePositionUniqueIndexWontReturnDupKeys_For auto cursor = sorted->newCursor(opCtx.get()); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); cursor->save(); removeFromIndex(opCtx, sorted, {{key1, loc1}}); @@ -614,7 +635,8 @@ TEST(SortedDataInterface, SaveAndRestorePositionStandardIndexConsidersRecordId_R auto cursor = sorted->newCursor(opCtx.get(), false); - ASSERT_EQ(cursor->seek(key2, true), IndexKeyEntry(key2, loc2)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, false, true)), + IndexKeyEntry(key2, loc2)); cursor->save(); removeFromIndex(opCtx, sorted, {{key2, loc2}}); @@ -653,7 +675,8 @@ TEST(SortedDataInterface, SaveAndRestorePositionUniqueIndexWontReturnDupKeys_Rev auto cursor = sorted->newCursor(opCtx.get(), false); - ASSERT_EQ(cursor->seek(key4, true), IndexKeyEntry(key4, loc2)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key4, false, true)), + IndexKeyEntry(key4, loc2)); cursor->save(); removeFromIndex(opCtx, sorted, {{key4, loc2}}); @@ -698,18 +721,21 @@ TEST(SortedDataInterface, SaveUnpositionedAndRestore) { auto cursor = sorted->newCursor(opCtx.get()); - ASSERT_EQ(cursor->seek(key2, true), IndexKeyEntry(key2, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, true, true)), + IndexKeyEntry(key2, loc1)); cursor->saveUnpositioned(); removeFromIndex(opCtx, sorted, {{key2, loc1}}); cursor->restore(); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); cursor->saveUnpositioned(); cursor->restore(); - ASSERT_EQ(cursor->seek(key3, true), IndexKeyEntry(key3, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key3, true, true)), + IndexKeyEntry(key3, loc1)); } } // namespace diff --git a/src/mongo/db/storage/sorted_data_interface_test_harness.cpp b/src/mongo/db/storage/sorted_data_interface_test_harness.cpp index 09e44da851d..38e2b77a0a7 100644 --- a/src/mongo/db/storage/sorted_data_interface_test_harness.cpp +++ b/src/mongo/db/storage/sorted_data_interface_test_harness.cpp @@ -77,6 +77,19 @@ mongo::KeyString::Value mongo::makeKeyString(SortedDataInterface* sorted, return builder.getValueCopy(); } +mongo::KeyString::Value mongo::makeKeyStringForSeek(SortedDataInterface* sorted, + BSONObj bsonKey, + bool isForward, + bool inclusive) { + BSONObj finalKey = BSONObj::stripFieldNames(bsonKey); + KeyString::Builder builder(sorted->getKeyStringVersion(), + finalKey, + sorted->getOrdering(), + isForward == inclusive ? KeyString::Discriminator::kExclusiveBefore + : KeyString::Discriminator::kExclusiveAfter); + return builder.getValueCopy(); +} + namespace mongo { namespace { @@ -401,7 +414,9 @@ TEST(SortedDataInterface, CursorIterate1) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); int n = 0; - for (auto entry = cursor->seek(BSONObj(), true); entry; entry = cursor->next()) { + for (auto entry = cursor->seek(makeKeyStringForSeek(sorted.get(), BSONObj(), true, true)); + entry; + entry = cursor->next()) { ASSERT_EQ(entry, IndexKeyEntry(BSON("" << n), RecordId(5, n * 2))); n++; } @@ -431,7 +446,9 @@ TEST(SortedDataInterface, CursorIterate1WithSaveRestore) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); int n = 0; - for (auto entry = cursor->seek(BSONObj(), true); entry; entry = cursor->next()) { + for (auto entry = cursor->seek(makeKeyStringForSeek(sorted.get(), BSONObj(), true, true)); + entry; + entry = cursor->next()) { ASSERT_EQ(entry, IndexKeyEntry(BSON("" << n), RecordId(5, n * 2))); n++; cursor->save(); @@ -464,7 +481,9 @@ TEST(SortedDataInterface, CursorIterateAllDupKeysWithSaveRestore) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); int n = 0; - for (auto entry = cursor->seek(BSONObj(), true); entry; entry = cursor->next()) { + for (auto entry = cursor->seek(makeKeyStringForSeek(sorted.get(), BSONObj(), true, true)); + entry; + entry = cursor->next()) { ASSERT_EQ(entry, IndexKeyEntry(BSON("" << 5), RecordId(5, n * 2))); n++; cursor->save(); @@ -486,7 +505,7 @@ TEST(SortedDataInterface, Locate1) { { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT(!cursor->seek(key, true)); + ASSERT(!cursor->seek(makeKeyStringForSeek(sorted.get(), key, true, true))); } { @@ -502,7 +521,8 @@ TEST(SortedDataInterface, Locate1) { { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key, true), IndexKeyEntry(key, loc)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key, true, true)), + IndexKeyEntry(key, loc)); } } @@ -535,7 +555,8 @@ TEST(SortedDataInterface, Locate2) { { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(BSON("a" << 2), true), IndexKeyEntry(BSON("" << 2), RecordId(1, 4))); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), BSON("a" << 2), true, true)), + IndexKeyEntry(BSON("" << 2), RecordId(1, 4))); ASSERT_EQ(cursor->next(), IndexKeyEntry(BSON("" << 3), RecordId(1, 6))); ASSERT_EQ(cursor->next(), boost::none); @@ -571,14 +592,16 @@ TEST(SortedDataInterface, Locate2Empty) { { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(BSONObj(), true), IndexKeyEntry(BSON("" << 1), RecordId(1, 2))); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), BSONObj(), true, true)), + IndexKeyEntry(BSON("" << 1), RecordId(1, 2))); } { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get(), false)); - ASSERT_EQ(cursor->seek(BSONObj(), false), boost::none); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), BSONObj(), false, false)), + boost::none); } } @@ -605,26 +628,37 @@ TEST(SortedDataInterface, Locate3Descending) { const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get(), true)); - ASSERT_EQ(cursor->seek(BSON("" << 5), true), buildEntry(5)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), BSON("" << 5), true, true)), + buildEntry(5)); ASSERT_EQ(cursor->next(), buildEntry(7)); cursor = sorted->newCursor(opCtx.get(), /*forward*/ false); - ASSERT_EQ(cursor->seek(BSON("" << 5), /*inclusive*/ false), buildEntry(4)); + ASSERT_EQ( + cursor->seek(makeKeyStringForSeek(sorted.get(), BSON("" << 5), false, /*inclusive*/ false)), + buildEntry(4)); cursor = sorted->newCursor(opCtx.get(), /*forward*/ false); - ASSERT_EQ(cursor->seek(BSON("" << 5), /*inclusive*/ true), buildEntry(5)); + ASSERT_EQ( + cursor->seek(makeKeyStringForSeek(sorted.get(), BSON("" << 5), false, /*inclusive*/ true)), + buildEntry(5)); ASSERT_EQ(cursor->next(), buildEntry(4)); cursor = sorted->newCursor(opCtx.get(), /*forward*/ false); - ASSERT_EQ(cursor->seek(BSON("" << 5), /*inclusive*/ false), buildEntry(4)); + ASSERT_EQ( + cursor->seek(makeKeyStringForSeek(sorted.get(), BSON("" << 5), false, /*inclusive*/ false)), + buildEntry(4)); ASSERT_EQ(cursor->next(), buildEntry(3)); cursor = sorted->newCursor(opCtx.get(), /*forward*/ false); - ASSERT_EQ(cursor->seek(BSON("" << 6), /*inclusive*/ true), buildEntry(5)); + ASSERT_EQ( + cursor->seek(makeKeyStringForSeek(sorted.get(), BSON("" << 6), false, /*inclusive*/ true)), + buildEntry(5)); ASSERT_EQ(cursor->next(), buildEntry(4)); cursor = sorted->newCursor(opCtx.get(), /*forward*/ false); - ASSERT_EQ(cursor->seek(BSON("" << 500), /*inclusive*/ true), buildEntry(9)); + ASSERT_EQ(cursor->seek( + makeKeyStringForSeek(sorted.get(), BSON("" << 500), false, /*inclusive*/ true)), + buildEntry(9)); ASSERT_EQ(cursor->next(), buildEntry(8)); } @@ -642,7 +676,8 @@ TEST(SortedDataInterface, Locate4) { { auto opCtx = harnessHelper->newOperationContext(); auto cursor = sorted->newCursor(opCtx.get()); - ASSERT_EQ(cursor->seek(BSON("a" << 1), true), IndexKeyEntry(BSON("" << 1), RecordId(1, 2))); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), BSON("a" << 1), true, true)), + IndexKeyEntry(BSON("" << 1), RecordId(1, 2))); ASSERT_EQ(cursor->next(), IndexKeyEntry(BSON("" << 1), RecordId(1, 4))); ASSERT_EQ(cursor->next(), IndexKeyEntry(BSON("" << 1), RecordId(1, 6))); @@ -653,7 +688,8 @@ TEST(SortedDataInterface, Locate4) { { auto opCtx = harnessHelper->newOperationContext(); auto cursor = sorted->newCursor(opCtx.get(), false); - ASSERT_EQ(cursor->seek(BSON("a" << 1), true), IndexKeyEntry(BSON("" << 1), RecordId(1, 6))); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), BSON("a" << 1), false, true)), + IndexKeyEntry(BSON("" << 1), RecordId(1, 6))); ASSERT_EQ(cursor->next(), IndexKeyEntry(BSON("" << 1), RecordId(1, 4))); ASSERT_EQ(cursor->next(), IndexKeyEntry(BSON("" << 1), RecordId(1, 2))); diff --git a/src/mongo/db/storage/sorted_data_interface_test_harness.h b/src/mongo/db/storage/sorted_data_interface_test_harness.h index 067143d9c40..4cc4e6375aa 100644 --- a/src/mongo/db/storage/sorted_data_interface_test_harness.h +++ b/src/mongo/db/storage/sorted_data_interface_test_harness.h @@ -106,6 +106,11 @@ KeyString::Value makeKeyString(SortedDataInterface* sorted, BSONObj bsonKey, boost::optional<RecordId> rid = boost::none); +KeyString::Value makeKeyStringForSeek(SortedDataInterface* sorted, + BSONObj bsonKey, + bool isForward, + bool inclusive); + /** * Inserts all entries in toInsert into index. * ASSERT_OKs the inserts. diff --git a/src/mongo/db/storage/sorted_data_interface_test_insert.cpp b/src/mongo/db/storage/sorted_data_interface_test_insert.cpp index 4eae05ceea6..784ee673a03 100644 --- a/src/mongo/db/storage/sorted_data_interface_test_insert.cpp +++ b/src/mongo/db/storage/sorted_data_interface_test_insert.cpp @@ -64,7 +64,8 @@ TEST(SortedDataInterface, Insert) { ASSERT_EQUALS(1, sorted->numEntries(opCtx.get())); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); } } @@ -95,7 +96,8 @@ TEST(SortedDataInterface, InsertKeyString) { ASSERT_EQUALS(1, sorted->numEntries(opCtx.get())); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); } } @@ -251,7 +253,8 @@ TEST(SortedDataInterface, InsertSameKey) { ASSERT_EQUALS(1, sorted->numEntries(opCtx.get())); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); } { @@ -269,7 +272,8 @@ TEST(SortedDataInterface, InsertSameKey) { ASSERT_EQUALS(1, sorted->numEntries(opCtx.get())); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); } } @@ -307,7 +311,8 @@ TEST(SortedDataInterface, InsertSameKeyString) { ASSERT_EQUALS(1, sorted->numEntries(opCtx.get())); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); } { @@ -324,7 +329,8 @@ TEST(SortedDataInterface, InsertSameKeyString) { ASSERT_EQUALS(1, sorted->numEntries(opCtx.get())); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); } } @@ -383,7 +389,8 @@ void _testInsertSameKeyWithDupsAllowed(const RecordId locs[3]) { const std::unique_ptr<SortedDataInterface::Cursor> cursor( sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, locs[keeper])); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, locs[keeper])); } } } @@ -429,8 +436,10 @@ TEST(SortedDataInterface, InsertMultiple) { ASSERT_EQUALS(2, sorted->numEntries(opCtx.get())); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); - ASSERT_EQ(cursor->seek(key2, true), IndexKeyEntry(key2, loc2)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, true, true)), + IndexKeyEntry(key2, loc2)); } { @@ -448,9 +457,12 @@ TEST(SortedDataInterface, InsertMultiple) { ASSERT_EQUALS(3, sorted->numEntries(opCtx.get())); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); - ASSERT_EQ(cursor->seek(key2, true), IndexKeyEntry(key2, loc2)); - ASSERT_EQ(cursor->seek(key3, true), IndexKeyEntry(key3, loc3)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, true, true)), + IndexKeyEntry(key2, loc2)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key3, true, true)), + IndexKeyEntry(key3, loc3)); } } @@ -487,8 +499,10 @@ TEST(SortedDataInterface, InsertMultipleKeyStrings) { ASSERT_EQUALS(2, sorted->numEntries(opCtx.get())); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); - ASSERT_EQ(cursor->seek(key2, true), IndexKeyEntry(key2, loc2)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, true, true)), + IndexKeyEntry(key2, loc2)); } { @@ -505,9 +519,12 @@ TEST(SortedDataInterface, InsertMultipleKeyStrings) { ASSERT_EQUALS(3, sorted->numEntries(opCtx.get())); const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get())); - ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1)); - ASSERT_EQ(cursor->seek(key2, true), IndexKeyEntry(key2, loc2)); - ASSERT_EQ(cursor->seek(key3, true), IndexKeyEntry(key3, loc3)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key1, true, true)), + IndexKeyEntry(key1, loc1)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key2, true, true)), + IndexKeyEntry(key2, loc2)); + ASSERT_EQ(cursor->seek(makeKeyStringForSeek(sorted.get(), key3, true, true)), + IndexKeyEntry(key3, loc3)); } } diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp index a6e0c62d253..f6bcc016c8c 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp @@ -308,7 +308,16 @@ void WiredTigerIndex::fullValidate(OperationContext* opCtx, TRACE_INDEX << " fullValidate"; const auto requestedInfo = TRACING_ENABLED ? Cursor::kKeyAndLoc : Cursor::kJustExistance; - for (auto kv = cursor->seek(BSONObj(), true, requestedInfo); kv; kv = cursor->next()) { + + KeyString::Value keyStringForSeek = + IndexEntryComparison::makeKeyStringFromBSONKeyForSeek(BSONObj(), + getKeyStringVersion(), + getOrdering(), + true, /* forward */ + true /* inclusive */ + ); + + for (auto kv = cursor->seek(keyStringForSeek, requestedInfo); kv; kv = cursor->next()) { TRACE_INDEX << "\t" << kv->key << ' ' << kv->loc; count++; } @@ -371,11 +380,17 @@ Status WiredTigerIndex::dupKeyCheck(OperationContext* opCtx, const KeyString::Va bool WiredTigerIndex::isEmpty(OperationContext* opCtx) { if (_prefix != KVPrefix::kNotPrefixed) { - const bool forward = true; - auto cursor = newCursor(opCtx, forward); - const bool inclusive = false; - return cursor->seek(kMinBSONKey, inclusive, Cursor::RequestedInfo::kJustExistance) == - boost::none; + auto cursor = newCursor(opCtx, true /* forward */); + + KeyString::Value keyStringForSeek = + IndexEntryComparison::makeKeyStringFromBSONKeyForSeek(kMinBSONKey, + getKeyStringVersion(), + getOrdering(), + true /* forward */, + false /* inclusive */ + ); + + return cursor->seek(keyStringForSeek, Cursor::RequestedInfo::kJustExistance) == boost::none; } WiredTigerCursor curwrap(_uri, _tableId, false, opCtx); @@ -822,19 +837,6 @@ public: _endPosition->resetToKey(BSONObj::stripFieldNames(key), _idx.getOrdering(), discriminator); } - boost::optional<IndexKeyEntry> seek(const BSONObj& key, - bool inclusive, - RequestedInfo parts) override { - dassert(_opCtx->lockState()->isReadLocked()); - const BSONObj finalKey = BSONObj::stripFieldNames(key); - const auto discriminator = _forward == inclusive - ? KeyString::Discriminator::kExclusiveBefore - : KeyString::Discriminator::kExclusiveAfter; - _query.resetToKey(finalKey, _idx.getOrdering(), discriminator); - seekForKeyString(_query.getValueCopy()); - return curr(parts); - } - boost::optional<IndexKeyEntry> seek(const KeyString::Value& keyString, RequestedInfo parts = kKeyAndLoc) override { seekForKeyString(keyString); diff --git a/src/mongo/dbtests/rollbacktests.cpp b/src/mongo/dbtests/rollbacktests.cpp index fd48e6f46a3..bc76af16a33 100644 --- a/src/mongo/dbtests/rollbacktests.cpp +++ b/src/mongo/dbtests/rollbacktests.cpp @@ -136,8 +136,14 @@ size_t getNumIndexEntries(OperationContext* opCtx, if (desc) { auto cursor = catalog->getEntry(desc)->accessMethod()->newCursor(opCtx); - - for (auto kv = cursor->seek(kMinBSONKey, true); kv; kv = cursor->next()) { + KeyString::Builder keyString( + catalog->getEntry(desc) + ->accessMethod() + ->getSortedDataInterface() + ->getKeyStringVersion(), + kMinBSONKey, + catalog->getEntry(desc)->accessMethod()->getSortedDataInterface()->getOrdering()); + for (auto kv = cursor->seek(keyString.getValueCopy()); kv; kv = cursor->next()) { numEntries++; } } diff --git a/src/mongo/dbtests/wildcard_multikey_persistence_test.cpp b/src/mongo/dbtests/wildcard_multikey_persistence_test.cpp index 3f7d762e8db..418ae86f0dc 100644 --- a/src/mongo/dbtests/wildcard_multikey_persistence_test.cpp +++ b/src/mongo/dbtests/wildcard_multikey_persistence_test.cpp @@ -101,7 +101,11 @@ protected: // Obtain a cursor over the index, and confirm that the keys are present in order. auto indexCursor = getIndexCursor(collection, indexName); - auto indexKey = indexCursor->seek(kMinBSONKey, true); + + KeyString::Value keyStringForSeek = IndexEntryComparison::makeKeyStringFromBSONKeyForSeek( + kMinBSONKey, KeyString::Version::V1, Ordering::make(BSONObj()), true, true); + + auto indexKey = indexCursor->seek(keyStringForSeek); try { for (const auto& expectedKey : expectedKeys) { ASSERT(indexKey); |