From 3cc79a60059ba61e8f7f3f1512ddf546a1387320 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Mon, 10 Nov 2014 12:05:45 +0100 Subject: [PATCH] Optimize apply/object filters refs #7622 --- lib/config/applyrule.cpp | 2 +- lib/config/config_parser.yy | 53 ++++++++++++++++++++++++++++--------- lib/config/expression.cpp | 2 +- lib/config/objectrule.cpp | 2 +- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/lib/config/applyrule.cpp b/lib/config/applyrule.cpp index d013c6b0a..f542cb63a 100644 --- a/lib/config/applyrule.cpp +++ b/lib/config/applyrule.cpp @@ -88,7 +88,7 @@ void ApplyRule::AddRule(const String& sourceType, const String& targetType, cons bool ApplyRule::EvaluateFilter(const Object::Ptr& scope) const { - return m_Filter->Evaluate(scope); + return m_Filter->Evaluate(scope).ToBool(); } void ApplyRule::EvaluateRules(bool clear) diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index 0e362aa6c..90f206a6a 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -427,8 +427,8 @@ object: m_Abstract.push(false); m_ObjectAssign.push(true); m_SeenAssign.push(false); - m_Assign.push(MakeLiteral(false)); - m_Ignore.push(MakeLiteral(false)); + m_Assign.push(NULL); + m_Ignore.push(NULL); } object_declaration identifier rterm rterm_scope { @@ -443,17 +443,29 @@ object: DictExpression *exprl = dynamic_cast($5); exprl->MakeInline(); - if (m_SeenAssign.top() && !ObjectRule::IsValidSourceType(type)) - BOOST_THROW_EXCEPTION(ConfigError("object rule 'assign' cannot be used for type '" + type + "'") << errinfo_debuginfo(DebugInfoRange(@2, @3))); - + bool seen_assign = m_SeenAssign.top(); m_SeenAssign.pop(); - Expression *rex = new LogicalNegateExpression(m_Ignore.top(), DebugInfoRange(@2, @5)); + Expression *ignore = m_Ignore.top(); m_Ignore.pop(); - Expression *filter = new LogicalAndExpression(m_Assign.top(), rex, DebugInfoRange(@2, @5)); + Expression *assign = m_Assign.top(); m_Assign.pop(); + Expression *filter = NULL; + + if (seen_assign) { + if (!ObjectRule::IsValidSourceType(type)) + BOOST_THROW_EXCEPTION(ConfigError("object rule 'assign' cannot be used for type '" + type + "'") << errinfo_debuginfo(DebugInfoRange(@2, @3))); + + if (ignore) { + Expression *rex = new LogicalNegateExpression(ignore, DebugInfoRange(@2, @5)); + + filter = new LogicalAndExpression(assign, rex, DebugInfoRange(@2, @5)); + } else + filter = assign; + } + $$ = new ObjectExpression(abstract, type, $4, filter, context->GetZone(), exprl, DebugInfoRange(@2, @5)); } ; @@ -589,7 +601,10 @@ lterm: indexer combined_set_op rterm m_SeenAssign.top() = true; - m_Assign.top() = new LogicalOrExpression(m_Assign.top(), $3, DebugInfoRange(@1, @3)); + if (m_Assign.top()) + m_Assign.top() = new LogicalOrExpression(m_Assign.top(), $3, DebugInfoRange(@1, @3)); + else + m_Assign.top() = $3; $$ = MakeLiteral(); } @@ -598,7 +613,10 @@ lterm: indexer combined_set_op rterm if ((m_Apply.empty() || !m_Apply.top()) && (m_ObjectAssign.empty() || !m_ObjectAssign.top())) BOOST_THROW_EXCEPTION(ConfigError("'ignore' keyword not valid in this context.")); - m_Ignore.top() = new LogicalOrExpression(m_Ignore.top(), $3, DebugInfoRange(@1, @3)); + if (m_Ignore.top()) + m_Ignore.top() = new LogicalOrExpression(m_Ignore.top(), $3, DebugInfoRange(@1, @3)); + else + m_Ignore.top() = $3; $$ = MakeLiteral(); } @@ -843,8 +861,8 @@ apply: { m_Apply.push(true); m_SeenAssign.push(false); - m_Assign.push(MakeLiteral(false)); - m_Ignore.push(MakeLiteral(false)); + m_Assign.push(NULL); + m_Ignore.push(NULL); m_FKVar.push(""); m_FVVar.push(""); m_FTerm.push(NULL); @@ -891,12 +909,21 @@ apply: m_SeenAssign.pop(); - Expression *rex = new LogicalNegateExpression(m_Ignore.top(), DebugInfoRange(@2, @5)); + Expression *ignore = m_Ignore.top(); m_Ignore.pop(); - Expression *filter = new LogicalAndExpression(m_Assign.top(), rex, DebugInfoRange(@2, @5)); + Expression *assign = m_Assign.top(); m_Assign.pop(); + Expression *filter; + + if (ignore) { + Expression *rex = new LogicalNegateExpression(ignore, DebugInfoRange(@2, @5)); + + filter = new LogicalAndExpression(assign, rex, DebugInfoRange(@2, @5)); + } else + filter = assign; + String fkvar = m_FKVar.top(); m_FKVar.pop(); diff --git a/lib/config/expression.cpp b/lib/config/expression.cpp index 0e6cd204a..db86ddf79 100644 --- a/lib/config/expression.cpp +++ b/lib/config/expression.cpp @@ -489,7 +489,7 @@ Value ObjectExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) item->SetZone(m_Zone); item->Compile()->Register(); - if (ObjectRule::IsValidSourceType(m_Type)) + if (m_Filter) ObjectRule::AddRule(m_Type, name, m_Filter, m_DebugInfo, context); return Empty; diff --git a/lib/config/objectrule.cpp b/lib/config/objectrule.cpp index fb38b81fe..37818cb41 100644 --- a/lib/config/objectrule.cpp +++ b/lib/config/objectrule.cpp @@ -59,7 +59,7 @@ void ObjectRule::AddRule(const String& sourceType, const String& name, bool ObjectRule::EvaluateFilter(const Object::Ptr& scope) const { - return m_Filter->Evaluate(scope); + return m_Filter->Evaluate(scope).ToBool(); } void ObjectRule::EvaluateRules(bool clear)