From 2133b1448c62a8cff7a9735a9b2e87b985aaf9a5 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 24 Jan 2017 18:19:25 +0100 Subject: [PATCH] Moved index API to return DocumentIdentifierTokens which are independent of the underlying storage engine. The agreement is, that the Engine gives a uint64_t sized identifier which allows to fetch any document back again. For MMFiles Engine this identifier is the revision. --- arangod/Aql/CollectionScanner.cpp | 2 +- arangod/Aql/CollectionScanner.h | 2 +- arangod/Aql/EnumerateCollectionBlock.cpp | 3 +- arangod/Aql/EnumerateCollectionBlock.h | 2 +- arangod/Aql/IndexBlock.cpp | 10 ++--- arangod/Aql/IndexBlock.h | 4 +- arangod/Aql/ShortestPathBlock.cpp | 14 +++---- arangod/Indexes/IndexIterator.cpp | 22 +++++------ arangod/Indexes/IndexIterator.h | 33 ++++------------ arangod/Indexes/IndexLookupContext.h | 4 +- arangod/MMFiles/MMFilesEdgeIndex.cpp | 27 +++++++------ arangod/MMFiles/MMFilesEdgeIndex.h | 10 ++--- arangod/MMFiles/MMFilesGeoIndex.cpp | 14 ++++--- arangod/MMFiles/MMFilesGeoIndex.h | 4 +- arangod/MMFiles/MMFilesHashIndex.cpp | 17 ++++---- arangod/MMFiles/MMFilesHashIndex.h | 6 +-- arangod/MMFiles/MMFilesIndexElement.cpp | 7 ++-- arangod/MMFiles/MMFilesPersistentIndex.cpp | 15 +++---- arangod/MMFiles/MMFilesPersistentIndex.h | 2 +- arangod/MMFiles/MMFilesPrimaryIndex.cpp | 25 ++++++------ arangod/MMFiles/MMFilesPrimaryIndex.h | 8 ++-- arangod/MMFiles/MMFilesSkiplistIndex.cpp | 13 +++--- arangod/MMFiles/MMFilesSkiplistIndex.h | 4 +- arangod/MMFiles/MMFilesToken.h | 46 ++++++++++++++++++++++ arangod/RestHandler/RestEdgesHandler.cpp | 10 ++--- arangod/StorageEngine/StorageEngine.h | 45 +++++++++++++++++++++ arangod/Utils/OperationCursor.cpp | 6 +-- arangod/Utils/OperationCursor.h | 4 +- arangod/Utils/Transaction.cpp | 10 ++--- arangod/V8Server/v8-query.cpp | 5 +-- arangod/VocBase/LogicalCollection.cpp | 8 ++++ arangod/VocBase/LogicalCollection.h | 2 + arangod/VocBase/SingleServerTraverser.cpp | 9 ++--- arangod/VocBase/SingleServerTraverser.h | 2 +- 34 files changed, 237 insertions(+), 158 deletions(-) create mode 100644 arangod/MMFiles/MMFilesToken.h diff --git a/arangod/Aql/CollectionScanner.cpp b/arangod/Aql/CollectionScanner.cpp index 5c50afe8e0..02c9d89235 100644 --- a/arangod/Aql/CollectionScanner.cpp +++ b/arangod/Aql/CollectionScanner.cpp @@ -42,7 +42,7 @@ CollectionScanner::CollectionScanner(arangodb::Transaction* trx, CollectionScanner::~CollectionScanner() {} -void CollectionScanner::scan(std::vector& result, size_t batchSize) { +void CollectionScanner::scan(std::vector& result, size_t batchSize) { result.clear(); if (!_cursor->hasMore()) { diff --git a/arangod/Aql/CollectionScanner.h b/arangod/Aql/CollectionScanner.h index 534324628e..7f122bb268 100644 --- a/arangod/Aql/CollectionScanner.h +++ b/arangod/Aql/CollectionScanner.h @@ -40,7 +40,7 @@ class CollectionScanner { ~CollectionScanner(); - void scan(std::vector& result, size_t batchSize); + void scan(std::vector& result, size_t batchSize); void reset(); diff --git a/arangod/Aql/EnumerateCollectionBlock.cpp b/arangod/Aql/EnumerateCollectionBlock.cpp index b36ef15589..009fc6507d 100644 --- a/arangod/Aql/EnumerateCollectionBlock.cpp +++ b/arangod/Aql/EnumerateCollectionBlock.cpp @@ -250,8 +250,7 @@ AqlItemBlock* EnumerateCollectionBlock::getSome(size_t, // atLeast, // The result is in the first variable of this depth, // we do not need to do a lookup in getPlanNode()->_registerPlan->varInfo, // but can just take cur->getNrRegs() as registerId: - TRI_voc_rid_t revisionId = _documents[_position].revisionId(); - if (c->readRevision(_trx, *_mmdr, revisionId)) { + if (c->readDocument(_trx, *_mmdr, _documents[_position])) { uint8_t const* vpack = _mmdr->vpack(); res->setValue(j, static_cast(curRegs), AqlValue(vpack, AqlValueFromManagedDocument())); } diff --git a/arangod/Aql/EnumerateCollectionBlock.h b/arangod/Aql/EnumerateCollectionBlock.h index 66d0587cbf..c26229bb4b 100644 --- a/arangod/Aql/EnumerateCollectionBlock.h +++ b/arangod/Aql/EnumerateCollectionBlock.h @@ -81,7 +81,7 @@ class EnumerateCollectionBlock : public ExecutionBlock { CollectionScanner _scanner; /// @brief document buffer - std::vector _documents; + std::vector _documents; /// @brief iterator over documents size_t _position; diff --git a/arangod/Aql/IndexBlock.cpp b/arangod/Aql/IndexBlock.cpp index 48abc621af..8c980bc71f 100644 --- a/arangod/Aql/IndexBlock.cpp +++ b/arangod/Aql/IndexBlock.cpp @@ -430,18 +430,17 @@ bool IndexBlock::readIndex(size_t atMost) { if (hasMultipleIndexes) { for (auto const& element : _result) { - TRI_voc_rid_t revisionId = element.revisionId(); - if (collection->readRevision(_trx, *_mmdr, revisionId)) { + if (collection->readDocument(_trx, *_mmdr, element)) { uint8_t const* vpack = _mmdr->vpack(); //back(); // uniqueness checks if (!isLastIndex) { // insert & check for duplicates in one go - if (_alreadyReturned.emplace(revisionId).second) { + if (_alreadyReturned.emplace(element).second) { _documents.emplace_back(vpack); } } else { // only check for duplicates - if (_alreadyReturned.find(revisionId) == _alreadyReturned.end()) { + if (_alreadyReturned.find(element) == _alreadyReturned.end()) { _documents.emplace_back(vpack); } } @@ -449,8 +448,7 @@ bool IndexBlock::readIndex(size_t atMost) { } } else { for (auto const& element : _result) { - TRI_voc_rid_t revisionId = element.revisionId(); - if (collection->readRevision(_trx, *_mmdr, revisionId)) { + if (collection->readDocument(_trx, *_mmdr, element)) { uint8_t const* vpack = _mmdr->vpack(); //back(); _documents.emplace_back(vpack); } diff --git a/arangod/Aql/IndexBlock.h b/arangod/Aql/IndexBlock.h index dd0982c885..74c09342c8 100644 --- a/arangod/Aql/IndexBlock.h +++ b/arangod/Aql/IndexBlock.h @@ -110,7 +110,7 @@ class IndexBlock : public ExecutionBlock { Collection const* _collection; /// @brief document result - std::vector _result; + std::vector _result; /// @brief document buffer std::vector _documents; @@ -149,7 +149,7 @@ class IndexBlock : public ExecutionBlock { AstNode const* _condition; /// @brief set of already returned documents. Used to make the result distinct - std::unordered_set _alreadyReturned; + std::unordered_set _alreadyReturned; /// @brief whether or not at least one expression uses v8 bool _hasV8Expression; diff --git a/arangod/Aql/ShortestPathBlock.cpp b/arangod/Aql/ShortestPathBlock.cpp index 9285fa5ac9..378b589700 100644 --- a/arangod/Aql/ShortestPathBlock.cpp +++ b/arangod/Aql/ShortestPathBlock.cpp @@ -70,7 +70,7 @@ struct ConstDistanceExpanderLocal { bool _isReverse; /// @brief Local cursor vector - std::vector _cursor; + std::vector _cursor; public: ConstDistanceExpanderLocal(ShortestPathBlock const* block, @@ -96,10 +96,9 @@ struct ConstDistanceExpanderLocal { _cursor.clear(); LogicalCollection* collection = edgeCursor->collection(); while (edgeCursor->hasMore()) { - edgeCursor->getMoreMptr(_cursor, UINT64_MAX); + edgeCursor->getMoreMptr(_cursor, 1000); for (auto const& element : _cursor) { - TRI_voc_rid_t revisionId = element.revisionId(); - if (collection->readRevision(_block->transaction(), *mmdr, revisionId)) { + if (collection->readDocument(_block->transaction(), *mmdr, element)) { VPackSlice edge(mmdr->vpack()); VPackSlice from = arangodb::Transaction::extractFromFromDocument(edge); @@ -220,7 +219,7 @@ struct EdgeWeightExpanderLocal { void operator()(VPackSlice const& source, std::vector& result) { ManagedDocumentResult* mmdr = _block->_mmdr.get(); - std::vector cursor; + std::vector cursor; std::unique_ptr edgeCursor; std::unordered_map candidates; for (auto const& edgeCollection : _block->_collectionInfos) { @@ -240,10 +239,9 @@ struct EdgeWeightExpanderLocal { cursor.clear(); LogicalCollection* collection = edgeCursor->collection(); while (edgeCursor->hasMore()) { - edgeCursor->getMoreMptr(cursor, UINT64_MAX); + edgeCursor->getMoreMptr(cursor, 1000); for (auto const& element : cursor) { - TRI_voc_rid_t revisionId = element.revisionId(); - if (collection->readRevision(_block->transaction(), *mmdr, revisionId)) { + if (collection->readDocument(_block->transaction(), *mmdr, element)) { VPackSlice edge(mmdr->vpack()); VPackSlice from = arangodb::Transaction::extractFromFromDocument(edge); diff --git a/arangod/Indexes/IndexIterator.cpp b/arangod/Indexes/IndexIterator.cpp index 23768d8aae..ea47622f22 100644 --- a/arangod/Indexes/IndexIterator.cpp +++ b/arangod/Indexes/IndexIterator.cpp @@ -51,16 +51,16 @@ IndexIterator::~IndexIterator() { } /// @brief default implementation for next -IndexLookupResult IndexIterator::next() { return IndexLookupResult(); } +DocumentIdentifierToken IndexIterator::next() { return DocumentIdentifierToken(); } /// @brief default implementation for nextBabies -void IndexIterator::nextBabies(std::vector& result, size_t batchSize) { +void IndexIterator::nextBabies(std::vector& result, size_t batchSize) { result.clear(); if (batchSize > 0) { while (true) { - IndexLookupResult element = next(); - if (!element) { + DocumentIdentifierToken element = next(); + if (element == 0) { return; } result.emplace_back(element); @@ -79,7 +79,7 @@ void IndexIterator::reset() {} void IndexIterator::skip(uint64_t count, uint64_t& skipped) { // Skip the first count-many entries // TODO: Can be improved - while (count > 0 && next()) { + while (count > 0 && next() != 0) { --count; skipped++; } @@ -88,16 +88,16 @@ void IndexIterator::skip(uint64_t count, uint64_t& skipped) { /// @brief Get the next element /// If one iterator is exhausted, the next one is used. /// A nullptr indicates that all iterators are exhausted -IndexLookupResult MultiIndexIterator::next() { +DocumentIdentifierToken MultiIndexIterator::next() { if (_current == nullptr) { - return IndexLookupResult(); + return DocumentIdentifierToken(); } - IndexLookupResult next = _current->next(); - while (!next) { + DocumentIdentifierToken next = _current->next(); + while (next == 0) { _currentIdx++; if (_currentIdx >= _iterators.size()) { _current = nullptr; - return IndexLookupResult(); + return DocumentIdentifierToken(); } _current = _iterators.at(_currentIdx); next = _current->next(); @@ -108,7 +108,7 @@ IndexLookupResult MultiIndexIterator::next() { /// @brief Get the next limit many elements /// If one iterator is exhausted, the next one will be used. /// An empty result vector indicates that all iterators are exhausted -void MultiIndexIterator::nextBabies(std::vector& result, size_t limit) { +void MultiIndexIterator::nextBabies(std::vector& result, size_t limit) { result.clear(); if (_current == nullptr) { diff --git a/arangod/Indexes/IndexIterator.h b/arangod/Indexes/IndexIterator.h index 7ee57260ab..eb2f56dd67 100644 --- a/arangod/Indexes/IndexIterator.h +++ b/arangod/Indexes/IndexIterator.h @@ -26,7 +26,7 @@ // // typeName() returns a string descibing the type of the indexIterator // -// The next() function of the IndexIterator returns IndexLookupResults that are +// The next() function of the IndexIterator returns DocumentIdentifierTokens that are // created from RevisionIds. If there is nothing more to return a default // constructed IndesLookupResult is returend. // @@ -51,6 +51,7 @@ #include "Basics/Common.h" #include "Cluster/ServerState.h" #include "Indexes/IndexLookupContext.h" +#include "StorageEngine/StorageEngine.h" #include "VocBase/ManagedDocumentResult.h" #include "VocBase/vocbase.h" @@ -59,24 +60,6 @@ class Index; class LogicalCollection; class Transaction; -class IndexLookupResult { - public: - constexpr IndexLookupResult() : _revisionId(0) {} - explicit IndexLookupResult(TRI_voc_rid_t revisionId) : _revisionId(revisionId) {} - IndexLookupResult(IndexLookupResult const& other) : _revisionId(other._revisionId) {} - IndexLookupResult& operator=(IndexLookupResult const& other) { - _revisionId = other._revisionId; - return *this; - } - - inline operator bool() const { return _revisionId != 0; } - - inline TRI_voc_rid_t revisionId() const { return _revisionId; } - - private: - TRI_voc_rid_t _revisionId; -}; - /// @brief a base class to iterate over the index. An iterator is requested /// at the index itself class IndexIterator { @@ -94,9 +77,9 @@ class IndexIterator { LogicalCollection* collection() const { return _collection; } arangodb::Transaction* transaction() const { return _trx; } - virtual IndexLookupResult next(); + virtual DocumentIdentifierToken next(); - virtual void nextBabies(std::vector&, size_t); + virtual void nextBabies(std::vector&, size_t); virtual void reset(); @@ -120,9 +103,9 @@ class EmptyIndexIterator final : public IndexIterator { char const* typeName() const override { return "empty-index-iterator"; } - IndexLookupResult next() override { return IndexLookupResult(); } + DocumentIdentifierToken next() override { return DocumentIdentifierToken(); } - void nextBabies(std::vector&, size_t) override {} + void nextBabies(std::vector&, size_t) override {} void reset() override {} @@ -161,12 +144,12 @@ class MultiIndexIterator final : public IndexIterator { /// @brief Get the next element /// If one iterator is exhausted, the next one is used. /// A nullptr indicates that all iterators are exhausted - IndexLookupResult next() override; + DocumentIdentifierToken next() override; /// @brief Get at most the next limit many elements /// If one iterator is exhausted, the next one will be used. /// An empty result vector indicates that all iterators are exhausted - void nextBabies(std::vector&, size_t) override; + void nextBabies(std::vector&, size_t) override; /// @brief Reset the cursor /// This will reset ALL internal iterators and start all over again diff --git a/arangod/Indexes/IndexLookupContext.h b/arangod/Indexes/IndexLookupContext.h index 985a0ac54b..c819b3f6be 100644 --- a/arangod/Indexes/IndexLookupContext.h +++ b/arangod/Indexes/IndexLookupContext.h @@ -45,9 +45,9 @@ class IndexLookupContext { ~IndexLookupContext() {} - uint8_t const* lookup(TRI_voc_rid_t revisionId) { + uint8_t const* lookup(DocumentIdentifierToken token) { try { - if (_collection->readRevision(_trx, *_result, revisionId)) { + if (_collection->readDocument(_trx, *_result, token)) { return _result->vpack(); } } catch (...) { diff --git a/arangod/MMFiles/MMFilesEdgeIndex.cpp b/arangod/MMFiles/MMFilesEdgeIndex.cpp index b33889ef71..49b97b969a 100644 --- a/arangod/MMFiles/MMFilesEdgeIndex.cpp +++ b/arangod/MMFiles/MMFilesEdgeIndex.cpp @@ -31,6 +31,7 @@ #include "Basics/hashes.h" #include "Indexes/IndexLookupContext.h" #include "Indexes/SimpleAttributeEqualityMatcher.h" +#include "MMFiles/MMFilesToken.h" #include "Utils/CollectionNameResolver.h" #include "Utils/Transaction.h" #include "Utils/TransactionContext.h" @@ -126,7 +127,7 @@ MMFilesEdgeIndexIterator::~MMFilesEdgeIndexIterator() { } } -IndexLookupResult MMFilesEdgeIndexIterator::next() { +DocumentIdentifierToken MMFilesEdgeIndexIterator::next() { while (_iterator.valid()) { if (_buffer.empty()) { // We start a new lookup @@ -150,17 +151,17 @@ IndexLookupResult MMFilesEdgeIndexIterator::next() { } else { _lastElement = _buffer.back(); // found something - return IndexLookupResult(_buffer[_posInBuffer++].revisionId()); + return MMFilesToken{_buffer[_posInBuffer++].revisionId()}; } // found no result. now go to next lookup value in _keys _iterator.next(); } - return IndexLookupResult(); + return MMFilesToken{}; } -void MMFilesEdgeIndexIterator::nextBabies(std::vector& buffer, size_t limit) { +void MMFilesEdgeIndexIterator::nextBabies(std::vector& buffer, size_t limit) { size_t atMost = _batchSize > limit ? limit : _batchSize; if (atMost == 0) { @@ -187,7 +188,7 @@ void MMFilesEdgeIndexIterator::nextBabies(std::vector& buffer } for (auto& it : _buffer) { - buffer.emplace_back(it.revisionId()); + buffer.emplace_back(MMFilesToken(it.revisionId())); } if (_buffer.empty()) { @@ -223,28 +224,28 @@ AnyDirectionMMFilesEdgeIndexIterator::AnyDirectionMMFilesEdgeIndexIterator(Logic _inbound(inboundIterator), _useInbound(false) {} -IndexLookupResult AnyDirectionMMFilesEdgeIndexIterator::next() { - IndexLookupResult res; +DocumentIdentifierToken AnyDirectionMMFilesEdgeIndexIterator::next() { + DocumentIdentifierToken res; if (_useInbound) { do { res = _inbound->next(); - } while (res && _seen.find(res.revisionId()) != _seen.end()); + } while (res != 0 && _seen.find(res) != _seen.end()); return res; } res = _outbound->next(); - if (!res) { + if (res == 0) { _useInbound = true; return next(); } - _seen.emplace(res.revisionId()); + _seen.emplace(res); return res; } -void AnyDirectionMMFilesEdgeIndexIterator::nextBabies(std::vector& result, size_t limit) { +void AnyDirectionMMFilesEdgeIndexIterator::nextBabies(std::vector& result, size_t limit) { result.clear(); for (size_t i = 0; i < limit; ++i) { - IndexLookupResult res = next(); - if (!res) { + DocumentIdentifierToken res = next(); + if (res == 0) { return; } result.emplace_back(res); diff --git a/arangod/MMFiles/MMFilesEdgeIndex.h b/arangod/MMFiles/MMFilesEdgeIndex.h index 10e1551ed5..418595546e 100644 --- a/arangod/MMFiles/MMFilesEdgeIndex.h +++ b/arangod/MMFiles/MMFilesEdgeIndex.h @@ -53,9 +53,9 @@ class MMFilesEdgeIndexIterator final : public IndexIterator { char const* typeName() const override { return "edge-index-iterator"; } - IndexLookupResult next() override; + DocumentIdentifierToken next() override; - void nextBabies(std::vector&, size_t) override; + void nextBabies(std::vector&, size_t) override; void reset() override; @@ -85,16 +85,16 @@ class AnyDirectionMMFilesEdgeIndexIterator final : public IndexIterator { char const* typeName() const override { return "any-edge-index-iterator"; } - IndexLookupResult next() override; + DocumentIdentifierToken next() override; - void nextBabies(std::vector&, size_t) override; + void nextBabies(std::vector&, size_t) override; void reset() override; private: MMFilesEdgeIndexIterator* _outbound; MMFilesEdgeIndexIterator* _inbound; - std::unordered_set _seen; + std::unordered_set _seen; bool _useInbound; }; diff --git a/arangod/MMFiles/MMFilesGeoIndex.cpp b/arangod/MMFiles/MMFilesGeoIndex.cpp index 03915b6e8d..8cace1db35 100644 --- a/arangod/MMFiles/MMFilesGeoIndex.cpp +++ b/arangod/MMFiles/MMFilesGeoIndex.cpp @@ -29,6 +29,7 @@ #include "Basics/StringRef.h" #include "Basics/VelocyPackHelper.h" #include "Logger/Logger.h" +#include "MMFiles/MMFilesToken.h" #include "VocBase/transaction.h" using namespace arangodb; @@ -85,7 +86,7 @@ void MMFilesGeoIndexIterator::evaluateCondition() { } } -IndexLookupResult MMFilesGeoIndexIterator::next() { +DocumentIdentifierToken MMFilesGeoIndexIterator::next() { if (!_cursor) { createCursor(_lat, _lon); } @@ -98,14 +99,14 @@ IndexLookupResult MMFilesGeoIndexIterator::next() { ) { auto revision = ::MMFilesGeoIndex::toRevision(coords->coordinates[0].data); - return IndexLookupResult{revision}; + return MMFilesToken{revision}; } } // if there are no more results we return the default constructed IndexLookupResult - return IndexLookupResult{}; + return MMFilesToken{}; } -void MMFilesGeoIndexIterator::nextBabies(std::vector& result, size_t batchSize) { +void MMFilesGeoIndexIterator::nextBabies(std::vector& result, size_t batchSize) { if (!_cursor) { createCursor(_lat, _lon); @@ -135,7 +136,8 @@ void MMFilesGeoIndexIterator::nextBabies(std::vector& result, withDistances = true; maxDistance = _radius; } - auto coords = std::unique_ptr(::GeoIndex_ReadCursor(_cursor, static_cast(batchSize), withDistances, maxDistance)); + auto coords = std::unique_ptr(::GeoIndex_ReadCursor( + _cursor, static_cast(batchSize), withDistances, maxDistance)); size_t const length = coords ? coords->length : 0; @@ -197,7 +199,7 @@ void MMFilesGeoIndexIterator::nextBabies(std::vector& result, result.reserve(numDocs); for (size_t i = 0; i < numDocs; ++i) { - result.emplace_back(IndexLookupResult(::MMFilesGeoIndex::toRevision(coords->coordinates[i].data))); + result.emplace_back(MMFilesToken(::MMFilesGeoIndex::toRevision(coords->coordinates[i].data))); } } diff --git a/arangod/MMFiles/MMFilesGeoIndex.h b/arangod/MMFiles/MMFilesGeoIndex.h index b713aab1a3..1193ccf9f5 100644 --- a/arangod/MMFiles/MMFilesGeoIndex.h +++ b/arangod/MMFiles/MMFilesGeoIndex.h @@ -56,9 +56,9 @@ class MMFilesGeoIndexIterator final : public IndexIterator { char const* typeName() const override { return "geo-index-iterator"; } - IndexLookupResult next() override; + DocumentIdentifierToken next() override; - void nextBabies(std::vector&, size_t) override; + void nextBabies(std::vector&, size_t) override; void reset() override; diff --git a/arangod/MMFiles/MMFilesHashIndex.cpp b/arangod/MMFiles/MMFilesHashIndex.cpp index 0900da3f22..630b1bf380 100644 --- a/arangod/MMFiles/MMFilesHashIndex.cpp +++ b/arangod/MMFiles/MMFilesHashIndex.cpp @@ -30,6 +30,7 @@ #include "Basics/VelocyPackHelper.h" #include "Indexes/IndexLookupContext.h" #include "Indexes/SimpleAttributeEqualityMatcher.h" +#include "MMFiles/MMFilesToken.h" #include "Utils/TransactionContext.h" #include "VocBase/LogicalCollection.h" #include "VocBase/transaction.h" @@ -294,12 +295,12 @@ MMFilesHashIndexIterator::MMFilesHashIndexIterator(LogicalCollection* collection _index->lookup(_trx, _lookups.lookup(), _buffer); } -IndexLookupResult MMFilesHashIndexIterator::next() { +DocumentIdentifierToken MMFilesHashIndexIterator::next() { while (true) { if (_posInBuffer >= _buffer.size()) { if (!_lookups.hasAndGetNext()) { // we're at the end of the lookup values - return IndexLookupResult(); + return MMFilesToken{}; } // We have to refill the buffer @@ -311,12 +312,12 @@ IndexLookupResult MMFilesHashIndexIterator::next() { if (!_buffer.empty()) { // found something - return IndexLookupResult(_buffer[_posInBuffer++]->revisionId()); + return MMFilesToken{_buffer[_posInBuffer++]->revisionId()}; } } } -void MMFilesHashIndexIterator::nextBabies(std::vector& result, size_t atMost) { +void MMFilesHashIndexIterator::nextBabies(std::vector& result, size_t atMost) { result.clear(); if (atMost == 0) { @@ -347,7 +348,7 @@ void MMFilesHashIndexIterator::nextBabies(std::vector& result } for (size_t i = _posInBuffer; i < atMost + _posInBuffer; ++i) { - result.emplace_back(_buffer[i]->revisionId()); + result.emplace_back(MMFilesToken{_buffer[i]->revisionId()}); } _posInBuffer += atMost; return; @@ -383,12 +384,12 @@ MMFilesHashIndexIteratorVPack::~MMFilesHashIndexIteratorVPack() { } } -IndexLookupResult MMFilesHashIndexIteratorVPack::next() { +DocumentIdentifierToken MMFilesHashIndexIteratorVPack::next() { while (true) { if (_posInBuffer >= _buffer.size()) { if (!_iterator.valid()) { // we're at the end of the lookup values - return IndexLookupResult(); + return MMFilesToken{}; } // We have to refill the buffer @@ -406,7 +407,7 @@ IndexLookupResult MMFilesHashIndexIteratorVPack::next() { if (!_buffer.empty()) { // found something - return IndexLookupResult(_buffer[_posInBuffer++]->revisionId()); + return MMFilesToken{_buffer[_posInBuffer++]->revisionId()}; } } } diff --git a/arangod/MMFiles/MMFilesHashIndex.h b/arangod/MMFiles/MMFilesHashIndex.h index 8d3b6de00e..2b75e3a602 100644 --- a/arangod/MMFiles/MMFilesHashIndex.h +++ b/arangod/MMFiles/MMFilesHashIndex.h @@ -90,9 +90,9 @@ class MMFilesHashIndexIterator final : public IndexIterator { char const* typeName() const override { return "hash-index-iterator"; } - IndexLookupResult next() override; + DocumentIdentifierToken next() override; - void nextBabies(std::vector&, size_t) override; + void nextBabies(std::vector&, size_t) override; void reset() override; @@ -117,7 +117,7 @@ class MMFilesHashIndexIteratorVPack final : public IndexIterator { char const* typeName() const override { return "hash-index-iterator-vpack"; } - IndexLookupResult next() override; + DocumentIdentifierToken next() override; void reset() override; diff --git a/arangod/MMFiles/MMFilesIndexElement.cpp b/arangod/MMFiles/MMFilesIndexElement.cpp index 6f68b3991b..e837669e7c 100644 --- a/arangod/MMFiles/MMFilesIndexElement.cpp +++ b/arangod/MMFiles/MMFilesIndexElement.cpp @@ -24,6 +24,7 @@ #include "MMFilesIndexElement.h" #include "Basics/VelocyPackHelper.h" #include "Indexes/IndexLookupContext.h" +#include "MMFiles/MMFilesToken.h" using namespace arangodb; @@ -57,7 +58,7 @@ arangodb::velocypack::Slice MMFilesHashIndexElement::slice(IndexLookupContext* c if (offset == 0) { return basics::VelocyPackHelper::NullValue(); } - uint8_t const* vpack = context->lookup(_revisionId); + uint8_t const* vpack = context->lookup(MMFilesToken{_revisionId}); if (vpack == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND); } @@ -133,7 +134,7 @@ arangodb::velocypack::Slice MMFilesSkiplistIndexElement::slice(IndexLookupContex if (offset == 0) { return basics::VelocyPackHelper::NullValue(); } - uint8_t const* vpack = context->lookup(_revisionId); + uint8_t const* vpack = context->lookup(MMFilesToken{_revisionId}); if (vpack == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND); } @@ -149,7 +150,7 @@ uint64_t MMFilesSimpleIndexElement::hash(arangodb::velocypack::Slice const& valu } VPackSlice MMFilesSimpleIndexElement::slice(IndexLookupContext* context) const { - uint8_t const* vpack = context->lookup(_revisionId); + uint8_t const* vpack = context->lookup(MMFilesToken{_revisionId}); if (vpack == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND); } diff --git a/arangod/MMFiles/MMFilesPersistentIndex.cpp b/arangod/MMFiles/MMFilesPersistentIndex.cpp index 7bef95d856..b0c0cfb83e 100644 --- a/arangod/MMFiles/MMFilesPersistentIndex.cpp +++ b/arangod/MMFiles/MMFilesPersistentIndex.cpp @@ -32,6 +32,7 @@ #include "MMFiles/MMFilesPrimaryIndex.h" #include "MMFiles/MMFilesPersistentIndexFeature.h" #include "MMFiles/MMFilesPersistentIndexKeyComparator.h" +#include "MMFiles/MMFilesToken.h" #include "Utils/Transaction.h" #include "VocBase/LogicalCollection.h" @@ -137,13 +138,13 @@ void PersistentIndexIterator::reset() { } /// @brief Get the next element in the index -IndexLookupResult PersistentIndexIterator::next() { +DocumentIdentifierToken PersistentIndexIterator::next() { auto comparator = RocksDBFeature::instance()->comparator(); while (true) { if (!_cursor->Valid()) { // We are exhausted already, sorry - return IndexLookupResult(); + return MMFilesToken{}; } rocksdb::Slice key = _cursor->key(); @@ -154,7 +155,7 @@ IndexLookupResult PersistentIndexIterator::next() { if (res < 0) { if (_reverse) { - return IndexLookupResult(); + return MMFilesToken{}; } else { _cursor->Next(); } @@ -164,7 +165,7 @@ IndexLookupResult PersistentIndexIterator::next() { res = comparator->Compare(key, rocksdb::Slice(_rightEndpoint->data(), _rightEndpoint->size())); // LOG(TRACE) << "comparing: " << VPackSlice(key.data() + PersistentIndex::keyPrefixSize()).toJson() << " with " << VPackSlice((char const*) _rightEndpoint->data() + PersistentIndex::keyPrefixSize()).toJson() << " - res: " << res; - IndexLookupResult doc; + MMFilesToken doc; if (res <= 0) { // get the value for _key, which is the last entry in the key array @@ -179,7 +180,7 @@ IndexLookupResult PersistentIndexIterator::next() { // use primary index to lookup the document MMFilesSimpleIndexElement element = _primaryIndex->lookupKey(_trx, keySlice[n - 1]); if (element) { - doc = IndexLookupResult(element.revisionId()); + doc = MMFilesToken{element.revisionId()}; } } @@ -191,13 +192,13 @@ IndexLookupResult PersistentIndexIterator::next() { if (res > 0) { if (!_probe) { - return IndexLookupResult(); + return MMFilesToken{}; } _probe = false; continue; } - if (doc) { + if (doc != 0) { return doc; } } diff --git a/arangod/MMFiles/MMFilesPersistentIndex.h b/arangod/MMFiles/MMFilesPersistentIndex.h index 3aa1480cba..4db67d21a1 100644 --- a/arangod/MMFiles/MMFilesPersistentIndex.h +++ b/arangod/MMFiles/MMFilesPersistentIndex.h @@ -75,7 +75,7 @@ class PersistentIndexIterator final : public IndexIterator { char const* typeName() const override { return "rocksdb-index-iterator"; } /// @brief Get the next element in the index - IndexLookupResult next() override; + DocumentIdentifierToken next() override; /// @brief Reset the cursor void reset() override; diff --git a/arangod/MMFiles/MMFilesPrimaryIndex.cpp b/arangod/MMFiles/MMFilesPrimaryIndex.cpp index e81f583e11..d73fcc8581 100644 --- a/arangod/MMFiles/MMFilesPrimaryIndex.cpp +++ b/arangod/MMFiles/MMFilesPrimaryIndex.cpp @@ -29,6 +29,7 @@ #include "Basics/tri-strings.h" #include "Indexes/IndexLookupContext.h" #include "Indexes/SimpleAttributeEqualityMatcher.h" +#include "MMFiles/MMFilesToken.h" #include "Utils/Transaction.h" #include "Utils/TransactionContext.h" #include "VocBase/LogicalCollection.h" @@ -106,20 +107,20 @@ MMFilesPrimaryIndexIterator::~MMFilesPrimaryIndexIterator() { } } -IndexLookupResult MMFilesPrimaryIndexIterator::next() { +DocumentIdentifierToken MMFilesPrimaryIndexIterator::next() { while (_iterator.valid()) { MMFilesSimpleIndexElement result = _index->lookupKey(_trx, _iterator.value()); _iterator.next(); if (result) { // found a result - return IndexLookupResult(result.revisionId()); + return MMFilesToken{result.revisionId()}; } // found no result. now go to next lookup value in _keys } - return IndexLookupResult(); + return MMFilesToken{}; } void MMFilesPrimaryIndexIterator::reset() { _iterator.reset(); } @@ -132,7 +133,7 @@ AllIndexIterator::AllIndexIterator(LogicalCollection* collection, bool reverse) : IndexIterator(collection, trx, mmdr, index), _index(indexImpl), _reverse(reverse), _total(0) {} -IndexLookupResult AllIndexIterator::next() { +DocumentIdentifierToken AllIndexIterator::next() { MMFilesSimpleIndexElement element; if (_reverse) { element = _index->findSequentialReverse(&_context, _position); @@ -140,12 +141,12 @@ IndexLookupResult AllIndexIterator::next() { element = _index->findSequential(&_context, _position, _total); } if (element) { - return IndexLookupResult(element.revisionId()); + return MMFilesToken{element.revisionId()}; } - return IndexLookupResult(); + return MMFilesToken{}; } -void AllIndexIterator::nextBabies(std::vector& buffer, size_t limit) { +void AllIndexIterator::nextBabies(std::vector& buffer, size_t limit) { size_t atMost = limit; buffer.clear(); @@ -154,9 +155,9 @@ void AllIndexIterator::nextBabies(std::vector& buffer, size_t } while (atMost > 0) { - IndexLookupResult result = next(); + DocumentIdentifierToken result = next(); - if (!result) { + if (result == 0) { return; } @@ -173,12 +174,12 @@ AnyIndexIterator::AnyIndexIterator(LogicalCollection* collection, arangodb::Tran MMFilesPrimaryIndexImpl const* indexImpl) : IndexIterator(collection, trx, mmdr, index), _index(indexImpl), _step(0), _total(0) {} -IndexLookupResult AnyIndexIterator::next() { +DocumentIdentifierToken AnyIndexIterator::next() { MMFilesSimpleIndexElement element = _index->findRandom(&_context, _initial, _position, _step, _total); if (element) { - return IndexLookupResult(element.revisionId()); + return MMFilesToken{element.revisionId()}; } - return IndexLookupResult(); + return MMFilesToken{}; } void AnyIndexIterator::reset() { diff --git a/arangod/MMFiles/MMFilesPrimaryIndex.h b/arangod/MMFiles/MMFilesPrimaryIndex.h index 5804e719b7..936c38434d 100644 --- a/arangod/MMFiles/MMFilesPrimaryIndex.h +++ b/arangod/MMFiles/MMFilesPrimaryIndex.h @@ -54,7 +54,7 @@ class MMFilesPrimaryIndexIterator final : public IndexIterator { char const* typeName() const override { return "primary-index-iterator"; } - IndexLookupResult next() override; + DocumentIdentifierToken next() override; void reset() override; @@ -77,9 +77,9 @@ class AllIndexIterator final : public IndexIterator { char const* typeName() const override { return "all-index-iterator"; } - IndexLookupResult next() override; + DocumentIdentifierToken next() override; - void nextBabies(std::vector&, size_t) override; + void nextBabies(std::vector&, size_t) override; void reset() override; @@ -101,7 +101,7 @@ class AnyIndexIterator final : public IndexIterator { char const* typeName() const override { return "any-index-iterator"; } - IndexLookupResult next() override; + DocumentIdentifierToken next() override; void reset() override; diff --git a/arangod/MMFiles/MMFilesSkiplistIndex.cpp b/arangod/MMFiles/MMFilesSkiplistIndex.cpp index 201c40be89..403f6e847e 100644 --- a/arangod/MMFiles/MMFilesSkiplistIndex.cpp +++ b/arangod/MMFiles/MMFilesSkiplistIndex.cpp @@ -29,6 +29,7 @@ #include "Basics/StaticStrings.h" #include "Basics/VelocyPackHelper.h" #include "Indexes/IndexLookupContext.h" +#include "MMFiles/MMFilesToken.h" #include "Utils/Transaction.h" #include "VocBase/LogicalCollection.h" @@ -520,10 +521,10 @@ void MMFilesSkiplistIterator::reset() { } /// @brief Get the next element in the skiplist -IndexLookupResult MMFilesSkiplistIterator::next() { +DocumentIdentifierToken MMFilesSkiplistIterator::next() { if (_cursor == nullptr) { // We are exhausted already, sorry - return IndexLookupResult(); + return MMFilesToken{}; } Node* tmp = _cursor; if (_reverse) { @@ -541,7 +542,7 @@ IndexLookupResult MMFilesSkiplistIterator::next() { } TRI_ASSERT(tmp != nullptr); TRI_ASSERT(tmp->document() != nullptr); - return IndexLookupResult(tmp->document()->revisionId()); + return MMFilesToken{tmp->document()->revisionId()}; } MMFilesSkiplistIterator2::MMFilesSkiplistIterator2(LogicalCollection* collection, arangodb::Transaction* trx, @@ -602,10 +603,10 @@ void MMFilesSkiplistIterator2::reset() { } /// @brief Get the next element in the skiplist -IndexLookupResult MMFilesSkiplistIterator2::next() { +DocumentIdentifierToken MMFilesSkiplistIterator2::next() { if (_cursor == nullptr) { // We are exhausted already, sorry - return IndexLookupResult(); + return MMFilesToken{}; } TRI_ASSERT(_currentInterval < _intervals.size()); auto const& interval = _intervals[_currentInterval]; @@ -625,7 +626,7 @@ IndexLookupResult MMFilesSkiplistIterator2::next() { } TRI_ASSERT(tmp != nullptr); TRI_ASSERT(tmp->document() != nullptr); - return IndexLookupResult(tmp->document()->revisionId()); + return MMFilesToken{tmp->document()->revisionId()}; } void MMFilesSkiplistIterator2::forwardCursor() { diff --git a/arangod/MMFiles/MMFilesSkiplistIndex.h b/arangod/MMFiles/MMFilesSkiplistIndex.h index 7f0c783dd3..15e7465a4a 100644 --- a/arangod/MMFiles/MMFilesSkiplistIndex.h +++ b/arangod/MMFiles/MMFilesSkiplistIndex.h @@ -196,7 +196,7 @@ class MMFilesSkiplistIterator final : public IndexIterator { char const* typeName() const override { return "skiplist-index-iterator"; } /// @brief Get the next element in the skiplist - IndexLookupResult next() override; + DocumentIdentifierToken next() override; /// @brief Reset the cursor void reset() override; @@ -257,7 +257,7 @@ class MMFilesSkiplistIterator2 final : public IndexIterator { char const* typeName() const override { return "skiplist-index-iterator2"; } /// @brief Get the next element in the skiplist - IndexLookupResult next() override; + DocumentIdentifierToken next() override; /// @brief Reset the cursor void reset() override; diff --git a/arangod/MMFiles/MMFilesToken.h b/arangod/MMFiles/MMFilesToken.h new file mode 100644 index 0000000000..b0f7caae5b --- /dev/null +++ b/arangod/MMFiles/MMFilesToken.h @@ -0,0 +1,46 @@ +//////////////////////////////////////////////////////////////////////////////// +/// DISCLAIMER +/// +/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany +/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is ArangoDB GmbH, Cologne, Germany +/// +/// @author Michael Hackstein +//////////////////////////////////////////////////////////////////////////////// + +#include "StorageEngine/StorageEngine.h" + +namespace arangodb { + +struct MMFilesToken : public DocumentIdentifierToken { + public: + MMFilesToken() : DocumentIdentifierToken() {} + explicit MMFilesToken(TRI_voc_rid_t revisionId) + : DocumentIdentifierToken(revisionId) {} + MMFilesToken(MMFilesToken const& other) + : DocumentIdentifierToken(other._data) {} + MMFilesToken& operator=(MMFilesToken const& other) { + _data = other._data; + return *this; + } + + inline TRI_voc_rid_t revisionId() const { + return static_cast(_data); + } +}; +static_assert(sizeof(MMFilesToken) == sizeof(uint64_t), "invalid MMFilesToken size"); + +} diff --git a/arangod/RestHandler/RestEdgesHandler.cpp b/arangod/RestHandler/RestEdgesHandler.cpp index 1fc6d7eea7..2c95449abd 100644 --- a/arangod/RestHandler/RestEdgesHandler.cpp +++ b/arangod/RestHandler/RestEdgesHandler.cpp @@ -91,7 +91,7 @@ bool RestEdgesHandler::getEdgesForVertexList( THROW_ARANGO_EXCEPTION(cursor->code); } - std::vector batch; + std::vector batch; ManagedDocumentResult mmdr; auto collection = trx.documentCollection(); while (cursor->hasMore()) { @@ -99,8 +99,7 @@ bool RestEdgesHandler::getEdgesForVertexList( scannedIndex += batch.size(); for (auto const& it : batch) { - TRI_voc_rid_t revisionId = it.revisionId(); - if (collection->readRevision(&trx, mmdr, revisionId)) { + if (collection->readDocument(&trx, mmdr, it)) { result.add(VPackSlice(mmdr.vpack())); } } @@ -129,7 +128,7 @@ bool RestEdgesHandler::getEdgesForVertex( THROW_ARANGO_EXCEPTION(cursor->code); } - std::vector batch; + std::vector batch; ManagedDocumentResult mmdr; auto collection = trx.documentCollection(); while (cursor->hasMore()) { @@ -137,8 +136,7 @@ bool RestEdgesHandler::getEdgesForVertex( scannedIndex += batch.size(); for (auto const& it : batch) { - TRI_voc_rid_t revisionId = it.revisionId(); - if (collection->readRevision(&trx, mmdr, revisionId)) { + if (collection->readDocument(&trx, mmdr, it)) { result.add(VPackSlice(mmdr.vpack())); } } diff --git a/arangod/StorageEngine/StorageEngine.h b/arangod/StorageEngine/StorageEngine.h index 24f79a1729..f69c7eb88c 100644 --- a/arangod/StorageEngine/StorageEngine.h +++ b/arangod/StorageEngine/StorageEngine.h @@ -37,6 +37,33 @@ namespace arangodb { class LogicalCollection; class PhysicalCollection; +// @brief This token is handed out by Indexes and +// is used by StorageEngines to return a document +// Only specializations of this token can be created. + +struct DocumentIdentifierToken { + public: + // TODO Replace by Engine::InvalidToken + constexpr DocumentIdentifierToken() : _data(0) {} + + ~DocumentIdentifierToken() {} + + inline bool operator==(DocumentIdentifierToken const& other) const { return _data == other._data; } + + inline bool operator==(uint64_t const& other) const { return _data == other; } + + inline bool operator!=(DocumentIdentifierToken const& other) const { return !(operator==(other)); } + inline bool operator!=(uint64_t const& other) const { return !(operator==(other)); } + + protected: + explicit DocumentIdentifierToken(uint64_t data) : _data(data) {} + + public: + uint64_t _data; +}; + + + class StorageEngine : public application_features::ApplicationFeature { public: @@ -249,4 +276,22 @@ class StorageEngine : public application_features::ApplicationFeature { } +namespace std { +template <> +struct hash { + inline size_t operator()(arangodb::DocumentIdentifierToken const& token) const noexcept { + return token._data; + } +}; + +template <> +struct equal_to { + bool operator()(arangodb::DocumentIdentifierToken const& lhs, + arangodb::DocumentIdentifierToken const& rhs) const { + return lhs == rhs; + } +}; + +} + #endif diff --git a/arangod/Utils/OperationCursor.cpp b/arangod/Utils/OperationCursor.cpp index 1a9d916d88..a5b14fc77a 100644 --- a/arangod/Utils/OperationCursor.cpp +++ b/arangod/Utils/OperationCursor.cpp @@ -47,8 +47,8 @@ void OperationCursor::reset() { /// NOTE: This will throw on OUT_OF_MEMORY ////////////////////////////////////////////////////////////////////////////// -std::vector OperationCursor::getMoreMptr(uint64_t batchSize) { - std::vector res; +std::vector OperationCursor::getMoreMptr(uint64_t batchSize) { + std::vector res; getMoreMptr(res, batchSize); return res; } @@ -62,7 +62,7 @@ std::vector OperationCursor::getMoreMptr(uint64_t batchSize) /// The caller shall NOT modify it. ////////////////////////////////////////////////////////////////////////////// -void OperationCursor::getMoreMptr(std::vector& result, +void OperationCursor::getMoreMptr(std::vector& result, uint64_t batchSize) { if (!hasMore()) { TRI_ASSERT(false); diff --git a/arangod/Utils/OperationCursor.h b/arangod/Utils/OperationCursor.h index 924dcb5491..f68c3508b7 100644 --- a/arangod/Utils/OperationCursor.h +++ b/arangod/Utils/OperationCursor.h @@ -108,7 +108,7 @@ struct OperationCursor { /// NOTE: This will throw on OUT_OF_MEMORY ////////////////////////////////////////////////////////////////////////////// - std::vector getMoreMptr(uint64_t batchSize = 1000); + std::vector getMoreMptr(uint64_t batchSize = 1000); ////////////////////////////////////////////////////////////////////////////// /// @brief Get next batchSize many elements. mptr variant @@ -118,7 +118,7 @@ struct OperationCursor { /// NOTE: The result vector handed in will be cleared. ////////////////////////////////////////////////////////////////////////////// - void getMoreMptr(std::vector& result, uint64_t batchSize = 1000); + void getMoreMptr(std::vector& result, uint64_t batchSize = 1000); ////////////////////////////////////////////////////////////////////////////// /// @brief Skip the next toSkip many elements. diff --git a/arangod/Utils/Transaction.cpp b/arangod/Utils/Transaction.cpp index a2bd243167..0a2d9db663 100644 --- a/arangod/Utils/Transaction.cpp +++ b/arangod/Utils/Transaction.cpp @@ -1286,14 +1286,13 @@ OperationResult Transaction::anyLocal(std::string const& collectionName, {}, &mmdr, skip, limit, 1000, false); LogicalCollection* collection = cursor->collection(); - std::vector result; + std::vector result; while (cursor->hasMore()) { result.clear(); cursor->getMoreMptr(result); for (auto const& element : result) { - TRI_voc_rid_t revisionId = element.revisionId(); - if (collection->readRevision(this, mmdr, revisionId)) { + if (collection->readDocument(this, mmdr, element)) { uint8_t const* vpack = mmdr.vpack(); resultBuilder.add(VPackSlice(vpack)); } @@ -2647,14 +2646,13 @@ OperationResult Transaction::allLocal(std::string const& collectionName, } LogicalCollection* collection = cursor->collection(); - std::vector result; + std::vector result; result.reserve(1000); while (cursor->hasMore()) { cursor->getMoreMptr(result, 1000); for (auto const& element : result) { - TRI_voc_rid_t revisionId = element.revisionId(); - if (collection->readRevision(this, mmdr, revisionId)) { + if (collection->readDocument(this, mmdr, element)) { uint8_t const* vpack = mmdr.vpack(); resultBuilder.addExternal(vpack); } diff --git a/arangod/V8Server/v8-query.cpp b/arangod/V8Server/v8-query.cpp index 9ececb655f..189890cf5c 100644 --- a/arangod/V8Server/v8-query.cpp +++ b/arangod/V8Server/v8-query.cpp @@ -254,7 +254,7 @@ static void JS_AllQuery(v8::FunctionCallbackInfo const& args) { VPackOptions resultOptions = VPackOptions::Defaults; resultOptions.customTypeHandler = transactionContext->orderCustomTypeHandler().get(); - std::vector batch; + std::vector batch; ManagedDocumentResult mmdr; VPackBuilder resultBuilder; resultBuilder.openArray(); @@ -262,8 +262,7 @@ static void JS_AllQuery(v8::FunctionCallbackInfo const& args) { opCursor->getMoreMptr(batch); // We only need this one call, limit == batchsize for (auto const& it : batch) { - TRI_voc_rid_t revisionId = it.revisionId(); - if (collection->readRevision(&trx, mmdr, revisionId)) { + if (collection->readDocument(&trx, mmdr, it)) { resultBuilder.add(VPackSlice(mmdr.vpack())); } } diff --git a/arangod/VocBase/LogicalCollection.cpp b/arangod/VocBase/LogicalCollection.cpp index 9aaac7fb22..a97b9e5756 100644 --- a/arangod/VocBase/LogicalCollection.cpp +++ b/arangod/VocBase/LogicalCollection.cpp @@ -48,6 +48,7 @@ #include "MMFiles/MMFilesPersistentIndex.h" #include "MMFiles/MMFilesPrimaryIndex.h" #include "MMFiles/MMFilesSkiplistIndex.h" +#include "MMFiles/MMFilesToken.h" #include "MMFiles/MMFilesWalMarker.h" #include "MMFiles/MMFilesWalSlots.h" #include "StorageEngine/StorageEngine.h" @@ -3766,6 +3767,13 @@ bool LogicalCollection::readRevisionConditional(Transaction* trx, return false; } +// TODO ONLY TEMP wrapper +bool LogicalCollection::readDocument(arangodb::Transaction* trx, ManagedDocumentResult& result, DocumentIdentifierToken const& token) { + // TODO This only works for MMFiles Engine. Has to be moved => StorageEngine + auto tkn = static_cast(&token); + return readRevision(trx, result, tkn->revisionId()); +} + void LogicalCollection::insertRevision(TRI_voc_rid_t revisionId, uint8_t const* dataptr, TRI_voc_fid_t fid, bool isInWal) { diff --git a/arangod/VocBase/LogicalCollection.h b/arangod/VocBase/LogicalCollection.h index 28b30d4bf9..4f6938b94c 100644 --- a/arangod/VocBase/LogicalCollection.h +++ b/arangod/VocBase/LogicalCollection.h @@ -25,6 +25,7 @@ #define ARANGOD_VOCBASE_LOGICAL_COLLECTION_H 1 #include "Basics/Common.h" +#include "StorageEngine/StorageEngine.h" #include "VocBase/PhysicalCollection.h" #include "VocBase/voc-types.h" #include "VocBase/vocbase.h" @@ -384,6 +385,7 @@ class LogicalCollection { bool readRevision(arangodb::Transaction*, ManagedDocumentResult& result, TRI_voc_rid_t revisionId); bool readRevisionConditional(arangodb::Transaction*, ManagedDocumentResult& result, TRI_voc_rid_t revisionId, TRI_voc_tick_t maxTick, bool excludeWal); + bool readDocument(arangodb::Transaction*, ManagedDocumentResult& result, DocumentIdentifierToken const& token); void insertRevision(TRI_voc_rid_t revisionId, uint8_t const* dataptr, TRI_voc_fid_t fid, bool isInWal); void updateRevision(TRI_voc_rid_t revisionId, uint8_t const* dataptr, TRI_voc_fid_t fid, bool isInWal); diff --git a/arangod/VocBase/SingleServerTraverser.cpp b/arangod/VocBase/SingleServerTraverser.cpp index 54c0ba42f7..2eda6ab3cb 100644 --- a/arangod/VocBase/SingleServerTraverser.cpp +++ b/arangod/VocBase/SingleServerTraverser.cpp @@ -78,8 +78,7 @@ bool SingleServerEdgeCursor::next(std::vector& result, _cachePos++; if (_cachePos < _cache.size()) { LogicalCollection* collection = _cursors[_currentCursor][_currentSubCursor]->collection(); - TRI_voc_rid_t revisionId = _cache[_cachePos].revisionId(); - if (collection->readRevision(_trx, *_mmdr, revisionId)) { + if (collection->readDocument(_trx, *_mmdr, _cache[_cachePos])) { result.emplace_back(_mmdr->vpack()); } if (_internalCursorMapping != nullptr) { @@ -128,8 +127,7 @@ bool SingleServerEdgeCursor::next(std::vector& result, TRI_ASSERT(_cachePos < _cache.size()); LogicalCollection* collection = cursor->collection(); - TRI_voc_rid_t revisionId = _cache[_cachePos].revisionId(); - if (collection->readRevision(_trx, *_mmdr, revisionId)) { + if (collection->readDocument(_trx, *_mmdr, _cache[_cachePos])) { result.emplace_back(_mmdr->vpack()); } if (_internalCursorMapping != nullptr) { @@ -162,8 +160,7 @@ bool SingleServerEdgeCursor::readAll(std::unordered_set& result, // because the cursor expect's it to be filled. cursor->getMoreMptr(_cache); for (auto const& element : _cache) { - TRI_voc_rid_t revisionId = element.revisionId(); - if (collection->readRevision(_trx, *_mmdr, revisionId)) { + if (collection->readDocument(_trx, *_mmdr, element)) { result.emplace(_mmdr->vpack()); } } diff --git a/arangod/VocBase/SingleServerTraverser.h b/arangod/VocBase/SingleServerTraverser.h index ea255c835a..db3c64fdff 100644 --- a/arangod/VocBase/SingleServerTraverser.h +++ b/arangod/VocBase/SingleServerTraverser.h @@ -48,7 +48,7 @@ class SingleServerEdgeCursor : public EdgeCursor { std::vector> _cursors; size_t _currentCursor; size_t _currentSubCursor; - std::vector _cache; + std::vector _cache; size_t _cachePos; std::vector const* _internalCursorMapping;