diff --git a/arangod/Indexes/HashIndex.cpp b/arangod/Indexes/HashIndex.cpp index e7682226e1..c5b3c0a112 100644 --- a/arangod/Indexes/HashIndex.cpp +++ b/arangod/Indexes/HashIndex.cpp @@ -204,9 +204,9 @@ HashIndex::HashIndex (TRI_idx_iid_t iid, } std::unique_ptr func(new HashElementFunc(_paths.size())); + std::unique_ptr compare(new IsEqualElementElementByKey(_paths.size())); if (unique) { - std::unique_ptr compare(new IsEqualElementElementByKey(_paths.size())); std::unique_ptr array(new TRI_HashArray_t(HashKey, *(func.get()), IsEqualKeyElementHash, @@ -221,8 +221,6 @@ HashIndex::HashIndex (TRI_idx_iid_t iid, else { _multiArray = nullptr; - std::unique_ptr compare(new IsEqualElementElementByKey(_paths.size())); - std::unique_ptr array(new TRI_HashArrayMulti_t(HashKey, *(func.get()), IsEqualKeyElement, @@ -234,9 +232,9 @@ HashIndex::HashIndex (TRI_idx_iid_t iid, _multiArray = new HashIndex::MultiArray(array.get(), func.get(), compare.get()); - compare.release(); array.release(); } + compare.release(); func.release(); } @@ -552,6 +550,7 @@ int HashIndex::insertMulti (TRI_doc_mptr_t const* doc, for (auto& hashElement : elements) { FreeElement(hashElement); } + return res; } auto work = [this] (TRI_index_element_t* element, bool isRollback) -> int { diff --git a/lib/Basics/AssocMulti.h b/lib/Basics/AssocMulti.h index dd52e2644e..03948bcf5b 100644 --- a/lib/Basics/AssocMulti.h +++ b/lib/Basics/AssocMulti.h @@ -36,12 +36,12 @@ // #define TRI_CHECK_MULTI_POINTER_HASH 1 #include "Basics/Common.h" -#include "Basics/prime-numbers.h" #include "Basics/JsonHelper.h" #include "Basics/logging.h" +#include "Basics/memory-map.h" #include "Basics/Mutex.h" #include "Basics/MutexLocker.h" -#include "Basics/memory-map.h" +#include "Basics/prime-numbers.h" namespace triagens { namespace basics { diff --git a/lib/Basics/AssocUnique.h b/lib/Basics/AssocUnique.h index d2e5593b26..8a592616e4 100644 --- a/lib/Basics/AssocUnique.h +++ b/lib/Basics/AssocUnique.h @@ -36,7 +36,9 @@ #include "Basics/gcd.h" #include "Basics/JsonHelper.h" #include "Basics/logging.h" +#include "Basics/memory-map.h" #include "Basics/MutexLocker.h" +#include "Basics/prime-numbers.h" #include "Basics/random.h" namespace triagens { @@ -230,9 +232,21 @@ namespace triagens { TRI_ASSERT(targetSize > 0); + targetSize = TRI_NearPrime(targetSize); + // This might throw, is catched outside b._table = new Element* [targetSize]; +#ifdef __linux__ + if (b._nrAlloc > 1000000) { + uintptr_t mem = reinterpret_cast(b._table); + uintptr_t pageSize = getpagesize(); + mem = (mem / pageSize) * pageSize; + void* memptr = reinterpret_cast(mem); + TRI_MMFileAdvise(memptr, b._nrAlloc * sizeof(Element*), + TRI_MADVISE_RANDOM); + } +#endif for (uint64_t i = 0; i < targetSize; i++) { b._table[i] = nullptr; } @@ -390,11 +404,14 @@ namespace triagens { //////////////////////////////////////////////////////////////////////////////// int resize (size_t size) { + size /= _buckets.size(); for (auto& b : _buckets) { + if (2 * (2 * size + 1) < 3 * b._nrUsed) { + return TRI_ERROR_BAD_PARAMETER; + } + try { - resizeInternal(b, - (uint64_t) (3 * size / 2 + 1) / _buckets.size(), - false); + resizeInternal(b, 2 * size + 1, false); } catch (...) { return TRI_ERROR_OUT_OF_MEMORY;