1
0
Fork 0

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.

This commit is contained in:
Michael Hackstein 2017-01-24 18:19:25 +01:00
parent f1df7ae882
commit 2133b1448c
34 changed files with 237 additions and 158 deletions

View File

@ -42,7 +42,7 @@ CollectionScanner::CollectionScanner(arangodb::Transaction* trx,
CollectionScanner::~CollectionScanner() {} CollectionScanner::~CollectionScanner() {}
void CollectionScanner::scan(std::vector<arangodb::IndexLookupResult>& result, size_t batchSize) { void CollectionScanner::scan(std::vector<arangodb::DocumentIdentifierToken>& result, size_t batchSize) {
result.clear(); result.clear();
if (!_cursor->hasMore()) { if (!_cursor->hasMore()) {

View File

@ -40,7 +40,7 @@ class CollectionScanner {
~CollectionScanner(); ~CollectionScanner();
void scan(std::vector<IndexLookupResult>& result, size_t batchSize); void scan(std::vector<DocumentIdentifierToken>& result, size_t batchSize);
void reset(); void reset();

View File

@ -250,8 +250,7 @@ AqlItemBlock* EnumerateCollectionBlock::getSome(size_t, // atLeast,
// The result is in the first variable of this depth, // The result is in the first variable of this depth,
// we do not need to do a lookup in getPlanNode()->_registerPlan->varInfo, // we do not need to do a lookup in getPlanNode()->_registerPlan->varInfo,
// but can just take cur->getNrRegs() as registerId: // but can just take cur->getNrRegs() as registerId:
TRI_voc_rid_t revisionId = _documents[_position].revisionId(); if (c->readDocument(_trx, *_mmdr, _documents[_position])) {
if (c->readRevision(_trx, *_mmdr, revisionId)) {
uint8_t const* vpack = _mmdr->vpack(); uint8_t const* vpack = _mmdr->vpack();
res->setValue(j, static_cast<arangodb::aql::RegisterId>(curRegs), AqlValue(vpack, AqlValueFromManagedDocument())); res->setValue(j, static_cast<arangodb::aql::RegisterId>(curRegs), AqlValue(vpack, AqlValueFromManagedDocument()));
} }

View File

@ -81,7 +81,7 @@ class EnumerateCollectionBlock : public ExecutionBlock {
CollectionScanner _scanner; CollectionScanner _scanner;
/// @brief document buffer /// @brief document buffer
std::vector<IndexLookupResult> _documents; std::vector<DocumentIdentifierToken> _documents;
/// @brief iterator over documents /// @brief iterator over documents
size_t _position; size_t _position;

View File

@ -430,18 +430,17 @@ bool IndexBlock::readIndex(size_t atMost) {
if (hasMultipleIndexes) { if (hasMultipleIndexes) {
for (auto const& element : _result) { for (auto const& element : _result) {
TRI_voc_rid_t revisionId = element.revisionId(); if (collection->readDocument(_trx, *_mmdr, element)) {
if (collection->readRevision(_trx, *_mmdr, revisionId)) {
uint8_t const* vpack = _mmdr->vpack(); //back(); uint8_t const* vpack = _mmdr->vpack(); //back();
// uniqueness checks // uniqueness checks
if (!isLastIndex) { if (!isLastIndex) {
// insert & check for duplicates in one go // insert & check for duplicates in one go
if (_alreadyReturned.emplace(revisionId).second) { if (_alreadyReturned.emplace(element).second) {
_documents.emplace_back(vpack); _documents.emplace_back(vpack);
} }
} else { } else {
// only check for duplicates // only check for duplicates
if (_alreadyReturned.find(revisionId) == _alreadyReturned.end()) { if (_alreadyReturned.find(element) == _alreadyReturned.end()) {
_documents.emplace_back(vpack); _documents.emplace_back(vpack);
} }
} }
@ -449,8 +448,7 @@ bool IndexBlock::readIndex(size_t atMost) {
} }
} else { } else {
for (auto const& element : _result) { for (auto const& element : _result) {
TRI_voc_rid_t revisionId = element.revisionId(); if (collection->readDocument(_trx, *_mmdr, element)) {
if (collection->readRevision(_trx, *_mmdr, revisionId)) {
uint8_t const* vpack = _mmdr->vpack(); //back(); uint8_t const* vpack = _mmdr->vpack(); //back();
_documents.emplace_back(vpack); _documents.emplace_back(vpack);
} }

View File

@ -110,7 +110,7 @@ class IndexBlock : public ExecutionBlock {
Collection const* _collection; Collection const* _collection;
/// @brief document result /// @brief document result
std::vector<IndexLookupResult> _result; std::vector<DocumentIdentifierToken> _result;
/// @brief document buffer /// @brief document buffer
std::vector<arangodb::velocypack::Slice> _documents; std::vector<arangodb::velocypack::Slice> _documents;
@ -149,7 +149,7 @@ class IndexBlock : public ExecutionBlock {
AstNode const* _condition; AstNode const* _condition;
/// @brief set of already returned documents. Used to make the result distinct /// @brief set of already returned documents. Used to make the result distinct
std::unordered_set<TRI_voc_rid_t> _alreadyReturned; std::unordered_set<DocumentIdentifierToken> _alreadyReturned;
/// @brief whether or not at least one expression uses v8 /// @brief whether or not at least one expression uses v8
bool _hasV8Expression; bool _hasV8Expression;

View File

@ -70,7 +70,7 @@ struct ConstDistanceExpanderLocal {
bool _isReverse; bool _isReverse;
/// @brief Local cursor vector /// @brief Local cursor vector
std::vector<IndexLookupResult> _cursor; std::vector<DocumentIdentifierToken> _cursor;
public: public:
ConstDistanceExpanderLocal(ShortestPathBlock const* block, ConstDistanceExpanderLocal(ShortestPathBlock const* block,
@ -96,10 +96,9 @@ struct ConstDistanceExpanderLocal {
_cursor.clear(); _cursor.clear();
LogicalCollection* collection = edgeCursor->collection(); LogicalCollection* collection = edgeCursor->collection();
while (edgeCursor->hasMore()) { while (edgeCursor->hasMore()) {
edgeCursor->getMoreMptr(_cursor, UINT64_MAX); edgeCursor->getMoreMptr(_cursor, 1000);
for (auto const& element : _cursor) { for (auto const& element : _cursor) {
TRI_voc_rid_t revisionId = element.revisionId(); if (collection->readDocument(_block->transaction(), *mmdr, element)) {
if (collection->readRevision(_block->transaction(), *mmdr, revisionId)) {
VPackSlice edge(mmdr->vpack()); VPackSlice edge(mmdr->vpack());
VPackSlice from = VPackSlice from =
arangodb::Transaction::extractFromFromDocument(edge); arangodb::Transaction::extractFromFromDocument(edge);
@ -220,7 +219,7 @@ struct EdgeWeightExpanderLocal {
void operator()(VPackSlice const& source, void operator()(VPackSlice const& source,
std::vector<ArangoDBPathFinder::Step*>& result) { std::vector<ArangoDBPathFinder::Step*>& result) {
ManagedDocumentResult* mmdr = _block->_mmdr.get(); ManagedDocumentResult* mmdr = _block->_mmdr.get();
std::vector<IndexLookupResult> cursor; std::vector<DocumentIdentifierToken> cursor;
std::unique_ptr<arangodb::OperationCursor> edgeCursor; std::unique_ptr<arangodb::OperationCursor> edgeCursor;
std::unordered_map<VPackSlice, size_t> candidates; std::unordered_map<VPackSlice, size_t> candidates;
for (auto const& edgeCollection : _block->_collectionInfos) { for (auto const& edgeCollection : _block->_collectionInfos) {
@ -240,10 +239,9 @@ struct EdgeWeightExpanderLocal {
cursor.clear(); cursor.clear();
LogicalCollection* collection = edgeCursor->collection(); LogicalCollection* collection = edgeCursor->collection();
while (edgeCursor->hasMore()) { while (edgeCursor->hasMore()) {
edgeCursor->getMoreMptr(cursor, UINT64_MAX); edgeCursor->getMoreMptr(cursor, 1000);
for (auto const& element : cursor) { for (auto const& element : cursor) {
TRI_voc_rid_t revisionId = element.revisionId(); if (collection->readDocument(_block->transaction(), *mmdr, element)) {
if (collection->readRevision(_block->transaction(), *mmdr, revisionId)) {
VPackSlice edge(mmdr->vpack()); VPackSlice edge(mmdr->vpack());
VPackSlice from = VPackSlice from =
arangodb::Transaction::extractFromFromDocument(edge); arangodb::Transaction::extractFromFromDocument(edge);

View File

@ -51,16 +51,16 @@ IndexIterator::~IndexIterator() {
} }
/// @brief default implementation for next /// @brief default implementation for next
IndexLookupResult IndexIterator::next() { return IndexLookupResult(); } DocumentIdentifierToken IndexIterator::next() { return DocumentIdentifierToken(); }
/// @brief default implementation for nextBabies /// @brief default implementation for nextBabies
void IndexIterator::nextBabies(std::vector<IndexLookupResult>& result, size_t batchSize) { void IndexIterator::nextBabies(std::vector<DocumentIdentifierToken>& result, size_t batchSize) {
result.clear(); result.clear();
if (batchSize > 0) { if (batchSize > 0) {
while (true) { while (true) {
IndexLookupResult element = next(); DocumentIdentifierToken element = next();
if (!element) { if (element == 0) {
return; return;
} }
result.emplace_back(element); result.emplace_back(element);
@ -79,7 +79,7 @@ void IndexIterator::reset() {}
void IndexIterator::skip(uint64_t count, uint64_t& skipped) { void IndexIterator::skip(uint64_t count, uint64_t& skipped) {
// Skip the first count-many entries // Skip the first count-many entries
// TODO: Can be improved // TODO: Can be improved
while (count > 0 && next()) { while (count > 0 && next() != 0) {
--count; --count;
skipped++; skipped++;
} }
@ -88,16 +88,16 @@ void IndexIterator::skip(uint64_t count, uint64_t& skipped) {
/// @brief Get the next element /// @brief Get the next element
/// If one iterator is exhausted, the next one is used. /// If one iterator is exhausted, the next one is used.
/// A nullptr indicates that all iterators are exhausted /// A nullptr indicates that all iterators are exhausted
IndexLookupResult MultiIndexIterator::next() { DocumentIdentifierToken MultiIndexIterator::next() {
if (_current == nullptr) { if (_current == nullptr) {
return IndexLookupResult(); return DocumentIdentifierToken();
} }
IndexLookupResult next = _current->next(); DocumentIdentifierToken next = _current->next();
while (!next) { while (next == 0) {
_currentIdx++; _currentIdx++;
if (_currentIdx >= _iterators.size()) { if (_currentIdx >= _iterators.size()) {
_current = nullptr; _current = nullptr;
return IndexLookupResult(); return DocumentIdentifierToken();
} }
_current = _iterators.at(_currentIdx); _current = _iterators.at(_currentIdx);
next = _current->next(); next = _current->next();
@ -108,7 +108,7 @@ IndexLookupResult MultiIndexIterator::next() {
/// @brief Get the next limit many elements /// @brief Get the next limit many elements
/// If one iterator is exhausted, the next one will be used. /// If one iterator is exhausted, the next one will be used.
/// An empty result vector indicates that all iterators are exhausted /// An empty result vector indicates that all iterators are exhausted
void MultiIndexIterator::nextBabies(std::vector<IndexLookupResult>& result, size_t limit) { void MultiIndexIterator::nextBabies(std::vector<DocumentIdentifierToken>& result, size_t limit) {
result.clear(); result.clear();
if (_current == nullptr) { if (_current == nullptr) {

View File

@ -26,7 +26,7 @@
// //
// typeName() returns a string descibing the type of the indexIterator // 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 // created from RevisionIds. If there is nothing more to return a default
// constructed IndesLookupResult is returend. // constructed IndesLookupResult is returend.
// //
@ -51,6 +51,7 @@
#include "Basics/Common.h" #include "Basics/Common.h"
#include "Cluster/ServerState.h" #include "Cluster/ServerState.h"
#include "Indexes/IndexLookupContext.h" #include "Indexes/IndexLookupContext.h"
#include "StorageEngine/StorageEngine.h"
#include "VocBase/ManagedDocumentResult.h" #include "VocBase/ManagedDocumentResult.h"
#include "VocBase/vocbase.h" #include "VocBase/vocbase.h"
@ -59,24 +60,6 @@ class Index;
class LogicalCollection; class LogicalCollection;
class Transaction; 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 /// @brief a base class to iterate over the index. An iterator is requested
/// at the index itself /// at the index itself
class IndexIterator { class IndexIterator {
@ -94,9 +77,9 @@ class IndexIterator {
LogicalCollection* collection() const { return _collection; } LogicalCollection* collection() const { return _collection; }
arangodb::Transaction* transaction() const { return _trx; } arangodb::Transaction* transaction() const { return _trx; }
virtual IndexLookupResult next(); virtual DocumentIdentifierToken next();
virtual void nextBabies(std::vector<IndexLookupResult>&, size_t); virtual void nextBabies(std::vector<DocumentIdentifierToken>&, size_t);
virtual void reset(); virtual void reset();
@ -120,9 +103,9 @@ class EmptyIndexIterator final : public IndexIterator {
char const* typeName() const override { return "empty-index-iterator"; } char const* typeName() const override { return "empty-index-iterator"; }
IndexLookupResult next() override { return IndexLookupResult(); } DocumentIdentifierToken next() override { return DocumentIdentifierToken(); }
void nextBabies(std::vector<IndexLookupResult>&, size_t) override {} void nextBabies(std::vector<DocumentIdentifierToken>&, size_t) override {}
void reset() override {} void reset() override {}
@ -161,12 +144,12 @@ class MultiIndexIterator final : public IndexIterator {
/// @brief Get the next element /// @brief Get the next element
/// If one iterator is exhausted, the next one is used. /// If one iterator is exhausted, the next one is used.
/// A nullptr indicates that all iterators are exhausted /// A nullptr indicates that all iterators are exhausted
IndexLookupResult next() override; DocumentIdentifierToken next() override;
/// @brief Get at most the next limit many elements /// @brief Get at most the next limit many elements
/// If one iterator is exhausted, the next one will be used. /// If one iterator is exhausted, the next one will be used.
/// An empty result vector indicates that all iterators are exhausted /// An empty result vector indicates that all iterators are exhausted
void nextBabies(std::vector<IndexLookupResult>&, size_t) override; void nextBabies(std::vector<DocumentIdentifierToken>&, size_t) override;
/// @brief Reset the cursor /// @brief Reset the cursor
/// This will reset ALL internal iterators and start all over again /// This will reset ALL internal iterators and start all over again

View File

@ -45,9 +45,9 @@ class IndexLookupContext {
~IndexLookupContext() {} ~IndexLookupContext() {}
uint8_t const* lookup(TRI_voc_rid_t revisionId) { uint8_t const* lookup(DocumentIdentifierToken token) {
try { try {
if (_collection->readRevision(_trx, *_result, revisionId)) { if (_collection->readDocument(_trx, *_result, token)) {
return _result->vpack(); return _result->vpack();
} }
} catch (...) { } catch (...) {

View File

@ -31,6 +31,7 @@
#include "Basics/hashes.h" #include "Basics/hashes.h"
#include "Indexes/IndexLookupContext.h" #include "Indexes/IndexLookupContext.h"
#include "Indexes/SimpleAttributeEqualityMatcher.h" #include "Indexes/SimpleAttributeEqualityMatcher.h"
#include "MMFiles/MMFilesToken.h"
#include "Utils/CollectionNameResolver.h" #include "Utils/CollectionNameResolver.h"
#include "Utils/Transaction.h" #include "Utils/Transaction.h"
#include "Utils/TransactionContext.h" #include "Utils/TransactionContext.h"
@ -126,7 +127,7 @@ MMFilesEdgeIndexIterator::~MMFilesEdgeIndexIterator() {
} }
} }
IndexLookupResult MMFilesEdgeIndexIterator::next() { DocumentIdentifierToken MMFilesEdgeIndexIterator::next() {
while (_iterator.valid()) { while (_iterator.valid()) {
if (_buffer.empty()) { if (_buffer.empty()) {
// We start a new lookup // We start a new lookup
@ -150,17 +151,17 @@ IndexLookupResult MMFilesEdgeIndexIterator::next() {
} else { } else {
_lastElement = _buffer.back(); _lastElement = _buffer.back();
// found something // found something
return IndexLookupResult(_buffer[_posInBuffer++].revisionId()); return MMFilesToken{_buffer[_posInBuffer++].revisionId()};
} }
// found no result. now go to next lookup value in _keys // found no result. now go to next lookup value in _keys
_iterator.next(); _iterator.next();
} }
return IndexLookupResult(); return MMFilesToken{};
} }
void MMFilesEdgeIndexIterator::nextBabies(std::vector<IndexLookupResult>& buffer, size_t limit) { void MMFilesEdgeIndexIterator::nextBabies(std::vector<DocumentIdentifierToken>& buffer, size_t limit) {
size_t atMost = _batchSize > limit ? limit : _batchSize; size_t atMost = _batchSize > limit ? limit : _batchSize;
if (atMost == 0) { if (atMost == 0) {
@ -187,7 +188,7 @@ void MMFilesEdgeIndexIterator::nextBabies(std::vector<IndexLookupResult>& buffer
} }
for (auto& it : _buffer) { for (auto& it : _buffer) {
buffer.emplace_back(it.revisionId()); buffer.emplace_back(MMFilesToken(it.revisionId()));
} }
if (_buffer.empty()) { if (_buffer.empty()) {
@ -223,28 +224,28 @@ AnyDirectionMMFilesEdgeIndexIterator::AnyDirectionMMFilesEdgeIndexIterator(Logic
_inbound(inboundIterator), _inbound(inboundIterator),
_useInbound(false) {} _useInbound(false) {}
IndexLookupResult AnyDirectionMMFilesEdgeIndexIterator::next() { DocumentIdentifierToken AnyDirectionMMFilesEdgeIndexIterator::next() {
IndexLookupResult res; DocumentIdentifierToken res;
if (_useInbound) { if (_useInbound) {
do { do {
res = _inbound->next(); res = _inbound->next();
} while (res && _seen.find(res.revisionId()) != _seen.end()); } while (res != 0 && _seen.find(res) != _seen.end());
return res; return res;
} }
res = _outbound->next(); res = _outbound->next();
if (!res) { if (res == 0) {
_useInbound = true; _useInbound = true;
return next(); return next();
} }
_seen.emplace(res.revisionId()); _seen.emplace(res);
return res; return res;
} }
void AnyDirectionMMFilesEdgeIndexIterator::nextBabies(std::vector<IndexLookupResult>& result, size_t limit) { void AnyDirectionMMFilesEdgeIndexIterator::nextBabies(std::vector<DocumentIdentifierToken>& result, size_t limit) {
result.clear(); result.clear();
for (size_t i = 0; i < limit; ++i) { for (size_t i = 0; i < limit; ++i) {
IndexLookupResult res = next(); DocumentIdentifierToken res = next();
if (!res) { if (res == 0) {
return; return;
} }
result.emplace_back(res); result.emplace_back(res);

View File

@ -53,9 +53,9 @@ class MMFilesEdgeIndexIterator final : public IndexIterator {
char const* typeName() const override { return "edge-index-iterator"; } char const* typeName() const override { return "edge-index-iterator"; }
IndexLookupResult next() override; DocumentIdentifierToken next() override;
void nextBabies(std::vector<IndexLookupResult>&, size_t) override; void nextBabies(std::vector<DocumentIdentifierToken>&, size_t) override;
void reset() override; void reset() override;
@ -85,16 +85,16 @@ class AnyDirectionMMFilesEdgeIndexIterator final : public IndexIterator {
char const* typeName() const override { return "any-edge-index-iterator"; } char const* typeName() const override { return "any-edge-index-iterator"; }
IndexLookupResult next() override; DocumentIdentifierToken next() override;
void nextBabies(std::vector<IndexLookupResult>&, size_t) override; void nextBabies(std::vector<DocumentIdentifierToken>&, size_t) override;
void reset() override; void reset() override;
private: private:
MMFilesEdgeIndexIterator* _outbound; MMFilesEdgeIndexIterator* _outbound;
MMFilesEdgeIndexIterator* _inbound; MMFilesEdgeIndexIterator* _inbound;
std::unordered_set<TRI_voc_rid_t> _seen; std::unordered_set<DocumentIdentifierToken> _seen;
bool _useInbound; bool _useInbound;
}; };

View File

@ -29,6 +29,7 @@
#include "Basics/StringRef.h" #include "Basics/StringRef.h"
#include "Basics/VelocyPackHelper.h" #include "Basics/VelocyPackHelper.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "MMFiles/MMFilesToken.h"
#include "VocBase/transaction.h" #include "VocBase/transaction.h"
using namespace arangodb; using namespace arangodb;
@ -85,7 +86,7 @@ void MMFilesGeoIndexIterator::evaluateCondition() {
} }
} }
IndexLookupResult MMFilesGeoIndexIterator::next() { DocumentIdentifierToken MMFilesGeoIndexIterator::next() {
if (!_cursor) { if (!_cursor) {
createCursor(_lat, _lon); createCursor(_lat, _lon);
} }
@ -98,14 +99,14 @@ IndexLookupResult MMFilesGeoIndexIterator::next() {
) )
{ {
auto revision = ::MMFilesGeoIndex::toRevision(coords->coordinates[0].data); 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 // if there are no more results we return the default constructed IndexLookupResult
return IndexLookupResult{}; return MMFilesToken{};
} }
void MMFilesGeoIndexIterator::nextBabies(std::vector<IndexLookupResult>& result, size_t batchSize) { void MMFilesGeoIndexIterator::nextBabies(std::vector<DocumentIdentifierToken>& result, size_t batchSize) {
if (!_cursor) { if (!_cursor) {
createCursor(_lat, _lon); createCursor(_lat, _lon);
@ -135,7 +136,8 @@ void MMFilesGeoIndexIterator::nextBabies(std::vector<IndexLookupResult>& result,
withDistances = true; withDistances = true;
maxDistance = _radius; maxDistance = _radius;
} }
auto coords = std::unique_ptr<GeoCoordinates>(::GeoIndex_ReadCursor(_cursor, static_cast<int>(batchSize), withDistances, maxDistance)); auto coords = std::unique_ptr<GeoCoordinates>(::GeoIndex_ReadCursor(
_cursor, static_cast<int>(batchSize), withDistances, maxDistance));
size_t const length = coords ? coords->length : 0; size_t const length = coords ? coords->length : 0;
@ -197,7 +199,7 @@ void MMFilesGeoIndexIterator::nextBabies(std::vector<IndexLookupResult>& result,
result.reserve(numDocs); result.reserve(numDocs);
for (size_t i = 0; i < numDocs; ++i) { 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)));
} }
} }

View File

@ -56,9 +56,9 @@ class MMFilesGeoIndexIterator final : public IndexIterator {
char const* typeName() const override { return "geo-index-iterator"; } char const* typeName() const override { return "geo-index-iterator"; }
IndexLookupResult next() override; DocumentIdentifierToken next() override;
void nextBabies(std::vector<IndexLookupResult>&, size_t) override; void nextBabies(std::vector<DocumentIdentifierToken>&, size_t) override;
void reset() override; void reset() override;

View File

@ -30,6 +30,7 @@
#include "Basics/VelocyPackHelper.h" #include "Basics/VelocyPackHelper.h"
#include "Indexes/IndexLookupContext.h" #include "Indexes/IndexLookupContext.h"
#include "Indexes/SimpleAttributeEqualityMatcher.h" #include "Indexes/SimpleAttributeEqualityMatcher.h"
#include "MMFiles/MMFilesToken.h"
#include "Utils/TransactionContext.h" #include "Utils/TransactionContext.h"
#include "VocBase/LogicalCollection.h" #include "VocBase/LogicalCollection.h"
#include "VocBase/transaction.h" #include "VocBase/transaction.h"
@ -294,12 +295,12 @@ MMFilesHashIndexIterator::MMFilesHashIndexIterator(LogicalCollection* collection
_index->lookup(_trx, _lookups.lookup(), _buffer); _index->lookup(_trx, _lookups.lookup(), _buffer);
} }
IndexLookupResult MMFilesHashIndexIterator::next() { DocumentIdentifierToken MMFilesHashIndexIterator::next() {
while (true) { while (true) {
if (_posInBuffer >= _buffer.size()) { if (_posInBuffer >= _buffer.size()) {
if (!_lookups.hasAndGetNext()) { if (!_lookups.hasAndGetNext()) {
// we're at the end of the lookup values // we're at the end of the lookup values
return IndexLookupResult(); return MMFilesToken{};
} }
// We have to refill the buffer // We have to refill the buffer
@ -311,12 +312,12 @@ IndexLookupResult MMFilesHashIndexIterator::next() {
if (!_buffer.empty()) { if (!_buffer.empty()) {
// found something // found something
return IndexLookupResult(_buffer[_posInBuffer++]->revisionId()); return MMFilesToken{_buffer[_posInBuffer++]->revisionId()};
} }
} }
} }
void MMFilesHashIndexIterator::nextBabies(std::vector<IndexLookupResult>& result, size_t atMost) { void MMFilesHashIndexIterator::nextBabies(std::vector<DocumentIdentifierToken>& result, size_t atMost) {
result.clear(); result.clear();
if (atMost == 0) { if (atMost == 0) {
@ -347,7 +348,7 @@ void MMFilesHashIndexIterator::nextBabies(std::vector<IndexLookupResult>& result
} }
for (size_t i = _posInBuffer; i < atMost + _posInBuffer; ++i) { for (size_t i = _posInBuffer; i < atMost + _posInBuffer; ++i) {
result.emplace_back(_buffer[i]->revisionId()); result.emplace_back(MMFilesToken{_buffer[i]->revisionId()});
} }
_posInBuffer += atMost; _posInBuffer += atMost;
return; return;
@ -383,12 +384,12 @@ MMFilesHashIndexIteratorVPack::~MMFilesHashIndexIteratorVPack() {
} }
} }
IndexLookupResult MMFilesHashIndexIteratorVPack::next() { DocumentIdentifierToken MMFilesHashIndexIteratorVPack::next() {
while (true) { while (true) {
if (_posInBuffer >= _buffer.size()) { if (_posInBuffer >= _buffer.size()) {
if (!_iterator.valid()) { if (!_iterator.valid()) {
// we're at the end of the lookup values // we're at the end of the lookup values
return IndexLookupResult(); return MMFilesToken{};
} }
// We have to refill the buffer // We have to refill the buffer
@ -406,7 +407,7 @@ IndexLookupResult MMFilesHashIndexIteratorVPack::next() {
if (!_buffer.empty()) { if (!_buffer.empty()) {
// found something // found something
return IndexLookupResult(_buffer[_posInBuffer++]->revisionId()); return MMFilesToken{_buffer[_posInBuffer++]->revisionId()};
} }
} }
} }

View File

@ -90,9 +90,9 @@ class MMFilesHashIndexIterator final : public IndexIterator {
char const* typeName() const override { return "hash-index-iterator"; } char const* typeName() const override { return "hash-index-iterator"; }
IndexLookupResult next() override; DocumentIdentifierToken next() override;
void nextBabies(std::vector<IndexLookupResult>&, size_t) override; void nextBabies(std::vector<DocumentIdentifierToken>&, size_t) override;
void reset() override; void reset() override;
@ -117,7 +117,7 @@ class MMFilesHashIndexIteratorVPack final : public IndexIterator {
char const* typeName() const override { return "hash-index-iterator-vpack"; } char const* typeName() const override { return "hash-index-iterator-vpack"; }
IndexLookupResult next() override; DocumentIdentifierToken next() override;
void reset() override; void reset() override;

View File

@ -24,6 +24,7 @@
#include "MMFilesIndexElement.h" #include "MMFilesIndexElement.h"
#include "Basics/VelocyPackHelper.h" #include "Basics/VelocyPackHelper.h"
#include "Indexes/IndexLookupContext.h" #include "Indexes/IndexLookupContext.h"
#include "MMFiles/MMFilesToken.h"
using namespace arangodb; using namespace arangodb;
@ -57,7 +58,7 @@ arangodb::velocypack::Slice MMFilesHashIndexElement::slice(IndexLookupContext* c
if (offset == 0) { if (offset == 0) {
return basics::VelocyPackHelper::NullValue(); return basics::VelocyPackHelper::NullValue();
} }
uint8_t const* vpack = context->lookup(_revisionId); uint8_t const* vpack = context->lookup(MMFilesToken{_revisionId});
if (vpack == nullptr) { if (vpack == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND); THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND);
} }
@ -133,7 +134,7 @@ arangodb::velocypack::Slice MMFilesSkiplistIndexElement::slice(IndexLookupContex
if (offset == 0) { if (offset == 0) {
return basics::VelocyPackHelper::NullValue(); return basics::VelocyPackHelper::NullValue();
} }
uint8_t const* vpack = context->lookup(_revisionId); uint8_t const* vpack = context->lookup(MMFilesToken{_revisionId});
if (vpack == nullptr) { if (vpack == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND); 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 { VPackSlice MMFilesSimpleIndexElement::slice(IndexLookupContext* context) const {
uint8_t const* vpack = context->lookup(_revisionId); uint8_t const* vpack = context->lookup(MMFilesToken{_revisionId});
if (vpack == nullptr) { if (vpack == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND); THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND);
} }

View File

@ -32,6 +32,7 @@
#include "MMFiles/MMFilesPrimaryIndex.h" #include "MMFiles/MMFilesPrimaryIndex.h"
#include "MMFiles/MMFilesPersistentIndexFeature.h" #include "MMFiles/MMFilesPersistentIndexFeature.h"
#include "MMFiles/MMFilesPersistentIndexKeyComparator.h" #include "MMFiles/MMFilesPersistentIndexKeyComparator.h"
#include "MMFiles/MMFilesToken.h"
#include "Utils/Transaction.h" #include "Utils/Transaction.h"
#include "VocBase/LogicalCollection.h" #include "VocBase/LogicalCollection.h"
@ -137,13 +138,13 @@ void PersistentIndexIterator::reset() {
} }
/// @brief Get the next element in the index /// @brief Get the next element in the index
IndexLookupResult PersistentIndexIterator::next() { DocumentIdentifierToken PersistentIndexIterator::next() {
auto comparator = RocksDBFeature::instance()->comparator(); auto comparator = RocksDBFeature::instance()->comparator();
while (true) { while (true) {
if (!_cursor->Valid()) { if (!_cursor->Valid()) {
// We are exhausted already, sorry // We are exhausted already, sorry
return IndexLookupResult(); return MMFilesToken{};
} }
rocksdb::Slice key = _cursor->key(); rocksdb::Slice key = _cursor->key();
@ -154,7 +155,7 @@ IndexLookupResult PersistentIndexIterator::next() {
if (res < 0) { if (res < 0) {
if (_reverse) { if (_reverse) {
return IndexLookupResult(); return MMFilesToken{};
} else { } else {
_cursor->Next(); _cursor->Next();
} }
@ -164,7 +165,7 @@ IndexLookupResult PersistentIndexIterator::next() {
res = comparator->Compare(key, rocksdb::Slice(_rightEndpoint->data(), _rightEndpoint->size())); 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; // 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) { if (res <= 0) {
// get the value for _key, which is the last entry in the key array // 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 // use primary index to lookup the document
MMFilesSimpleIndexElement element = _primaryIndex->lookupKey(_trx, keySlice[n - 1]); MMFilesSimpleIndexElement element = _primaryIndex->lookupKey(_trx, keySlice[n - 1]);
if (element) { if (element) {
doc = IndexLookupResult(element.revisionId()); doc = MMFilesToken{element.revisionId()};
} }
} }
@ -191,13 +192,13 @@ IndexLookupResult PersistentIndexIterator::next() {
if (res > 0) { if (res > 0) {
if (!_probe) { if (!_probe) {
return IndexLookupResult(); return MMFilesToken{};
} }
_probe = false; _probe = false;
continue; continue;
} }
if (doc) { if (doc != 0) {
return doc; return doc;
} }
} }

View File

@ -75,7 +75,7 @@ class PersistentIndexIterator final : public IndexIterator {
char const* typeName() const override { return "rocksdb-index-iterator"; } char const* typeName() const override { return "rocksdb-index-iterator"; }
/// @brief Get the next element in the index /// @brief Get the next element in the index
IndexLookupResult next() override; DocumentIdentifierToken next() override;
/// @brief Reset the cursor /// @brief Reset the cursor
void reset() override; void reset() override;

View File

@ -29,6 +29,7 @@
#include "Basics/tri-strings.h" #include "Basics/tri-strings.h"
#include "Indexes/IndexLookupContext.h" #include "Indexes/IndexLookupContext.h"
#include "Indexes/SimpleAttributeEqualityMatcher.h" #include "Indexes/SimpleAttributeEqualityMatcher.h"
#include "MMFiles/MMFilesToken.h"
#include "Utils/Transaction.h" #include "Utils/Transaction.h"
#include "Utils/TransactionContext.h" #include "Utils/TransactionContext.h"
#include "VocBase/LogicalCollection.h" #include "VocBase/LogicalCollection.h"
@ -106,20 +107,20 @@ MMFilesPrimaryIndexIterator::~MMFilesPrimaryIndexIterator() {
} }
} }
IndexLookupResult MMFilesPrimaryIndexIterator::next() { DocumentIdentifierToken MMFilesPrimaryIndexIterator::next() {
while (_iterator.valid()) { while (_iterator.valid()) {
MMFilesSimpleIndexElement result = _index->lookupKey(_trx, _iterator.value()); MMFilesSimpleIndexElement result = _index->lookupKey(_trx, _iterator.value());
_iterator.next(); _iterator.next();
if (result) { if (result) {
// found a result // found a result
return IndexLookupResult(result.revisionId()); return MMFilesToken{result.revisionId()};
} }
// found no result. now go to next lookup value in _keys // found no result. now go to next lookup value in _keys
} }
return IndexLookupResult(); return MMFilesToken{};
} }
void MMFilesPrimaryIndexIterator::reset() { _iterator.reset(); } void MMFilesPrimaryIndexIterator::reset() { _iterator.reset(); }
@ -132,7 +133,7 @@ AllIndexIterator::AllIndexIterator(LogicalCollection* collection,
bool reverse) bool reverse)
: IndexIterator(collection, trx, mmdr, index), _index(indexImpl), _reverse(reverse), _total(0) {} : IndexIterator(collection, trx, mmdr, index), _index(indexImpl), _reverse(reverse), _total(0) {}
IndexLookupResult AllIndexIterator::next() { DocumentIdentifierToken AllIndexIterator::next() {
MMFilesSimpleIndexElement element; MMFilesSimpleIndexElement element;
if (_reverse) { if (_reverse) {
element = _index->findSequentialReverse(&_context, _position); element = _index->findSequentialReverse(&_context, _position);
@ -140,12 +141,12 @@ IndexLookupResult AllIndexIterator::next() {
element = _index->findSequential(&_context, _position, _total); element = _index->findSequential(&_context, _position, _total);
} }
if (element) { if (element) {
return IndexLookupResult(element.revisionId()); return MMFilesToken{element.revisionId()};
} }
return IndexLookupResult(); return MMFilesToken{};
} }
void AllIndexIterator::nextBabies(std::vector<IndexLookupResult>& buffer, size_t limit) { void AllIndexIterator::nextBabies(std::vector<DocumentIdentifierToken>& buffer, size_t limit) {
size_t atMost = limit; size_t atMost = limit;
buffer.clear(); buffer.clear();
@ -154,9 +155,9 @@ void AllIndexIterator::nextBabies(std::vector<IndexLookupResult>& buffer, size_t
} }
while (atMost > 0) { while (atMost > 0) {
IndexLookupResult result = next(); DocumentIdentifierToken result = next();
if (!result) { if (result == 0) {
return; return;
} }
@ -173,12 +174,12 @@ AnyIndexIterator::AnyIndexIterator(LogicalCollection* collection, arangodb::Tran
MMFilesPrimaryIndexImpl const* indexImpl) MMFilesPrimaryIndexImpl const* indexImpl)
: IndexIterator(collection, trx, mmdr, index), _index(indexImpl), _step(0), _total(0) {} : 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); MMFilesSimpleIndexElement element = _index->findRandom(&_context, _initial, _position, _step, _total);
if (element) { if (element) {
return IndexLookupResult(element.revisionId()); return MMFilesToken{element.revisionId()};
} }
return IndexLookupResult(); return MMFilesToken{};
} }
void AnyIndexIterator::reset() { void AnyIndexIterator::reset() {

View File

@ -54,7 +54,7 @@ class MMFilesPrimaryIndexIterator final : public IndexIterator {
char const* typeName() const override { return "primary-index-iterator"; } char const* typeName() const override { return "primary-index-iterator"; }
IndexLookupResult next() override; DocumentIdentifierToken next() override;
void reset() override; void reset() override;
@ -77,9 +77,9 @@ class AllIndexIterator final : public IndexIterator {
char const* typeName() const override { return "all-index-iterator"; } char const* typeName() const override { return "all-index-iterator"; }
IndexLookupResult next() override; DocumentIdentifierToken next() override;
void nextBabies(std::vector<IndexLookupResult>&, size_t) override; void nextBabies(std::vector<DocumentIdentifierToken>&, size_t) override;
void reset() override; void reset() override;
@ -101,7 +101,7 @@ class AnyIndexIterator final : public IndexIterator {
char const* typeName() const override { return "any-index-iterator"; } char const* typeName() const override { return "any-index-iterator"; }
IndexLookupResult next() override; DocumentIdentifierToken next() override;
void reset() override; void reset() override;

View File

@ -29,6 +29,7 @@
#include "Basics/StaticStrings.h" #include "Basics/StaticStrings.h"
#include "Basics/VelocyPackHelper.h" #include "Basics/VelocyPackHelper.h"
#include "Indexes/IndexLookupContext.h" #include "Indexes/IndexLookupContext.h"
#include "MMFiles/MMFilesToken.h"
#include "Utils/Transaction.h" #include "Utils/Transaction.h"
#include "VocBase/LogicalCollection.h" #include "VocBase/LogicalCollection.h"
@ -520,10 +521,10 @@ void MMFilesSkiplistIterator::reset() {
} }
/// @brief Get the next element in the skiplist /// @brief Get the next element in the skiplist
IndexLookupResult MMFilesSkiplistIterator::next() { DocumentIdentifierToken MMFilesSkiplistIterator::next() {
if (_cursor == nullptr) { if (_cursor == nullptr) {
// We are exhausted already, sorry // We are exhausted already, sorry
return IndexLookupResult(); return MMFilesToken{};
} }
Node* tmp = _cursor; Node* tmp = _cursor;
if (_reverse) { if (_reverse) {
@ -541,7 +542,7 @@ IndexLookupResult MMFilesSkiplistIterator::next() {
} }
TRI_ASSERT(tmp != nullptr); TRI_ASSERT(tmp != nullptr);
TRI_ASSERT(tmp->document() != nullptr); TRI_ASSERT(tmp->document() != nullptr);
return IndexLookupResult(tmp->document()->revisionId()); return MMFilesToken{tmp->document()->revisionId()};
} }
MMFilesSkiplistIterator2::MMFilesSkiplistIterator2(LogicalCollection* collection, arangodb::Transaction* trx, MMFilesSkiplistIterator2::MMFilesSkiplistIterator2(LogicalCollection* collection, arangodb::Transaction* trx,
@ -602,10 +603,10 @@ void MMFilesSkiplistIterator2::reset() {
} }
/// @brief Get the next element in the skiplist /// @brief Get the next element in the skiplist
IndexLookupResult MMFilesSkiplistIterator2::next() { DocumentIdentifierToken MMFilesSkiplistIterator2::next() {
if (_cursor == nullptr) { if (_cursor == nullptr) {
// We are exhausted already, sorry // We are exhausted already, sorry
return IndexLookupResult(); return MMFilesToken{};
} }
TRI_ASSERT(_currentInterval < _intervals.size()); TRI_ASSERT(_currentInterval < _intervals.size());
auto const& interval = _intervals[_currentInterval]; auto const& interval = _intervals[_currentInterval];
@ -625,7 +626,7 @@ IndexLookupResult MMFilesSkiplistIterator2::next() {
} }
TRI_ASSERT(tmp != nullptr); TRI_ASSERT(tmp != nullptr);
TRI_ASSERT(tmp->document() != nullptr); TRI_ASSERT(tmp->document() != nullptr);
return IndexLookupResult(tmp->document()->revisionId()); return MMFilesToken{tmp->document()->revisionId()};
} }
void MMFilesSkiplistIterator2::forwardCursor() { void MMFilesSkiplistIterator2::forwardCursor() {

View File

@ -196,7 +196,7 @@ class MMFilesSkiplistIterator final : public IndexIterator {
char const* typeName() const override { return "skiplist-index-iterator"; } char const* typeName() const override { return "skiplist-index-iterator"; }
/// @brief Get the next element in the skiplist /// @brief Get the next element in the skiplist
IndexLookupResult next() override; DocumentIdentifierToken next() override;
/// @brief Reset the cursor /// @brief Reset the cursor
void reset() override; void reset() override;
@ -257,7 +257,7 @@ class MMFilesSkiplistIterator2 final : public IndexIterator {
char const* typeName() const override { return "skiplist-index-iterator2"; } char const* typeName() const override { return "skiplist-index-iterator2"; }
/// @brief Get the next element in the skiplist /// @brief Get the next element in the skiplist
IndexLookupResult next() override; DocumentIdentifierToken next() override;
/// @brief Reset the cursor /// @brief Reset the cursor
void reset() override; void reset() override;

View File

@ -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<TRI_voc_rid_t>(_data);
}
};
static_assert(sizeof(MMFilesToken) == sizeof(uint64_t), "invalid MMFilesToken size");
}

View File

@ -91,7 +91,7 @@ bool RestEdgesHandler::getEdgesForVertexList(
THROW_ARANGO_EXCEPTION(cursor->code); THROW_ARANGO_EXCEPTION(cursor->code);
} }
std::vector<IndexLookupResult> batch; std::vector<DocumentIdentifierToken> batch;
ManagedDocumentResult mmdr; ManagedDocumentResult mmdr;
auto collection = trx.documentCollection(); auto collection = trx.documentCollection();
while (cursor->hasMore()) { while (cursor->hasMore()) {
@ -99,8 +99,7 @@ bool RestEdgesHandler::getEdgesForVertexList(
scannedIndex += batch.size(); scannedIndex += batch.size();
for (auto const& it : batch) { for (auto const& it : batch) {
TRI_voc_rid_t revisionId = it.revisionId(); if (collection->readDocument(&trx, mmdr, it)) {
if (collection->readRevision(&trx, mmdr, revisionId)) {
result.add(VPackSlice(mmdr.vpack())); result.add(VPackSlice(mmdr.vpack()));
} }
} }
@ -129,7 +128,7 @@ bool RestEdgesHandler::getEdgesForVertex(
THROW_ARANGO_EXCEPTION(cursor->code); THROW_ARANGO_EXCEPTION(cursor->code);
} }
std::vector<IndexLookupResult> batch; std::vector<DocumentIdentifierToken> batch;
ManagedDocumentResult mmdr; ManagedDocumentResult mmdr;
auto collection = trx.documentCollection(); auto collection = trx.documentCollection();
while (cursor->hasMore()) { while (cursor->hasMore()) {
@ -137,8 +136,7 @@ bool RestEdgesHandler::getEdgesForVertex(
scannedIndex += batch.size(); scannedIndex += batch.size();
for (auto const& it : batch) { for (auto const& it : batch) {
TRI_voc_rid_t revisionId = it.revisionId(); if (collection->readDocument(&trx, mmdr, it)) {
if (collection->readRevision(&trx, mmdr, revisionId)) {
result.add(VPackSlice(mmdr.vpack())); result.add(VPackSlice(mmdr.vpack()));
} }
} }

View File

@ -37,6 +37,33 @@ namespace arangodb {
class LogicalCollection; class LogicalCollection;
class PhysicalCollection; 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 { class StorageEngine : public application_features::ApplicationFeature {
public: public:
@ -249,4 +276,22 @@ class StorageEngine : public application_features::ApplicationFeature {
} }
namespace std {
template <>
struct hash<arangodb::DocumentIdentifierToken> {
inline size_t operator()(arangodb::DocumentIdentifierToken const& token) const noexcept {
return token._data;
}
};
template <>
struct equal_to<arangodb::DocumentIdentifierToken> {
bool operator()(arangodb::DocumentIdentifierToken const& lhs,
arangodb::DocumentIdentifierToken const& rhs) const {
return lhs == rhs;
}
};
}
#endif #endif

View File

@ -47,8 +47,8 @@ void OperationCursor::reset() {
/// NOTE: This will throw on OUT_OF_MEMORY /// NOTE: This will throw on OUT_OF_MEMORY
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
std::vector<IndexLookupResult> OperationCursor::getMoreMptr(uint64_t batchSize) { std::vector<DocumentIdentifierToken> OperationCursor::getMoreMptr(uint64_t batchSize) {
std::vector<IndexLookupResult> res; std::vector<DocumentIdentifierToken> res;
getMoreMptr(res, batchSize); getMoreMptr(res, batchSize);
return res; return res;
} }
@ -62,7 +62,7 @@ std::vector<IndexLookupResult> OperationCursor::getMoreMptr(uint64_t batchSize)
/// The caller shall NOT modify it. /// The caller shall NOT modify it.
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
void OperationCursor::getMoreMptr(std::vector<IndexLookupResult>& result, void OperationCursor::getMoreMptr(std::vector<DocumentIdentifierToken>& result,
uint64_t batchSize) { uint64_t batchSize) {
if (!hasMore()) { if (!hasMore()) {
TRI_ASSERT(false); TRI_ASSERT(false);

View File

@ -108,7 +108,7 @@ struct OperationCursor {
/// NOTE: This will throw on OUT_OF_MEMORY /// NOTE: This will throw on OUT_OF_MEMORY
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
std::vector<IndexLookupResult> getMoreMptr(uint64_t batchSize = 1000); std::vector<DocumentIdentifierToken> getMoreMptr(uint64_t batchSize = 1000);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief Get next batchSize many elements. mptr variant /// @brief Get next batchSize many elements. mptr variant
@ -118,7 +118,7 @@ struct OperationCursor {
/// NOTE: The result vector handed in will be cleared. /// NOTE: The result vector handed in will be cleared.
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
void getMoreMptr(std::vector<IndexLookupResult>& result, uint64_t batchSize = 1000); void getMoreMptr(std::vector<DocumentIdentifierToken>& result, uint64_t batchSize = 1000);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief Skip the next toSkip many elements. /// @brief Skip the next toSkip many elements.

View File

@ -1286,14 +1286,13 @@ OperationResult Transaction::anyLocal(std::string const& collectionName,
{}, &mmdr, skip, limit, 1000, false); {}, &mmdr, skip, limit, 1000, false);
LogicalCollection* collection = cursor->collection(); LogicalCollection* collection = cursor->collection();
std::vector<IndexLookupResult> result; std::vector<DocumentIdentifierToken> result;
while (cursor->hasMore()) { while (cursor->hasMore()) {
result.clear(); result.clear();
cursor->getMoreMptr(result); cursor->getMoreMptr(result);
for (auto const& element : result) { for (auto const& element : result) {
TRI_voc_rid_t revisionId = element.revisionId(); if (collection->readDocument(this, mmdr, element)) {
if (collection->readRevision(this, mmdr, revisionId)) {
uint8_t const* vpack = mmdr.vpack(); uint8_t const* vpack = mmdr.vpack();
resultBuilder.add(VPackSlice(vpack)); resultBuilder.add(VPackSlice(vpack));
} }
@ -2647,14 +2646,13 @@ OperationResult Transaction::allLocal(std::string const& collectionName,
} }
LogicalCollection* collection = cursor->collection(); LogicalCollection* collection = cursor->collection();
std::vector<IndexLookupResult> result; std::vector<DocumentIdentifierToken> result;
result.reserve(1000); result.reserve(1000);
while (cursor->hasMore()) { while (cursor->hasMore()) {
cursor->getMoreMptr(result, 1000); cursor->getMoreMptr(result, 1000);
for (auto const& element : result) { for (auto const& element : result) {
TRI_voc_rid_t revisionId = element.revisionId(); if (collection->readDocument(this, mmdr, element)) {
if (collection->readRevision(this, mmdr, revisionId)) {
uint8_t const* vpack = mmdr.vpack(); uint8_t const* vpack = mmdr.vpack();
resultBuilder.addExternal(vpack); resultBuilder.addExternal(vpack);
} }

View File

@ -254,7 +254,7 @@ static void JS_AllQuery(v8::FunctionCallbackInfo<v8::Value> const& args) {
VPackOptions resultOptions = VPackOptions::Defaults; VPackOptions resultOptions = VPackOptions::Defaults;
resultOptions.customTypeHandler = transactionContext->orderCustomTypeHandler().get(); resultOptions.customTypeHandler = transactionContext->orderCustomTypeHandler().get();
std::vector<IndexLookupResult> batch; std::vector<DocumentIdentifierToken> batch;
ManagedDocumentResult mmdr; ManagedDocumentResult mmdr;
VPackBuilder resultBuilder; VPackBuilder resultBuilder;
resultBuilder.openArray(); resultBuilder.openArray();
@ -262,8 +262,7 @@ static void JS_AllQuery(v8::FunctionCallbackInfo<v8::Value> const& args) {
opCursor->getMoreMptr(batch); opCursor->getMoreMptr(batch);
// We only need this one call, limit == batchsize // We only need this one call, limit == batchsize
for (auto const& it : batch) { for (auto const& it : batch) {
TRI_voc_rid_t revisionId = it.revisionId(); if (collection->readDocument(&trx, mmdr, it)) {
if (collection->readRevision(&trx, mmdr, revisionId)) {
resultBuilder.add(VPackSlice(mmdr.vpack())); resultBuilder.add(VPackSlice(mmdr.vpack()));
} }
} }

View File

@ -48,6 +48,7 @@
#include "MMFiles/MMFilesPersistentIndex.h" #include "MMFiles/MMFilesPersistentIndex.h"
#include "MMFiles/MMFilesPrimaryIndex.h" #include "MMFiles/MMFilesPrimaryIndex.h"
#include "MMFiles/MMFilesSkiplistIndex.h" #include "MMFiles/MMFilesSkiplistIndex.h"
#include "MMFiles/MMFilesToken.h"
#include "MMFiles/MMFilesWalMarker.h" #include "MMFiles/MMFilesWalMarker.h"
#include "MMFiles/MMFilesWalSlots.h" #include "MMFiles/MMFilesWalSlots.h"
#include "StorageEngine/StorageEngine.h" #include "StorageEngine/StorageEngine.h"
@ -3766,6 +3767,13 @@ bool LogicalCollection::readRevisionConditional(Transaction* trx,
return false; 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<MMFilesToken const*>(&token);
return readRevision(trx, result, tkn->revisionId());
}
void LogicalCollection::insertRevision(TRI_voc_rid_t revisionId, void LogicalCollection::insertRevision(TRI_voc_rid_t revisionId,
uint8_t const* dataptr, uint8_t const* dataptr,
TRI_voc_fid_t fid, bool isInWal) { TRI_voc_fid_t fid, bool isInWal) {

View File

@ -25,6 +25,7 @@
#define ARANGOD_VOCBASE_LOGICAL_COLLECTION_H 1 #define ARANGOD_VOCBASE_LOGICAL_COLLECTION_H 1
#include "Basics/Common.h" #include "Basics/Common.h"
#include "StorageEngine/StorageEngine.h"
#include "VocBase/PhysicalCollection.h" #include "VocBase/PhysicalCollection.h"
#include "VocBase/voc-types.h" #include "VocBase/voc-types.h"
#include "VocBase/vocbase.h" #include "VocBase/vocbase.h"
@ -384,6 +385,7 @@ class LogicalCollection {
bool readRevision(arangodb::Transaction*, ManagedDocumentResult& result, TRI_voc_rid_t revisionId); 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 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 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); void updateRevision(TRI_voc_rid_t revisionId, uint8_t const* dataptr, TRI_voc_fid_t fid, bool isInWal);

View File

@ -78,8 +78,7 @@ bool SingleServerEdgeCursor::next(std::vector<VPackSlice>& result,
_cachePos++; _cachePos++;
if (_cachePos < _cache.size()) { if (_cachePos < _cache.size()) {
LogicalCollection* collection = _cursors[_currentCursor][_currentSubCursor]->collection(); LogicalCollection* collection = _cursors[_currentCursor][_currentSubCursor]->collection();
TRI_voc_rid_t revisionId = _cache[_cachePos].revisionId(); if (collection->readDocument(_trx, *_mmdr, _cache[_cachePos])) {
if (collection->readRevision(_trx, *_mmdr, revisionId)) {
result.emplace_back(_mmdr->vpack()); result.emplace_back(_mmdr->vpack());
} }
if (_internalCursorMapping != nullptr) { if (_internalCursorMapping != nullptr) {
@ -128,8 +127,7 @@ bool SingleServerEdgeCursor::next(std::vector<VPackSlice>& result,
TRI_ASSERT(_cachePos < _cache.size()); TRI_ASSERT(_cachePos < _cache.size());
LogicalCollection* collection = cursor->collection(); LogicalCollection* collection = cursor->collection();
TRI_voc_rid_t revisionId = _cache[_cachePos].revisionId(); if (collection->readDocument(_trx, *_mmdr, _cache[_cachePos])) {
if (collection->readRevision(_trx, *_mmdr, revisionId)) {
result.emplace_back(_mmdr->vpack()); result.emplace_back(_mmdr->vpack());
} }
if (_internalCursorMapping != nullptr) { if (_internalCursorMapping != nullptr) {
@ -162,8 +160,7 @@ bool SingleServerEdgeCursor::readAll(std::unordered_set<VPackSlice>& result,
// because the cursor expect's it to be filled. // because the cursor expect's it to be filled.
cursor->getMoreMptr(_cache); cursor->getMoreMptr(_cache);
for (auto const& element : _cache) { for (auto const& element : _cache) {
TRI_voc_rid_t revisionId = element.revisionId(); if (collection->readDocument(_trx, *_mmdr, element)) {
if (collection->readRevision(_trx, *_mmdr, revisionId)) {
result.emplace(_mmdr->vpack()); result.emplace(_mmdr->vpack());
} }
} }

View File

@ -48,7 +48,7 @@ class SingleServerEdgeCursor : public EdgeCursor {
std::vector<std::vector<OperationCursor*>> _cursors; std::vector<std::vector<OperationCursor*>> _cursors;
size_t _currentCursor; size_t _currentCursor;
size_t _currentSubCursor; size_t _currentSubCursor;
std::vector<IndexLookupResult> _cache; std::vector<DocumentIdentifierToken> _cache;
size_t _cachePos; size_t _cachePos;
std::vector<size_t> const* _internalCursorMapping; std::vector<size_t> const* _internalCursorMapping;