Skip to content

Commit 981902d

Browse files
paroskiEvergreen Agent
authored andcommitted
SERVER-83458 Fix regression in ProjectionDottedField benchmarks
1 parent 1d7055b commit 981902d

File tree

4 files changed

+92
-145
lines changed

4 files changed

+92
-145
lines changed

src/mongo/db/exec/sbe/vm/makeobj.cpp

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ void ByteCode::produceBsonObject(const MakeObjSpec* spec,
119119
const size_t numMandatoryLamsAndMakeObjs = spec->mandatoryFields.size() - spec->numValueArgs;
120120
const bool isClosed = spec->fieldsScopeIsClosed();
121121
const bool recordVisits = numValueArgs + numMandatoryLamsAndMakeObjs > 0;
122+
const auto defActionType =
123+
isClosed ? MakeObjSpec::ActionType::kDrop : MakeObjSpec::ActionType::kKeep;
122124

123125
// The 'visited' array keeps track of which computed fields have been visited so far so
124126
// that later we can append the non-visited computed fields to the end of the object.
@@ -141,9 +143,10 @@ void ByteCode::produceBsonObject(const MakeObjSpec* spec,
141143
// 'isClosed' is true, loop over the input object until 'fieldsLeft == 0' is true or until
142144
// 'fieldsLeft == 1 && valueArgsLeft == 1' is true.
143145
for (; !cursor.atEnd() && (fieldsLeft > (isClosed ? 1 : 0) || fieldsLeft != valueArgsLeft);
144-
cursor.moveNext()) {
145-
// Get the idx and type of the current field.
146-
auto [fieldIdx, t] = cursor.fieldIdxAndType();
146+
cursor.moveNext(fields)) {
147+
// Get the idx of the current field and the corresponding action type.
148+
auto fieldIdx = cursor.fieldIdx();
149+
auto t = fieldIdx != StringListSet::npos ? actions[fieldIdx].type() : defActionType;
147150

148151
if (t == MakeObjSpec::ActionType::kDrop) {
149152
fieldsLeft -= static_cast<uint8_t>(!isClosed);
@@ -218,7 +221,7 @@ void ByteCode::produceBsonObject(const MakeObjSpec* spec,
218221
// If 'isClosed' is false and 'cursor' has not reached the end of the input object, copy over
219222
// the remaining fields from the input object to the output object.
220223
if (!isClosed) {
221-
for (; !cursor.atEnd(); cursor.moveNext()) {
224+
for (; !cursor.atEnd(); cursor.moveNext(fields)) {
222225
cursor.appendTo(bob);
223226
}
224227
}
@@ -238,7 +241,7 @@ void ByteCode::produceBsonObject(const MakeObjSpec* spec,
238241

239242
// Get the field name for this field, and then consult 'action' to see what
240243
// action should be taken.
241-
auto fieldName = StringData(fields[fieldIdx]);
244+
StringData fieldName = fields[fieldIdx];
242245
auto& action = actions[fieldIdx];
243246

244247
if (action.isValueArg()) {
@@ -332,46 +335,32 @@ void ByteCode::produceBsonObjectWithInputFields(const MakeObjSpec* spec,
332335
using InputFields = MakeObjCursorInputFields;
333336

334337
const auto& fields = spec->fields;
335-
const auto& actions = spec->actions;
336-
const auto defActionType = spec->fieldsScopeIsClosed() ? MakeObjSpec::ActionType::kDrop
337-
: MakeObjSpec::ActionType::kKeep;
338-
339338
const size_t numInputFields = spec->numInputFields ? *spec->numInputFields : 0;
340339

341340
auto [fieldsStackOff, _] = stackOffs;
342341
auto inputFields = InputFields(*this, fieldsStackOff, numInputFields);
343342

344343
auto bsonObjCursor = objTag == TypeTags::bsonObject
345-
? boost::make_optional(
346-
BsonObjCursor(fields, actions, defActionType, value::bitcastTo<const char*>(objVal)))
344+
? boost::make_optional(BsonObjCursor(fields, value::bitcastTo<const char*>(objVal)))
347345
: boost::none;
348346
auto objCursor = objTag == TypeTags::Object
349-
? boost::make_optional(
350-
ObjectCursor(fields, actions, defActionType, value::getObjectView(objVal)))
347+
? boost::make_optional(ObjectCursor(fields, value::getObjectView(objVal)))
351348
: boost::none;
352349

353350
// Invoke the produceBsonObject() lambda with the appropriate cursor type.
354351
if (objTag == TypeTags::Null) {
355352
size_t n = numInputFields;
356-
produceBsonObject(spec,
357-
stackOffs,
358-
code,
359-
bob,
360-
InputFieldsOnlyCursor(fields, actions, defActionType, inputFields, n));
353+
produceBsonObject(
354+
spec, stackOffs, code, bob, InputFieldsOnlyCursor(fields, inputFields, n));
361355
} else if (objTag == TypeTags::bsonObject) {
362356
produceBsonObject(spec,
363357
stackOffs,
364358
code,
365359
bob,
366-
BsonObjWithInputFieldsCursor(
367-
fields, actions, defActionType, inputFields, *bsonObjCursor));
360+
BsonObjWithInputFieldsCursor(fields, inputFields, *bsonObjCursor));
368361
} else if (objTag == TypeTags::Object) {
369362
produceBsonObject(
370-
spec,
371-
stackOffs,
372-
code,
373-
bob,
374-
ObjWithInputFieldsCursor(fields, actions, defActionType, inputFields, *objCursor));
363+
spec, stackOffs, code, bob, ObjWithInputFieldsCursor(fields, inputFields, *objCursor));
375364
} else {
376365
MONGO_UNREACHABLE_TASSERT(8146602);
377366
}

src/mongo/db/exec/sbe/vm/makeobj_cursors.h

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -60,60 +60,56 @@ class BsonObjCursor {
6060
public:
6161
using InputFields = MakeObjCursorInputFields;
6262

63-
BsonObjCursor(const StringListSet& fields,
64-
const std::vector<MakeObjSpec::FieldAction>& actions,
65-
MakeObjSpec::ActionType defActionType,
66-
const char* be)
67-
: _fields(fields), _actions(actions), _defActionType(defActionType), _be(be) {
63+
BsonObjCursor(const StringListSet& fields, const char* be) : _be(be) {
6864
_last = _be + ConstDataView(_be).read<LittleEndian<uint32_t>>() - 1;
6965
_be += 4;
7066
if (_be != _last) {
67+
// Initialize '_name' and '_nextBe'.
7168
_name = bson::fieldNameAndLength(_be);
7269
_nextBe = bson::advance(_be, _name.size());
70+
// Look up '_name' in the 'fields' set.
71+
_fieldIdx = fields.findPos(_name);
7372
}
7473
}
7574

76-
inline bool atEnd() const {
75+
MONGO_COMPILER_ALWAYS_INLINE bool atEnd() const {
7776
return _be == _last;
7877
}
79-
inline void moveNext() {
78+
MONGO_COMPILER_ALWAYS_INLINE void moveNext(const StringListSet& fields) {
8079
_be = _nextBe;
8180
if (_be != _last) {
81+
// Update '_name' and '_nextBe'.
8282
_name = bson::fieldNameAndLength(_be);
8383
_nextBe = bson::advance(_be, _name.size());
84+
// Look up '_name' in the 'fields' set.
85+
_fieldIdx = fields.findPos(_name);
8486
}
8587
}
86-
inline StringData fieldName() const {
88+
MONGO_COMPILER_ALWAYS_INLINE StringData fieldName() const {
8789
return _name;
8890
}
89-
inline std::pair<size_t, MakeObjSpec::ActionType> fieldIdxAndType() const {
90-
// Look up '_name' in the '_fields' set.
91-
size_t fieldIdx = _fields.findPos(_name);
92-
// Return the index ('npos' if not found) and the ActionType for this field.
93-
auto type = fieldIdx != StringListSet::npos ? _actions[fieldIdx].type() : _defActionType;
94-
return {fieldIdx, type};
91+
MONGO_COMPILER_ALWAYS_INLINE size_t fieldIdx() const {
92+
return _fieldIdx;
9593
}
96-
inline std::pair<value::TypeTags, value::Value> value() const {
94+
MONGO_COMPILER_ALWAYS_INLINE std::pair<value::TypeTags, value::Value> value() const {
9795
return bson::convertFrom<true>(bsonElement());
9896
}
99-
inline void appendTo(UniqueBSONObjBuilder& bob) const {
97+
MONGO_COMPILER_ALWAYS_INLINE void appendTo(UniqueBSONObjBuilder& bob) const {
10098
bob.append(bsonElement());
10199
}
102100

103101
private:
104-
inline BSONElement bsonElement() const {
102+
MONGO_COMPILER_ALWAYS_INLINE BSONElement bsonElement() const {
105103
auto fieldNameLenWithNull = _name.size() + 1;
106104
auto totalSize = _nextBe - _be;
107105
return BSONElement(_be, fieldNameLenWithNull, totalSize, BSONElement::TrustedInitTag{});
108106
}
109107

110-
const StringListSet& _fields;
111-
const std::vector<MakeObjSpec::FieldAction>& _actions;
112-
MakeObjSpec::ActionType _defActionType;
113-
114108
const char* _be{nullptr};
115109
const char* _nextBe{nullptr};
116110
const char* _last{nullptr};
111+
112+
size_t _fieldIdx{0};
117113
StringData _name;
118114
};
119115

@@ -122,49 +118,49 @@ class ObjectCursor {
122118
public:
123119
using InputFields = MakeObjCursorInputFields;
124120

125-
ObjectCursor(const StringListSet& fields,
126-
const std::vector<MakeObjSpec::FieldAction>& actions,
127-
MakeObjSpec::ActionType defActionType,
128-
value::Object* objRoot)
129-
: _fields(fields),
130-
_actions(actions),
131-
_defActionType(defActionType),
132-
_objRoot(objRoot),
133-
_idx(0),
134-
_endIdx(_objRoot->size()) {}
135-
136-
inline bool atEnd() const {
121+
ObjectCursor(const StringListSet& fields, value::Object* objRoot)
122+
: _objRoot(objRoot), _idx(0), _endIdx(_objRoot->size()) {
123+
if (_idx != _endIdx) {
124+
// Initialize '_name'.
125+
_name = StringData(_objRoot->field(_idx));
126+
// Look up '_name' in the 'fields' set.
127+
_fieldIdx = fields.findPos(_name);
128+
}
129+
}
130+
131+
MONGO_COMPILER_ALWAYS_INLINE bool atEnd() const {
137132
return _idx == _endIdx;
138133
}
139-
inline void moveNext() {
134+
MONGO_COMPILER_ALWAYS_INLINE void moveNext(const StringListSet& fields) {
140135
++_idx;
136+
if (_idx != _endIdx) {
137+
// Update '_name'.
138+
_name = StringData(_objRoot->field(_idx));
139+
// Look up '_name' in the 'fields' set.
140+
_fieldIdx = fields.findPos(_name);
141+
}
141142
}
142-
inline StringData fieldName() const {
143+
MONGO_COMPILER_ALWAYS_INLINE StringData fieldName() const {
143144
return StringData(_objRoot->field(_idx));
144145
}
145-
inline std::pair<size_t, MakeObjSpec::ActionType> fieldIdxAndType() const {
146-
// Look up '_name' in the '_fields' set.
147-
size_t fieldIdx = _fields.findPos(fieldName());
148-
// Return the index ('npos' if not found) and the ActionType for this field.
149-
auto type = fieldIdx != StringListSet::npos ? _actions[fieldIdx].type() : _defActionType;
150-
return {fieldIdx, type};
146+
MONGO_COMPILER_ALWAYS_INLINE size_t fieldIdx() const {
147+
return _fieldIdx;
151148
}
152-
inline std::pair<value::TypeTags, value::Value> value() const {
149+
MONGO_COMPILER_ALWAYS_INLINE std::pair<value::TypeTags, value::Value> value() const {
153150
return _objRoot->getAt(_idx);
154151
}
155-
inline void appendTo(UniqueBSONObjBuilder& bob) const {
152+
MONGO_COMPILER_ALWAYS_INLINE void appendTo(UniqueBSONObjBuilder& bob) const {
156153
auto [tag, val] = value();
157154
bson::appendValueToBsonObj(bob, fieldName(), tag, val);
158155
}
159156

160157
private:
161-
const StringListSet& _fields;
162-
const std::vector<MakeObjSpec::FieldAction>& _actions;
163-
MakeObjSpec::ActionType _defActionType;
164-
165158
value::Object* _objRoot{nullptr};
166159
size_t _idx{0};
167160
size_t _endIdx{0};
161+
162+
size_t _fieldIdx{0};
163+
StringData _name;
168164
};
169165

170166
} // namespace mongo::sbe::vm

src/mongo/db/exec/sbe/vm/makeobj_input_fields_cursors.h

Lines changed: 22 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -59,24 +59,16 @@ class InputFieldsOnlyCursor {
5959
public:
6060
using InputFields = MakeObjCursorInputFields;
6161

62-
InputFieldsOnlyCursor(const StringListSet& fields,
63-
const std::vector<MakeObjSpec::FieldAction>& actions,
64-
MakeObjSpec::ActionType defActionType,
65-
const InputFields& values,
66-
size_t numItems)
67-
: _fields(fields),
68-
_actions(actions),
69-
_defActionType(defActionType),
70-
_values(values),
71-
_numItems(numItems) {
72-
moveNext();
62+
InputFieldsOnlyCursor(const StringListSet& fields, const InputFields& values, size_t numItems)
63+
: _values(values), _numItems(numItems) {
64+
moveNext(fields);
7365
}
7466

75-
inline bool atEnd() const {
67+
MONGO_COMPILER_ALWAYS_INLINE bool atEnd() const {
7668
return _reachedEnd;
7769
}
7870

79-
inline void moveNext() {
71+
MONGO_COMPILER_ALWAYS_INLINE void moveNext(const StringListSet& fields) {
8072
while (_current < _numItems) {
8173
size_t pos = _current;
8274
++_current;
@@ -85,7 +77,7 @@ class InputFieldsOnlyCursor {
8577

8678
if (tag != value::TypeTags::Nothing) {
8779
_fieldIdx = pos;
88-
_name = StringData(_fields[pos]);
80+
_name = fields[pos];
8981
_tag = tag;
9082
_val = val;
9183
return;
@@ -95,27 +87,24 @@ class InputFieldsOnlyCursor {
9587
_reachedEnd = true;
9688
}
9789

98-
inline StringData fieldName() const {
90+
MONGO_COMPILER_ALWAYS_INLINE StringData fieldName() const {
9991
return _name;
10092
}
10193

102-
inline std::pair<size_t, MakeObjSpec::ActionType> fieldIdxAndType() const {
103-
return {_fieldIdx, _actions[_fieldIdx].type()};
94+
MONGO_COMPILER_ALWAYS_INLINE size_t fieldIdx() const {
95+
return _fieldIdx;
10496
}
10597

106-
inline std::pair<value::TypeTags, value::Value> value() const {
98+
MONGO_COMPILER_ALWAYS_INLINE std::pair<value::TypeTags, value::Value> value() const {
10799
return {_tag, _val};
108100
}
109101

110-
inline void appendTo(UniqueBSONObjBuilder& bob) const {
102+
MONGO_COMPILER_ALWAYS_INLINE void appendTo(UniqueBSONObjBuilder& bob) const {
111103
auto [tag, val] = value();
112104
bson::appendValueToBsonObj(bob, _name, tag, val);
113105
}
114106

115107
private:
116-
const StringListSet& _fields;
117-
const std::vector<MakeObjSpec::FieldAction>& _actions;
118-
MakeObjSpec::ActionType _defActionType;
119108
const InputFields& _values;
120109

121110
size_t _current = 0;
@@ -134,30 +123,24 @@ class ObjectAndInputFieldsCursorBase {
134123
using InputFields = MakeObjCursorInputFields;
135124

136125
ObjectAndInputFieldsCursorBase(const StringListSet& fields,
137-
const std::vector<MakeObjSpec::FieldAction>& actions,
138-
MakeObjSpec::ActionType defActionType,
139126
const InputFields& values,
140127
ObjectCursorT objectCursor)
141-
: _fields(fields),
142-
_actions(actions),
143-
_defActionType(defActionType),
144-
_values(values),
145-
_objectCursor(std::move(objectCursor)) {
146-
moveNext();
128+
: _values(values), _objectCursor(std::move(objectCursor)) {
129+
moveNext(fields);
147130
}
148131

149-
inline bool atEnd() const {
132+
MONGO_COMPILER_ALWAYS_INLINE bool atEnd() const {
150133
return _reachedEnd;
151134
}
152135

153-
inline void moveNext() {
136+
MONGO_COMPILER_ALWAYS_INLINE void moveNext(const StringListSet& fields) {
154137
while (!_objectCursor.atEnd()) {
155138
StringData name = _objectCursor.fieldName();
156139
auto [fieldFromObjTag, fieldFromObjVal] = _objectCursor.value();
157140

158-
_objectCursor.moveNext();
141+
_objectCursor.moveNext(fields);
159142

160-
size_t pos = _fields.findPos(name);
143+
size_t pos = fields.findPos(name);
161144

162145
if (pos >= _values.size()) {
163146
_fieldIdx = pos;
@@ -181,31 +164,24 @@ class ObjectAndInputFieldsCursorBase {
181164
_reachedEnd = true;
182165
}
183166

184-
inline StringData fieldName() const {
167+
MONGO_COMPILER_ALWAYS_INLINE StringData fieldName() const {
185168
return _name;
186169
}
187170

188-
inline std::pair<size_t, MakeObjSpec::ActionType> fieldIdxAndType() const {
189-
if (_fieldIdx != StringListSet::npos) {
190-
return {_fieldIdx, _actions[_fieldIdx].type()};
191-
} else {
192-
return {StringListSet::npos, _defActionType};
193-
}
171+
MONGO_COMPILER_ALWAYS_INLINE size_t fieldIdx() const {
172+
return _fieldIdx;
194173
}
195174

196-
inline std::pair<value::TypeTags, value::Value> value() const {
175+
MONGO_COMPILER_ALWAYS_INLINE std::pair<value::TypeTags, value::Value> value() const {
197176
return {_tag, _val};
198177
}
199178

200-
inline void appendTo(UniqueBSONObjBuilder& bob) const {
179+
MONGO_COMPILER_ALWAYS_INLINE void appendTo(UniqueBSONObjBuilder& bob) const {
201180
auto [tag, val] = value();
202181
bson::appendValueToBsonObj(bob, _name, tag, val);
203182
}
204183

205184
private:
206-
const StringListSet& _fields;
207-
const std::vector<MakeObjSpec::FieldAction>& _actions;
208-
MakeObjSpec::ActionType _defActionType;
209185
const InputFields& _values;
210186

211187
ObjectCursorT _objectCursor;

0 commit comments

Comments
 (0)