@@ -68,86 +68,118 @@ class MetadataFilter::LeafNode : public Node {
6868 std::unique_ptr<Filter> filter_;
6969};
7070
71- struct MetadataFilter ::AndNode : Node {
71+ struct MetadataFilter ::ConditionNode : Node {
7272 static std::unique_ptr<Node> create (
73- std::unique_ptr<Node> lhs,
74- std::unique_ptr<Node> rhs) {
75- if (!lhs) {
76- return rhs;
77- }
78- if (!rhs) {
79- return lhs;
73+ bool conjuction,
74+ std::vector<std::unique_ptr<Node>> args);
75+
76+ static std::unique_ptr<Node> fromExpression (
77+ const std::vector<core::TypedExprPtr>& inputs,
78+ core::ExpressionEvaluator* evaluator,
79+ bool conjunction,
80+ bool negated) {
81+ conjunction = negated ? !conjunction : conjunction;
82+ std::vector<std::unique_ptr<Node>> args;
83+ args.reserve (inputs.size ());
84+ for (const auto & input : inputs) {
85+ auto node = Node::fromExpression (*input, evaluator, negated);
86+ if (node) {
87+ args.push_back (std::move (node));
88+ } else if (!conjunction) {
89+ return nullptr ;
90+ }
8091 }
81- return std::make_unique<AndNode>( std::move (lhs) , std::move (rhs ));
92+ return create (conjunction , std::move (args ));
8293 }
8394
84- AndNode (std::unique_ptr<Node> lhs, std::unique_ptr<Node> rhs )
85- : lhs_( std::move(lhs)), rhs_(std::move(rhs)) {}
95+ explicit ConditionNode (std::vector< std::unique_ptr<Node>> args )
96+ : args_{ std::move (args)} {}
8697
87- void addToScanSpec (ScanSpec& scanSpec) const override {
88- lhs_->addToScanSpec (scanSpec);
89- rhs_->addToScanSpec (scanSpec);
90- }
91-
92- uint64_t * eval (LeafResults& leafResults, int size) const override {
93- auto * l = lhs_->eval (leafResults, size);
94- auto * r = rhs_->eval (leafResults, size);
95- if (!l) {
96- return r;
97- }
98- if (!r) {
99- return l;
98+ void addToScanSpec (ScanSpec& scanSpec) const final {
99+ for (const auto & arg : args_) {
100+ arg->addToScanSpec (scanSpec);
100101 }
101- bits::orBits (l, r, 0 , size);
102- return l;
103102 }
104103
105- std::string toString () const override {
106- return " and(" + lhs_->toString () + " ," + rhs_->toString () + " )" ;
104+ protected:
105+ std::string ToStringImpl (std::string_view prefix) const {
106+ std::string result{prefix};
107+ for (size_t i = 0 ; i < args_.size (); ++i) {
108+ if (i != 0 ) {
109+ result += " ," ;
110+ }
111+ result += args_[i]->toString ();
112+ }
113+ result += " )" ;
114+ return result;
107115 }
108116
109- private:
110- std::unique_ptr<Node> lhs_;
111- std::unique_ptr<Node> rhs_;
117+ std::vector<std::unique_ptr<Node>> args_;
112118};
113119
114- struct MetadataFilter ::OrNode : Node {
115- static std::unique_ptr<Node> create (
116- std::unique_ptr<Node> lhs,
117- std::unique_ptr<Node> rhs) {
118- if (!lhs || !rhs) {
119- return nullptr ;
120+ struct MetadataFilter ::AndNode final : ConditionNode {
121+ using ConditionNode::ConditionNode;
122+
123+ uint64_t * eval (LeafResults& leafResults, int size) const final {
124+ uint64_t * result = nullptr ;
125+ for (const auto & arg : args_) {
126+ auto * a = arg->eval (leafResults, size);
127+ if (!a) {
128+ continue ;
129+ }
130+ if (!result) {
131+ result = a;
132+ } else {
133+ bits::orBits (result, a, 0 , size);
134+ }
120135 }
121- return std::make_unique<OrNode>( std::move (lhs), std::move (rhs)) ;
136+ return result ;
122137 }
123138
124- OrNode (std::unique_ptr<Node> lhs, std::unique_ptr<Node> rhs)
125- : lhs_(std::move(lhs)), rhs_(std::move(rhs)) {}
126-
127- void addToScanSpec (ScanSpec& scanSpec) const override {
128- lhs_->addToScanSpec (scanSpec);
129- rhs_->addToScanSpec (scanSpec);
139+ std::string toString () const final {
140+ return ToStringImpl (" and(" );
130141 }
142+ };
131143
132- uint64_t * eval (LeafResults& leafResults, int size) const override {
133- auto * l = lhs_->eval (leafResults, size);
134- auto * r = rhs_->eval (leafResults, size);
135- if (!l || !r) {
136- return nullptr ;
144+ struct MetadataFilter ::OrNode final : ConditionNode {
145+ using ConditionNode::ConditionNode;
146+
147+ uint64_t * eval (LeafResults& leafResults, int size) const final {
148+ uint64_t * result = nullptr ;
149+ for (const auto & arg : args_) {
150+ auto * a = arg->eval (leafResults, size);
151+ if (!a) {
152+ return nullptr ;
153+ }
154+ if (!result) {
155+ result = a;
156+ } else {
157+ bits::andBits (result, a, 0 , size);
158+ }
137159 }
138- bits::andBits (l, r, 0 , size);
139- return l;
160+ return result;
140161 }
141162
142- std::string toString () const override {
143- return " or(" + lhs_-> toString () + " , " + rhs_-> toString () + " ) " ;
163+ std::string toString () const final {
164+ return ToStringImpl ( " or(" ) ;
144165 }
145-
146- private:
147- std::unique_ptr<Node> lhs_;
148- std::unique_ptr<Node> rhs_;
149166};
150167
168+ std::unique_ptr<MetadataFilter::Node> MetadataFilter::ConditionNode::create (
169+ bool conjunction,
170+ std::vector<std::unique_ptr<Node>> args) {
171+ if (args.empty ()) {
172+ return nullptr ;
173+ }
174+ if (args.size () == 1 ) {
175+ return std::move (args[0 ]);
176+ }
177+ if (conjunction) {
178+ return std::make_unique<AndNode>(std::move (args));
179+ }
180+ return std::make_unique<OrNode>(std::move (args));
181+ }
182+
151183namespace {
152184
153185const core::CallTypedExpr* asCall (const core::ITypedExpr* expr) {
@@ -165,16 +197,12 @@ std::unique_ptr<MetadataFilter::Node> MetadataFilter::Node::fromExpression(
165197 return nullptr ;
166198 }
167199 if (call->name () == expression::kAnd ) {
168- auto lhs = fromExpression (*call->inputs ()[0 ], evaluator, negated);
169- auto rhs = fromExpression (*call->inputs ()[1 ], evaluator, negated);
170- return negated ? OrNode::create (std::move (lhs), std::move (rhs))
171- : AndNode::create (std::move (lhs), std::move (rhs));
200+ return ConditionNode::fromExpression (
201+ call->inputs (), evaluator, true , negated);
172202 }
173203 if (call->name () == expression::kOr ) {
174- auto lhs = fromExpression (*call->inputs ()[0 ], evaluator, negated);
175- auto rhs = fromExpression (*call->inputs ()[1 ], evaluator, negated);
176- return negated ? AndNode::create (std::move (lhs), std::move (rhs))
177- : OrNode::create (std::move (lhs), std::move (rhs));
204+ return ConditionNode::fromExpression (
205+ call->inputs (), evaluator, false , negated);
178206 }
179207 if (call->name () == " not" ) {
180208 return fromExpression (*call->inputs ()[0 ], evaluator, !negated);
0 commit comments