diff --git a/arangod/Aql/ModificationBlocks.cpp b/arangod/Aql/ModificationBlocks.cpp index 328220fcdd..67797f3951 100644 --- a/arangod/Aql/ModificationBlocks.cpp +++ b/arangod/Aql/ModificationBlocks.cpp @@ -184,7 +184,6 @@ int ModificationBlock::extractKey(AqlValue const& value, void ModificationBlock::constructMptr(TRI_doc_mptr_t* dst, TRI_df_marker_t const* marker) const { - dst->_rid = TRI_EXTRACT_MARKER_RID(marker); dst->_fid = 0; dst->_hash = 0; dst->setDataPtr(marker); diff --git a/arangod/Replication/InitialSyncer.cpp b/arangod/Replication/InitialSyncer.cpp index ec219b5919..155fd082b0 100644 --- a/arangod/Replication/InitialSyncer.cpp +++ b/arangod/Replication/InitialSyncer.cpp @@ -1450,7 +1450,7 @@ int InitialSyncer::handleSyncKeys(TRI_vocbase_col_t* col, if (mptr == nullptr) { // key not found locally toFetch.emplace_back(i); - } else if (std::to_string(mptr->_rid) != + } else if (std::to_string(mptr->revisionId()) != std::string(ridJson->_value._string.data, ridJson->_value._string.length - 1)) { // key found, but rid differs diff --git a/arangod/Utils/Transaction.cpp b/arangod/Utils/Transaction.cpp index abe5793bdc..9df0f6ecf9 100644 --- a/arangod/Utils/Transaction.cpp +++ b/arangod/Utils/Transaction.cpp @@ -542,10 +542,10 @@ OperationResult Transaction::documentLocal(std::string const& collectionName, } TRI_ASSERT(mptr.getDataPtr() != nullptr); - if (expectedRevision != 0 && expectedRevision != mptr._rid) { + if (expectedRevision != 0 && expectedRevision != mptr.revisionId()) { // still return VPackBuilder resultBuilder; - buildDocumentIdentity(resultBuilder, cid, key, mptr._rid, ""); + buildDocumentIdentity(resultBuilder, cid, key, mptr.revisionId(), ""); return OperationResult(resultBuilder.steal(), nullptr, "", TRI_ERROR_ARANGO_CONFLICT, @@ -763,7 +763,7 @@ OperationResult Transaction::insertLocal(std::string const& collectionName, TRI_ASSERT(mptr.getDataPtr() != nullptr); - buildDocumentIdentity(resultBuilder, cid, keyString, mptr._rid, ""); + buildDocumentIdentity(resultBuilder, cid, keyString, mptr.revisionId(), ""); return TRI_ERROR_NO_ERROR; }; @@ -946,7 +946,7 @@ OperationResult Transaction::updateLocal(std::string const& collectionName, if (res == TRI_ERROR_ARANGO_CONFLICT) { // still return VPackBuilder resultBuilder; - buildDocumentIdentity(resultBuilder, cid, key, mptr._rid, ""); + buildDocumentIdentity(resultBuilder, cid, key, mptr.revisionId(), ""); return OperationResult(resultBuilder.steal(), nullptr, "", TRI_ERROR_ARANGO_CONFLICT, @@ -1130,7 +1130,7 @@ OperationResult Transaction::replaceLocal(std::string const& collectionName, if (res == TRI_ERROR_ARANGO_CONFLICT) { // still return VPackBuilder resultBuilder; - buildDocumentIdentity(resultBuilder, cid, key, mptr._rid, ""); + buildDocumentIdentity(resultBuilder, cid, key, mptr.revisionId(), ""); return OperationResult(resultBuilder.steal(), nullptr, "", TRI_ERROR_ARANGO_CONFLICT, diff --git a/arangod/V8Server/v8-query.cpp b/arangod/V8Server/v8-query.cpp index b19692096c..0251846f50 100644 --- a/arangod/V8Server/v8-query.cpp +++ b/arangod/V8Server/v8-query.cpp @@ -1073,19 +1073,29 @@ static bool ChecksumCalculator(TRI_doc_mptr_t const* mptr, // TODO vpack if (marker->_type == TRI_DOC_MARKER_KEY_DOCUMENT || marker->_type == TRI_WAL_MARKER_VPACK_DOCUMENT) { + TRI_voc_rid_t rid = 0; + if (WR) { + rid = mptr->revisionId(); + } + localCrc = TRI_Crc32HashString( TRI_EXTRACT_MARKER_KEY(mptr)); // PROTECTED by trx in calling function // TRI_DocumentIteratorDocumentCollection if (WR) { - localCrc += TRI_Crc32HashPointer(&mptr->_rid, sizeof(TRI_voc_rid_t)); + localCrc += TRI_Crc32HashPointer(&rid, sizeof(TRI_voc_rid_t)); } } else if (marker->_type == TRI_DOC_MARKER_KEY_EDGE) { // must convert _rid, _fromCid, _toCid into strings for portability + TRI_voc_rid_t rid = 0; + if (WR) { + rid = mptr->revisionId(); + } + localCrc = TRI_Crc32HashString( TRI_EXTRACT_MARKER_KEY(mptr)); // PROTECTED by trx in calling function // TRI_DocumentIteratorDocumentCollection if (WR) { - localCrc += TRI_Crc32HashPointer(&mptr->_rid, sizeof(TRI_voc_rid_t)); + localCrc += TRI_Crc32HashPointer(&rid, sizeof(TRI_voc_rid_t)); } if (marker->_type == TRI_DOC_MARKER_KEY_EDGE) { diff --git a/arangod/VocBase/ExampleMatcher.cpp b/arangod/VocBase/ExampleMatcher.cpp index 9cd3ae8536..6d9da0e939 100644 --- a/arangod/VocBase/ExampleMatcher.cpp +++ b/arangod/VocBase/ExampleMatcher.cpp @@ -485,8 +485,7 @@ bool ExampleMatcher::matches(TRI_voc_cid_t cid, // Match _rev it = def._internal.find(internalAttr::rev); if (it != def._internal.end()) { - if (arangodb::basics::StringUtils::uint64(it->second.key) != - mptr->_rid) { + if (arangodb::basics::StringUtils::uint64(it->second.key) != mptr->revisionId()) { goto nextExample; } } diff --git a/arangod/VocBase/compactor.cpp b/arangod/VocBase/compactor.cpp index a46237f1ad..90fc21106c 100644 --- a/arangod/VocBase/compactor.cpp +++ b/arangod/VocBase/compactor.cpp @@ -398,9 +398,8 @@ static bool Compactifier(TRI_df_marker_t const* marker, void* data, // check if the document is still active auto primaryIndex = document->primaryIndex(); - auto found = static_cast( - primaryIndex->lookupKey(context->_trx, keySlice)); - bool deleted = (found == nullptr || found->_rid > rid); + auto found = primaryIndex->lookupKey(context->_trx, keySlice); + bool deleted = (found == nullptr || found->revisionId() > rid); if (deleted) { // found a dead document @@ -544,9 +543,8 @@ static bool CalculateSize(TRI_df_marker_t const* marker, void* data, // check if the document is still active auto primaryIndex = document->primaryIndex(); - auto found = static_cast( - primaryIndex->lookupKey(context->_trx, keySlice)); - bool deleted = (found == nullptr || found->_rid > rid); + auto found = primaryIndex->lookupKey(context->_trx, keySlice); + bool deleted = (found == nullptr || found->revisionId() > rid); if (deleted) { return true; diff --git a/arangod/VocBase/document-collection.cpp b/arangod/VocBase/document-collection.cpp index 59182b212f..dcbea8ed92 100644 --- a/arangod/VocBase/document-collection.cpp +++ b/arangod/VocBase/document-collection.cpp @@ -32,6 +32,7 @@ #include "Basics/Logger.h" #include "Basics/tri-strings.h" #include "Basics/ThreadPool.h" +#include "Basics/VelocyPackHelper.h" #include "Basics/WriteLocker.h" #include "Cluster/ServerState.h" #include "FulltextIndex/fulltext-index.h" @@ -67,6 +68,18 @@ using namespace arangodb; using namespace arangodb::basics; + +TRI_voc_rid_t TRI_doc_mptr_t::revisionId() const { + VPackSlice const slice(vpack()); + VPackSlice const revisionSlice = slice.get(TRI_VOC_ATTRIBUTE_REV); + if (revisionSlice.isString()) { + return arangodb::basics::VelocyPackHelper::stringUInt64(revisionSlice); + } + else if (revisionSlice.isNumber()) { + return revisionSlice.getNumber(); + } + return 0; +} //////////////////////////////////////////////////////////////////////////////// /// @brief create a document collection @@ -738,19 +751,6 @@ static int CleanupIndexes(TRI_document_collection_t* document) { return res; } -//////////////////////////////////////////////////////////////////////////////// -/// @brief generates a new revision id if not yet set -//////////////////////////////////////////////////////////////////////////////// - -static inline TRI_voc_rid_t GetRevisionId(TRI_voc_rid_t previous) { - if (previous != 0) { - return previous; - } - - // generate new revision id - return static_cast(TRI_NewTickServer()); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief state during opening of a collection //////////////////////////////////////////////////////////////////////////////// @@ -848,10 +848,9 @@ static int OpenIteratorHandleDocumentMarker(TRI_df_marker_t const* marker, return TRI_ERROR_OUT_OF_MEMORY; } - header->_rid = rid; header->_fid = fid; - header->setDataPtr(marker); // ONLY IN OPENITERATOR header->_hash = primaryIndex->calculateHash(trx, keySlice); + header->setDataPtr(marker); // ONLY IN OPENITERATOR // insert into primary index void const* result = nullptr; @@ -872,13 +871,12 @@ static int OpenIteratorHandleDocumentMarker(TRI_df_marker_t const* marker, } // it is an update, but only if found has a smaller revision identifier - else if (found->_rid < rid || - (found->_rid == rid && found->_fid <= fid)) { + else if (found->revisionId() < rid || + (found->revisionId() == rid && found->_fid <= fid)) { // save the old data TRI_doc_mptr_t oldData = *found; // update the header info - found->_rid = rid; found->_fid = fid; found->setDataPtr(marker); @@ -3644,7 +3642,6 @@ TRI_ASSERT(false); // update the header we got void* mem = operation.marker->mem(); - header->_rid = rid; header->setDataPtr(mem); // PROTECTED by trx in trxCollection header->_hash = hash; @@ -3825,7 +3822,6 @@ int TRI_document_collection_t::read(Transaction* trx, std::string const& key, } TRI_ASSERT(mptr->getDataPtr() != nullptr); - TRI_ASSERT(mptr->_rid > 0); return TRI_ERROR_NO_ERROR; } @@ -3844,8 +3840,6 @@ int TRI_document_collection_t::insert(Transaction* trx, VPackSlice const* slice, VPackSlice const key(slice->get(TRI_VOC_ATTRIBUTE_KEY)); uint64_t const hash = key.hash(); - TRI_voc_rid_t revisionId = Transaction::extractRevisionId(slice); - std::unique_ptr marker; if (options.recoveryMarker == nullptr) { marker.reset(createVPackInsertMarker(trx, slice)); @@ -3895,7 +3889,6 @@ int TRI_document_collection_t::insert(Transaction* trx, VPackSlice const* slice, // update the header we got void* mem = operation.marker->mem(); - header->_rid = revisionId; header->_hash = hash; header->setDataPtr(mem); // PROTECTED by trx in trxCollection @@ -3998,7 +3991,6 @@ int TRI_document_collection_t::update(Transaction* trx, VPackSlice const* slice, if (res == TRI_ERROR_NO_ERROR) { TRI_ASSERT(mptr->getDataPtr() != nullptr); - TRI_ASSERT(mptr->_rid > 0); } if (markerTick > 0) { @@ -4085,7 +4077,6 @@ int TRI_document_collection_t::replace(Transaction* trx, VPackSlice const* slice if (res == TRI_ERROR_NO_ERROR) { TRI_ASSERT(mptr->getDataPtr() != nullptr); - TRI_ASSERT(mptr->_rid > 0); } if (markerTick > 0) { @@ -4295,7 +4286,7 @@ int TRI_document_collection_t::lookupDocument( } if (policy != nullptr) { - return policy->check(header->_rid); + return policy->check(header->revisionId()); } return TRI_ERROR_NO_ERROR; @@ -4329,9 +4320,7 @@ int TRI_document_collection_t::updateDocument(arangodb::Transaction* trx, TRI_doc_mptr_t* newHeader = oldHeader; // update the header. this will modify oldHeader, too !!! - newHeader->_rid = revisionId; - newHeader->setDataPtr( - operation.marker->mem()); + newHeader->setDataPtr(operation.marker->mem()); // insert new document into secondary indexes res = insertSecondaryIndexes(trx, newHeader, false); @@ -4434,8 +4423,7 @@ int TRI_document_collection_t::insertPrimaryIndex(arangodb::Transaction* trx, TRI_doc_mptr_t* found; TRI_ASSERT(header != nullptr); - TRI_ASSERT(header->getDataPtr() != - nullptr); // ONLY IN INDEX, PROTECTED by RUNTIME + TRI_ASSERT(header->getDataPtr() != nullptr); // insert into primary index int res = primaryIndex()->insertKey(trx, header, (void const**)&found); diff --git a/arangod/VocBase/document-collection.h b/arangod/VocBase/document-collection.h index 175bad29fb..25575fcdac 100644 --- a/arangod/VocBase/document-collection.h +++ b/arangod/VocBase/document-collection.h @@ -54,13 +54,11 @@ class Slice; } } - //////////////////////////////////////////////////////////////////////////////// /// @brief master pointer //////////////////////////////////////////////////////////////////////////////// struct TRI_doc_mptr_t { - TRI_voc_rid_t _rid; // this is the revision identifier TRI_voc_fid_t _fid; // this is the datafile identifier uint64_t _hash; // the pre-calculated hash value of the key protected: @@ -69,8 +67,7 @@ struct TRI_doc_mptr_t { public: TRI_doc_mptr_t() - : _rid(0), - _fid(0), + : _fid(0), _hash(0), _dataptr(nullptr) {} @@ -78,15 +75,13 @@ struct TRI_doc_mptr_t { ~TRI_doc_mptr_t() {} void clear() { - _rid = 0; _fid = 0; - setDataPtr(nullptr); _hash = 0; + setDataPtr(nullptr); } void copy(TRI_doc_mptr_t const& that) { // This is for cases where we explicitly have to copy originals! - _rid = that._rid; _fid = that._fid; _dataptr = that._dataptr; _hash = that._hash; @@ -113,12 +108,11 @@ struct TRI_doc_mptr_t { inline void setDataPtr(void const* d) { _dataptr = d; } inline uint8_t const* vpack() const { - TRI_df_marker_t const* marker = - static_cast(_dataptr); - - return reinterpret_cast(marker) + arangodb::DatafileHelper::VPackOffset(TRI_WAL_MARKER_VPACK_DOCUMENT); + return reinterpret_cast(_dataptr) + arangodb::DatafileHelper::VPackOffset(TRI_WAL_MARKER_VPACK_DOCUMENT); } + TRI_voc_rid_t revisionId() const; + ////////////////////////////////////////////////////////////////////////////// /// @brief return a pointer to the beginning of the shaped json stored in the /// marker diff --git a/arangod/Wal/CollectorThread.cpp b/arangod/Wal/CollectorThread.cpp index 7f36a53a13..5b642d5705 100644 --- a/arangod/Wal/CollectorThread.cpp +++ b/arangod/Wal/CollectorThread.cpp @@ -695,7 +695,7 @@ void CollectorThread::processCollectionMarker( auto found = document->primaryIndex()->lookupKey(&trx, slice.get(TRI_VOC_ATTRIBUTE_KEY)); - if (found == nullptr || found->_rid != revisionId || + if (found == nullptr || found->revisionId() != revisionId || found->getDataPtr() != walMarker) { // somebody inserted a new revision of the document or the revision // was already moved by the compactor @@ -727,7 +727,7 @@ void CollectorThread::processCollectionMarker( auto found = document->primaryIndex()->lookupKey(&trx, slice.get(TRI_VOC_ATTRIBUTE_KEY)); - if (found != nullptr && found->_rid > revisionId) { + if (found != nullptr && found->revisionId() > revisionId) { // somebody re-created the document with a newer revision dfi.numberDead++; dfi.sizeDead += DatafileHelper::AlignedSize(datafileMarkerSize);