summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/exec/distinct_scan.cpp7
-rw-r--r--src/mongo/db/exec/index_scan.cpp13
-rw-r--r--src/mongo/db/index/wildcard_access_method.cpp101
-rw-r--r--src/mongo/db/storage/biggie/biggie_sorted_impl.cpp54
-rw-r--r--src/mongo/db/storage/biggie/biggie_sorted_impl.h11
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.cpp26
-rw-r--r--src/mongo/db/storage/index_entry_comparison.cpp13
-rw-r--r--src/mongo/db/storage/index_entry_comparison.h16
-rw-r--r--src/mongo/db/storage/key_string.cpp88
-rw-r--r--src/mongo/db/storage/key_string.h8
-rw-r--r--src/mongo/db/storage/mobile/mobile_index.cpp17
-rw-r--r--src/mongo/db/storage/sorted_data_interface.h17
-rw-r--r--src/mongo/db/storage/sorted_data_interface_test_cursor_advanceto.cpp151
-rw-r--r--src/mongo/db/storage/sorted_data_interface_test_insert.cpp4
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp22
15 files changed, 382 insertions, 166 deletions
diff --git a/src/mongo/db/exec/distinct_scan.cpp b/src/mongo/db/exec/distinct_scan.cpp
index 22af764672f..3b18a3e6bbd 100644
--- a/src/mongo/db/exec/distinct_scan.cpp
+++ b/src/mongo/db/exec/distinct_scan.cpp
@@ -79,7 +79,12 @@ PlanStage::StageState DistinctScan::doWork(WorkingSetID* out) {
try {
if (!_cursor)
_cursor = indexAccessMethod()->newCursor(getOpCtx(), _scanDirection == 1);
- kv = _cursor->seek(_seekPoint);
+ kv = _cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ _seekPoint,
+ indexAccessMethod()->getSortedDataInterface()->getKeyStringVersion(),
+ indexAccessMethod()->getSortedDataInterface()->getOrdering(),
+ _scanDirection == 1));
+
} catch (const WriteConflictException&) {
*out = WorkingSet::INVALID_ID;
return PlanStage::NEED_YIELD;
diff --git a/src/mongo/db/exec/index_scan.cpp b/src/mongo/db/exec/index_scan.cpp
index 7e5c9c19152..4fee1efa50d 100644
--- a/src/mongo/db/exec/index_scan.cpp
+++ b/src/mongo/db/exec/index_scan.cpp
@@ -114,8 +114,11 @@ boost::optional<IndexKeyEntry> IndexScan::initIndexScan() {
if (!_checker->getStartSeekPoint(&_seekPoint))
return boost::none;
-
- return _indexCursor->seek(_seekPoint);
+ return _indexCursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ _seekPoint,
+ indexAccessMethod()->getSortedDataInterface()->getKeyStringVersion(),
+ indexAccessMethod()->getSortedDataInterface()->getOrdering(),
+ _forward));
}
}
}
@@ -133,7 +136,11 @@ PlanStage::StageState IndexScan::doWork(WorkingSetID* out) {
break;
case NEED_SEEK:
++_specificStats.seeks;
- kv = _indexCursor->seek(_seekPoint);
+ kv = _indexCursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ _seekPoint,
+ indexAccessMethod()->getSortedDataInterface()->getKeyStringVersion(),
+ indexAccessMethod()->getSortedDataInterface()->getOrdering(),
+ _forward));
break;
case HIT_END:
return PlanStage::IS_EOF;
diff --git a/src/mongo/db/index/wildcard_access_method.cpp b/src/mongo/db/index/wildcard_access_method.cpp
index 8a6a5564e0a..cabf81df2c6 100644
--- a/src/mongo/db/index/wildcard_access_method.cpp
+++ b/src/mongo/db/index/wildcard_access_method.cpp
@@ -90,51 +90,62 @@ std::set<FieldRef> WildcardAccessMethod::_getMultikeyPathSet(
OperationContext* opCtx,
const IndexBounds& indexBounds,
MultikeyMetadataAccessStats* stats) const {
- return writeConflictRetry(opCtx,
- "wildcard multikey path retrieval",
- _descriptor->parentNS().ns(),
- [&]() -> std::set<FieldRef> {
- stats->numSeeks = 0;
- stats->keysExamined = 0;
- auto cursor = newCursor(opCtx);
-
- constexpr int kForward = 1;
- const auto keyPattern = BSON("" << 1 << "" << 1);
- IndexBoundsChecker checker(&indexBounds, keyPattern, kForward);
- IndexSeekPoint seekPoint;
- if (!checker.getStartSeekPoint(&seekPoint)) {
- return {};
- }
-
- std::set<FieldRef> multikeyPaths{};
- auto entry = cursor->seek(seekPoint);
- ++stats->numSeeks;
- while (entry) {
- ++stats->keysExamined;
-
- switch (checker.checkKey(entry->key, &seekPoint)) {
- case IndexBoundsChecker::VALID:
- multikeyPaths.emplace(
- extractMultikeyPathFromIndexKey(*entry));
- entry = cursor->next();
- break;
-
- case IndexBoundsChecker::MUST_ADVANCE:
- ++stats->numSeeks;
- entry = cursor->seek(seekPoint);
- break;
-
- case IndexBoundsChecker::DONE:
- entry = boost::none;
- break;
-
- default:
- MONGO_UNREACHABLE;
- }
- }
-
- return multikeyPaths;
- });
+ return writeConflictRetry(
+ opCtx,
+ "wildcard multikey path retrieval",
+ _descriptor->parentNS().ns(),
+ [&]() -> std::set<FieldRef> {
+ stats->numSeeks = 0;
+ stats->keysExamined = 0;
+ auto cursor = newCursor(opCtx);
+
+ constexpr int kForward = 1;
+ const auto keyPattern = BSON("" << 1 << "" << 1);
+ IndexBoundsChecker checker(&indexBounds, keyPattern, kForward);
+ IndexSeekPoint seekPoint;
+ if (!checker.getStartSeekPoint(&seekPoint)) {
+ return {};
+ }
+
+ std::set<FieldRef> multikeyPaths{};
+ auto entry = cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint,
+ getSortedDataInterface()->getKeyStringVersion(),
+ getSortedDataInterface()->getOrdering(),
+ kForward));
+
+
+ ++stats->numSeeks;
+ while (entry) {
+ ++stats->keysExamined;
+
+ switch (checker.checkKey(entry->key, &seekPoint)) {
+ case IndexBoundsChecker::VALID:
+ multikeyPaths.emplace(extractMultikeyPathFromIndexKey(*entry));
+ entry = cursor->next();
+ break;
+
+ case IndexBoundsChecker::MUST_ADVANCE:
+ ++stats->numSeeks;
+ entry = cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint,
+ getSortedDataInterface()->getKeyStringVersion(),
+ getSortedDataInterface()->getOrdering(),
+ kForward));
+
+ break;
+
+ case IndexBoundsChecker::DONE:
+ entry = boost::none;
+ break;
+
+ default:
+ MONGO_UNREACHABLE;
+ }
+ }
+
+ return multikeyPaths;
+ });
}
diff --git a/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp b/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp
index 7e80c580f4b..eba274f6c62 100644
--- a/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp
+++ b/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp
@@ -729,12 +729,11 @@ boost::optional<IndexKeyEntry> SortedDataInterface::Cursor::next(RequestedInfo p
return keyStringToIndexKeyEntry(_reverseIt->first, _reverseIt->second, _order);
}
-boost::optional<IndexKeyEntry> SortedDataInterface::Cursor::seekAfterProcessing(BSONObj finalKey,
- bool inclusive) {
+boost::optional<IndexKeyEntry> SortedDataInterface::Cursor::seekAfterProcessing(BSONObj finalKey) {
std::string workingCopyBound;
KeyString::Builder ks(KeyString::Version::V1, finalKey, _order);
- auto ksEntry = seekAfterProcessing(ks.getValueCopy(), inclusive);
+ auto ksEntry = seekAfterProcessing(ks.getValueCopy());
const BSONObj bson = KeyString::toBson(ksEntry->keyString.getBuffer(),
ksEntry->keyString.getSize(),
@@ -744,7 +743,24 @@ boost::optional<IndexKeyEntry> SortedDataInterface::Cursor::seekAfterProcessing(
}
boost::optional<KeyStringEntry> SortedDataInterface::Cursor::seekAfterProcessing(
- const KeyString::Value& keyStringVal, bool inclusive) {
+ const KeyString::Value& keyStringVal) {
+
+ KeyString::Discriminator discriminator = KeyString::decodeDiscriminator(
+ keyStringVal.getBuffer(), keyStringVal.getSize(), _order, keyStringVal.getTypeBits());
+
+ bool inclusive;
+ switch (discriminator) {
+ case KeyString::Discriminator::kInclusive:
+ inclusive = true;
+ break;
+ case KeyString::Discriminator::kExclusiveBefore:
+ inclusive = _forward;
+ break;
+ case KeyString::Discriminator::kExclusiveAfter:
+ inclusive = !_forward;
+ break;
+ }
+
std::string workingCopyBound;
// Similar to above, if forward and inclusive or reverse and not inclusive, then use min() for
// recordId. Else, we should use max().
@@ -818,23 +834,15 @@ boost::optional<IndexKeyEntry> SortedDataInterface::Cursor::seek(const BSONObj&
bool inclusive,
RequestedInfo) {
BSONObj finalKey = BSONObj::stripFieldNames(key);
- KeyString::Builder keyString(KeyString::Version::V1, finalKey, _order);
- auto ksValue = seek(keyString.getValueCopy(), inclusive);
- if (ksValue) {
- BSONObj bson = KeyString::toBson(ksValue->keyString.getBuffer(),
- ksValue->keyString.getSize(),
- _order,
- ksValue->keyString.getTypeBits());
- return IndexKeyEntry(bson, ksValue->loc);
- }
- return boost::none;
+ 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 IndexSeekPoint& seekPoint,
+boost::optional<IndexKeyEntry> SortedDataInterface::Cursor::seek(const KeyString::Value& keyString,
RequestedInfo parts) {
- const BSONObj key = IndexEntryComparison::makeQueryObject(seekPoint, _forward);
- KeyString::Builder keyString(KeyString::Version::V1, key, _order);
- auto ksValue = seek(keyString.getValueCopy(), true);
+ boost::optional<KeyStringEntry> ksValue = seekForKeyString(keyString);
if (ksValue) {
BSONObj bson = KeyString::toBson(ksValue->keyString.getBuffer(),
ksValue->keyString.getSize(),
@@ -845,11 +853,11 @@ boost::optional<IndexKeyEntry> SortedDataInterface::Cursor::seek(const IndexSeek
return boost::none;
}
-boost::optional<KeyStringEntry> SortedDataInterface::Cursor::seek(
- const KeyString::Value& keyStringValue, bool inclusive) {
+boost::optional<KeyStringEntry> SortedDataInterface::Cursor::seekForKeyString(
+ const KeyString::Value& keyStringValue) {
_lastMoveWasRestore = false;
_atEOF = false;
- return seekAfterProcessing(keyStringValue, inclusive);
+ return seekAfterProcessing(keyStringValue);
}
boost::optional<IndexKeyEntry> SortedDataInterface::Cursor::seekExact(const BSONObj& key,
@@ -862,7 +870,7 @@ boost::optional<IndexKeyEntry> SortedDataInterface::Cursor::seekExact(const BSON
ksEntry->keyString.getSize(),
_order,
ksEntry->keyString.getTypeBits());
- auto kv = seekAfterProcessing(bson, true);
+ auto kv = seekAfterProcessing(bson);
if (kv) {
return kv;
}
@@ -872,7 +880,7 @@ boost::optional<IndexKeyEntry> SortedDataInterface::Cursor::seekExact(const BSON
boost::optional<KeyStringEntry> SortedDataInterface::Cursor::seekExact(
const KeyString::Value& keyStringValue) {
- auto ksEntry = seek(keyStringValue, true);
+ auto ksEntry = seekForKeyString(keyStringValue);
if (!ksEntry) {
return {};
}
diff --git a/src/mongo/db/storage/biggie/biggie_sorted_impl.h b/src/mongo/db/storage/biggie/biggie_sorted_impl.h
index e315602492b..5e208c039e3 100644
--- a/src/mongo/db/storage/biggie/biggie_sorted_impl.h
+++ b/src/mongo/db/storage/biggie/biggie_sorted_impl.h
@@ -123,10 +123,10 @@ public:
virtual boost::optional<IndexKeyEntry> seek(const BSONObj& key,
bool inclusive,
RequestedInfo parts = kKeyAndLoc) override;
- virtual boost::optional<IndexKeyEntry> seek(const IndexSeekPoint& seekPoint,
+ virtual boost::optional<IndexKeyEntry> seek(const KeyString::Value& keyString,
RequestedInfo parts = kKeyAndLoc) override;
- virtual boost::optional<KeyStringEntry> seek(const KeyString::Value& keyStringValue,
- bool inclusive) override;
+ virtual boost::optional<KeyStringEntry> seekForKeyString(
+ const KeyString::Value& keyStringValue) override;
virtual boost::optional<IndexKeyEntry> seekExact(const BSONObj& key,
RequestedInfo parts = kKeyAndLoc) override;
virtual boost::optional<KeyStringEntry> seekExact(
@@ -142,9 +142,8 @@ public:
// This is a helper function to check if the cursor is valid or not.
bool checkCursorValid();
// This is a helper function for seek.
- boost::optional<IndexKeyEntry> seekAfterProcessing(BSONObj finalKey, bool inclusive);
- boost::optional<KeyStringEntry> seekAfterProcessing(const KeyString::Value& keyString,
- bool inclusive);
+ boost::optional<IndexKeyEntry> seekAfterProcessing(BSONObj finalKey);
+ boost::optional<KeyStringEntry> seekAfterProcessing(const KeyString::Value& keyString);
OperationContext* _opCtx;
// This is the "working copy" of the master "branch" in the git analogy.
StringStore* _workingCopy;
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 7c64337d5b1..7e5f213a0c9 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
@@ -324,10 +324,11 @@ public:
return *_it;
}
- boost::optional<IndexKeyEntry> seek(const IndexSeekPoint& seekPoint,
- RequestedInfo) override {
- // Query encodes exclusive case so it can be treated as an inclusive query.
- const BSONObj query = IndexEntryComparison::makeQueryObject(seekPoint, _forward);
+ boost::optional<IndexKeyEntry> seek(
+ const KeyString::Value& keyString,
+ RequestedInfo parts = RequestedInfo::kKeyAndLoc) override {
+ const BSONObj query = KeyString::toBsonSafeWithDiscriminator(
+ keyString.getBuffer(), keyString.getSize(), _ordering, keyString.getTypeBits());
locate(query, _forward ? RecordId::min() : RecordId::max());
_lastMoveWasRestore = false;
if (_isEOF)
@@ -336,17 +337,12 @@ public:
return *_it;
}
- boost::optional<KeyStringEntry> seek(const KeyString::Value& keyStringValue,
- bool inclusive) override {
- const BSONObj query = KeyString::toBson(keyStringValue.getBuffer(),
- keyStringValue.getSize(),
- _ordering,
- keyStringValue.getTypeBits());
- auto kv = seek(query, inclusive, kKeyAndLoc);
- if (kv) {
- KeyString::Builder ks(KeyString::Version::V1, kv->key, _ordering);
- ks.appendRecordId(kv->loc);
- return KeyStringEntry(ks.getValueCopy(), kv->loc);
+ boost::optional<KeyStringEntry> seekForKeyString(const KeyString::Value& keyStringValue) {
+ auto indexKeyEntry = seek(keyStringValue);
+ if (indexKeyEntry) {
+ KeyString::Builder builder(KeyString::Version::V1, indexKeyEntry->key, _ordering);
+ builder.appendRecordId(indexKeyEntry->loc);
+ return KeyStringEntry(builder.getValueCopy(), indexKeyEntry->loc);
} else {
return {};
}
diff --git a/src/mongo/db/storage/index_entry_comparison.cpp b/src/mongo/db/storage/index_entry_comparison.cpp
index a3d4fcd98d4..14823066fba 100644
--- a/src/mongo/db/storage/index_entry_comparison.cpp
+++ b/src/mongo/db/storage/index_entry_comparison.cpp
@@ -169,6 +169,19 @@ BSONObj IndexEntryComparison::makeQueryObject(const BSONObj& keyPrefix,
return bb.obj();
}
+KeyString::Value IndexEntryComparison::makeKeyStringForSeekPoint(const IndexSeekPoint& seekPoint,
+ KeyString::Version version,
+ Ordering ord,
+ bool isForward) {
+ BSONObj key = IndexEntryComparison::makeQueryObject(seekPoint, isForward);
+
+ const auto discriminator = isForward ? KeyString::Discriminator::kExclusiveBefore
+ : KeyString::Discriminator::kExclusiveAfter;
+
+ KeyString::Builder builder(version, key, ord, discriminator);
+ 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 0bed9e79200..35dc1def735 100644
--- a/src/mongo/db/storage/index_entry_comparison.h
+++ b/src/mongo/db/storage/index_entry_comparison.h
@@ -232,6 +232,22 @@ public:
isForward ? 1 : -1);
}
+ /**
+ * 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
+ * can be exclusive. This means that the first matching entry in the index is the first key in
+ * the index after the query. The meaning of "after" depends on isForward.
+ *
+ * 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);
+
private:
// Ordering is used in comparison() to compare BSONElements
const Ordering _order;
diff --git a/src/mongo/db/storage/key_string.cpp b/src/mongo/db/storage/key_string.cpp
index 92005ed1ab2..2e959cc349f 100644
--- a/src/mongo/db/storage/key_string.cpp
+++ b/src/mongo/db/storage/key_string.cpp
@@ -2380,6 +2380,94 @@ size_t getKeySize(const char* buffer, size_t len, Ordering ord, const TypeBits&
return (len - (remainingBytes - 1));
}
+// Unlike toBsonSafe(), this function will convert the discriminator byte back.
+// This discriminator byte only exists in KeyStrings for queries, not in KeyStrings stored in an
+// index. This function is only used by EphemeralForTest because it uses BSON with discriminator
+// rather than KeyString to compare.
+BSONObj toBsonSafeWithDiscriminator(const char* buffer,
+ size_t len,
+ Ordering ord,
+ const TypeBits& typeBits) {
+ boost::optional<std::string> discriminatorBit;
+ int fieldNo = -1;
+
+ // First pass, get the discriminatorBit if there is any.
+ {
+ BSONObjBuilder builder;
+ BufReader reader(buffer, len);
+ TypeBits::Reader typeBitsReader(typeBits);
+ for (int i = 0; reader.remaining(); i++) {
+ const bool invert = (ord.get(i) == -1);
+ uint8_t ctype = readType<uint8_t>(&reader, invert);
+ if (ctype == kLess || ctype == kGreater) {
+ discriminatorBit = ctype == kLess ? "l" : "r";
+ fieldNo = i - 1;
+ ctype = readType<uint8_t>(&reader, invert);
+ invariant(ctype == kEnd);
+ }
+
+ if (ctype == kEnd) {
+ break;
+ }
+
+ toBsonValue(
+ ctype, &reader, &typeBitsReader, invert, typeBits.version, &(builder << ""), 1);
+ }
+ // Early return if there is no discriminatorBit.
+ if (!discriminatorBit)
+ return builder.obj();
+ }
+
+ // Second pass, add discriminatorBit as the fieldName.
+ {
+ BSONObjBuilder builder;
+ BufReader reader(buffer, len);
+ TypeBits::Reader typeBitsReader(typeBits);
+ for (int i = 0; reader.remaining(); i++) {
+ const bool invert = (ord.get(i) == -1);
+ uint8_t ctype = readType<uint8_t>(&reader, invert);
+ if (ctype == kLess || ctype == kGreater) {
+ ctype = readType<uint8_t>(&reader, invert);
+ invariant(ctype == kEnd);
+ }
+
+ if (ctype == kEnd) {
+ break;
+ }
+
+ auto fn = i == fieldNo ? discriminatorBit.get() : "";
+ toBsonValue(
+ ctype, &reader, &typeBitsReader, invert, typeBits.version, &(builder << fn), 1);
+ }
+ return builder.obj();
+ }
+}
+
+// This discriminator byte only exists in KeyStrings for queries, not in KeyStrings stored in an
+// index. This function is only used by Biggie because it needs to extract the discriminator to do
+// the query.
+Discriminator decodeDiscriminator(const char* buffer,
+ size_t len,
+ Ordering ord,
+ const TypeBits& typeBits) {
+ BSONObjBuilder builder;
+ BufReader reader(buffer, len);
+ TypeBits::Reader typeBitsReader(typeBits);
+ for (int i = 0; reader.remaining(); i++) {
+ const bool invert = (ord.get(i) == -1);
+ uint8_t ctype = readType<uint8_t>(&reader, invert);
+ if (ctype == kLess || ctype == kGreater) {
+ return ctype == kLess ? Discriminator::kExclusiveBefore
+ : Discriminator::kExclusiveAfter;
+ }
+
+ if (ctype == kEnd)
+ break;
+ toBsonValue(ctype, &reader, &typeBitsReader, invert, typeBits.version, &(builder << ""), 1);
+ }
+ return Discriminator::kInclusive;
+}
+
BSONObj toBsonSafe(const char* buffer, size_t len, Ordering ord, const TypeBits& typeBits) {
BSONObjBuilder builder;
BufReader reader(buffer, len);
diff --git a/src/mongo/db/storage/key_string.h b/src/mongo/db/storage/key_string.h
index 82410924f67..f82dd4a2259 100644
--- a/src/mongo/db/storage/key_string.h
+++ b/src/mongo/db/storage/key_string.h
@@ -803,6 +803,14 @@ size_t getKeySize(const char* buffer, size_t len, Ordering ord, const TypeBits&
BSONObj toBson(StringData data, Ordering ord, const TypeBits& types);
BSONObj toBson(const char* buffer, size_t len, Ordering ord, const TypeBits& types) noexcept;
BSONObj toBsonSafe(const char* buffer, size_t len, Ordering ord, const TypeBits& types);
+BSONObj toBsonSafeWithDiscriminator(const char* buffer,
+ size_t len,
+ Ordering ord,
+ const TypeBits& typeBits);
+Discriminator decodeDiscriminator(const char* buffer,
+ size_t len,
+ Ordering ord,
+ const TypeBits& typeBits);
template <class T>
BSONObj toBson(const T& keyString, Ordering ord) noexcept {
diff --git a/src/mongo/db/storage/mobile/mobile_index.cpp b/src/mongo/db/storage/mobile/mobile_index.cpp
index 1b4621d2502..0ed2e365e47 100644
--- a/src/mongo/db/storage/mobile/mobile_index.cpp
+++ b/src/mongo/db/storage/mobile/mobile_index.cpp
@@ -413,29 +413,24 @@ public:
: KeyString::Discriminator::kExclusiveAfter;
_startPosition.resetToKey(
BSONObj::stripFieldNames(key), _index.getOrdering(), discriminator);
- seek(_startPosition.getValueCopy(), inclusive /* unused by implementation */);
+ seekForKeyString(_startPosition.getValueCopy());
if (_isEOF) {
return {};
}
return getCurrentEntry(parts);
}
- boost::optional<IndexKeyEntry> seek(const IndexSeekPoint& seekPoint,
+ boost::optional<IndexKeyEntry> seek(const KeyString::Value& keyString,
RequestedInfo parts) override {
- BSONObj startKey = IndexEntryComparison::makeQueryObject(seekPoint, _isForward);
-
- const auto discriminator = _isForward ? KeyString::Discriminator::kExclusiveBefore
- : KeyString::Discriminator::kExclusiveAfter;
- _startPosition.resetToKey(startKey, _index.getOrdering(), discriminator);
-
- seek(_startPosition.getValueCopy(), true /* unused by implementation */);
+ seekForKeyString(keyString);
if (_isEOF) {
return {};
}
return getCurrentEntry(parts);
}
- boost::optional<KeyStringEntry> seek(const KeyString::Value& keyStringValue, bool) override {
+ boost::optional<KeyStringEntry> seekForKeyString(
+ const KeyString::Value& keyStringValue) override {
_startPosition.resetFromBuffer(keyStringValue.getBuffer(), keyStringValue.getSize());
_doSeek();
_updatePosition();
@@ -484,7 +479,7 @@ public:
}
boost::optional<KeyStringEntry> seekExact(const KeyString::Value& keyStringValue) override {
- auto ksEntry = seek(keyStringValue, true);
+ auto ksEntry = seekForKeyString(keyStringValue);
if (!ksEntry) {
return {};
}
diff --git a/src/mongo/db/storage/sorted_data_interface.h b/src/mongo/db/storage/sorted_data_interface.h
index 53c991a8652..004ab479fd6 100644
--- a/src/mongo/db/storage/sorted_data_interface.h
+++ b/src/mongo/db/storage/sorted_data_interface.h
@@ -283,16 +283,19 @@ public:
RequestedInfo parts = kKeyAndLoc) = 0;
/**
- * Seeks to the position described by seekPoint and returns the current position.
- *
- * NOTE: most implementations should just pass seekPoint to
- * IndexEntryComparison::makeQueryObject().
+ * Seeks to the provided keyString and returns the KeyStringEntry.
+ * The provided keyString has discriminator information encoded.
+ */
+ virtual boost::optional<KeyStringEntry> seekForKeyString(
+ const KeyString::Value& keyString) = 0;
+
+ /**
+ * Seeks to the provided keyString and returns the IndexKeyEntry.
+ * The provided keyString has discriminator information encoded.
*/
- virtual boost::optional<IndexKeyEntry> seek(const IndexSeekPoint& seekPoint,
+ virtual boost::optional<IndexKeyEntry> seek(const KeyString::Value& keyString,
RequestedInfo parts = kKeyAndLoc) = 0;
- virtual boost::optional<KeyStringEntry> seek(const KeyString::Value& keyString,
- bool inclusive) = 0;
/**
* Seeks to a key with a hint to the implementation that you only want exact matches. If
* an exact match can't be found, boost::none will be returned and the resulting
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 7b459a9b22b..084242d145b 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
@@ -89,16 +89,24 @@ TEST(SortedDataInterface, AdvanceTo) {
seekPoint.keyPrefix = key1;
seekPoint.prefixLen = 1;
seekPoint.prefixExclusive = false;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key1, loc1));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key1, loc1));
seekPoint.keyPrefix = key2;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key2, loc4));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key2, loc4));
seekPoint.keyPrefix = key3;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key3, loc5));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key3, loc5));
seekPoint.keyPrefix = key4;
- ASSERT_EQ(cursor->seek(seekPoint), boost::none);
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ boost::none);
}
}
@@ -145,9 +153,10 @@ TEST(SortedDataInterface, AdvanceToReversed) {
}
{
+ bool isForward = false;
const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
const std::unique_ptr<SortedDataInterface::Cursor> cursor(
- sorted->newCursor(opCtx.get(), false));
+ sorted->newCursor(opCtx.get(), isForward));
ASSERT_EQ(cursor->seek(key3, true), IndexKeyEntry(key3, loc5));
@@ -155,16 +164,24 @@ TEST(SortedDataInterface, AdvanceToReversed) {
seekPoint.keyPrefix = key3;
seekPoint.prefixLen = 1;
seekPoint.prefixExclusive = false;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key3, loc5));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ IndexKeyEntry(key3, loc5));
seekPoint.keyPrefix = key2;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key2, loc2));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ IndexKeyEntry(key2, loc2));
seekPoint.keyPrefix = key1;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key1, loc1));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ IndexKeyEntry(key1, loc1));
seekPoint.keyPrefix = key0;
- ASSERT_EQ(cursor->seek(seekPoint), boost::none);
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ boost::none);
}
}
@@ -208,10 +225,14 @@ TEST(SortedDataInterface, AdvanceToKeyBeforeCursorPosition) {
seekPoint.keyPrefix = key0;
seekPoint.prefixLen = 1;
seekPoint.prefixExclusive = false;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key1, loc1));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key1, loc1));
seekPoint.prefixExclusive = true;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key1, loc1));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key1, loc1));
}
}
@@ -246,9 +267,10 @@ TEST(SortedDataInterface, AdvanceToKeyAfterCursorPositionReversed) {
}
{
+ bool isForward = false;
const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
const std::unique_ptr<SortedDataInterface::Cursor> cursor(
- sorted->newCursor(opCtx.get(), false));
+ sorted->newCursor(opCtx.get(), isForward));
ASSERT_EQ(cursor->seek(key2, true), IndexKeyEntry(key2, loc2));
@@ -256,10 +278,14 @@ TEST(SortedDataInterface, AdvanceToKeyAfterCursorPositionReversed) {
seekPoint.keyPrefix = key3;
seekPoint.prefixLen = 1;
seekPoint.prefixExclusive = false;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key2, loc2));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ IndexKeyEntry(key2, loc2));
seekPoint.prefixExclusive = true;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key2, loc2));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ IndexKeyEntry(key2, loc2));
}
}
@@ -303,10 +329,14 @@ TEST(SortedDataInterface, AdvanceToKeyAtCursorPosition) {
seekPoint.keyPrefix = key1;
seekPoint.prefixLen = 1;
seekPoint.prefixExclusive = false;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key1, loc1));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key1, loc1));
seekPoint.prefixExclusive = true;
- ASSERT_EQ(cursor->seek(seekPoint), boost::none);
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ boost::none);
}
}
@@ -341,9 +371,10 @@ TEST(SortedDataInterface, AdvanceToKeyAtCursorPositionReversed) {
}
{
+ bool isForward = false;
const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
const std::unique_ptr<SortedDataInterface::Cursor> cursor(
- sorted->newCursor(opCtx.get(), false));
+ sorted->newCursor(opCtx.get(), isForward));
ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1));
@@ -351,10 +382,14 @@ TEST(SortedDataInterface, AdvanceToKeyAtCursorPositionReversed) {
seekPoint.keyPrefix = key1;
seekPoint.prefixLen = 1;
seekPoint.prefixExclusive = false;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key1, loc1));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ IndexKeyEntry(key1, loc1));
seekPoint.prefixExclusive = true;
- ASSERT_EQ(cursor->seek(seekPoint), boost::none);
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ boost::none);
}
}
@@ -409,16 +444,24 @@ TEST(SortedDataInterface, AdvanceToExclusive) {
seekPoint.keyPrefix = key1;
seekPoint.prefixLen = 1;
seekPoint.prefixExclusive = true;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key2, loc4));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key2, loc4));
seekPoint.keyPrefix = key2;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key3, loc5));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key3, loc5));
seekPoint.keyPrefix = key3;
- ASSERT_EQ(cursor->seek(seekPoint), boost::none);
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ boost::none);
seekPoint.keyPrefix = key4;
- ASSERT_EQ(cursor->seek(seekPoint), boost::none);
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ boost::none);
}
}
@@ -464,9 +507,10 @@ TEST(SortedDataInterface, AdvanceToExclusiveReversed) {
}
{
+ bool isForward = false;
const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
const std::unique_ptr<SortedDataInterface::Cursor> cursor(
- sorted->newCursor(opCtx.get(), false));
+ sorted->newCursor(opCtx.get(), isForward));
ASSERT_EQ(cursor->seek(key3, true), IndexKeyEntry(key3, loc5));
@@ -474,16 +518,24 @@ TEST(SortedDataInterface, AdvanceToExclusiveReversed) {
seekPoint.keyPrefix = key3;
seekPoint.prefixLen = 1;
seekPoint.prefixExclusive = true;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key2, loc2));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ IndexKeyEntry(key2, loc2));
seekPoint.keyPrefix = key2;
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key1, loc1));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ IndexKeyEntry(key1, loc1));
seekPoint.keyPrefix = key1;
- ASSERT_EQ(cursor->seek(seekPoint), boost::none);
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ boost::none);
seekPoint.keyPrefix = key0;
- ASSERT_EQ(cursor->seek(seekPoint), boost::none);
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ boost::none);
}
}
@@ -534,10 +586,14 @@ TEST(SortedDataInterface, AdvanceToIndirect) {
seekPoint.suffixInclusive = {true};
suffix0 = key2.firstElement();
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key3, loc2));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key3, loc2));
suffix0 = key4.firstElement();
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key5, loc3));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key5, loc3));
}
}
@@ -589,10 +645,14 @@ TEST(SortedDataInterface, AdvanceToIndirectReversed) {
seekPoint.suffixInclusive = {true};
suffix0 = key4.firstElement();
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key3, loc2));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key3, loc2));
suffix0 = key2.firstElement();
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key1, loc1));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key1, loc1));
}
}
@@ -645,15 +705,21 @@ TEST(SortedDataInterface, AdvanceToIndirectExclusive) {
seekPoint.suffixInclusive = {false};
suffix0 = key2.firstElement();
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key3, loc2));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key3, loc2));
suffix0 = key4.firstElement();
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key5, loc3));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key5, loc3));
ASSERT_EQ(cursor->seek(key1, true), IndexKeyEntry(key1, loc1));
suffix0 = key3.firstElement();
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key5, loc3));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), true)),
+ IndexKeyEntry(key5, loc3));
}
}
@@ -694,9 +760,10 @@ TEST(SortedDataInterface, AdvanceToIndirectExclusiveReversed) {
}
{
+ bool isForward = false;
const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
const std::unique_ptr<SortedDataInterface::Cursor> cursor(
- sorted->newCursor(opCtx.get(), false));
+ sorted->newCursor(opCtx.get(), isForward));
ASSERT_EQ(cursor->seek(key5, true), IndexKeyEntry(key5, loc3));
@@ -707,15 +774,21 @@ TEST(SortedDataInterface, AdvanceToIndirectExclusiveReversed) {
seekPoint.suffixInclusive = {false};
suffix0 = key4.firstElement();
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key3, loc2));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ IndexKeyEntry(key3, loc2));
suffix0 = key2.firstElement();
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key1, loc1));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ IndexKeyEntry(key1, loc1));
ASSERT_EQ(cursor->seek(key5, true), IndexKeyEntry(key5, loc3));
suffix0 = key3.firstElement();
- ASSERT_EQ(cursor->seek(seekPoint), IndexKeyEntry(key1, loc1));
+ ASSERT_EQ(cursor->seek(IndexEntryComparison::makeKeyStringForSeekPoint(
+ seekPoint, sorted->getKeyStringVersion(), sorted->getOrdering(), isForward)),
+ IndexKeyEntry(key1, loc1));
}
}
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 49ebc79d238..4eae05ceea6 100644
--- a/src/mongo/db/storage/sorted_data_interface_test_insert.cpp
+++ b/src/mongo/db/storage/sorted_data_interface_test_insert.cpp
@@ -546,11 +546,11 @@ TEST(SortedDataInterface, InsertAndSeekKeyString) {
const std::unique_ptr<SortedDataInterface::Cursor> cursor(sorted->newCursor(opCtx.get()));
- auto ksEntry1 = cursor->seek(keyString1WithoutRecordId, true);
+ auto ksEntry1 = cursor->seekForKeyString(keyString1WithoutRecordId);
ASSERT_EQUALS(ksEntry1->keyString.compare(keyString1), 0);
ASSERT_EQUALS(ksEntry1->keyString.compare(keyString2), -1);
- auto ksEntry2 = cursor->seek(keyString2WithoutRecordId, true);
+ auto ksEntry2 = cursor->seekForKeyString(keyString2WithoutRecordId);
ASSERT_EQUALS(ksEntry2->keyString.compare(keyString2), 0);
ASSERT_EQUALS(ksEntry2->keyString.compare(keyString1), 1);
}
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
index a0bc61aebcd..a6e0c62d253 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
@@ -44,6 +44,7 @@
#include "mongo/db/json.h"
#include "mongo/db/repl/repl_settings.h"
#include "mongo/db/service_context.h"
+#include "mongo/db/storage/index_entry_comparison.h"
#include "mongo/db/storage/storage_options.h"
#include "mongo/db/storage/wiredtiger/wiredtiger_customization_hooks.h"
#include "mongo/db/storage/wiredtiger/wiredtiger_global_options.h"
@@ -830,25 +831,18 @@ public:
? KeyString::Discriminator::kExclusiveBefore
: KeyString::Discriminator::kExclusiveAfter;
_query.resetToKey(finalKey, _idx.getOrdering(), discriminator);
- seek(_query.getValueCopy(), inclusive /* unused by implementation */);
+ seekForKeyString(_query.getValueCopy());
return curr(parts);
}
- boost::optional<IndexKeyEntry> seek(const IndexSeekPoint& seekPoint,
- RequestedInfo parts) override {
- dassert(_opCtx->lockState()->isReadLocked());
- // TODO: don't go to a bson obj then to a KeyString, go straight
- BSONObj key = IndexEntryComparison::makeQueryObject(seekPoint, _forward);
-
- // makeQueryObject handles the discriminator in the real exclusive cases.
- const auto discriminator = _forward ? KeyString::Discriminator::kExclusiveBefore
- : KeyString::Discriminator::kExclusiveAfter;
- _query.resetToKey(key, _idx.getOrdering(), discriminator);
- seek(_query.getValueCopy(), true /* unused by implementation */);
+ boost::optional<IndexKeyEntry> seek(const KeyString::Value& keyString,
+ RequestedInfo parts = kKeyAndLoc) override {
+ seekForKeyString(keyString);
return curr(parts);
}
- boost::optional<KeyStringEntry> seek(const KeyString::Value& keyStringValue, bool) override {
+ boost::optional<KeyStringEntry> seekForKeyString(
+ const KeyString::Value& keyStringValue) override {
dassert(_opCtx->lockState()->isReadLocked());
seekWTCursor(keyStringValue);
@@ -899,7 +893,7 @@ public:
}
boost::optional<KeyStringEntry> seekExact(const KeyString::Value& keyStringValue) override {
- auto ksEntry = seek(keyStringValue, true);
+ auto ksEntry = seekForKeyString(keyStringValue);
if (!ksEntry) {
return {};
}