Optimize apply/object filters

refs #7622
This commit is contained in:
Gunnar Beutner 2014-11-10 12:05:45 +01:00
parent ec109b04dd
commit 3cc79a6005
4 changed files with 43 additions and 16 deletions

View 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)

View 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();

View 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;

View 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)