diff --git a/arangod/Aql/Index.h b/arangod/Aql/Index.h index c7b43c6a70..cdd48397db 100644 --- a/arangod/Aql/Index.h +++ b/arangod/Aql/Index.h @@ -34,9 +34,8 @@ #include "Basics/Exceptions.h" #include "Basics/json.h" #include "Basics/JsonHelper.h" -#include "Indexes/HashIndex.h" #include "Indexes/Index.h" -#include "Indexes/SkiplistIndex.h" +#include "Indexes/PathBasedIndex.h" namespace triagens { namespace aql { @@ -67,15 +66,11 @@ namespace triagens { if (type == triagens::arango::Index::TRI_IDX_TYPE_PRIMARY_INDEX) { unique = true; } - else if (type == triagens::arango::Index::TRI_IDX_TYPE_HASH_INDEX) { - auto hashIndex = static_cast(idx); - sparse = hashIndex->sparse(); - unique = hashIndex->unique(); - } - else if (type == triagens::arango::Index::TRI_IDX_TYPE_SKIPLIST_INDEX) { - auto skiplistIndex = static_cast(idx); - sparse = skiplistIndex->sparse(); - unique = skiplistIndex->unique(); + else if (type == triagens::arango::Index::TRI_IDX_TYPE_HASH_INDEX || + type == triagens::arango::Index::TRI_IDX_TYPE_SKIPLIST_INDEX) { + auto pathBasedIndex = static_cast(idx); + sparse = pathBasedIndex->sparse(); + unique = pathBasedIndex->unique(); } } diff --git a/arangod/Aql/IndexRangeBlock.h b/arangod/Aql/IndexRangeBlock.h index 3be901ec74..5f84a972d3 100644 --- a/arangod/Aql/IndexRangeBlock.h +++ b/arangod/Aql/IndexRangeBlock.h @@ -31,6 +31,7 @@ #include "Aql/Collection.h" #include "Aql/ExecutionBlock.h" #include "Aql/ExecutionNode.h" +#include "Indexes/SkiplistIndex.h" #include "Utils/AqlTransaction.h" #include "VocBase/shaped-json.h" diff --git a/arangod/Aql/RangeInfo.h b/arangod/Aql/RangeInfo.h index 9371cb0731..24c055f8a6 100644 --- a/arangod/Aql/RangeInfo.h +++ b/arangod/Aql/RangeInfo.h @@ -32,6 +32,7 @@ #include "Aql/AstNode.h" #include "Basics/JsonHelper.h" #include "Basics/json-utilities.h" +#include "IndexOperators/index-operator.h" class VocShaper; diff --git a/arangod/Indexes/HashIndex.cpp b/arangod/Indexes/HashIndex.cpp index 4ca8d7f452..e7682226e1 100644 --- a/arangod/Indexes/HashIndex.cpp +++ b/arangod/Indexes/HashIndex.cpp @@ -203,7 +203,7 @@ HashIndex::HashIndex (TRI_idx_iid_t iid, indexBuckets = collection->_info._indexBuckets; } - std::unique_ptr func(new HashElementFunc(numPaths())); + std::unique_ptr func(new HashElementFunc(_paths.size())); if (unique) { std::unique_ptr compare(new IsEqualElementElementByKey(_paths.size())); @@ -221,7 +221,7 @@ HashIndex::HashIndex (TRI_idx_iid_t iid, else { _multiArray = nullptr; - std::unique_ptr compare(new IsEqualElementElementByKey(numPaths())); + std::unique_ptr compare(new IsEqualElementElementByKey(_paths.size())); std::unique_ptr array(new TRI_HashArrayMulti_t(HashKey, *(func.get()), @@ -494,13 +494,14 @@ int HashIndex::insertUnique (TRI_doc_mptr_t const* doc, return _uniqueArray->_hashArray->insert(element); }; - size_t count = elements.size(); - for (size_t i = 0; i < count; ++i) { + size_t const n = elements.size(); + + for (size_t i = 0; i < n; ++i) { auto hashElement = elements[i]; res = work(hashElement, isRollback); if (res != TRI_ERROR_NO_ERROR) { - for (size_t j = i; j < count; ++j) { + for (size_t j = i; j < n; ++j) { // Free all elements that are not yet in the index FreeElement(elements[j]); } @@ -527,6 +528,7 @@ int HashIndex::batchInsertUnique (std::vector const* docu return res; } } + int res = _uniqueArray->_hashArray->batchInsert(&elements, numThreads); if (res != TRI_ERROR_NO_ERROR) { @@ -545,6 +547,12 @@ int HashIndex::insertMulti (TRI_doc_mptr_t const* doc, std::vector elements; int res = fillElement(elements, doc); + + if (res != TRI_ERROR_NO_ERROR) { + for (auto& hashElement : elements) { + FreeElement(hashElement); + } + } auto work = [this] (TRI_index_element_t* element, bool isRollback) -> int { TRI_IF_FAILURE("InsertHashIndex") { @@ -564,12 +572,14 @@ int HashIndex::insertMulti (TRI_doc_mptr_t const* doc, return TRI_ERROR_NO_ERROR; }; - size_t const count = elements.size(); - for (size_t i = 0; i < count; ++i) { + size_t const n = elements.size(); + + for (size_t i = 0; i < n; ++i) { auto hashElement = elements[i]; res = work(hashElement, isRollback); + if (res != TRI_ERROR_NO_ERROR) { - for (size_t j = i; j < count; ++j) { + for (size_t j = i; j < n; ++j) { // Free all elements that are not yet in the index FreeElement(elements[j]); } @@ -643,29 +653,36 @@ int HashIndex::removeUnique (TRI_doc_mptr_t const* doc, bool isRollback) { } int HashIndex::removeMultiElement (TRI_index_element_t* element, bool isRollback) { - TRI_IF_FAILURE("RemoveHashIndex") { - return TRI_ERROR_DEBUG; - } + TRI_IF_FAILURE("RemoveHashIndex") { + return TRI_ERROR_DEBUG; + } - TRI_index_element_t* old = _multiArray->_hashArray->remove(element); - - if (old == nullptr) { - // not found - if (isRollback) { // ignore in this case, because it can happen - return TRI_ERROR_NO_ERROR; - } - else { - return TRI_ERROR_INTERNAL; - } + TRI_index_element_t* old = _multiArray->_hashArray->remove(element); + + if (old == nullptr) { + // not found + if (isRollback) { // ignore in this case, because it can happen + return TRI_ERROR_NO_ERROR; } - FreeElement(old); - return TRI_ERROR_NO_ERROR; + else { + return TRI_ERROR_INTERNAL; + } + } + FreeElement(old); + + return TRI_ERROR_NO_ERROR; } int HashIndex::removeMulti (TRI_doc_mptr_t const* doc, bool isRollback) { std::vector elements; int res = fillElement(elements, doc); + if (res != TRI_ERROR_NO_ERROR) { + for (auto& hashElement : elements) { + FreeElement(hashElement); + } + } + for (auto& hashElement : elements) { res = removeMultiElement(hashElement, isRollback); FreeElement(hashElement); diff --git a/arangod/V8Server/v8-query.cpp b/arangod/V8Server/v8-query.cpp index 7ab66d51d6..fe13ac9d65 100644 --- a/arangod/V8Server/v8-query.cpp +++ b/arangod/V8Server/v8-query.cpp @@ -34,6 +34,7 @@ #include "Basics/string-buffer.h" #include "Indexes/FulltextIndex.h" #include "Indexes/GeoIndex2.h" +#include "Indexes/HashIndex.h" #include "Indexes/SkiplistIndex.h" #include "FulltextIndex/fulltext-index.h" #include "FulltextIndex/fulltext-result.h" diff --git a/lib/Basics/AssocUnique.h b/lib/Basics/AssocUnique.h index c03046eb7f..d2e5593b26 100644 --- a/lib/Basics/AssocUnique.h +++ b/lib/Basics/AssocUnique.h @@ -323,11 +323,11 @@ namespace triagens { uint64_t i = hash % n; uint64_t k = i; - for (; i < n && b._table[i] != nullptr && - ! _isEqualElementElementByKey(element, b._table[i]); ++i); + for (; i < n && b._table[i] != nullptr && + ! _isEqualElementElementByKey(element, b._table[i]); ++i); if (i == n) { for (i = 0; i < k && b._table[i] != nullptr && - ! _isEqualElementElementByKey(element, b._table[i]); ++i); + ! _isEqualElementElementByKey(element, b._table[i]); ++i); } Element* arrayElement = b._table[i]; @@ -337,7 +337,6 @@ namespace triagens { } b._table[i] = element; - TRI_ASSERT(b._table[i] != nullptr); b._nrUsed++; return TRI_ERROR_NO_ERROR;