mirror of https://gitee.com/bigwinds/arangodb
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:
parent
f1df7ae882
commit
2133b1448c
|
@ -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()) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 (...) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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()};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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");
|
||||||
|
|
||||||
|
}
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue