mirror of https://gitee.com/bigwinds/arangodb
some optimisations
This commit is contained in:
parent
2234a38ab9
commit
4174b215f7
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue