diff --git a/arangod/Aql/ExecutionBlock.cpp b/arangod/Aql/ExecutionBlock.cpp index 64a2cb4ca5..d5383e40a0 100644 --- a/arangod/Aql/ExecutionBlock.cpp +++ b/arangod/Aql/ExecutionBlock.cpp @@ -2427,7 +2427,7 @@ void IndexRangeBlock::readSkiplistIndex (size_t atMost) { try { size_t nrSent = 0; while (nrSent < atMost && _skiplistIterator !=nullptr) { - TRI_skiplist_index_element_t* indexElement = _skiplistIterator->next(_skiplistIterator); + TRI_index_element_t* indexElement = _skiplistIterator->next(_skiplistIterator); if (indexElement == nullptr) { TRI_FreeSkiplistIterator(_skiplistIterator); @@ -2441,7 +2441,7 @@ void IndexRangeBlock::readSkiplistIndex (size_t atMost) { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); } - _documents.emplace_back(*(indexElement->_document)); + _documents.emplace_back(*(indexElement->document())); ++nrSent; ++_engine->_stats.scannedIndex; } diff --git a/arangod/Indexes/HashIndex.cpp b/arangod/Indexes/HashIndex.cpp index 2f62941c9a..ba3a2d97b4 100644 --- a/arangod/Indexes/HashIndex.cpp +++ b/arangod/Indexes/HashIndex.cpp @@ -389,6 +389,7 @@ int HashIndex::insertUnique (TRI_doc_mptr_t const* doc, auto allocate = [this] () -> TRI_index_element_t* { return TRI_index_element_t::allocate(keyEntrySize(), false); }; + std::vector elements; int res = fillElement(allocate, elements, doc, paths(), sparse()); diff --git a/arangod/Indexes/SkiplistIndex2.cpp b/arangod/Indexes/SkiplistIndex2.cpp index 6387e44047..365d761146 100644 --- a/arangod/Indexes/SkiplistIndex2.cpp +++ b/arangod/Indexes/SkiplistIndex2.cpp @@ -177,47 +177,25 @@ triagens::basics::Json SkiplistIndex2::toJson (TRI_memory_zone_t* zone) const { int SkiplistIndex2::insert (TRI_doc_mptr_t const* doc, bool) { - auto skiplistElement = static_cast(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, SkiplistIndex_ElementSize(_skiplistIndex), false)); - if (skiplistElement == nullptr) { - return TRI_ERROR_OUT_OF_MEMORY; - } + auto allocate = [this] () -> TRI_index_element_t* { + return TRI_index_element_t::allocate(SkiplistIndex_ElementSize(_skiplistIndex), false); + }; + std::vector elements; - int res = fillElement2(skiplistElement, SkiplistIndex_Subobjects(skiplistElement), doc, _paths, _sparse); - - // ........................................................................... - // most likely the cause of this error is that the index is sparse - // and not all attributes the index needs are set -- so the document - // is ignored. So not really an error at all. Note that this does - // not happen in a non-sparse skiplist index, in which empty - // attributes are always treated as if they were bound to null, so - // TRI_ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING cannot happen at - // all. - // ........................................................................... - - // ......................................................................... - // It may happen that the document does not have the necessary - // attributes to be included within the hash index, in this case do - // not report back an error. - // ......................................................................... - - if (res == TRI_ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING) { - if (_sparse) { - TRI_Free(TRI_UNKNOWN_MEM_ZONE, skiplistElement); - return TRI_ERROR_NO_ERROR; - } - - res = TRI_ERROR_NO_ERROR; - } - - if (res != TRI_ERROR_NO_ERROR) { - TRI_Free(TRI_UNKNOWN_MEM_ZONE, skiplistElement); - return res; - } + int res = fillElement(allocate, elements, doc, _paths, _sparse); // insert into the index. the memory for the element will be owned or freed // by the index - return SkiplistIndex_insert(_skiplistIndex, skiplistElement); + + for (auto& skiplistElement : elements) { + res = SkiplistIndex_insert(_skiplistIndex, skiplistElement); + if (res != TRI_ERROR_NO_ERROR) { + // TODO FIXME + } + } + // TODO FIXME + return res; } //////////////////////////////////////////////////////////////////////////////// @@ -226,36 +204,25 @@ int SkiplistIndex2::insert (TRI_doc_mptr_t const* doc, int SkiplistIndex2::remove (TRI_doc_mptr_t const* doc, bool) { - auto skiplistElement = static_cast(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, SkiplistIndex_ElementSize(_skiplistIndex), false)); - if (skiplistElement == nullptr) { - return TRI_ERROR_OUT_OF_MEMORY; - } + auto allocate = [this] () -> TRI_index_element_t* { + return TRI_index_element_t::allocate(SkiplistIndex_ElementSize(_skiplistIndex), false); + }; - int res = fillElement2(skiplistElement, SkiplistIndex_Subobjects(skiplistElement), doc, _paths, _sparse); - - // .......................................................................... - // Error returned generally implies that the document never was part of the - // skiplist index - // .......................................................................... - if (res == TRI_ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING) { - if (_sparse) { - TRI_Free(TRI_UNKNOWN_MEM_ZONE, skiplistElement); - return TRI_ERROR_NO_ERROR; - } - - res = TRI_ERROR_NO_ERROR; - } - - if (res != TRI_ERROR_NO_ERROR) { - TRI_Free(TRI_UNKNOWN_MEM_ZONE, skiplistElement); - return res; - } + std::vector elements; + int res = fillElement(allocate, elements, doc, _paths, _sparse); // attempt the removal for skiplist indexes // ownership for the index element is transferred to the index - return SkiplistIndex_remove(_skiplistIndex, skiplistElement); + for (auto& skiplistElement : elements) { + res = SkiplistIndex_remove(_skiplistIndex, skiplistElement); + if (res != TRI_ERROR_NO_ERROR) { + // TODO FIXME + } + } + // TODO FIXME + return res; } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/SkipLists/skiplistIndex.cpp b/arangod/SkipLists/skiplistIndex.cpp index 98d94b2c94..9095563f4f 100644 --- a/arangod/SkipLists/skiplistIndex.cpp +++ b/arangod/SkipLists/skiplistIndex.cpp @@ -61,19 +61,19 @@ //////////////////////////////////////////////////////////////////////////////// static int CompareKeyElement (TRI_shaped_json_t const* left, - TRI_skiplist_index_element_t const* right, + TRI_index_element_t const* right, size_t rightPosition, VocShaper* shaper) { TRI_ASSERT(nullptr != left); TRI_ASSERT(nullptr != right); - auto rightSubobjects = SkiplistIndex_Subobjects(right); + auto rightSubobjects = right->subObjects(); return TRI_CompareShapeTypes(nullptr, nullptr, left, shaper, - right->_document->getShapedJsonPtr(), + right->document()->getShapedJsonPtr(), &rightSubobjects[rightPosition], nullptr, shaper); @@ -83,22 +83,22 @@ static int CompareKeyElement (TRI_shaped_json_t const* left, /// @brief compares elements, version with proper types //////////////////////////////////////////////////////////////////////////////// -static int CompareElementElement (TRI_skiplist_index_element_t const* left, +static int CompareElementElement (TRI_index_element_t const* left, size_t leftPosition, - TRI_skiplist_index_element_t const* right, + TRI_index_element_t const* right, size_t rightPosition, VocShaper* shaper) { TRI_ASSERT(nullptr != left); TRI_ASSERT(nullptr != right); - auto leftSubobjects = SkiplistIndex_Subobjects(left); - auto rightSubobjects = SkiplistIndex_Subobjects(right); + auto leftSubobjects = left->subObjects(); + auto rightSubobjects = right->subObjects(); - return TRI_CompareShapeTypes(left->_document->getShapedJsonPtr(), + return TRI_CompareShapeTypes(left->document()->getShapedJsonPtr(), &leftSubobjects[leftPosition], nullptr, shaper, - right->_document->getShapedJsonPtr(), + right->document()->getShapedJsonPtr(), &rightSubobjects[rightPosition], nullptr, shaper); @@ -113,8 +113,8 @@ static int CmpElmElm (void* sli, void* right, triagens::basics::SkipListCmpType cmptype) { - auto leftElement = static_cast(left); - auto rightElement = static_cast(right); + auto leftElement = static_cast(left); + auto rightElement = static_cast(right); TRI_ASSERT(nullptr != left); TRI_ASSERT(nullptr != right); @@ -124,7 +124,7 @@ static int CmpElmElm (void* sli, // .......................................................................... if (leftElement == rightElement || - leftElement->_document == rightElement->_document) { + leftElement->document() == rightElement->document()) { return 0; } @@ -155,8 +155,8 @@ static int CmpElmElm (void* sli, } // We break this tie in the key comparison by looking at the key: - int compareResult = strcmp(TRI_EXTRACT_MARKER_KEY(leftElement->_document), // ONLY IN INDEX, PROTECTED by RUNTIME - TRI_EXTRACT_MARKER_KEY(rightElement->_document)); // ONLY IN INDEX, PROTECTED by RUNTIME + int compareResult = strcmp(TRI_EXTRACT_MARKER_KEY(leftElement->document()), // ONLY IN INDEX, PROTECTED by RUNTIME + TRI_EXTRACT_MARKER_KEY(rightElement->document())); // ONLY IN INDEX, PROTECTED by RUNTIME if (compareResult < 0) { return -1; @@ -175,7 +175,7 @@ static int CmpKeyElm (void* sli, void* left, void* right) { auto leftKey = static_cast(left); - auto rightElement = static_cast(right); + auto rightElement = static_cast(right); TRI_ASSERT(nullptr != left); TRI_ASSERT(nullptr != right); @@ -202,8 +202,9 @@ static int CmpKeyElm (void* sli, //////////////////////////////////////////////////////////////////////////////// static void FreeElm (void* e) { - auto element = static_cast(e); - TRI_Free(TRI_UNKNOWN_MEM_ZONE, element); + auto element = static_cast(e); + TRI_index_element_t::free(element); + // TRI_Free(TRI_UNKNOWN_MEM_ZONE, element); } //////////////////////////////////////////////////////////////////////////////// @@ -286,7 +287,7 @@ static bool SkiplistHasNextIterationCallback (TRI_skiplist_iterator_t const* ite /// @brief Jumps backwards by jumpSize and returns the document //////////////////////////////////////////////////////////////////////////////// -static TRI_skiplist_index_element_t* SkiplistPrevIterationCallback ( +static TRI_index_element_t* SkiplistPrevIterationCallback ( TRI_skiplist_iterator_t* iterator) { static const int64_t jumpSize = 1; @@ -331,14 +332,14 @@ static TRI_skiplist_index_element_t* SkiplistPrevIterationCallback ( } TRI_ASSERT(result != nullptr); - return static_cast(result->document()); //iterator->_cursor->document()); + return static_cast(result->document()); //iterator->_cursor->document()); } //////////////////////////////////////////////////////////////////////////////// /// @brief Jumps forwards by jumpSize and returns the document //////////////////////////////////////////////////////////////////////////////// -static TRI_skiplist_index_element_t* SkiplistNextIterationCallback ( +static TRI_index_element_t* SkiplistNextIterationCallback ( TRI_skiplist_iterator_t* iterator) { static const int64_t jumpSize = 1; @@ -378,7 +379,7 @@ static TRI_skiplist_index_element_t* SkiplistNextIterationCallback ( } } - return static_cast(iterator->_cursor->document()); + return static_cast(iterator->_cursor->document()); } // ----------------------------------------------------------------------------- @@ -978,11 +979,11 @@ TRI_skiplist_iterator_t* SkiplistIndex_find (SkiplistIndex* skiplistIndex, //////////////////////////////////////////////////////////////////////////////// int SkiplistIndex_insert (SkiplistIndex* skiplistIndex, - TRI_skiplist_index_element_t* element) { + TRI_index_element_t* element) { int res = skiplistIndex->skiplist->insert(element); if (res != TRI_ERROR_NO_ERROR) { - TRI_Free(TRI_UNKNOWN_MEM_ZONE, element); + TRI_index_element_t::free(element); } return res; @@ -994,10 +995,10 @@ int SkiplistIndex_insert (SkiplistIndex* skiplistIndex, //////////////////////////////////////////////////////////////////////////////// int SkiplistIndex_remove (SkiplistIndex* skiplistIndex, - TRI_skiplist_index_element_t* element) { + TRI_index_element_t* element) { int res = skiplistIndex->skiplist->remove(element); - TRI_Free(TRI_UNKNOWN_MEM_ZONE, element); + TRI_index_element_t::free(element); if (res == TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND) { // This is for the case of a rollback in an aborted transaction. diff --git a/arangod/SkipLists/skiplistIndex.h b/arangod/SkipLists/skiplistIndex.h index 5113a7b5d3..5f0a7d2ce4 100644 --- a/arangod/SkipLists/skiplistIndex.h +++ b/arangod/SkipLists/skiplistIndex.h @@ -32,6 +32,7 @@ #include "Basics/Common.h" #include "Basics/SkipList.h" +#include "Indexes/Index.h" #include "IndexOperators/index-operator.h" #include "VocBase/shaped-json.h" @@ -63,13 +64,6 @@ typedef struct { } TRI_skiplist_index_key_t; -typedef struct { - struct TRI_doc_mptr_t* _document; // master document pointer - // note: the index element also contains a list of shaped subs as follows - // TRI_shaped_sub_t* _subObjects; -} -TRI_skiplist_index_element_t; - //////////////////////////////////////////////////////////////////////////////// /// @brief Iterator structure for skip list. We require a start and stop node /// @@ -103,7 +97,7 @@ typedef struct TRI_skiplist_iterator_s { // SkiplistPrevIterationCallback for the exact // condition for the iterator to be exhausted. bool (*hasNext) (struct TRI_skiplist_iterator_s const*); - TRI_skiplist_index_element_t* (*next)(struct TRI_skiplist_iterator_s*); + TRI_index_element_t* (*next)(struct TRI_skiplist_iterator_s*); } TRI_skiplist_iterator_t; @@ -149,12 +143,12 @@ TRI_skiplist_iterator_t* SkiplistIndex_find (SkiplistIndex*, TRI_index_operator_t const*, bool); -int SkiplistIndex_insert (SkiplistIndex*, TRI_skiplist_index_element_t*); +int SkiplistIndex_insert (SkiplistIndex*, TRI_index_element_t*); -int SkiplistIndex_remove (SkiplistIndex*, TRI_skiplist_index_element_t*); +int SkiplistIndex_remove (SkiplistIndex*, TRI_index_element_t*); -bool SkiplistIndex_update (SkiplistIndex*, const TRI_skiplist_index_element_t*, - const TRI_skiplist_index_element_t*); +bool SkiplistIndex_update (SkiplistIndex*, const TRI_index_element_t*, + const TRI_index_element_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief return the number of elements in the index @@ -180,7 +174,7 @@ inline size_t SkiplistIndex_ElementSize (SkiplistIndex const* idx) { /// @brief return the base address for the shaped subs inside an element //////////////////////////////////////////////////////////////////////////////// -inline TRI_shaped_sub_t const* SkiplistIndex_Subobjects (TRI_skiplist_index_element_t const* element) { +inline TRI_shaped_sub_t const* SkiplistIndex_Subobjects (TRI_index_element_t const* element) { return reinterpret_cast(reinterpret_cast(element) + sizeof(TRI_doc_mptr_t*)); } @@ -188,7 +182,7 @@ inline TRI_shaped_sub_t const* SkiplistIndex_Subobjects (TRI_skiplist_index_elem /// @brief return the base address for the shaped subs inside an element //////////////////////////////////////////////////////////////////////////////// -inline TRI_shaped_sub_t* SkiplistIndex_Subobjects (TRI_skiplist_index_element_t* element) { +inline TRI_shaped_sub_t* SkiplistIndex_Subobjects (TRI_index_element_t* element) { return reinterpret_cast(reinterpret_cast(element) + sizeof(TRI_doc_mptr_t*)); } diff --git a/arangod/V8Server/v8-query.cpp b/arangod/V8Server/v8-query.cpp index 82b1b6001f..bd4ece0823 100644 --- a/arangod/V8Server/v8-query.cpp +++ b/arangod/V8Server/v8-query.cpp @@ -634,7 +634,7 @@ static void ExecuteSkiplistQuery (const v8::FunctionCallbackInfo& arg } while (limit > 0) { - TRI_skiplist_index_element_t* indexElement = skiplistIterator->next(skiplistIterator); + TRI_index_element_t* indexElement = skiplistIterator->next(skiplistIterator); if (indexElement == nullptr) { break; @@ -645,7 +645,7 @@ static void ExecuteSkiplistQuery (const v8::FunctionCallbackInfo& arg if (total > skip && count < limit) { v8::Handle doc = WRAP_SHAPED_JSON(trx, col->_cid, - ((TRI_doc_mptr_t const*) indexElement->_document)->getDataPtr()); + ((TRI_doc_mptr_t const*) indexElement->document())->getDataPtr()); if (doc.IsEmpty()) { error = true;