diff --git a/arangod/VocBase/index.cpp b/arangod/VocBase/index.cpp index 32ac9909ec..d928afae0e 100644 --- a/arangod/VocBase/index.cpp +++ b/arangod/VocBase/index.cpp @@ -736,11 +736,11 @@ static bool IsEqualKeyEdgeTo (void const* left, } //////////////////////////////////////////////////////////////////////////////// -/// @brief checks for elements are equal (_from case) +/// @brief checks for elements are equal (_from and _to case) //////////////////////////////////////////////////////////////////////////////// -static bool IsEqualElementEdgeFrom (void const* left, - void const* right) { +static bool IsEqualElementEdge (void const* left, + void const* right) { return left == right; } @@ -750,11 +750,11 @@ static bool IsEqualElementEdgeFrom (void const* left, static bool IsEqualElementEdgeFromByKey (void const* left, void const* right) { + char const* lKey = nullptr; + char const* rKey = nullptr; + TRI_voc_cid_t lCid = 0; + TRI_voc_cid_t rCid = 0; TRI_df_marker_t const* marker; - char const* lKey; - TRI_voc_cid_t lCid; - char const* rKey; - TRI_voc_cid_t rCid; // left element TRI_doc_mptr_t const* lMptr = static_cast(left); @@ -770,9 +770,6 @@ static bool IsEqualElementEdgeFromByKey (void const* left, lKey = (char const*) lEdge + lEdge->_offsetFromKey; lCid = lEdge->_fromCid; } - else { - return false; - } // right element TRI_doc_mptr_t const* rMptr = static_cast(right); @@ -788,7 +785,8 @@ static bool IsEqualElementEdgeFromByKey (void const* left, rKey = (char const*) rEdge + rEdge->_offsetFromKey; rCid = rEdge->_fromCid; } - else { + + if (lKey == nullptr || rKey == nullptr) { return false; } @@ -801,22 +799,13 @@ static bool IsEqualElementEdgeFromByKey (void const* left, /// @brief checks for elements are equal (_to case) //////////////////////////////////////////////////////////////////////////////// -static bool IsEqualElementEdgeTo (void const* left, - void const* right) { - return left == right; -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief checks for elements are equal (_to case) -//////////////////////////////////////////////////////////////////////////////// - static bool IsEqualElementEdgeToByKey (void const* left, void const* right) { + char const* lKey = nullptr; + char const* rKey = nullptr; + TRI_voc_cid_t lCid = 0; + TRI_voc_cid_t rCid = 0; TRI_df_marker_t const* marker; - char const* lKey; - TRI_voc_cid_t lCid; - char const* rKey; - TRI_voc_cid_t rCid; // left element TRI_doc_mptr_t const* lMptr = static_cast(left); @@ -832,9 +821,6 @@ static bool IsEqualElementEdgeToByKey (void const* left, lKey = (char const*) lEdge + lEdge->_offsetToKey; lCid = lEdge->_toCid; } - else { - return false; - } // right element TRI_doc_mptr_t const* rMptr = static_cast(right); @@ -850,7 +836,8 @@ static bool IsEqualElementEdgeToByKey (void const* left, rKey = (char const*) rEdge + rEdge->_offsetToKey; rCid = rEdge->_toCid; } - else { + + if (lKey == nullptr || rKey == nullptr) { return false; } @@ -944,8 +931,6 @@ static TRI_json_t* JsonEdge (TRI_index_t const* idx) { static int SizeHintEdge (TRI_index_t* idx, size_t size) { - int err; - TRI_multi_pointer_t* edgesIndex = &(((TRI_edge_index_t*) idx)->_edges_from); // we assume this is called when setting up the index and the index @@ -954,7 +939,7 @@ static int SizeHintEdge (TRI_index_t* idx, // set an initial size for the index for some new nodes to be created // without resizing - err = TRI_ResizeMultiPointer(edgesIndex, size + 2049); + int err = TRI_ResizeMultiPointer(edgesIndex, size + 2049); if (err != TRI_ERROR_NO_ERROR) { return err; @@ -997,7 +982,7 @@ TRI_index_t* TRI_CreateEdgeIndex (TRI_document_collection_t* document, HashElementKey, HashElementEdgeFrom, IsEqualKeyEdgeFrom, - IsEqualElementEdgeFrom, + IsEqualElementEdge, IsEqualElementEdgeFromByKey); if (res != TRI_ERROR_NO_ERROR) { @@ -1010,7 +995,7 @@ TRI_index_t* TRI_CreateEdgeIndex (TRI_document_collection_t* document, HashElementKey, HashElementEdgeTo, IsEqualKeyEdgeTo, - IsEqualElementEdgeTo, + IsEqualElementEdge, IsEqualElementEdgeToByKey); if (res != TRI_ERROR_NO_ERROR) { diff --git a/lib/Basics/associative-multi.cpp b/lib/Basics/associative-multi.cpp index 77f51619fd..c948aebf96 100644 --- a/lib/Basics/associative-multi.cpp +++ b/lib/Basics/associative-multi.cpp @@ -210,9 +210,9 @@ bool TRI_CheckMultiPointerHash (TRI_multi_pointer_t* array, bool checkCount, /// @brief find an element or its place using the element hash function //////////////////////////////////////////////////////////////////////////////// +template static inline uint64_t FindElementPlace (TRI_multi_pointer_t* array, - void const* element, - bool checkEquality) { + void const* element) { // This either finds a place to store element or an entry in the table // that is equal to element. If checkEquality is set to false, the caller // guarantees that there is no entry that compares equal to element @@ -220,17 +220,18 @@ static inline uint64_t FindElementPlace (TRI_multi_pointer_t* array, // always returns a pointer into the table, which is either empty or // points to an entry that compares equal to element. - uint64_t const hash = array->hashElement(element, false); - uint64_t i = hash % array->_nrAlloc; + uint64_t const n = array->_nrAlloc; + uint64_t i = array->hashElement(element, false) % n; while (array->_table[i].ptr != nullptr && (! checkEquality || ! array->isEqualElementElement(element, array->_table[i].ptr))) { - i = TRI_IncModU64(i, array->_nrAlloc); + i = TRI_IncModU64(i, n); #ifdef TRI_INTERNAL_STATS array->_nrProbes++; #endif } + return i; } @@ -272,7 +273,7 @@ static uint64_t LookupByElement (TRI_multi_pointer_t* array, } // Now we have to look for it in its hash position: - uint64_t j = FindElementPlace(array, element, true); + uint64_t j = FindElementPlace(array, element); // We have either found an equal element or nothing: return j; @@ -296,10 +297,12 @@ static inline bool IsBetween (uint64_t from, uint64_t x, uint64_t to) { //////////////////////////////////////////////////////////////////////////////// static inline void InvalidateEntry (TRI_multi_pointer_t* array, uint64_t i) { - array->_table[i].hash = 0; - array->_table[i].ptr = nullptr; - array->_table[i].next = TRI_MULTI_POINTER_INVALID_INDEX; - array->_table[i].prev = TRI_MULTI_POINTER_INVALID_INDEX; + array->_table[i] = { + 0, + nullptr, + TRI_MULTI_POINTER_INVALID_INDEX, + TRI_MULTI_POINTER_INVALID_INDEX + }; } //////////////////////////////////////////////////////////////////////////////// @@ -381,10 +384,12 @@ static void InsertElementMultiPointer (TRI_multi_pointer_t* array, // If this slot is free, just use it: if (nullptr == array->_table[i].ptr) { - array->_table[i].hash = hash; - array->_table[i].ptr = element; - array->_table[i].next = TRI_MULTI_POINTER_INVALID_INDEX; - array->_table[i].prev = TRI_MULTI_POINTER_INVALID_INDEX; + array->_table[i] = { + hash, + element, + TRI_MULTI_POINTER_INVALID_INDEX, + TRI_MULTI_POINTER_INVALID_INDEX + }; array->_nrUnique++; #ifdef TRI_CHECK_MULTI_POINTER_HASH TRI_CheckMultiPointerHash(array, true, true); @@ -403,15 +408,16 @@ static void InsertElementMultiPointer (TRI_multi_pointer_t* array, // update statistics array->_ProbesA++; #endif - } - + // If this is free, we are the first with this key: if (nullptr == array->_table[i].ptr) { - array->_table[i].hash = hash; - array->_table[i].ptr = element; - array->_table[i].next = TRI_MULTI_POINTER_INVALID_INDEX; - array->_table[i].prev = TRI_MULTI_POINTER_INVALID_INDEX; + array->_table[i] = { + hash, + element, + TRI_MULTI_POINTER_INVALID_INDEX, + TRI_MULTI_POINTER_INVALID_INDEX + }; array->_nrUnique++; #ifdef TRI_CHECK_MULTI_POINTER_HASH TRI_CheckMultiPointerHash(array, true, true); @@ -420,7 +426,7 @@ static void InsertElementMultiPointer (TRI_multi_pointer_t* array, } // Now find a new home for element in this linked list: - uint64_t j = FindElementPlace(array, element, false); + uint64_t j = FindElementPlace(array, element); // if we found an element, update it if (array->_table[j].ptr != nullptr) { @@ -434,10 +440,12 @@ static void InsertElementMultiPointer (TRI_multi_pointer_t* array, } // add a new element to the associative array and linked list (in pos 2): - array->_table[j].hash = hash; - array->_table[j].ptr = element; - array->_table[j].next = array->_table[i].next; - array->_table[j].prev = i; + array->_table[j] = { + hash, + element, + array->_table[i].next, + static_cast(i) + }; array->_table[i].next = j; // Finally, we need to find the successor to patch it up: if (array->_table[j].next != TRI_MULTI_POINTER_INVALID_INDEX) { @@ -481,10 +489,16 @@ static int ResizeMultiPointer (TRI_multi_pointer_t* array, #endif // table is already clear by allocate, copy old data - for (uint64_t j = 0; j < oldAlloc; j++) { - if (oldTable[j].ptr != nullptr) { - InsertElementMultiPointer(array, oldTable[j].hash, oldTable[j].ptr); - } + { + TRI_multi_pointer_entry_t* p = oldTable; + TRI_multi_pointer_entry_t* e = oldTable + oldAlloc; + + while (p < e) { + if (p->ptr != nullptr) { + InsertElementMultiPointer(array, p->hash, p->ptr); + } + ++p; + } } // update _nrUsed only once for the complete table @@ -550,15 +564,13 @@ void* TRI_InsertElementMultiPointer (TRI_multi_pointer_t* array, #endif // compute the hash by the key only first + uint64_t const n = array->_nrAlloc; uint64_t const hash = array->hashElement(element, true); - uint64_t i = hash % array->_nrAlloc; + uint64_t i = hash % n; // If this slot is free, just use it: if (nullptr == array->_table[i].ptr) { - array->_table[i].hash = hash; - array->_table[i].ptr = element; - array->_table[i].next = TRI_MULTI_POINTER_INVALID_INDEX; - array->_table[i].prev = TRI_MULTI_POINTER_INVALID_INDEX; + array->_table[i] = { hash, element, TRI_MULTI_POINTER_INVALID_INDEX, TRI_MULTI_POINTER_INVALID_INDEX }; array->_nrUsed++; array->_nrUnique++; #ifdef TRI_CHECK_MULTI_POINTER_HASH @@ -567,26 +579,20 @@ void* TRI_InsertElementMultiPointer (TRI_multi_pointer_t* array, return nullptr; } - // Now find the first slot with an entry with the same key that is the - // start of a linked list, or a free slot: while (array->_table[i].ptr != nullptr && (array->_table[i].prev != TRI_MULTI_POINTER_INVALID_INDEX || array->_table[i].hash != hash || ! array->isEqualElementElementByKey(element, array->_table[i].ptr))) { - i = TRI_IncModU64(i, array->_nrAlloc); + i = TRI_IncModU64(i, n); #ifdef TRI_INTERNAL_STATS // update statistics array->_ProbesA++; #endif - } // If this is free, we are the first with this key: if (nullptr == array->_table[i].ptr) { - array->_table[i].hash = hash; - array->_table[i].ptr = element; - array->_table[i].next = TRI_MULTI_POINTER_INVALID_INDEX; - array->_table[i].prev = TRI_MULTI_POINTER_INVALID_INDEX; + array->_table[i] = { hash, element, TRI_MULTI_POINTER_INVALID_INDEX, TRI_MULTI_POINTER_INVALID_INDEX }; array->_nrUsed++; array->_nrUnique++; #ifdef TRI_CHECK_MULTI_POINTER_HASH @@ -612,7 +618,13 @@ void* TRI_InsertElementMultiPointer (TRI_multi_pointer_t* array, } // Now find a new home for element in this linked list: - uint64_t j = FindElementPlace(array, element, checkEquality); + uint64_t j; + if (checkEquality) { + j = FindElementPlace(array, element); + } + else { + j = FindElementPlace(array, element); + } void* old = array->_table[j].ptr; @@ -629,10 +641,7 @@ void* TRI_InsertElementMultiPointer (TRI_multi_pointer_t* array, } // add a new element to the associative array and linked list (in pos 2): - array->_table[j].hash = hash; - array->_table[j].ptr = element; - array->_table[j].next = array->_table[i].next; - array->_table[j].prev = i; + array->_table[j] = { hash, element, array->_table[i].next, static_cast(i) }; array->_table[i].next = j; // Finally, we need to find the successor to patch it up: if (array->_table[j].next != TRI_MULTI_POINTER_INVALID_INDEX) {