void restore() override {
            // Always do a full seek on restore. We cannot use our last position since index
            // entries may have been inserted closer to our endpoint and we would need to move
            // over them.
            seekEndCursor();

            if (_savedAtEnd) {
                _isEOF = true;
                return;
            }

            // Need to find our position from the root.
            locate(_savedKey, _savedLoc);

            _lastMoveWasRestore = _isEOF;  // We weren't EOF but now are.
            if (!_lastMoveWasRestore) {
                // For standard (non-unique) indices, restoring to either a new key or a new record
                // id means that the next key should be the one we just restored to.
                //
                // Cursors for unique indices should never return the same key twice, so we don't
                // consider the restore as having moved the cursor position if the record id
                // changes. In this case we use a null record id so that only the keys are compared.
                auto savedLocToUse = _isUnique ? RecordId() : _savedLoc;
                _lastMoveWasRestore =
                    (_data.value_comp().compare(*_it, {_savedKey, savedLocToUse}) != 0);
            }
        }
        void setEndPosition(const BSONObj& key, bool inclusive) override {
            if (key.isEmpty()) {
                // This means scan to end of index.
                _endState = boost::none;
                return;
            }

            // NOTE: this uses the opposite min/max rules as a normal seek because a forward
            // scan should land after the key if inclusive and before if exclusive.
            _endState = EndState(stripFieldNames(key),
                                 _forward == inclusive ? RecordId::max() : RecordId::min());
            seekEndCursor();
        }
        void restore() override {
            // Always do a full seek on restore. We cannot use our last position since index
            // entries may have been inserted closer to our endpoint and we would need to move
            // over them.
            seekEndCursor();

            if (_savedAtEnd) {
                _isEOF = true;
                return;
            }

            // Need to find our position from the root.
            locate(_savedKey, _savedLoc);

            _lastMoveWasRestore = _isEOF  // We weren't EOF but now are.
                || _data.value_comp().compare(*_it, {_savedKey, _savedLoc}) != 0;
        }