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() {}
|
||||
|
||||
void CollectionScanner::scan(std::vector<arangodb::IndexLookupResult>& result, size_t batchSize) {
|
||||
void CollectionScanner::scan(std::vector<arangodb::DocumentIdentifierToken>& result, size_t batchSize) {
|
||||
result.clear();
|
||||
|
||||
if (!_cursor->hasMore()) {
|
||||
|
|
|
@ -40,7 +40,7 @@ class CollectionScanner {
|
|||
|
||||
~CollectionScanner();
|
||||
|
||||
void scan(std::vector<IndexLookupResult>& result, size_t batchSize);
|
||||
void scan(std::vector<DocumentIdentifierToken>& result, size_t batchSize);
|
||||
|
||||
void reset();
|
||||
|
||||
|
|
|
@ -250,8 +250,7 @@ AqlItemBlock* EnumerateCollectionBlock::getSome(size_t, // atLeast,
|
|||
// The result is in the first variable of this depth,
|
||||
// we do not need to do a lookup in getPlanNode()->_registerPlan->varInfo,
|
||||
// but can just take cur->getNrRegs() as registerId:
|
||||
TRI_voc_rid_t revisionId = _documents[_position].revisionId();
|
||||
if (c->readRevision(_trx, *_mmdr, revisionId)) {
|
||||
if (c->readDocument(_trx, *_mmdr, _documents[_position])) {
|
||||
uint8_t const* vpack = _mmdr->vpack();
|
||||
res->setValue(j, static_cast<arangodb::aql::RegisterId>(curRegs), AqlValue(vpack, AqlValueFromManagedDocument()));
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ class EnumerateCollectionBlock : public ExecutionBlock {
|
|||
CollectionScanner _scanner;
|
||||
|
||||
/// @brief document buffer
|
||||
std::vector<IndexLookupResult> _documents;
|
||||
std::vector<DocumentIdentifierToken> _documents;
|
||||
|
||||
/// @brief iterator over documents
|
||||
size_t _position;
|
||||
|
|
|
@ -430,18 +430,17 @@ bool IndexBlock::readIndex(size_t atMost) {
|
|||
|
||||
if (hasMultipleIndexes) {
|
||||
for (auto const& element : _result) {
|
||||
TRI_voc_rid_t revisionId = element.revisionId();
|
||||
if (collection->readRevision(_trx, *_mmdr, revisionId)) {
|
||||
if (collection->readDocument(_trx, *_mmdr, element)) {
|
||||
uint8_t const* vpack = _mmdr->vpack(); //back();
|
||||
// uniqueness checks
|
||||
if (!isLastIndex) {
|
||||
// insert & check for duplicates in one go
|
||||
if (_alreadyReturned.emplace(revisionId).second) {
|
||||
if (_alreadyReturned.emplace(element).second) {
|
||||
_documents.emplace_back(vpack);
|
||||
}
|
||||
} else {
|
||||
// only check for duplicates
|
||||
if (_alreadyReturned.find(revisionId) == _alreadyReturned.end()) {
|
||||
if (_alreadyReturned.find(element) == _alreadyReturned.end()) {
|
||||
_documents.emplace_back(vpack);
|
||||
}
|
||||
}
|
||||
|
@ -449,8 +448,7 @@ bool IndexBlock::readIndex(size_t atMost) {
|
|||
}
|
||||
} else {
|
||||
for (auto const& element : _result) {
|
||||
TRI_voc_rid_t revisionId = element.revisionId();
|
||||
if (collection->readRevision(_trx, *_mmdr, revisionId)) {
|
||||
if (collection->readDocument(_trx, *_mmdr, element)) {
|
||||
uint8_t const* vpack = _mmdr->vpack(); //back();
|
||||
_documents.emplace_back(vpack);
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ class IndexBlock : public ExecutionBlock {
|
|||
Collection const* _collection;
|
||||
|
||||
/// @brief document result
|
||||
std::vector<IndexLookupResult> _result;
|
||||
std::vector<DocumentIdentifierToken> _result;
|
||||
|
||||
/// @brief document buffer
|
||||
std::vector<arangodb::velocypack::Slice> _documents;
|
||||
|
@ -149,7 +149,7 @@ class IndexBlock : public ExecutionBlock {
|
|||
AstNode const* _condition;
|
||||
|
||||
/// @brief set of already returned documents. Used to make the result distinct
|
||||
std::unordered_set<TRI_voc_rid_t> _alreadyReturned;
|
||||
std::unordered_set<DocumentIdentifierToken> _alreadyReturned;
|
||||
|
||||
/// @brief whether or not at least one expression uses v8
|
||||
bool _hasV8Expression;
|
||||
|
|
|
@ -70,7 +70,7 @@ struct ConstDistanceExpanderLocal {
|
|||
bool _isReverse;
|
||||
|
||||
/// @brief Local cursor vector
|
||||
std::vector<IndexLookupResult> _cursor;
|
||||
std::vector<DocumentIdentifierToken> _cursor;
|
||||
|
||||
public:
|
||||
ConstDistanceExpanderLocal(ShortestPathBlock const* block,
|
||||
|
@ -96,10 +96,9 @@ struct ConstDistanceExpanderLocal {
|
|||
_cursor.clear();
|
||||
LogicalCollection* collection = edgeCursor->collection();
|
||||
while (edgeCursor->hasMore()) {
|
||||
edgeCursor->getMoreMptr(_cursor, UINT64_MAX);
|
||||
edgeCursor->getMoreMptr(_cursor, 1000);
|
||||
for (auto const& element : _cursor) {
|
||||
TRI_voc_rid_t revisionId = element.revisionId();
|
||||
if (collection->readRevision(_block->transaction(), *mmdr, revisionId)) {
|
||||
if (collection->readDocument(_block->transaction(), *mmdr, element)) {
|
||||
VPackSlice edge(mmdr->vpack());
|
||||
VPackSlice from =
|
||||
arangodb::Transaction::extractFromFromDocument(edge);
|
||||
|
@ -220,7 +219,7 @@ struct EdgeWeightExpanderLocal {
|
|||
void operator()(VPackSlice const& source,
|
||||
std::vector<ArangoDBPathFinder::Step*>& result) {
|
||||
ManagedDocumentResult* mmdr = _block->_mmdr.get();
|
||||
std::vector<IndexLookupResult> cursor;
|
||||
std::vector<DocumentIdentifierToken> cursor;
|
||||
std::unique_ptr<arangodb::OperationCursor> edgeCursor;
|
||||
std::unordered_map<VPackSlice, size_t> candidates;
|
||||
for (auto const& edgeCollection : _block->_collectionInfos) {
|
||||
|
@ -240,10 +239,9 @@ struct EdgeWeightExpanderLocal {
|
|||
cursor.clear();
|
||||
LogicalCollection* collection = edgeCursor->collection();
|
||||
while (edgeCursor->hasMore()) {
|
||||
edgeCursor->getMoreMptr(cursor, UINT64_MAX);
|
||||
edgeCursor->getMoreMptr(cursor, 1000);
|
||||
for (auto const& element : cursor) {
|
||||
TRI_voc_rid_t revisionId = element.revisionId();
|
||||
if (collection->readRevision(_block->transaction(), *mmdr, revisionId)) {
|
||||
if (collection->readDocument(_block->transaction(), *mmdr, element)) {
|
||||
VPackSlice edge(mmdr->vpack());
|
||||
VPackSlice from =
|
||||
arangodb::Transaction::extractFromFromDocument(edge);
|
||||
|
|
|
@ -51,16 +51,16 @@ IndexIterator::~IndexIterator() {
|
|||
}
|
||||
|
||||
/// @brief default implementation for next
|
||||
IndexLookupResult IndexIterator::next() { return IndexLookupResult(); }
|
||||
DocumentIdentifierToken IndexIterator::next() { return DocumentIdentifierToken(); }
|
||||
|
||||
/// @brief default implementation for nextBabies
|
||||
void IndexIterator::nextBabies(std::vector<IndexLookupResult>& result, size_t batchSize) {
|
||||
void IndexIterator::nextBabies(std::vector<DocumentIdentifierToken>& result, size_t batchSize) {
|
||||
result.clear();
|
||||
|
||||
if (batchSize > 0) {
|
||||
while (true) {
|
||||
IndexLookupResult element = next();
|
||||
if (!element) {
|
||||
DocumentIdentifierToken element = next();
|
||||
if (element == 0) {
|
||||
return;
|
||||
}
|
||||
result.emplace_back(element);
|
||||
|
@ -79,7 +79,7 @@ void IndexIterator::reset() {}
|
|||
void IndexIterator::skip(uint64_t count, uint64_t& skipped) {
|
||||
// Skip the first count-many entries
|
||||
// TODO: Can be improved
|
||||
while (count > 0 && next()) {
|
||||
while (count > 0 && next() != 0) {
|
||||
--count;
|
||||
skipped++;
|
||||
}
|
||||
|
@ -88,16 +88,16 @@ void IndexIterator::skip(uint64_t count, uint64_t& skipped) {
|
|||
/// @brief Get the next element
|
||||
/// If one iterator is exhausted, the next one is used.
|
||||
/// A nullptr indicates that all iterators are exhausted
|
||||
IndexLookupResult MultiIndexIterator::next() {
|
||||
DocumentIdentifierToken MultiIndexIterator::next() {
|
||||
if (_current == nullptr) {
|
||||
return IndexLookupResult();
|
||||
return DocumentIdentifierToken();
|
||||
}
|
||||
IndexLookupResult next = _current->next();
|
||||
while (!next) {
|
||||
DocumentIdentifierToken next = _current->next();
|
||||
while (next == 0) {
|
||||
_currentIdx++;
|
||||
if (_currentIdx >= _iterators.size()) {
|
||||
_current = nullptr;
|
||||
return IndexLookupResult();
|
||||
return DocumentIdentifierToken();
|
||||
}
|
||||
_current = _iterators.at(_currentIdx);
|
||||
next = _current->next();
|
||||
|
@ -108,7 +108,7 @@ IndexLookupResult MultiIndexIterator::next() {
|
|||
/// @brief Get the next limit many elements
|
||||
/// If one iterator is exhausted, the next one will be used.
|
||||
/// An empty result vector indicates that all iterators are exhausted
|
||||
void MultiIndexIterator::nextBabies(std::vector<IndexLookupResult>& result, size_t limit) {
|
||||
void MultiIndexIterator::nextBabies(std::vector<DocumentIdentifierToken>& result, size_t limit) {
|
||||
result.clear();
|
||||
|
||||
if (_current == nullptr) {
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
//
|
||||
// typeName() returns a string descibing the type of the indexIterator
|
||||
//
|
||||
// The next() function of the IndexIterator returns IndexLookupResults that are
|
||||
// The next() function of the IndexIterator returns DocumentIdentifierTokens that are
|
||||
// created from RevisionIds. If there is nothing more to return a default
|
||||
// constructed IndesLookupResult is returend.
|
||||
//
|
||||
|
@ -51,6 +51,7 @@
|
|||
#include "Basics/Common.h"
|
||||
#include "Cluster/ServerState.h"
|
||||
#include "Indexes/IndexLookupContext.h"
|
||||
#include "StorageEngine/StorageEngine.h"
|
||||
#include "VocBase/ManagedDocumentResult.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
|
@ -59,24 +60,6 @@ class Index;
|
|||
class LogicalCollection;
|
||||
class Transaction;
|
||||
|
||||
class IndexLookupResult {
|
||||
public:
|
||||
constexpr IndexLookupResult() : _revisionId(0) {}
|
||||
explicit IndexLookupResult(TRI_voc_rid_t revisionId) : _revisionId(revisionId) {}
|
||||
IndexLookupResult(IndexLookupResult const& other) : _revisionId(other._revisionId) {}
|
||||
IndexLookupResult& operator=(IndexLookupResult const& other) {
|
||||
_revisionId = other._revisionId;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline operator bool() const { return _revisionId != 0; }
|
||||
|
||||
inline TRI_voc_rid_t revisionId() const { return _revisionId; }
|
||||
|
||||
private:
|
||||
TRI_voc_rid_t _revisionId;
|
||||
};
|
||||
|
||||
/// @brief a base class to iterate over the index. An iterator is requested
|
||||
/// at the index itself
|
||||
class IndexIterator {
|
||||
|
@ -94,9 +77,9 @@ class IndexIterator {
|
|||
LogicalCollection* collection() const { return _collection; }
|
||||
arangodb::Transaction* transaction() const { return _trx; }
|
||||
|
||||
virtual IndexLookupResult next();
|
||||
virtual DocumentIdentifierToken next();
|
||||
|
||||
virtual void nextBabies(std::vector<IndexLookupResult>&, size_t);
|
||||
virtual void nextBabies(std::vector<DocumentIdentifierToken>&, size_t);
|
||||
|
||||
virtual void reset();
|
||||
|
||||
|
@ -120,9 +103,9 @@ class EmptyIndexIterator final : public IndexIterator {
|
|||
|
||||
char const* typeName() const override { return "empty-index-iterator"; }
|
||||
|
||||
IndexLookupResult next() override { return IndexLookupResult(); }
|
||||
DocumentIdentifierToken next() override { return DocumentIdentifierToken(); }
|
||||
|
||||
void nextBabies(std::vector<IndexLookupResult>&, size_t) override {}
|
||||
void nextBabies(std::vector<DocumentIdentifierToken>&, size_t) override {}
|
||||
|
||||
void reset() override {}
|
||||
|
||||
|
@ -161,12 +144,12 @@ class MultiIndexIterator final : public IndexIterator {
|
|||
/// @brief Get the next element
|
||||
/// If one iterator is exhausted, the next one is used.
|
||||
/// A nullptr indicates that all iterators are exhausted
|
||||
IndexLookupResult next() override;
|
||||
DocumentIdentifierToken next() override;
|
||||
|
||||
/// @brief Get at most the next limit many elements
|
||||
/// If one iterator is exhausted, the next one will be used.
|
||||
/// An empty result vector indicates that all iterators are exhausted
|
||||
void nextBabies(std::vector<IndexLookupResult>&, size_t) override;
|
||||
void nextBabies(std::vector<DocumentIdentifierToken>&, size_t) override;
|
||||
|
||||
/// @brief Reset the cursor
|
||||
/// This will reset ALL internal iterators and start all over again
|
||||
|
|
|
@ -45,9 +45,9 @@ class IndexLookupContext {
|
|||
|
||||
~IndexLookupContext() {}
|
||||
|
||||
uint8_t const* lookup(TRI_voc_rid_t revisionId) {
|
||||
uint8_t const* lookup(DocumentIdentifierToken token) {
|
||||
try {
|
||||
if (_collection->readRevision(_trx, *_result, revisionId)) {
|
||||
if (_collection->readDocument(_trx, *_result, token)) {
|
||||
return _result->vpack();
|
||||
}
|
||||
} catch (...) {
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "Basics/hashes.h"
|
||||
#include "Indexes/IndexLookupContext.h"
|
||||
#include "Indexes/SimpleAttributeEqualityMatcher.h"
|
||||
#include "MMFiles/MMFilesToken.h"
|
||||
#include "Utils/CollectionNameResolver.h"
|
||||
#include "Utils/Transaction.h"
|
||||
#include "Utils/TransactionContext.h"
|
||||
|
@ -126,7 +127,7 @@ MMFilesEdgeIndexIterator::~MMFilesEdgeIndexIterator() {
|
|||
}
|
||||
}
|
||||
|
||||
IndexLookupResult MMFilesEdgeIndexIterator::next() {
|
||||
DocumentIdentifierToken MMFilesEdgeIndexIterator::next() {
|
||||
while (_iterator.valid()) {
|
||||
if (_buffer.empty()) {
|
||||
// We start a new lookup
|
||||
|
@ -150,17 +151,17 @@ IndexLookupResult MMFilesEdgeIndexIterator::next() {
|
|||
} else {
|
||||
_lastElement = _buffer.back();
|
||||
// found something
|
||||
return IndexLookupResult(_buffer[_posInBuffer++].revisionId());
|
||||
return MMFilesToken{_buffer[_posInBuffer++].revisionId()};
|
||||
}
|
||||
|
||||
// found no result. now go to next lookup value in _keys
|
||||
_iterator.next();
|
||||
}
|
||||
|
||||
return IndexLookupResult();
|
||||
return MMFilesToken{};
|
||||
}
|
||||
|
||||
void MMFilesEdgeIndexIterator::nextBabies(std::vector<IndexLookupResult>& buffer, size_t limit) {
|
||||
void MMFilesEdgeIndexIterator::nextBabies(std::vector<DocumentIdentifierToken>& buffer, size_t limit) {
|
||||
size_t atMost = _batchSize > limit ? limit : _batchSize;
|
||||
|
||||
if (atMost == 0) {
|
||||
|
@ -187,7 +188,7 @@ void MMFilesEdgeIndexIterator::nextBabies(std::vector<IndexLookupResult>& buffer
|
|||
}
|
||||
|
||||
for (auto& it : _buffer) {
|
||||
buffer.emplace_back(it.revisionId());
|
||||
buffer.emplace_back(MMFilesToken(it.revisionId()));
|
||||
}
|
||||
|
||||
if (_buffer.empty()) {
|
||||
|
@ -223,28 +224,28 @@ AnyDirectionMMFilesEdgeIndexIterator::AnyDirectionMMFilesEdgeIndexIterator(Logic
|
|||
_inbound(inboundIterator),
|
||||
_useInbound(false) {}
|
||||
|
||||
IndexLookupResult AnyDirectionMMFilesEdgeIndexIterator::next() {
|
||||
IndexLookupResult res;
|
||||
DocumentIdentifierToken AnyDirectionMMFilesEdgeIndexIterator::next() {
|
||||
DocumentIdentifierToken res;
|
||||
if (_useInbound) {
|
||||
do {
|
||||
res = _inbound->next();
|
||||
} while (res && _seen.find(res.revisionId()) != _seen.end());
|
||||
} while (res != 0 && _seen.find(res) != _seen.end());
|
||||
return res;
|
||||
}
|
||||
res = _outbound->next();
|
||||
if (!res) {
|
||||
if (res == 0) {
|
||||
_useInbound = true;
|
||||
return next();
|
||||
}
|
||||
_seen.emplace(res.revisionId());
|
||||
_seen.emplace(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
void AnyDirectionMMFilesEdgeIndexIterator::nextBabies(std::vector<IndexLookupResult>& result, size_t limit) {
|
||||
void AnyDirectionMMFilesEdgeIndexIterator::nextBabies(std::vector<DocumentIdentifierToken>& result, size_t limit) {
|
||||
result.clear();
|
||||
for (size_t i = 0; i < limit; ++i) {
|
||||
IndexLookupResult res = next();
|
||||
if (!res) {
|
||||
DocumentIdentifierToken res = next();
|
||||
if (res == 0) {
|
||||
return;
|
||||
}
|
||||
result.emplace_back(res);
|
||||
|
|
|
@ -53,9 +53,9 @@ class MMFilesEdgeIndexIterator final : public IndexIterator {
|
|||
|
||||
char const* typeName() const override { return "edge-index-iterator"; }
|
||||
|
||||
IndexLookupResult next() override;
|
||||
DocumentIdentifierToken next() override;
|
||||
|
||||
void nextBabies(std::vector<IndexLookupResult>&, size_t) override;
|
||||
void nextBabies(std::vector<DocumentIdentifierToken>&, size_t) override;
|
||||
|
||||
void reset() override;
|
||||
|
||||
|
@ -85,16 +85,16 @@ class AnyDirectionMMFilesEdgeIndexIterator final : public IndexIterator {
|
|||
|
||||
char const* typeName() const override { return "any-edge-index-iterator"; }
|
||||
|
||||
IndexLookupResult next() override;
|
||||
DocumentIdentifierToken next() override;
|
||||
|
||||
void nextBabies(std::vector<IndexLookupResult>&, size_t) override;
|
||||
void nextBabies(std::vector<DocumentIdentifierToken>&, size_t) override;
|
||||
|
||||
void reset() override;
|
||||
|
||||
private:
|
||||
MMFilesEdgeIndexIterator* _outbound;
|
||||
MMFilesEdgeIndexIterator* _inbound;
|
||||
std::unordered_set<TRI_voc_rid_t> _seen;
|
||||
std::unordered_set<DocumentIdentifierToken> _seen;
|
||||
bool _useInbound;
|
||||
};
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "Basics/StringRef.h"
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "MMFiles/MMFilesToken.h"
|
||||
#include "VocBase/transaction.h"
|
||||
|
||||
using namespace arangodb;
|
||||
|
@ -85,7 +86,7 @@ void MMFilesGeoIndexIterator::evaluateCondition() {
|
|||
}
|
||||
}
|
||||
|
||||
IndexLookupResult MMFilesGeoIndexIterator::next() {
|
||||
DocumentIdentifierToken MMFilesGeoIndexIterator::next() {
|
||||
if (!_cursor) {
|
||||
createCursor(_lat, _lon);
|
||||
}
|
||||
|
@ -98,14 +99,14 @@ IndexLookupResult MMFilesGeoIndexIterator::next() {
|
|||
)
|
||||
{
|
||||
auto revision = ::MMFilesGeoIndex::toRevision(coords->coordinates[0].data);
|
||||
return IndexLookupResult{revision};
|
||||
return MMFilesToken{revision};
|
||||
}
|
||||
}
|
||||
// if there are no more results we return the default constructed IndexLookupResult
|
||||
return IndexLookupResult{};
|
||||
return MMFilesToken{};
|
||||
}
|
||||
|
||||
void MMFilesGeoIndexIterator::nextBabies(std::vector<IndexLookupResult>& result, size_t batchSize) {
|
||||
void MMFilesGeoIndexIterator::nextBabies(std::vector<DocumentIdentifierToken>& result, size_t batchSize) {
|
||||
if (!_cursor) {
|
||||
createCursor(_lat, _lon);
|
||||
|
||||
|
@ -135,7 +136,8 @@ void MMFilesGeoIndexIterator::nextBabies(std::vector<IndexLookupResult>& result,
|
|||
withDistances = true;
|
||||
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;
|
||||
|
||||
|
@ -197,7 +199,7 @@ void MMFilesGeoIndexIterator::nextBabies(std::vector<IndexLookupResult>& result,
|
|||
result.reserve(numDocs);
|
||||
|
||||
for (size_t i = 0; i < numDocs; ++i) {
|
||||
result.emplace_back(IndexLookupResult(::MMFilesGeoIndex::toRevision(coords->coordinates[i].data)));
|
||||
result.emplace_back(MMFilesToken(::MMFilesGeoIndex::toRevision(coords->coordinates[i].data)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,9 +56,9 @@ class MMFilesGeoIndexIterator final : public IndexIterator {
|
|||
|
||||
char const* typeName() const override { return "geo-index-iterator"; }
|
||||
|
||||
IndexLookupResult next() override;
|
||||
DocumentIdentifierToken next() override;
|
||||
|
||||
void nextBabies(std::vector<IndexLookupResult>&, size_t) override;
|
||||
void nextBabies(std::vector<DocumentIdentifierToken>&, size_t) override;
|
||||
|
||||
void reset() override;
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "Basics/VelocyPackHelper.h"
|
||||
#include "Indexes/IndexLookupContext.h"
|
||||
#include "Indexes/SimpleAttributeEqualityMatcher.h"
|
||||
#include "MMFiles/MMFilesToken.h"
|
||||
#include "Utils/TransactionContext.h"
|
||||
#include "VocBase/LogicalCollection.h"
|
||||
#include "VocBase/transaction.h"
|
||||
|
@ -294,12 +295,12 @@ MMFilesHashIndexIterator::MMFilesHashIndexIterator(LogicalCollection* collection
|
|||
_index->lookup(_trx, _lookups.lookup(), _buffer);
|
||||
}
|
||||
|
||||
IndexLookupResult MMFilesHashIndexIterator::next() {
|
||||
DocumentIdentifierToken MMFilesHashIndexIterator::next() {
|
||||
while (true) {
|
||||
if (_posInBuffer >= _buffer.size()) {
|
||||
if (!_lookups.hasAndGetNext()) {
|
||||
// we're at the end of the lookup values
|
||||
return IndexLookupResult();
|
||||
return MMFilesToken{};
|
||||
}
|
||||
|
||||
// We have to refill the buffer
|
||||
|
@ -311,12 +312,12 @@ IndexLookupResult MMFilesHashIndexIterator::next() {
|
|||
|
||||
if (!_buffer.empty()) {
|
||||
// found something
|
||||
return IndexLookupResult(_buffer[_posInBuffer++]->revisionId());
|
||||
return MMFilesToken{_buffer[_posInBuffer++]->revisionId()};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MMFilesHashIndexIterator::nextBabies(std::vector<IndexLookupResult>& result, size_t atMost) {
|
||||
void MMFilesHashIndexIterator::nextBabies(std::vector<DocumentIdentifierToken>& result, size_t atMost) {
|
||||
result.clear();
|
||||
|
||||
if (atMost == 0) {
|
||||
|
@ -347,7 +348,7 @@ void MMFilesHashIndexIterator::nextBabies(std::vector<IndexLookupResult>& result
|
|||
}
|
||||
|
||||
for (size_t i = _posInBuffer; i < atMost + _posInBuffer; ++i) {
|
||||
result.emplace_back(_buffer[i]->revisionId());
|
||||
result.emplace_back(MMFilesToken{_buffer[i]->revisionId()});
|
||||
}
|
||||
_posInBuffer += atMost;
|
||||
return;
|
||||
|
@ -383,12 +384,12 @@ MMFilesHashIndexIteratorVPack::~MMFilesHashIndexIteratorVPack() {
|
|||
}
|
||||
}
|
||||
|
||||
IndexLookupResult MMFilesHashIndexIteratorVPack::next() {
|
||||
DocumentIdentifierToken MMFilesHashIndexIteratorVPack::next() {
|
||||
while (true) {
|
||||
if (_posInBuffer >= _buffer.size()) {
|
||||
if (!_iterator.valid()) {
|
||||
// we're at the end of the lookup values
|
||||
return IndexLookupResult();
|
||||
return MMFilesToken{};
|
||||
}
|
||||
|
||||
// We have to refill the buffer
|
||||
|
@ -406,7 +407,7 @@ IndexLookupResult MMFilesHashIndexIteratorVPack::next() {
|
|||
|
||||
if (!_buffer.empty()) {
|
||||
// found something
|
||||
return IndexLookupResult(_buffer[_posInBuffer++]->revisionId());
|
||||
return MMFilesToken{_buffer[_posInBuffer++]->revisionId()};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,9 +90,9 @@ class MMFilesHashIndexIterator final : public IndexIterator {
|
|||
|
||||
char const* typeName() const override { return "hash-index-iterator"; }
|
||||
|
||||
IndexLookupResult next() override;
|
||||
DocumentIdentifierToken next() override;
|
||||
|
||||
void nextBabies(std::vector<IndexLookupResult>&, size_t) override;
|
||||
void nextBabies(std::vector<DocumentIdentifierToken>&, size_t) override;
|
||||
|
||||
void reset() override;
|
||||
|
||||
|
@ -117,7 +117,7 @@ class MMFilesHashIndexIteratorVPack final : public IndexIterator {
|
|||
|
||||
char const* typeName() const override { return "hash-index-iterator-vpack"; }
|
||||
|
||||
IndexLookupResult next() override;
|
||||
DocumentIdentifierToken next() override;
|
||||
|
||||
void reset() override;
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "MMFilesIndexElement.h"
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
#include "Indexes/IndexLookupContext.h"
|
||||
#include "MMFiles/MMFilesToken.h"
|
||||
|
||||
using namespace arangodb;
|
||||
|
||||
|
@ -57,7 +58,7 @@ arangodb::velocypack::Slice MMFilesHashIndexElement::slice(IndexLookupContext* c
|
|||
if (offset == 0) {
|
||||
return basics::VelocyPackHelper::NullValue();
|
||||
}
|
||||
uint8_t const* vpack = context->lookup(_revisionId);
|
||||
uint8_t const* vpack = context->lookup(MMFilesToken{_revisionId});
|
||||
if (vpack == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND);
|
||||
}
|
||||
|
@ -133,7 +134,7 @@ arangodb::velocypack::Slice MMFilesSkiplistIndexElement::slice(IndexLookupContex
|
|||
if (offset == 0) {
|
||||
return basics::VelocyPackHelper::NullValue();
|
||||
}
|
||||
uint8_t const* vpack = context->lookup(_revisionId);
|
||||
uint8_t const* vpack = context->lookup(MMFilesToken{_revisionId});
|
||||
if (vpack == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND);
|
||||
}
|
||||
|
@ -149,7 +150,7 @@ uint64_t MMFilesSimpleIndexElement::hash(arangodb::velocypack::Slice const& valu
|
|||
}
|
||||
|
||||
VPackSlice MMFilesSimpleIndexElement::slice(IndexLookupContext* context) const {
|
||||
uint8_t const* vpack = context->lookup(_revisionId);
|
||||
uint8_t const* vpack = context->lookup(MMFilesToken{_revisionId});
|
||||
if (vpack == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "MMFiles/MMFilesPrimaryIndex.h"
|
||||
#include "MMFiles/MMFilesPersistentIndexFeature.h"
|
||||
#include "MMFiles/MMFilesPersistentIndexKeyComparator.h"
|
||||
#include "MMFiles/MMFilesToken.h"
|
||||
#include "Utils/Transaction.h"
|
||||
#include "VocBase/LogicalCollection.h"
|
||||
|
||||
|
@ -137,13 +138,13 @@ void PersistentIndexIterator::reset() {
|
|||
}
|
||||
|
||||
/// @brief Get the next element in the index
|
||||
IndexLookupResult PersistentIndexIterator::next() {
|
||||
DocumentIdentifierToken PersistentIndexIterator::next() {
|
||||
auto comparator = RocksDBFeature::instance()->comparator();
|
||||
|
||||
while (true) {
|
||||
if (!_cursor->Valid()) {
|
||||
// We are exhausted already, sorry
|
||||
return IndexLookupResult();
|
||||
return MMFilesToken{};
|
||||
}
|
||||
|
||||
rocksdb::Slice key = _cursor->key();
|
||||
|
@ -154,7 +155,7 @@ IndexLookupResult PersistentIndexIterator::next() {
|
|||
|
||||
if (res < 0) {
|
||||
if (_reverse) {
|
||||
return IndexLookupResult();
|
||||
return MMFilesToken{};
|
||||
} else {
|
||||
_cursor->Next();
|
||||
}
|
||||
|
@ -164,7 +165,7 @@ IndexLookupResult PersistentIndexIterator::next() {
|
|||
res = comparator->Compare(key, rocksdb::Slice(_rightEndpoint->data(), _rightEndpoint->size()));
|
||||
// LOG(TRACE) << "comparing: " << VPackSlice(key.data() + PersistentIndex::keyPrefixSize()).toJson() << " with " << VPackSlice((char const*) _rightEndpoint->data() + PersistentIndex::keyPrefixSize()).toJson() << " - res: " << res;
|
||||
|
||||
IndexLookupResult doc;
|
||||
MMFilesToken doc;
|
||||
|
||||
if (res <= 0) {
|
||||
// get the value for _key, which is the last entry in the key array
|
||||
|
@ -179,7 +180,7 @@ IndexLookupResult PersistentIndexIterator::next() {
|
|||
// use primary index to lookup the document
|
||||
MMFilesSimpleIndexElement element = _primaryIndex->lookupKey(_trx, keySlice[n - 1]);
|
||||
if (element) {
|
||||
doc = IndexLookupResult(element.revisionId());
|
||||
doc = MMFilesToken{element.revisionId()};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,13 +192,13 @@ IndexLookupResult PersistentIndexIterator::next() {
|
|||
|
||||
if (res > 0) {
|
||||
if (!_probe) {
|
||||
return IndexLookupResult();
|
||||
return MMFilesToken{};
|
||||
}
|
||||
_probe = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (doc) {
|
||||
if (doc != 0) {
|
||||
return doc;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ class PersistentIndexIterator final : public IndexIterator {
|
|||
char const* typeName() const override { return "rocksdb-index-iterator"; }
|
||||
|
||||
/// @brief Get the next element in the index
|
||||
IndexLookupResult next() override;
|
||||
DocumentIdentifierToken next() override;
|
||||
|
||||
/// @brief Reset the cursor
|
||||
void reset() override;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "Basics/tri-strings.h"
|
||||
#include "Indexes/IndexLookupContext.h"
|
||||
#include "Indexes/SimpleAttributeEqualityMatcher.h"
|
||||
#include "MMFiles/MMFilesToken.h"
|
||||
#include "Utils/Transaction.h"
|
||||
#include "Utils/TransactionContext.h"
|
||||
#include "VocBase/LogicalCollection.h"
|
||||
|
@ -106,20 +107,20 @@ MMFilesPrimaryIndexIterator::~MMFilesPrimaryIndexIterator() {
|
|||
}
|
||||
}
|
||||
|
||||
IndexLookupResult MMFilesPrimaryIndexIterator::next() {
|
||||
DocumentIdentifierToken MMFilesPrimaryIndexIterator::next() {
|
||||
while (_iterator.valid()) {
|
||||
MMFilesSimpleIndexElement result = _index->lookupKey(_trx, _iterator.value());
|
||||
_iterator.next();
|
||||
|
||||
if (result) {
|
||||
// found a result
|
||||
return IndexLookupResult(result.revisionId());
|
||||
return MMFilesToken{result.revisionId()};
|
||||
}
|
||||
|
||||
// found no result. now go to next lookup value in _keys
|
||||
}
|
||||
|
||||
return IndexLookupResult();
|
||||
return MMFilesToken{};
|
||||
}
|
||||
|
||||
void MMFilesPrimaryIndexIterator::reset() { _iterator.reset(); }
|
||||
|
@ -132,7 +133,7 @@ AllIndexIterator::AllIndexIterator(LogicalCollection* collection,
|
|||
bool reverse)
|
||||
: IndexIterator(collection, trx, mmdr, index), _index(indexImpl), _reverse(reverse), _total(0) {}
|
||||
|
||||
IndexLookupResult AllIndexIterator::next() {
|
||||
DocumentIdentifierToken AllIndexIterator::next() {
|
||||
MMFilesSimpleIndexElement element;
|
||||
if (_reverse) {
|
||||
element = _index->findSequentialReverse(&_context, _position);
|
||||
|
@ -140,12 +141,12 @@ IndexLookupResult AllIndexIterator::next() {
|
|||
element = _index->findSequential(&_context, _position, _total);
|
||||
}
|
||||
if (element) {
|
||||
return IndexLookupResult(element.revisionId());
|
||||
return MMFilesToken{element.revisionId()};
|
||||
}
|
||||
return IndexLookupResult();
|
||||
return MMFilesToken{};
|
||||
}
|
||||
|
||||
void AllIndexIterator::nextBabies(std::vector<IndexLookupResult>& buffer, size_t limit) {
|
||||
void AllIndexIterator::nextBabies(std::vector<DocumentIdentifierToken>& buffer, size_t limit) {
|
||||
size_t atMost = limit;
|
||||
|
||||
buffer.clear();
|
||||
|
@ -154,9 +155,9 @@ void AllIndexIterator::nextBabies(std::vector<IndexLookupResult>& buffer, size_t
|
|||
}
|
||||
|
||||
while (atMost > 0) {
|
||||
IndexLookupResult result = next();
|
||||
DocumentIdentifierToken result = next();
|
||||
|
||||
if (!result) {
|
||||
if (result == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -173,12 +174,12 @@ AnyIndexIterator::AnyIndexIterator(LogicalCollection* collection, arangodb::Tran
|
|||
MMFilesPrimaryIndexImpl const* indexImpl)
|
||||
: IndexIterator(collection, trx, mmdr, index), _index(indexImpl), _step(0), _total(0) {}
|
||||
|
||||
IndexLookupResult AnyIndexIterator::next() {
|
||||
DocumentIdentifierToken AnyIndexIterator::next() {
|
||||
MMFilesSimpleIndexElement element = _index->findRandom(&_context, _initial, _position, _step, _total);
|
||||
if (element) {
|
||||
return IndexLookupResult(element.revisionId());
|
||||
return MMFilesToken{element.revisionId()};
|
||||
}
|
||||
return IndexLookupResult();
|
||||
return MMFilesToken{};
|
||||
}
|
||||
|
||||
void AnyIndexIterator::reset() {
|
||||
|
|
|
@ -54,7 +54,7 @@ class MMFilesPrimaryIndexIterator final : public IndexIterator {
|
|||
|
||||
char const* typeName() const override { return "primary-index-iterator"; }
|
||||
|
||||
IndexLookupResult next() override;
|
||||
DocumentIdentifierToken next() override;
|
||||
|
||||
void reset() override;
|
||||
|
||||
|
@ -77,9 +77,9 @@ class AllIndexIterator final : public IndexIterator {
|
|||
|
||||
char const* typeName() const override { return "all-index-iterator"; }
|
||||
|
||||
IndexLookupResult next() override;
|
||||
DocumentIdentifierToken next() override;
|
||||
|
||||
void nextBabies(std::vector<IndexLookupResult>&, size_t) override;
|
||||
void nextBabies(std::vector<DocumentIdentifierToken>&, size_t) override;
|
||||
|
||||
void reset() override;
|
||||
|
||||
|
@ -101,7 +101,7 @@ class AnyIndexIterator final : public IndexIterator {
|
|||
|
||||
char const* typeName() const override { return "any-index-iterator"; }
|
||||
|
||||
IndexLookupResult next() override;
|
||||
DocumentIdentifierToken next() override;
|
||||
|
||||
void reset() override;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "Basics/StaticStrings.h"
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
#include "Indexes/IndexLookupContext.h"
|
||||
#include "MMFiles/MMFilesToken.h"
|
||||
#include "Utils/Transaction.h"
|
||||
#include "VocBase/LogicalCollection.h"
|
||||
|
||||
|
@ -520,10 +521,10 @@ void MMFilesSkiplistIterator::reset() {
|
|||
}
|
||||
|
||||
/// @brief Get the next element in the skiplist
|
||||
IndexLookupResult MMFilesSkiplistIterator::next() {
|
||||
DocumentIdentifierToken MMFilesSkiplistIterator::next() {
|
||||
if (_cursor == nullptr) {
|
||||
// We are exhausted already, sorry
|
||||
return IndexLookupResult();
|
||||
return MMFilesToken{};
|
||||
}
|
||||
Node* tmp = _cursor;
|
||||
if (_reverse) {
|
||||
|
@ -541,7 +542,7 @@ IndexLookupResult MMFilesSkiplistIterator::next() {
|
|||
}
|
||||
TRI_ASSERT(tmp != nullptr);
|
||||
TRI_ASSERT(tmp->document() != nullptr);
|
||||
return IndexLookupResult(tmp->document()->revisionId());
|
||||
return MMFilesToken{tmp->document()->revisionId()};
|
||||
}
|
||||
|
||||
MMFilesSkiplistIterator2::MMFilesSkiplistIterator2(LogicalCollection* collection, arangodb::Transaction* trx,
|
||||
|
@ -602,10 +603,10 @@ void MMFilesSkiplistIterator2::reset() {
|
|||
}
|
||||
|
||||
/// @brief Get the next element in the skiplist
|
||||
IndexLookupResult MMFilesSkiplistIterator2::next() {
|
||||
DocumentIdentifierToken MMFilesSkiplistIterator2::next() {
|
||||
if (_cursor == nullptr) {
|
||||
// We are exhausted already, sorry
|
||||
return IndexLookupResult();
|
||||
return MMFilesToken{};
|
||||
}
|
||||
TRI_ASSERT(_currentInterval < _intervals.size());
|
||||
auto const& interval = _intervals[_currentInterval];
|
||||
|
@ -625,7 +626,7 @@ IndexLookupResult MMFilesSkiplistIterator2::next() {
|
|||
}
|
||||
TRI_ASSERT(tmp != nullptr);
|
||||
TRI_ASSERT(tmp->document() != nullptr);
|
||||
return IndexLookupResult(tmp->document()->revisionId());
|
||||
return MMFilesToken{tmp->document()->revisionId()};
|
||||
}
|
||||
|
||||
void MMFilesSkiplistIterator2::forwardCursor() {
|
||||
|
|
|
@ -196,7 +196,7 @@ class MMFilesSkiplistIterator final : public IndexIterator {
|
|||
char const* typeName() const override { return "skiplist-index-iterator"; }
|
||||
|
||||
/// @brief Get the next element in the skiplist
|
||||
IndexLookupResult next() override;
|
||||
DocumentIdentifierToken next() override;
|
||||
|
||||
/// @brief Reset the cursor
|
||||
void reset() override;
|
||||
|
@ -257,7 +257,7 @@ class MMFilesSkiplistIterator2 final : public IndexIterator {
|
|||
char const* typeName() const override { return "skiplist-index-iterator2"; }
|
||||
|
||||
/// @brief Get the next element in the skiplist
|
||||
IndexLookupResult next() override;
|
||||
DocumentIdentifierToken next() override;
|
||||
|
||||
/// @brief Reset the cursor
|
||||
void reset() override;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
std::vector<IndexLookupResult> batch;
|
||||
std::vector<DocumentIdentifierToken> batch;
|
||||
ManagedDocumentResult mmdr;
|
||||
auto collection = trx.documentCollection();
|
||||
while (cursor->hasMore()) {
|
||||
|
@ -99,8 +99,7 @@ bool RestEdgesHandler::getEdgesForVertexList(
|
|||
scannedIndex += batch.size();
|
||||
|
||||
for (auto const& it : batch) {
|
||||
TRI_voc_rid_t revisionId = it.revisionId();
|
||||
if (collection->readRevision(&trx, mmdr, revisionId)) {
|
||||
if (collection->readDocument(&trx, mmdr, it)) {
|
||||
result.add(VPackSlice(mmdr.vpack()));
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +128,7 @@ bool RestEdgesHandler::getEdgesForVertex(
|
|||
THROW_ARANGO_EXCEPTION(cursor->code);
|
||||
}
|
||||
|
||||
std::vector<IndexLookupResult> batch;
|
||||
std::vector<DocumentIdentifierToken> batch;
|
||||
ManagedDocumentResult mmdr;
|
||||
auto collection = trx.documentCollection();
|
||||
while (cursor->hasMore()) {
|
||||
|
@ -137,8 +136,7 @@ bool RestEdgesHandler::getEdgesForVertex(
|
|||
scannedIndex += batch.size();
|
||||
|
||||
for (auto const& it : batch) {
|
||||
TRI_voc_rid_t revisionId = it.revisionId();
|
||||
if (collection->readRevision(&trx, mmdr, revisionId)) {
|
||||
if (collection->readDocument(&trx, mmdr, it)) {
|
||||
result.add(VPackSlice(mmdr.vpack()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,33 @@ namespace arangodb {
|
|||
class LogicalCollection;
|
||||
class PhysicalCollection;
|
||||
|
||||
// @brief This token is handed out by Indexes and
|
||||
// is used by StorageEngines to return a document
|
||||
// Only specializations of this token can be created.
|
||||
|
||||
struct DocumentIdentifierToken {
|
||||
public:
|
||||
// TODO Replace by Engine::InvalidToken
|
||||
constexpr DocumentIdentifierToken() : _data(0) {}
|
||||
|
||||
~DocumentIdentifierToken() {}
|
||||
|
||||
inline bool operator==(DocumentIdentifierToken const& other) const { return _data == other._data; }
|
||||
|
||||
inline bool operator==(uint64_t const& other) const { return _data == other; }
|
||||
|
||||
inline bool operator!=(DocumentIdentifierToken const& other) const { return !(operator==(other)); }
|
||||
inline bool operator!=(uint64_t const& other) const { return !(operator==(other)); }
|
||||
|
||||
protected:
|
||||
explicit DocumentIdentifierToken(uint64_t data) : _data(data) {}
|
||||
|
||||
public:
|
||||
uint64_t _data;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class StorageEngine : public application_features::ApplicationFeature {
|
||||
public:
|
||||
|
||||
|
@ -249,4 +276,22 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<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
|
||||
|
|
|
@ -47,8 +47,8 @@ void OperationCursor::reset() {
|
|||
/// NOTE: This will throw on OUT_OF_MEMORY
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<IndexLookupResult> OperationCursor::getMoreMptr(uint64_t batchSize) {
|
||||
std::vector<IndexLookupResult> res;
|
||||
std::vector<DocumentIdentifierToken> OperationCursor::getMoreMptr(uint64_t batchSize) {
|
||||
std::vector<DocumentIdentifierToken> res;
|
||||
getMoreMptr(res, batchSize);
|
||||
return res;
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ std::vector<IndexLookupResult> OperationCursor::getMoreMptr(uint64_t batchSize)
|
|||
/// The caller shall NOT modify it.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void OperationCursor::getMoreMptr(std::vector<IndexLookupResult>& result,
|
||||
void OperationCursor::getMoreMptr(std::vector<DocumentIdentifierToken>& result,
|
||||
uint64_t batchSize) {
|
||||
if (!hasMore()) {
|
||||
TRI_ASSERT(false);
|
||||
|
|
|
@ -108,7 +108,7 @@ struct OperationCursor {
|
|||
/// 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
|
||||
|
@ -118,7 +118,7 @@ struct OperationCursor {
|
|||
/// 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.
|
||||
|
|
|
@ -1286,14 +1286,13 @@ OperationResult Transaction::anyLocal(std::string const& collectionName,
|
|||
{}, &mmdr, skip, limit, 1000, false);
|
||||
|
||||
LogicalCollection* collection = cursor->collection();
|
||||
std::vector<IndexLookupResult> result;
|
||||
std::vector<DocumentIdentifierToken> result;
|
||||
|
||||
while (cursor->hasMore()) {
|
||||
result.clear();
|
||||
cursor->getMoreMptr(result);
|
||||
for (auto const& element : result) {
|
||||
TRI_voc_rid_t revisionId = element.revisionId();
|
||||
if (collection->readRevision(this, mmdr, revisionId)) {
|
||||
if (collection->readDocument(this, mmdr, element)) {
|
||||
uint8_t const* vpack = mmdr.vpack();
|
||||
resultBuilder.add(VPackSlice(vpack));
|
||||
}
|
||||
|
@ -2647,14 +2646,13 @@ OperationResult Transaction::allLocal(std::string const& collectionName,
|
|||
}
|
||||
|
||||
LogicalCollection* collection = cursor->collection();
|
||||
std::vector<IndexLookupResult> result;
|
||||
std::vector<DocumentIdentifierToken> result;
|
||||
result.reserve(1000);
|
||||
|
||||
while (cursor->hasMore()) {
|
||||
cursor->getMoreMptr(result, 1000);
|
||||
for (auto const& element : result) {
|
||||
TRI_voc_rid_t revisionId = element.revisionId();
|
||||
if (collection->readRevision(this, mmdr, revisionId)) {
|
||||
if (collection->readDocument(this, mmdr, element)) {
|
||||
uint8_t const* vpack = mmdr.vpack();
|
||||
resultBuilder.addExternal(vpack);
|
||||
}
|
||||
|
|
|
@ -254,7 +254,7 @@ static void JS_AllQuery(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
VPackOptions resultOptions = VPackOptions::Defaults;
|
||||
resultOptions.customTypeHandler = transactionContext->orderCustomTypeHandler().get();
|
||||
|
||||
std::vector<IndexLookupResult> batch;
|
||||
std::vector<DocumentIdentifierToken> batch;
|
||||
ManagedDocumentResult mmdr;
|
||||
VPackBuilder resultBuilder;
|
||||
resultBuilder.openArray();
|
||||
|
@ -262,8 +262,7 @@ static void JS_AllQuery(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
opCursor->getMoreMptr(batch);
|
||||
// We only need this one call, limit == batchsize
|
||||
for (auto const& it : batch) {
|
||||
TRI_voc_rid_t revisionId = it.revisionId();
|
||||
if (collection->readRevision(&trx, mmdr, revisionId)) {
|
||||
if (collection->readDocument(&trx, mmdr, it)) {
|
||||
resultBuilder.add(VPackSlice(mmdr.vpack()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "MMFiles/MMFilesPersistentIndex.h"
|
||||
#include "MMFiles/MMFilesPrimaryIndex.h"
|
||||
#include "MMFiles/MMFilesSkiplistIndex.h"
|
||||
#include "MMFiles/MMFilesToken.h"
|
||||
#include "MMFiles/MMFilesWalMarker.h"
|
||||
#include "MMFiles/MMFilesWalSlots.h"
|
||||
#include "StorageEngine/StorageEngine.h"
|
||||
|
@ -3766,6 +3767,13 @@ bool LogicalCollection::readRevisionConditional(Transaction* trx,
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO ONLY TEMP wrapper
|
||||
bool LogicalCollection::readDocument(arangodb::Transaction* trx, ManagedDocumentResult& result, DocumentIdentifierToken const& token) {
|
||||
// TODO This only works for MMFiles Engine. Has to be moved => StorageEngine
|
||||
auto tkn = static_cast<MMFilesToken const*>(&token);
|
||||
return readRevision(trx, result, tkn->revisionId());
|
||||
}
|
||||
|
||||
void LogicalCollection::insertRevision(TRI_voc_rid_t revisionId,
|
||||
uint8_t const* dataptr,
|
||||
TRI_voc_fid_t fid, bool isInWal) {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#define ARANGOD_VOCBASE_LOGICAL_COLLECTION_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "StorageEngine/StorageEngine.h"
|
||||
#include "VocBase/PhysicalCollection.h"
|
||||
#include "VocBase/voc-types.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
@ -384,6 +385,7 @@ class LogicalCollection {
|
|||
|
||||
bool readRevision(arangodb::Transaction*, ManagedDocumentResult& result, TRI_voc_rid_t revisionId);
|
||||
bool readRevisionConditional(arangodb::Transaction*, ManagedDocumentResult& result, TRI_voc_rid_t revisionId, TRI_voc_tick_t maxTick, bool excludeWal);
|
||||
bool readDocument(arangodb::Transaction*, ManagedDocumentResult& result, DocumentIdentifierToken const& token);
|
||||
|
||||
void insertRevision(TRI_voc_rid_t revisionId, uint8_t const* dataptr, TRI_voc_fid_t fid, bool isInWal);
|
||||
void updateRevision(TRI_voc_rid_t revisionId, uint8_t const* dataptr, TRI_voc_fid_t fid, bool isInWal);
|
||||
|
|
|
@ -78,8 +78,7 @@ bool SingleServerEdgeCursor::next(std::vector<VPackSlice>& result,
|
|||
_cachePos++;
|
||||
if (_cachePos < _cache.size()) {
|
||||
LogicalCollection* collection = _cursors[_currentCursor][_currentSubCursor]->collection();
|
||||
TRI_voc_rid_t revisionId = _cache[_cachePos].revisionId();
|
||||
if (collection->readRevision(_trx, *_mmdr, revisionId)) {
|
||||
if (collection->readDocument(_trx, *_mmdr, _cache[_cachePos])) {
|
||||
result.emplace_back(_mmdr->vpack());
|
||||
}
|
||||
if (_internalCursorMapping != nullptr) {
|
||||
|
@ -128,8 +127,7 @@ bool SingleServerEdgeCursor::next(std::vector<VPackSlice>& result,
|
|||
|
||||
TRI_ASSERT(_cachePos < _cache.size());
|
||||
LogicalCollection* collection = cursor->collection();
|
||||
TRI_voc_rid_t revisionId = _cache[_cachePos].revisionId();
|
||||
if (collection->readRevision(_trx, *_mmdr, revisionId)) {
|
||||
if (collection->readDocument(_trx, *_mmdr, _cache[_cachePos])) {
|
||||
result.emplace_back(_mmdr->vpack());
|
||||
}
|
||||
if (_internalCursorMapping != nullptr) {
|
||||
|
@ -162,8 +160,7 @@ bool SingleServerEdgeCursor::readAll(std::unordered_set<VPackSlice>& result,
|
|||
// because the cursor expect's it to be filled.
|
||||
cursor->getMoreMptr(_cache);
|
||||
for (auto const& element : _cache) {
|
||||
TRI_voc_rid_t revisionId = element.revisionId();
|
||||
if (collection->readRevision(_trx, *_mmdr, revisionId)) {
|
||||
if (collection->readDocument(_trx, *_mmdr, element)) {
|
||||
result.emplace(_mmdr->vpack());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ class SingleServerEdgeCursor : public EdgeCursor {
|
|||
std::vector<std::vector<OperationCursor*>> _cursors;
|
||||
size_t _currentCursor;
|
||||
size_t _currentSubCursor;
|
||||
std::vector<IndexLookupResult> _cache;
|
||||
std::vector<DocumentIdentifierToken> _cache;
|
||||
size_t _cachePos;
|
||||
std::vector<size_t> const* _internalCursorMapping;
|
||||
|
||||
|
|
Loading…
Reference in New Issue