1
0
Fork 0

fixed memleaks

This commit is contained in:
Jan Steemann 2012-05-08 17:40:19 +02:00
parent 1816a56fb2
commit 96903af8e4
7 changed files with 160 additions and 39 deletions

View File

@ -126,9 +126,6 @@ static void FreeAccess (TRI_aql_context_t* const context,
TRI_aql_field_access_t* const fieldAccess) { TRI_aql_field_access_t* const fieldAccess) {
assert(fieldAccess); assert(fieldAccess);
// remove from hash first
TRI_RemoveKeyAssociativePointer(&context->_ranges, fieldAccess->_fieldName);
FreeAccessMembers(fieldAccess); FreeAccessMembers(fieldAccess);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, fieldAccess->_fieldName); TRI_Free(TRI_UNKNOWN_MEM_ZONE, fieldAccess->_fieldName);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, fieldAccess); TRI_Free(TRI_UNKNOWN_MEM_ZONE, fieldAccess);
@ -300,7 +297,7 @@ static TRI_aql_field_access_t* MergeAndList (TRI_aql_context_t* const context,
} }
FreeAccessMembers(lhs); FreeAccessMembers(lhs);
FreeAccessMembers(rhs); FreeAccess(context, rhs);
if (merged->_value._objects._length > 0) { if (merged->_value._objects._length > 0) {
// merged list is not empty // merged list is not empty
@ -308,6 +305,7 @@ static TRI_aql_field_access_t* MergeAndList (TRI_aql_context_t* const context,
} }
else { else {
// merged list is empty // merged list is empty
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, merged);
lhs->_type = TRI_AQL_ACCESS_IMPOSSIBLE; lhs->_type = TRI_AQL_ACCESS_IMPOSSIBLE;
} }
@ -341,7 +339,7 @@ static TRI_aql_field_access_t* MergeAndList (TRI_aql_context_t* const context,
} }
FreeAccessMembers(lhs); FreeAccessMembers(lhs);
FreeAccessMembers(rhs); FreeAccess(context, rhs);
if (listInRange->_value._objects._length > 0) { if (listInRange->_value._objects._length > 0) {
// merged list is not empty // merged list is not empty
@ -349,6 +347,7 @@ static TRI_aql_field_access_t* MergeAndList (TRI_aql_context_t* const context,
} }
else { else {
// merged list is empty // merged list is empty
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, listInRange);
lhs->_type = TRI_AQL_ACCESS_IMPOSSIBLE; lhs->_type = TRI_AQL_ACCESS_IMPOSSIBLE;
} }
@ -373,7 +372,7 @@ static TRI_aql_field_access_t* MergeAndList (TRI_aql_context_t* const context,
} }
FreeAccessMembers(lhs); FreeAccessMembers(lhs);
FreeAccessMembers(rhs); FreeAccess(context, rhs);
if (listInRange->_value._objects._length > 0) { if (listInRange->_value._objects._length > 0) {
// merged list is not empty // merged list is not empty
@ -381,6 +380,7 @@ static TRI_aql_field_access_t* MergeAndList (TRI_aql_context_t* const context,
} }
else { else {
// merged list is empty // merged list is empty
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, listInRange);
lhs->_type = TRI_AQL_ACCESS_IMPOSSIBLE; lhs->_type = TRI_AQL_ACCESS_IMPOSSIBLE;
} }
@ -929,7 +929,7 @@ static TRI_aql_field_access_t* MergeOrList (TRI_aql_context_t* const context,
} }
FreeAccessMembers(lhs); FreeAccessMembers(lhs);
FreeAccessMembers(rhs); FreeAccess(context, rhs);
if (merged->_value._objects._length > 0) { if (merged->_value._objects._length > 0) {
// merged list is not empty // merged list is not empty
@ -937,6 +937,7 @@ static TRI_aql_field_access_t* MergeOrList (TRI_aql_context_t* const context,
} }
else { else {
// merged list is empty // merged list is empty
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, merged);
lhs->_type = TRI_AQL_ACCESS_IMPOSSIBLE; lhs->_type = TRI_AQL_ACCESS_IMPOSSIBLE;
} }
@ -1081,8 +1082,10 @@ static TRI_aql_field_access_t* MergeAccess (TRI_aql_context_t* const context,
const TRI_aql_logical_e logicalType, const TRI_aql_logical_e logicalType,
TRI_aql_field_access_t* lhs, TRI_aql_field_access_t* lhs,
TRI_aql_field_access_t* rhs) { TRI_aql_field_access_t* rhs) {
assert(context);
assert(lhs); assert(lhs);
assert(rhs); assert(rhs);
assert(logicalType == TRI_AQL_LOGICAL_AND || logicalType == TRI_AQL_LOGICAL_OR);
assert(lhs->_fieldName != NULL); assert(lhs->_fieldName != NULL);
assert(rhs->_fieldName != NULL); assert(rhs->_fieldName != NULL);
@ -1146,6 +1149,7 @@ static TRI_aql_field_access_t* CreateAccessForNode (TRI_aql_context_t* const con
TRI_aql_field_access_t* fieldAccess; TRI_aql_field_access_t* fieldAccess;
TRI_json_t* value; TRI_json_t* value;
assert(context);
assert(field); assert(field);
assert(field->_name._buffer); assert(field->_name._buffer);
assert(node); assert(node);
@ -1232,6 +1236,9 @@ static void NoteAttributeAccess (TRI_aql_context_t* const context,
const TRI_aql_node_t* const node) { const TRI_aql_node_t* const node) {
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(node);
if (!field || !field->_name._buffer) { if (!field || !field->_name._buffer) {
return; return;
@ -1245,12 +1252,16 @@ static void NoteAttributeAccess (TRI_aql_context_t* const context,
} }
// look up previous range first // look up previous range first
previous = (TRI_aql_field_access_t*) TRI_LookupByKeyAssociativePointer(&context->_ranges, fieldAccess->_fieldName); previous = (TRI_aql_field_access_t*) TRI_LookupByKeyAssociativePointer(context->_ranges, fieldAccess->_fieldName);
if (previous) { if (previous) {
TRI_aql_field_access_t* merged;
// previous range exists, now merge new access type with previous one // previous range exists, now merge new access type with previous one
// remove from hash first
TRI_RemoveKeyAssociativePointer(context->_ranges, fieldAccess->_fieldName);
// MergeAccess() will free previous and/or fieldAccess // MergeAccess() will free previous and/or fieldAccess
TRI_aql_field_access_t* merged = MergeAccess(context, logicalType, fieldAccess, previous); merged = MergeAccess(context, logicalType, fieldAccess, previous);
if (!merged) { if (!merged) {
// OOM // OOM
@ -1258,11 +1269,11 @@ static void NoteAttributeAccess (TRI_aql_context_t* const context,
return; return;
} }
TRI_InsertKeyAssociativePointer(&context->_ranges, merged->_fieldName, merged, true); TRI_InsertKeyAssociativePointer(context->_ranges, merged->_fieldName, merged, true);
} }
else { else {
// no previous access exists, no need to merge // no previous access exists, no need to merge
TRI_InsertKeyAssociativePointer(&context->_ranges, fieldAccess->_fieldName, fieldAccess, false); TRI_InsertKeyAssociativePointer(context->_ranges, fieldAccess->_fieldName, fieldAccess, false);
} }
} }
@ -1273,6 +1284,9 @@ static void NoteAttributeAccess (TRI_aql_context_t* const context,
static TRI_aql_attribute_name_t* GetAttributeName (TRI_aql_context_t* const context, static TRI_aql_attribute_name_t* GetAttributeName (TRI_aql_context_t* const context,
const TRI_aql_node_t* const node) { const TRI_aql_node_t* const node) {
assert(context);
assert(node);
if (node->_type == AQL_NODE_ATTRIBUTE_ACCESS) { if (node->_type == AQL_NODE_ATTRIBUTE_ACCESS) {
TRI_aql_attribute_name_t* field = GetAttributeName(context, TRI_AQL_NODE_MEMBER(node, 0)); TRI_aql_attribute_name_t* field = GetAttributeName(context, TRI_AQL_NODE_MEMBER(node, 0));
@ -1309,6 +1323,70 @@ static TRI_aql_attribute_name_t* GetAttributeName (TRI_aql_context_t* const cont
/// @} /// @}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Ahuacatl
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief init the optimizer
////////////////////////////////////////////////////////////////////////////////
bool TRI_InitOptimizerAql (TRI_aql_context_t* const context) {
assert(context);
assert(context->_ranges == NULL);
context->_ranges = (TRI_associative_pointer_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_associative_pointer_t), false);
if (!context->_ranges) {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
return false;
}
TRI_InitAssociativePointer(context->_ranges,
TRI_UNKNOWN_MEM_ZONE,
&TRI_HashStringKeyAssociativePointer,
&HashFieldAccess,
&EqualFieldAccess,
NULL);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief shutdown the optimizer
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeOptimizerAql (TRI_aql_context_t* const context) {
assert(context);
if (context->_ranges) {
size_t i, n;
// free all remaining access elements
n = context->_ranges->_nrAlloc;
for (i = 0; i < n; ++i) {
TRI_aql_field_access_t* fieldAccess = (TRI_aql_field_access_t*) context->_ranges->_table[i];
if (!fieldAccess) {
continue;
}
FreeAccess(context, fieldAccess);
}
// free hash array
TRI_FreeAssociativePointer(TRI_UNKNOWN_MEM_ZONE, context->_ranges);
context->_ranges = NULL;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- public functions // --SECTION-- public functions
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -1324,9 +1402,11 @@ static TRI_aql_attribute_name_t* GetAttributeName (TRI_aql_context_t* const cont
void TRI_DumpRangesAql (TRI_aql_context_t* const context) { void TRI_DumpRangesAql (TRI_aql_context_t* const context) {
size_t i; size_t i;
assert(context);
for (i = 0; i < context->_ranges._nrAlloc; ++i) { for (i = 0; i < context->_ranges->_nrAlloc; ++i) {
TRI_aql_field_access_t* fieldAccess = context->_ranges._table[i]; TRI_aql_field_access_t* fieldAccess = context->_ranges->_table[i];
if (!fieldAccess) { if (!fieldAccess) {
continue; continue;
@ -1340,6 +1420,7 @@ void TRI_DumpRangesAql (TRI_aql_context_t* const context) {
TRI_StringifyJson(&b, fieldAccess->_value._value); TRI_StringifyJson(&b, fieldAccess->_value._value);
printf("- VALUE: %s\n", b._buffer); printf("- VALUE: %s\n", b._buffer);
TRI_DestroyStringBuffer(&b);
} }
else if (fieldAccess->_type == TRI_AQL_ACCESS_RANGE_SINGLE) { else if (fieldAccess->_type == TRI_AQL_ACCESS_RANGE_SINGLE) {
TRI_string_buffer_t b; TRI_string_buffer_t b;
@ -1347,6 +1428,7 @@ void TRI_DumpRangesAql (TRI_aql_context_t* const context) {
TRI_StringifyJson(&b, fieldAccess->_value._singleRange._value); TRI_StringifyJson(&b, fieldAccess->_value._singleRange._value);
printf("- VALUE: %s\n", b._buffer); printf("- VALUE: %s\n", b._buffer);
TRI_DestroyStringBuffer(&b);
} }
else if (fieldAccess->_type == TRI_AQL_ACCESS_RANGE_DOUBLE) { else if (fieldAccess->_type == TRI_AQL_ACCESS_RANGE_DOUBLE) {
TRI_string_buffer_t b; TRI_string_buffer_t b;
@ -1356,24 +1438,11 @@ void TRI_DumpRangesAql (TRI_aql_context_t* const context) {
TRI_StringifyJson(&b, fieldAccess->_value._between._upper._value); TRI_StringifyJson(&b, fieldAccess->_value._between._upper._value);
printf("- VALUE: %s\n", b._buffer); printf("- VALUE: %s\n", b._buffer);
TRI_DestroyStringBuffer(&b);
} }
} }
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief init the optimizer
////////////////////////////////////////////////////////////////////////////////
void TRI_InitOptimizerAql (TRI_aql_context_t* const context) {
// TODO: must free
TRI_InitAssociativePointer(&context->_ranges,
TRI_UNKNOWN_MEM_ZONE,
&TRI_HashStringKeyAssociativePointer,
&HashFieldAccess,
&EqualFieldAccess,
NULL);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief inspect a condition and note all accesses found for it /// @brief inspect a condition and note all accesses found for it
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -134,6 +134,31 @@ TRI_aql_attribute_name_t;
/// @} /// @}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Ahuacatl
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief init the optimizer
////////////////////////////////////////////////////////////////////////////////
bool TRI_InitOptimizerAql (TRI_aql_context_t* const);
////////////////////////////////////////////////////////////////////////////////
/// @brief shutdown the optimizer
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeOptimizerAql (TRI_aql_context_t* const);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- public functions // --SECTION-- public functions
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -149,12 +174,6 @@ TRI_aql_attribute_name_t;
void TRI_DumpRangesAql (TRI_aql_context_t* const); void TRI_DumpRangesAql (TRI_aql_context_t* const);
////////////////////////////////////////////////////////////////////////////////
/// @brief init the optimizer
////////////////////////////////////////////////////////////////////////////////
void TRI_InitOptimizerAql (TRI_aql_context_t* const);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief inspect a condition and note all accesses found for it /// @brief inspect a condition and note all accesses found for it
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -31,7 +31,7 @@
#include "V8/v8-execution.h" #include "V8/v8-execution.h"
#undef RANGE_OPTIMIZER #undef RANGE_OPTIMIZER
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private functions // --SECTION-- private functions
@ -660,7 +660,10 @@ TRI_aql_node_t* TRI_FoldConstantsAql (TRI_aql_context_t* const context,
TRI_aql_modify_tree_walker_t* walker; TRI_aql_modify_tree_walker_t* walker;
#ifdef RANGE_OPTIMIZER #ifdef RANGE_OPTIMIZER
TRI_InitOptimizerAql(context); if (!TRI_InitOptimizerAql(context)) {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
return node;
}
#endif #endif
walker = TRI_CreateModifyTreeWalkerAql((void*) context, &ModifyNode); walker = TRI_CreateModifyTreeWalkerAql((void*) context, &ModifyNode);

View File

@ -26,6 +26,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include "Ahuacatl/ahuacatl-context.h" #include "Ahuacatl/ahuacatl-context.h"
#include "Ahuacatl/ahuacatl-access-optimizer.h"
#include "Ahuacatl/ahuacatl-ast-node.h" #include "Ahuacatl/ahuacatl-ast-node.h"
#include "Ahuacatl/ahuacatl-bind-parameter.h" #include "Ahuacatl/ahuacatl-bind-parameter.h"
#include "Ahuacatl/ahuacatl-collections.h" #include "Ahuacatl/ahuacatl-collections.h"
@ -77,6 +78,8 @@ TRI_aql_context_t* TRI_CreateContextAql (TRI_vocbase_t* vocbase,
} }
context->_vocbase = vocbase; context->_vocbase = vocbase;
context->_ranges = NULL;
context->_variableIndex = 0; context->_variableIndex = 0;
// actual bind parameter values // actual bind parameter values
@ -161,6 +164,9 @@ void TRI_FreeContextAql (TRI_aql_context_t* const context) {
} }
TRI_DestroyVectorPointer(&context->_scopes); TRI_DestroyVectorPointer(&context->_scopes);
// free range optimizer
TRI_FreeOptimizerAql(context);
// free all strings registered // free all strings registered
i = context->_strings._length; i = context->_strings._length;
while (i--) { while (i--) {

View File

@ -82,7 +82,7 @@ typedef struct TRI_aql_context_s {
TRI_associative_pointer_t _parameterValues; TRI_associative_pointer_t _parameterValues;
TRI_associative_pointer_t _parameterNames; TRI_associative_pointer_t _parameterNames;
TRI_associative_pointer_t _collectionNames; TRI_associative_pointer_t _collectionNames;
TRI_associative_pointer_t _ranges; TRI_associative_pointer_t* _ranges;
size_t _variableIndex; size_t _variableIndex;
void* _first; void* _first;
char* _query; char* _query;

View File

@ -89,7 +89,12 @@ TRI_json_t* TRI_NodeJsonAql (TRI_aql_context_t* const context,
if (result) { if (result) {
n = node->_members._length; n = node->_members._length;
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
TRI_PushBackListJson(TRI_UNKNOWN_MEM_ZONE, result, TRI_NodeJsonAql(context, TRI_AQL_NODE_MEMBER(node, i))); TRI_json_t* subValue = TRI_NodeJsonAql(context, TRI_AQL_NODE_MEMBER(node, i));
if (subValue) {
TRI_PushBack2ListJson(result, subValue);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, subValue);
}
} }
} }
return result; return result;
@ -102,7 +107,15 @@ TRI_json_t* TRI_NodeJsonAql (TRI_aql_context_t* const context,
n = node->_members._length; n = node->_members._length;
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
TRI_aql_node_t* element = TRI_AQL_NODE_MEMBER(node, i); TRI_aql_node_t* element = TRI_AQL_NODE_MEMBER(node, i);
TRI_InsertArrayJson(TRI_UNKNOWN_MEM_ZONE, result, TRI_AQL_NODE_STRING(element), TRI_NodeJsonAql(context, TRI_AQL_NODE_MEMBER(element, 0))); TRI_json_t* subValue = TRI_NodeJsonAql(context, TRI_AQL_NODE_MEMBER(element, 0));
if (subValue) {
TRI_Insert2ArrayJson(TRI_UNKNOWN_MEM_ZONE,
result,
TRI_AQL_NODE_STRING(element),
subValue);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, subValue);
}
} }
} }
return result; return result;

View File

@ -141,6 +141,8 @@ char* TRI_GetContextErrorAql (const char* const query, const size_t line, const
size_t currentLine = 1; size_t currentLine = 1;
size_t currentColumn = 1; size_t currentColumn = 1;
const char* p = query; const char* p = query;
char* temp;
char* result;
size_t offset; size_t offset;
char c; char c;
@ -169,7 +171,16 @@ char* TRI_GetContextErrorAql (const char* const query, const size_t line, const
return TRI_DuplicateString2(query + offset, strlen(query) - offset); return TRI_DuplicateString2(query + offset, strlen(query) - offset);
} }
return TRI_Concatenate2String(TRI_DuplicateString2(query + offset, SNIPPET_LENGTH), SNIPPET_SUFFIX); temp = TRI_DuplicateString2(query + offset, SNIPPET_LENGTH);
if (!temp) {
// out of memory
return NULL;
}
result = TRI_Concatenate2String(temp, SNIPPET_SUFFIX);
TRI_FreeString(TRI_CORE_MEM_ZONE, temp);
return result;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////