1
0
Fork 0

some optimisations

This commit is contained in:
Jan Steemann 2012-05-09 09:53:32 +02:00
parent 2234a38ab9
commit 4174b215f7
3 changed files with 78 additions and 11 deletions

View File

@ -59,6 +59,21 @@ static bool EqualFieldAccess (TRI_associative_pointer_t* array,
return TRI_EqualString(key, fieldAccess->_fieldName); return TRI_EqualString(key, fieldAccess->_fieldName);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief return the logical type for a sub operation
////////////////////////////////////////////////////////////////////////////////
static inline TRI_aql_logical_e SubOperator (const TRI_aql_logical_e preferredType,
const TRI_aql_logical_e parentType) {
if (parentType == TRI_AQL_LOGICAL_NOT) {
// logical NOT is sticky
return parentType;
}
// all other operators are not
return preferredType;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief return the name of an access type /// @brief return the name of an access type
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -131,6 +146,25 @@ static void FreeAccess (TRI_aql_context_t* const context,
TRI_Free(TRI_UNKNOWN_MEM_ZONE, fieldAccess); TRI_Free(TRI_UNKNOWN_MEM_ZONE, fieldAccess);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief merge two access structures using a logical NOT
///
/// this always returns the all items range because we cannot evaluate the
/// negated condition
////////////////////////////////////////////////////////////////////////////////
static TRI_aql_field_access_t* MergeNot (TRI_aql_context_t* const context,
TRI_aql_field_access_t* lhs,
TRI_aql_field_access_t* rhs) {
// always returns all
FreeAccess(context, rhs);
FreeAccessMembers(lhs);
lhs->_type = TRI_AQL_ACCESS_ALL;
return lhs;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief merge two access structures using a logical AND /// @brief merge two access structures using a logical AND
/// ///
@ -1081,11 +1115,18 @@ static TRI_aql_field_access_t* MergeAccess (TRI_aql_context_t* const context,
assert(context); assert(context);
assert(lhs); assert(lhs);
assert(rhs); assert(rhs);
assert(logicalType == TRI_AQL_LOGICAL_AND || logicalType == TRI_AQL_LOGICAL_OR); assert(logicalType == TRI_AQL_LOGICAL_AND ||
logicalType == TRI_AQL_LOGICAL_OR ||
logicalType == TRI_AQL_LOGICAL_NOT);
assert(lhs->_fieldName != NULL); assert(lhs->_fieldName != NULL);
assert(rhs->_fieldName != NULL); assert(rhs->_fieldName != NULL);
if (logicalType == TRI_AQL_LOGICAL_NOT) {
// logical NOT is simple. we simply turn everything into an all range
return MergeNot(context, lhs, rhs);
}
if (lhs->_type > rhs->_type) { if (lhs->_type > rhs->_type) {
// swap operands so they are always sorted // swap operands so they are always sorted
TRI_aql_field_access_t* tmp = lhs; TRI_aql_field_access_t* tmp = lhs;
@ -1233,7 +1274,10 @@ static void NoteAttributeAccess (TRI_aql_context_t* const context,
TRI_aql_field_access_t* previous; TRI_aql_field_access_t* previous;
TRI_aql_field_access_t* fieldAccess; TRI_aql_field_access_t* fieldAccess;
assert(logicalType == TRI_AQL_LOGICAL_AND || logicalType == TRI_AQL_LOGICAL_OR); assert(context);
assert(logicalType == TRI_AQL_LOGICAL_AND ||
logicalType == TRI_AQL_LOGICAL_OR ||
logicalType == TRI_AQL_LOGICAL_NOT);
assert(node); assert(node);
if (!field || !field->_name._buffer) { if (!field || !field->_name._buffer) {
@ -1444,28 +1488,50 @@ void TRI_DumpRangesAql (TRI_aql_context_t* const context) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void TRI_InspectConditionAql (TRI_aql_context_t* const context, void TRI_InspectConditionAql (TRI_aql_context_t* const context,
const TRI_aql_logical_e type, const TRI_aql_logical_e logicalType,
TRI_aql_node_t* node) { TRI_aql_node_t* node) {
assert(context);
assert(logicalType == TRI_AQL_LOGICAL_AND ||
logicalType == TRI_AQL_LOGICAL_OR ||
logicalType == TRI_AQL_LOGICAL_NOT);
if (node->_type == AQL_NODE_OPERATOR_UNARY_NOT) { if (node->_type == AQL_NODE_OPERATOR_UNARY_NOT) {
TRI_aql_node_t* lhs = TRI_AQL_NODE_MEMBER(node, 0);
assert(lhs);
TRI_InspectConditionAql(context, TRI_AQL_LOGICAL_NOT, lhs);
return; return;
} }
if (node->_type == AQL_NODE_OPERATOR_BINARY_OR) { if (node->_type == AQL_NODE_OPERATOR_BINARY_OR) {
TRI_aql_node_t* lhs = TRI_AQL_NODE_MEMBER(node, 0); TRI_aql_node_t* lhs = TRI_AQL_NODE_MEMBER(node, 0);
TRI_aql_node_t* rhs = TRI_AQL_NODE_MEMBER(node, 1); TRI_aql_node_t* rhs = TRI_AQL_NODE_MEMBER(node, 1);
TRI_aql_logical_e nextOperator;
assert(lhs);
assert(rhs);
// recurse into next level // recurse into next level
TRI_InspectConditionAql(context, TRI_AQL_LOGICAL_OR, lhs); nextOperator = SubOperator(TRI_AQL_LOGICAL_OR, logicalType);
TRI_InspectConditionAql(context, TRI_AQL_LOGICAL_OR, rhs); TRI_InspectConditionAql(context, nextOperator, lhs);
TRI_InspectConditionAql(context, nextOperator, rhs);
return;
} }
if (node->_type == AQL_NODE_OPERATOR_BINARY_AND) { if (node->_type == AQL_NODE_OPERATOR_BINARY_AND) {
TRI_aql_node_t* lhs = TRI_AQL_NODE_MEMBER(node, 0); TRI_aql_node_t* lhs = TRI_AQL_NODE_MEMBER(node, 0);
TRI_aql_node_t* rhs = TRI_AQL_NODE_MEMBER(node, 1); TRI_aql_node_t* rhs = TRI_AQL_NODE_MEMBER(node, 1);
TRI_aql_logical_e nextOperator;
assert(lhs);
assert(rhs);
// recurse into next level // recurse into next level
TRI_InspectConditionAql(context, TRI_AQL_LOGICAL_AND, lhs); nextOperator = SubOperator(TRI_AQL_LOGICAL_AND, logicalType);
TRI_InspectConditionAql(context, TRI_AQL_LOGICAL_AND, rhs); TRI_InspectConditionAql(context, nextOperator, lhs);
TRI_InspectConditionAql(context, nextOperator, rhs);
return;
} }
if (node->_type == AQL_NODE_OPERATOR_BINARY_EQ || if (node->_type == AQL_NODE_OPERATOR_BINARY_EQ ||
@ -1482,7 +1548,7 @@ void TRI_InspectConditionAql (TRI_aql_context_t* const context,
TRI_aql_attribute_name_t* field = GetAttributeName(context, lhs); TRI_aql_attribute_name_t* field = GetAttributeName(context, lhs);
if (field) { if (field) {
NoteAttributeAccess(context, type, field, node->_type, rhs); NoteAttributeAccess(context, logicalType, field, node->_type, rhs);
TRI_DestroyStringBuffer(&field->_name); TRI_DestroyStringBuffer(&field->_name);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, field); TRI_Free(TRI_UNKNOWN_MEM_ZONE, field);
} }
@ -1491,7 +1557,7 @@ void TRI_InspectConditionAql (TRI_aql_context_t* const context,
TRI_aql_attribute_name_t* field = GetAttributeName(context, rhs); TRI_aql_attribute_name_t* field = GetAttributeName(context, rhs);
if (field) { if (field) {
NoteAttributeAccess(context, type, field, node->_type, lhs); NoteAttributeAccess(context, logicalType, field, node->_type, lhs);
TRI_DestroyStringBuffer(&field->_name); TRI_DestroyStringBuffer(&field->_name);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, field); TRI_Free(TRI_UNKNOWN_MEM_ZONE, field);
} }

View File

@ -59,7 +59,8 @@ extern "C" {
typedef enum { typedef enum {
TRI_AQL_LOGICAL_AND, TRI_AQL_LOGICAL_AND,
TRI_AQL_LOGICAL_OR TRI_AQL_LOGICAL_OR,
TRI_AQL_LOGICAL_NOT
} }
TRI_aql_logical_e; TRI_aql_logical_e;