Skip to content

Commit e501014

Browse files
aligusnetEvergreen Agent
authored andcommitted
SERVER-83162 remove unnecessary allocations in Bitset Tree converter
* replace std::vector by absl::InlinedVector in Bitset Tree converter * do not allocate additional Bitset Tree node for the root
1 parent a082c2a commit e501014

7 files changed

+60
-66
lines changed

src/mongo/db/matcher/expression_bitset_tree_converter.cpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ struct Context {
120120
return containsSchemaExpressions || _maximumNumberOfUniquePredicates <= expressions.size();
121121
}
122122

123-
std::vector<ExpressionBitInfo> expressions;
123+
BitsetTreeTransformResult::ExpressionList expressions;
124124

125125
BitConflict bitConflict{None};
126126

@@ -141,8 +141,8 @@ struct Context {
141141
*/
142142
class BitsetVisitor : public MatchExpressionConstVisitor {
143143
public:
144-
BitsetVisitor(Context& context, BitsetTreeNode& parent, bool isNegated)
145-
: _context(context), _parent(parent), _isNegated{isNegated} {}
144+
BitsetVisitor(Context& context, BitsetTreeNode& parent, bool isNegated, bool isRoot = false)
145+
: _context(context), _parent(parent), _isNegated{isNegated}, _isRoot{isRoot} {}
146146

147147
void visit(const AndMatchExpression* expr) final {
148148
++_context.expressionSize;
@@ -170,7 +170,7 @@ class BitsetVisitor : public MatchExpressionConstVisitor {
170170
}
171171
}
172172

173-
_parent.internalChildren.emplace_back(std::move(node));
173+
appendChild(std::move(node));
174174
}
175175

176176
void visit(const OrMatchExpression* expr) final {
@@ -199,7 +199,7 @@ class BitsetVisitor : public MatchExpressionConstVisitor {
199199
}
200200
}
201201

202-
_parent.internalChildren.emplace_back(std::move(node));
202+
appendChild(std::move(node));
203203
}
204204

205205
void visit(const NorMatchExpression* expr) final {
@@ -229,7 +229,7 @@ class BitsetVisitor : public MatchExpressionConstVisitor {
229229
}
230230
}
231231

232-
_parent.internalChildren.emplace_back(std::move(node));
232+
appendChild(std::move(node));
233233
}
234234

235235
void visit(const NotMatchExpression* expr) final {
@@ -416,6 +416,14 @@ class BitsetVisitor : public MatchExpressionConstVisitor {
416416
}
417417

418418
private:
419+
void appendChild(BitsetTreeNode&& child) {
420+
if (_isRoot) {
421+
_parent = std::move(child);
422+
} else {
423+
_parent.internalChildren.emplace_back(std::move(child));
424+
}
425+
}
426+
419427
void visitLeafNode(const MatchExpression* expr) {
420428
++_context.expressionSize;
421429

@@ -443,15 +451,16 @@ class BitsetVisitor : public MatchExpressionConstVisitor {
443451
Context& _context;
444452
BitsetTreeNode& _parent;
445453
const bool _isNegated;
454+
const bool _isRoot;
446455
};
447456
} // namespace
448457

449458
boost::optional<BitsetTreeTransformResult> transformToBitsetTree(
450459
const MatchExpression* root, size_t maximumNumberOfUniquePredicates) {
451460
Context context{maximumNumberOfUniquePredicates};
452461

453-
BitsetTreeNode bitsetRoot{BitsetTreeNode::And, false};
454-
BitsetVisitor visitor{context, bitsetRoot, false};
462+
BitsetTreeNode bitsetRoot{BitsetTreeNode::And, /* isNegated */ false};
463+
BitsetVisitor visitor{context, bitsetRoot, /* isNegated */ false, /* isRoot */ true};
455464
root->acceptVisitor(&visitor);
456465

457466
if (MONGO_unlikely(context.isAborted())) {
@@ -473,14 +482,6 @@ boost::optional<BitsetTreeTransformResult> transformToBitsetTree(
473482
context.expressionSize}};
474483
}
475484

476-
// If we have just one child return it to avoid unnecessary $and or $or nodes with only one
477-
// child.
478-
if (bitsetRoot.leafChildren.mask.count() == 0 && bitsetRoot.internalChildren.size() == 1) {
479-
return {{std::move(bitsetRoot.internalChildren[0]),
480-
std::move(context.expressions),
481-
context.expressionSize}};
482-
}
483-
484485
return {{std::move(bitsetRoot), std::move(context.expressions), context.expressionSize}};
485486
}
486487
} // namespace mongo

src/mongo/db/matcher/expression_bitset_tree_converter.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,14 @@ struct ExpressionBitInfo {
4646
* Contains result of 'transformToBitsetTree' function.
4747
*/
4848
struct BitsetTreeTransformResult {
49+
using ExpressionList = absl::InlinedVector<ExpressionBitInfo, 4>;
50+
4951
// The root node of the bitset tree.
5052
boolean_simplification::BitsetTreeNode bitsetTree;
5153

5254
// A vector of ExpressionBitInfo represented by bits in the bitset tree. The size of the vector
5355
// equals to the number of bits of the BitSet tree.
54-
std::vector<ExpressionBitInfo> expressions;
56+
ExpressionList expressions;
5557

5658
// The number of nodes of the original MatchExpression tree.
5759
size_t expressionSize;

src/mongo/db/matcher/expression_bitset_tree_converter_test.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ BitsetTreeTransformResult transformToBitsetTreeTest(const MatchExpression* root)
4747
return std::move(*result);
4848
}
4949

50-
inline void assertExprInfo(const std::vector<ExpressionBitInfo>& expected,
51-
const std::vector<ExpressionBitInfo>& actual) {
50+
inline void assertExprInfo(const BitsetTreeTransformResult::ExpressionList& expected,
51+
const BitsetTreeTransformResult::ExpressionList& actual) {
5252
ASSERT_EQ(expected.size(), actual.size());
5353
for (size_t i = 0; i < expected.size(); ++i) {
5454
ASSERT_TRUE(expected[i].expression->equivalent(actual[i].expression))
@@ -61,7 +61,7 @@ inline void assertExprInfo(const std::vector<ExpressionBitInfo>& expected,
6161
TEST(BitsetTreeConverterTests, AlwaysTrue) {
6262
AndMatchExpression expr{};
6363

64-
std::vector<ExpressionBitInfo> expectedExpressions{};
64+
BitsetTreeTransformResult::ExpressionList expectedExpressions{};
6565

6666
BitsetTreeNode expectedTree{BitsetTreeNode::And, false};
6767

@@ -74,7 +74,7 @@ TEST(BitsetTreeConverterTests, AlwaysTrue) {
7474
TEST(BitsetTreeConverterTests, AlwaysFalse) {
7575
AlwaysFalseMatchExpression expr{};
7676

77-
std::vector<ExpressionBitInfo> expectedExpressions{};
77+
BitsetTreeTransformResult::ExpressionList expectedExpressions{};
7878

7979
BitsetTreeNode expectedTree{BitsetTreeNode::Or, false};
8080

@@ -88,7 +88,7 @@ TEST(BitsetTreeConverterTests, NorOfAlwaysFalse) {
8888
NorMatchExpression expr{};
8989
expr.add(std::make_unique<AlwaysFalseMatchExpression>());
9090

91-
std::vector<ExpressionBitInfo> expectedExpressions{};
91+
BitsetTreeTransformResult::ExpressionList expectedExpressions{};
9292

9393
BitsetTreeNode expectedTree{BitsetTreeNode::Or, true};
9494

@@ -102,7 +102,7 @@ TEST(BitsetTreeConverterTests, NorOfAlwaysTrue) {
102102
NorMatchExpression expr{};
103103
expr.add(std::make_unique<AlwaysTrueMatchExpression>());
104104

105-
std::vector<ExpressionBitInfo> expectedExpressions{};
105+
BitsetTreeTransformResult::ExpressionList expectedExpressions{};
106106

107107
BitsetTreeNode expectedTree{BitsetTreeNode::Or, false};
108108

@@ -117,7 +117,7 @@ TEST(BitsetTreeConverterTests, AlwaysTrueNorAlwaysFalse) {
117117
expr.add(std::make_unique<AlwaysTrueMatchExpression>());
118118
expr.add(std::make_unique<AlwaysFalseMatchExpression>());
119119

120-
std::vector<ExpressionBitInfo> expectedExpressions{};
120+
BitsetTreeTransformResult::ExpressionList expectedExpressions{};
121121

122122
BitsetTreeNode expectedTree{BitsetTreeNode::Or, false};
123123

@@ -135,7 +135,7 @@ TEST(BitsetTreeConverterTests, NeNorEq) {
135135
expr.add(eq->clone());
136136
expr.add(std::make_unique<NotMatchExpression>(eq->clone()));
137137

138-
std::vector<ExpressionBitInfo> expectedExpressions{ExpressionBitInfo{eq.get()}};
138+
BitsetTreeTransformResult::ExpressionList expectedExpressions{ExpressionBitInfo{eq.get()}};
139139

140140
BitsetTreeNode expectedTree{BitsetTreeNode::Or, false};
141141

@@ -148,7 +148,7 @@ TEST(BitsetTreeConverterTests, NeNorEq) {
148148
TEST(BitsetTreeConverterTests, NotAlwaysTrue) {
149149
NotMatchExpression expr{std::make_unique<AlwaysTrueMatchExpression>()};
150150

151-
std::vector<ExpressionBitInfo> expectedExpressions{};
151+
BitsetTreeTransformResult::ExpressionList expectedExpressions{};
152152

153153
BitsetTreeNode expectedTree{BitsetTreeNode::Or, false};
154154

@@ -161,7 +161,7 @@ TEST(BitsetTreeConverterTests, NotAlwaysTrue) {
161161
TEST(BitsetTreeConverterTests, NotAlwaysFalse) {
162162
NotMatchExpression expr{std::make_unique<AlwaysFalseMatchExpression>()};
163163

164-
std::vector<ExpressionBitInfo> expectedExpressions{};
164+
BitsetTreeTransformResult::ExpressionList expectedExpressions{};
165165

166166
BitsetTreeNode expectedTree{BitsetTreeNode::And, false};
167167

@@ -175,7 +175,7 @@ TEST(BitsetTreeConverterTests, GtExpression) {
175175
auto operand = BSON("$gt" << 5);
176176
GTMatchExpression expr{"a"_sd, operand["$gt"]};
177177

178-
std::vector<ExpressionBitInfo> expectedExpressions{ExpressionBitInfo{&expr}};
178+
BitsetTreeTransformResult::ExpressionList expectedExpressions{ExpressionBitInfo{&expr}};
179179

180180
BitsetTreeNode expectedTree{BitsetTreeNode::And, false};
181181
expectedTree.leafChildren = makeBitsetTerm("1", "1");
@@ -191,7 +191,7 @@ TEST(BitsetTreeConverterTests, AndExpression) {
191191
auto secondOperand = BSON("$eq" << 10);
192192
auto gtExpr = std::make_unique<GTMatchExpression>("a"_sd, firstOperand["$gt"]);
193193
auto eqExpr = std::make_unique<EqualityMatchExpression>("b"_sd, secondOperand["$eq"]);
194-
std::vector<ExpressionBitInfo> expectedExpressions{
194+
BitsetTreeTransformResult::ExpressionList expectedExpressions{
195195
ExpressionBitInfo{gtExpr.get()},
196196
ExpressionBitInfo{eqExpr.get()},
197197
};
@@ -217,7 +217,7 @@ TEST(BitsetTreeConverterTests, OrExpression) {
217217
auto eqExpr = std::make_unique<EqualityMatchExpression>("b"_sd, secondOperand["$eq"]);
218218
auto ltExpr = std::make_unique<LTMatchExpression>("c"_sd, thirdOperand["$lt"]);
219219

220-
std::vector<ExpressionBitInfo> expectedExpressions{
220+
BitsetTreeTransformResult::ExpressionList expectedExpressions{
221221
ExpressionBitInfo{gtExpr.get()},
222222
ExpressionBitInfo{eqExpr.get()},
223223
ExpressionBitInfo{ltExpr.get()},
@@ -265,7 +265,7 @@ TEST(BitsetTreeConverterTests, NorExpression) {
265265
auto eqExpr = std::make_unique<EqualityMatchExpression>("b"_sd, secondOperand["$eq"]);
266266
auto ltExpr = std::make_unique<LTMatchExpression>("c"_sd, thirdOperand["$lt"]);
267267

268-
std::vector<ExpressionBitInfo> expectedExpressions{
268+
BitsetTreeTransformResult::ExpressionList expectedExpressions{
269269
ExpressionBitInfo{gtExpr.get()},
270270
ExpressionBitInfo{eqExpr.get()},
271271
ExpressionBitInfo{ltExpr.get()},
@@ -316,7 +316,7 @@ TEST(BitsetTreeConverterTests, ElemMatch) {
316316
expr->add(std::make_unique<EqualityMatchExpression>(""_sd, secondOperand["$eq"]));
317317
expr->add(std::make_unique<LTMatchExpression>(""_sd, thirdOperand["$lt"]));
318318

319-
std::vector<ExpressionBitInfo> expectedExpressions{ExpressionBitInfo{expr.get()}};
319+
BitsetTreeTransformResult::ExpressionList expectedExpressions{ExpressionBitInfo{expr.get()}};
320320

321321
BitsetTreeNode expectedTree{BitsetTreeNode::And, false};
322322
expectedTree.leafChildren = makeBitsetTerm("1", "1");
@@ -345,7 +345,7 @@ TEST(BitsetTreeConverterTests, TwoElemMatches) {
345345
expr->add(elemMatchGt->clone());
346346
expr->add(notElemMatchLt->clone());
347347

348-
std::vector<ExpressionBitInfo> expectedExpressions{
348+
BitsetTreeTransformResult::ExpressionList expectedExpressions{
349349
ExpressionBitInfo{elemMatchGt.get()},
350350
ExpressionBitInfo{elemMatchLt.get()},
351351
};

src/mongo/db/matcher/expression_restorer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ using boolean_simplification::Minterm;
4343
class MatchExpressionRestorer {
4444
public:
4545
MatchExpressionRestorer(const BitsetTreeNode& root,
46-
const std::vector<ExpressionBitInfo>& expressions)
46+
const BitsetTreeTransformResult::ExpressionList& expressions)
4747
: _root(root), _expressions(expressions) {}
4848

4949
std::unique_ptr<MatchExpression> restore() const {
@@ -95,13 +95,13 @@ class MatchExpressionRestorer {
9595
}
9696

9797
const BitsetTreeNode& _root;
98-
const std::vector<ExpressionBitInfo>& _expressions;
98+
const BitsetTreeTransformResult::ExpressionList& _expressions;
9999
};
100100
} // namespace
101101

102102
std::unique_ptr<MatchExpression> restoreMatchExpression(
103103
const boolean_simplification::BitsetTreeNode& bitsetTree,
104-
const std::vector<ExpressionBitInfo>& expressions) {
104+
const BitsetTreeTransformResult::ExpressionList& expressions) {
105105
MatchExpressionRestorer restorer(bitsetTree, expressions);
106106
return restorer.restore();
107107
}

src/mongo/db/matcher/expression_restorer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,5 @@ namespace mongo {
4141
*/
4242
std::unique_ptr<MatchExpression> restoreMatchExpression(
4343
const boolean_simplification::BitsetTreeNode& bitsetTree,
44-
const std::vector<ExpressionBitInfo>& expressions);
44+
const BitsetTreeTransformResult::ExpressionList& expressions);
4545
} // namespace mongo

src/mongo/db/matcher/expression_restorer_test.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ inline void ASSERT_EXPR(const MatchExpression& expected,
5151

5252
std::unique_ptr<MatchExpression> restoreMatchExpression(
5353
const boolean_simplification::Maxterm& maxterm,
54-
const std::vector<ExpressionBitInfo>& expressions) {
54+
const BitsetTreeTransformResult::ExpressionList& expressions) {
5555
BitsetTreeNode root = boolean_simplification::convertToBitsetTree(maxterm);
5656
return restoreMatchExpression(root, expressions);
5757
}
@@ -62,7 +62,7 @@ DEATH_TEST_REGEX(RestoreSingleMatchExpressionTests,
6262
"Tripwire assertion.*8163020") {
6363
auto operand = BSON("$gt" << 5);
6464
auto gtExpr = std::make_unique<GTMatchExpression>("a"_sd, operand["$gt"]);
65-
std::vector<ExpressionBitInfo> expressions{ExpressionBitInfo{gtExpr.get()}};
65+
BitsetTreeTransformResult::ExpressionList expressions{ExpressionBitInfo{gtExpr.get()}};
6666

6767
BitsetTreeNode root{BitsetTreeNode::And, /* isNegated */ true};
6868
root.leafChildren.set(0, true);
@@ -71,7 +71,7 @@ DEATH_TEST_REGEX(RestoreSingleMatchExpressionTests,
7171
}
7272

7373
TEST(RestoreSingleMatchExpressionTests, AlwaysTrue) {
74-
std::vector<ExpressionBitInfo> expressions{};
74+
BitsetTreeTransformResult::ExpressionList expressions{};
7575

7676
BitsetTreeNode root{BitsetTreeNode::And, /* isNegated */ false};
7777

@@ -82,7 +82,7 @@ TEST(RestoreSingleMatchExpressionTests, AlwaysTrue) {
8282
}
8383

8484
TEST(RestoreSingleMatchExpressionTests, NotAlwaysTrue) {
85-
std::vector<ExpressionBitInfo> expressions{};
85+
BitsetTreeTransformResult::ExpressionList expressions{};
8686

8787
BitsetTreeNode root{BitsetTreeNode::And, /* isNegated */ true};
8888

@@ -98,7 +98,7 @@ TEST(RestoreSingleMatchExpressionTests, NotAlwaysTrue) {
9898
}
9999

100100
TEST(RestoreSingleMatchExpressionTests, AlwaysFalse) {
101-
std::vector<ExpressionBitInfo> expressions{};
101+
BitsetTreeTransformResult::ExpressionList expressions{};
102102

103103
BitsetTreeNode root{BitsetTreeNode::Or, /* isNegated */ false};
104104

@@ -109,7 +109,7 @@ TEST(RestoreSingleMatchExpressionTests, AlwaysFalse) {
109109
}
110110

111111
TEST(RestoreSingleMatchExpressionTests, NotAlwaysFalse) {
112-
std::vector<ExpressionBitInfo> expressions{};
112+
BitsetTreeTransformResult::ExpressionList expressions{};
113113

114114
BitsetTreeNode root{BitsetTreeNode::Or, /* isNegated */ true};
115115

@@ -127,7 +127,7 @@ TEST(RestoreSingleMatchExpressionTests, NotAlwaysFalse) {
127127
TEST(RestoreSingleMatchExpressionTests, GtExpression) {
128128
auto operand = BSON("$gt" << 5);
129129
auto gtExpr = std::make_unique<GTMatchExpression>("a"_sd, operand["$gt"]);
130-
std::vector<ExpressionBitInfo> expressions{ExpressionBitInfo{gtExpr.get()}};
130+
BitsetTreeTransformResult::ExpressionList expressions{ExpressionBitInfo{gtExpr.get()}};
131131

132132
Maxterm maxterm{
133133
{"1", "1"},
@@ -144,7 +144,7 @@ TEST(RestoreSingleMatchExpressionTests, AndExpression) {
144144
auto secondOperand = BSON("$eq" << 10);
145145
auto gtExpr = std::make_unique<GTMatchExpression>("a"_sd, firstOperand["$gt"]);
146146
auto eqExpr = std::make_unique<EqualityMatchExpression>("b"_sd, secondOperand["$eq"]);
147-
std::vector<ExpressionBitInfo> expressions{
147+
BitsetTreeTransformResult::ExpressionList expressions{
148148
ExpressionBitInfo{gtExpr.get()},
149149
ExpressionBitInfo{eqExpr.get()},
150150
};
@@ -168,7 +168,7 @@ TEST(RestoreSingleMatchExpressionTests, OrExpression) {
168168
auto gtExpr = std::make_unique<GTMatchExpression>("a"_sd, firstOperand["$gt"]);
169169
auto eqExpr = std::make_unique<EqualityMatchExpression>("b"_sd, secondOperand["$eq"]);
170170
auto ltExpr = std::make_unique<LTMatchExpression>("c"_sd, thirdOperand["$lt"]);
171-
std::vector<ExpressionBitInfo> expressions{
171+
BitsetTreeTransformResult::ExpressionList expressions{
172172
ExpressionBitInfo{gtExpr.get()},
173173
ExpressionBitInfo{eqExpr.get()},
174174
ExpressionBitInfo{ltExpr.get()},
@@ -204,7 +204,7 @@ TEST(RestoreSingleMatchExpressionTests, NorExpression) {
204204
auto firstExpr = std::make_unique<GTMatchExpression>("a"_sd, firstOperand["$gt"]);
205205
auto secondExpr = std::make_unique<EqualityMatchExpression>("b"_sd, secondOperand["$eq"]);
206206
auto thirdExpr = std::make_unique<LTMatchExpression>("c"_sd, thirdOperand["$lt"]);
207-
std::vector<ExpressionBitInfo> expressions{
207+
BitsetTreeTransformResult::ExpressionList expressions{
208208
ExpressionBitInfo{firstExpr.get()},
209209
ExpressionBitInfo{secondExpr.get()},
210210
ExpressionBitInfo{thirdExpr.get()},
@@ -260,7 +260,7 @@ TEST(RestoreSingleMatchExpressionTests, ElemMatch) {
260260
expr->add(std::make_unique<EqualityMatchExpression>(""_sd, secondOperand["$eq"]));
261261
expr->add(std::make_unique<LTMatchExpression>(""_sd, thirdOperand["$lt"]));
262262

263-
std::vector<ExpressionBitInfo> expressions{ExpressionBitInfo{expr.get()}};
263+
BitsetTreeTransformResult::ExpressionList expressions{ExpressionBitInfo{expr.get()}};
264264

265265
Maxterm maxterm{
266266
Minterm{"1", "1"},
@@ -283,7 +283,7 @@ TEST(RestoreSingleMatchExpressionTests, ElemMatchObject) {
283283

284284
auto expr = std::make_unique<ElemMatchObjectMatchExpression>("a"_sd, std::move(child));
285285

286-
std::vector<ExpressionBitInfo> expressions{ExpressionBitInfo{expr.get()}};
286+
BitsetTreeTransformResult::ExpressionList expressions{ExpressionBitInfo{expr.get()}};
287287

288288
Maxterm maxterm{
289289
Minterm{"1", "1"},

0 commit comments

Comments
 (0)