]> granicus.if.org Git - icinga2/commitdiff
Optimize apply/object filters
authorGunnar Beutner <gunnar.beutner@netways.de>
Mon, 10 Nov 2014 11:05:45 +0000 (12:05 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Mon, 10 Nov 2014 11:06:29 +0000 (12:06 +0100)
refs #7622

lib/config/applyrule.cpp
lib/config/config_parser.yy
lib/config/expression.cpp
lib/config/objectrule.cpp

index d013c6b0a790dee3cd6e7fbec0cc26fc14e7f55b..f542cb63a247f325b7ca79649471a942aebb8aa1 100644 (file)
@@ -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)
index 0e362aa6c7e46b3545e2f2aaaa724808c30d0b1a..90f206a6a222216a06c4bd3ea48ef2efa2aa737e 100644 (file)
@@ -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<DictExpression *>($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();
 
index 0e6cd204aaae2716105ac5a9231d6acbbea015c6..db86ddf79fd14d95b3817bbb92e057ffce46b0c9 100644 (file)
@@ -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;
index fb38b81fec036c34b5a20c1ea9de41848e1fdf59..37818cb41a3144d0e5da8d535632b4bacfb3d925 100644 (file)
@@ -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)