From cf0ea1b615a4f2c2f91f8944efcd16eb32706a5c Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Thu, 27 Mar 2014 09:27:13 +0100 Subject: [PATCH] fixed deallocation of edges --- arangod/VocBase/edge-collection.h | 2 +- arangod/VocBase/index.c | 28 +++++++++++++++++++--------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/arangod/VocBase/edge-collection.h b/arangod/VocBase/edge-collection.h index a51af77538..4dfb5688cd 100644 --- a/arangod/VocBase/edge-collection.h +++ b/arangod/VocBase/edge-collection.h @@ -95,7 +95,7 @@ extern "C" { /// whether the edge is directed //////////////////////////////////////////////////////////////////////////////// -typedef uint8_t TRI_edge_flags_t; +typedef uint32_t TRI_edge_flags_t; //////////////////////////////////////////////////////////////////////////////// /// @brief edge from and to diff --git a/arangod/VocBase/index.c b/arangod/VocBase/index.c index f9e4280ecc..a9868904f6 100644 --- a/arangod/VocBase/index.c +++ b/arangod/VocBase/index.c @@ -820,14 +820,14 @@ static int InsertEdge (TRI_index_t* idx, entryIn->_cid = edge->_toCid; entryIn->_searchKey._offsetKey = edge->_offsetToKey; TRI_InsertElementMultiPointer(edgesIndex, entryIn, true, isRollback); - + // second slot: OUT entryOut->_mptr = mptr; entryOut->_flags = TRI_FlagsEdge(TRI_EDGE_OUT, isReflexive); entryOut->_cid = edge->_fromCid; entryOut->_searchKey._offsetKey = edge->_offsetFromKey; TRI_InsertElementMultiPointer(edgesIndex, entryOut, true, isRollback); - + return TRI_ERROR_NO_ERROR; } @@ -937,14 +937,14 @@ TRI_index_t* TRI_CreateEdgeIndex (struct TRI_primary_collection_s* primary, if (edgeIndex == NULL) { return NULL; } - + res = TRI_InitMultiPointer(&edgeIndex->_edges, TRI_UNKNOWN_MEM_ZONE, HashElementEdge, HashElementEdge, IsEqualKeyEdge, IsEqualElementEdge); - + if (res != TRI_ERROR_NO_ERROR) { TRI_Free(TRI_CORE_MEM_ZONE, edgeIndex); @@ -983,16 +983,26 @@ void TRI_DestroyEdgeIndex (TRI_index_t* idx) { // free all elements in the edges index n = (size_t) edgesIndex->_edges._nrAlloc; + + // deletion from the index is done in two steps as memory was only allocated for IN edges + // the OUT edges are at memory position IN + sizeof(edge_header) and + // must not be freed themselves + // step 1: zero out all the out edges (we must not free them directly) + for (i = 0; i < n; ++i) { + TRI_edge_header_t* element = edgesIndex->_edges._table[i]; + + if (element != NULL && (element->_flags & TRI_EDGE_BIT_DIRECTION_OUT)) { + edgesIndex->_edges._table[i] = NULL; + } + } + + // step 2: free the allocated memory for (i = 0; i < n; ++i) { TRI_edge_header_t* element = edgesIndex->_edges._table[i]; - if (element != NULL && (element->_flags & TRI_EDGE_BIT_DIRECTION_IN)) { - // memory was only allocated for IN edges + if (element != NULL) { TRI_Free(TRI_UNKNOWN_MEM_ZONE, element); - - // the OUT edges are at memory position IN + sizeof(edge_header) and - // must not be freed themselves } }