From 647cdc0ffe5659e23814069997ca583cd31923c0 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Thu, 25 Feb 2016 13:47:31 +0100 Subject: [PATCH] Implemented a indexScan iterator for Primary Index and moved the AQL iterator for it to VPack as well. Right now the AQL iterator is not functional is the memory management is not yet working. --- arangod/Indexes/PrimaryIndex.cpp | 45 ++++++++++++++++++++++++-------- arangod/Indexes/PrimaryIndex.h | 12 ++++++--- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/arangod/Indexes/PrimaryIndex.cpp b/arangod/Indexes/PrimaryIndex.cpp index 6c6337494c..7f8c0a03cb 100644 --- a/arangod/Indexes/PrimaryIndex.cpp +++ b/arangod/Indexes/PrimaryIndex.cpp @@ -80,12 +80,16 @@ static bool IsEqualElementElement(void* userData, TRI_doc_mptr_t const* left, TRI_doc_mptr_t* PrimaryIndexIterator::next() { while (true) { - if (_position >= _keys.size()) { + if (_position >= static_cast(_keys.length())) { // we're at the end of the lookup values return nullptr; } - auto result = _index->lookupKey(_trx, _keys[_position++]); + VPackSlice eqMatch = _keys.at(_position++); + if (!eqMatch.hasKey(TRI_SLICE_KEY_EQUAL)) { + continue; + } + auto result = _index->lookupKey(_trx, eqMatch.get(TRI_SLICE_KEY_EQUAL)); if (result != nullptr) { // found a result @@ -432,6 +436,20 @@ IndexIterator* PrimaryIndex::iteratorForCondition( return nullptr; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief creates an IndexIterator for the given slice +//////////////////////////////////////////////////////////////////////////////// + +IndexIterator* PrimaryIndex::iteratorForSlice( + arangodb::Transaction* trx, IndexIteratorContext* ctxt, + arangodb::velocypack::Slice const searchValues, bool) const { + if (!searchValues.isArray()) { + // Invalid searchValue + return nullptr; + } + return new PrimaryIndexIterator(trx, this, searchValues); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief specializes the condition for use with the index //////////////////////////////////////////////////////////////////////////////// @@ -458,14 +476,13 @@ IndexIterator* PrimaryIndex::createIterator( bool const isId = (strcmp(attrNode->getStringValue(), TRI_VOC_ATTRIBUTE_ID) == 0); + // TODO Where to store the BUILDER? + // only leave the valid elements in the vector - size_t const n = valNodes.size(); - std::vector keys; - keys.reserve(n); - - for (size_t i = 0; i < n; ++i) { - auto valNode = valNodes[i]; + VPackBuilder keys; + keys.openArray(); + for (auto const& valNode : valNodes) { if (!valNode->isStringValue()) { continue; } @@ -500,14 +517,20 @@ IndexIterator* PrimaryIndex::createIterator( } // use _key value from _id - keys.push_back(key); + keys.openObject(); + keys.add(TRI_SLICE_KEY_EQUAL, VPackValue(key)); + keys.close(); } else { - keys.emplace_back(valNode->getStringValue()); + keys.openObject(); + keys.add(TRI_SLICE_KEY_EQUAL, VPackValue(valNode->getStringValue())); + keys.close(); } } TRI_IF_FAILURE("PrimaryIndex::noIterator") { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); } - return new PrimaryIndexIterator(trx, this, keys); + keys.close(); + TRI_ASSERT(false); // TODO This has undefined behaviour. We have to put keys somewhere! + return new PrimaryIndexIterator(trx, this, keys.slice()); } diff --git a/arangod/Indexes/PrimaryIndex.h b/arangod/Indexes/PrimaryIndex.h index 74721ccae4..728a6d345e 100644 --- a/arangod/Indexes/PrimaryIndex.h +++ b/arangod/Indexes/PrimaryIndex.h @@ -41,8 +41,10 @@ class Transaction; class PrimaryIndexIterator final : public IndexIterator { public: PrimaryIndexIterator(arangodb::Transaction* trx, PrimaryIndex const* index, - std::vector& keys) - : _trx(trx), _index(index), _keys(std::move(keys)), _position(0) {} + arangodb::velocypack::Slice const keys) + : _trx(trx), _index(index), _keys(keys), _position(0) { + TRI_ASSERT(_keys.isArray()); + } ~PrimaryIndexIterator() {} @@ -53,7 +55,7 @@ class PrimaryIndexIterator final : public IndexIterator { private: arangodb::Transaction* _trx; PrimaryIndex const* _index; - std::vector _keys; + arangodb::velocypack::Slice const _keys; size_t _position; }; @@ -245,6 +247,10 @@ class PrimaryIndex final : public Index { arangodb::aql::Variable const*, bool) const override; + IndexIterator* iteratorForSlice(arangodb::Transaction*, IndexIteratorContext*, + arangodb::velocypack::Slice const, + bool) const override; + arangodb::aql::AstNode* specializeCondition( arangodb::aql::AstNode*, arangodb::aql::Variable const*) const override;