//////////////////////////////////////////////////////////////////////////////// /// 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 //////////////////////////////////////////////////////////////////////////////// #ifndef ARANGOD_GRAPH_EDGEDOCUMENTTOKEN_H #define ARANGOD_GRAPH_EDGEDOCUMENTTOKEN_H 1 #include "Basics/Common.h" #include "Basics/StringRef.h" #include "Cluster/ServerState.h" #include "VocBase/LocalDocumentId.h" #include "VocBase/voc-types.h" namespace arangodb { namespace graph { /// @brief Pure virtual abstract class to uniquely identify an edge struct EdgeDocumentToken { EdgeDocumentToken() noexcept #ifdef ARANGODB_ENABLE_MAINTAINER_MODE : _data(0, LocalDocumentId()), _type(TokenType::NONE) { } #else : _data(0, LocalDocumentId()) { } #endif EdgeDocumentToken(EdgeDocumentToken&& edtkn) noexcept : _data(edtkn._data) { #ifdef ARANGODB_ENABLE_MAINTAINER_MODE _type = edtkn._type; #endif } EdgeDocumentToken(EdgeDocumentToken const& edtkn) noexcept : _data(edtkn._data) { #ifdef ARANGODB_ENABLE_MAINTAINER_MODE _type = edtkn._type; #endif } EdgeDocumentToken(TRI_voc_cid_t const cid, LocalDocumentId const localDocumentId) noexcept : _data(cid, localDocumentId) { #ifdef ARANGODB_ENABLE_MAINTAINER_MODE _type = EdgeDocumentToken::TokenType::LOCAL; #endif } EdgeDocumentToken(arangodb::velocypack::Slice const& edge) noexcept : _data(edge) { #ifdef ARANGODB_ENABLE_MAINTAINER_MODE _type = EdgeDocumentToken::TokenType::COORDINATOR; #endif } EdgeDocumentToken& operator=(EdgeDocumentToken&& edtkn) { #ifdef ARANGODB_ENABLE_MAINTAINER_MODE _type = edtkn._type; #endif _data = edtkn._data; return *this; } TRI_voc_cid_t cid() const { #ifdef ARANGODB_ENABLE_MAINTAINER_MODE TRI_ASSERT(_type == TokenType::LOCAL); #endif TRI_ASSERT(_data.document.cid != 0); return _data.document.cid; } LocalDocumentId localDocumentId() const { #ifdef ARANGODB_ENABLE_MAINTAINER_MODE TRI_ASSERT(_type == TokenType::LOCAL); #endif TRI_ASSERT(_data.document.localDocumentId.isSet()); return _data.document.localDocumentId; } uint8_t const* vpack() const { #ifdef ARANGODB_ENABLE_MAINTAINER_MODE TRI_ASSERT(_type == TokenType::COORDINATOR); #endif TRI_ASSERT(_data.vpack); return _data.vpack; } bool equalsCoordinator(EdgeDocumentToken const& other) const { #ifdef ARANGODB_ENABLE_MAINTAINER_MODE TRI_ASSERT(_type == TokenType::COORDINATOR); #endif // FIXME: return velocypack::Slice(_data.vpack) == velocypack::Slice(other._data.vpack); } bool equalsLocal(EdgeDocumentToken const& other) const { #ifdef ARANGODB_ENABLE_MAINTAINER_MODE TRI_ASSERT(_type == TokenType::LOCAL); #endif return _data.document.cid == other.cid() && _data.document.localDocumentId == other.localDocumentId(); } bool equals(EdgeDocumentToken const& other) const { if (ServerState::instance()->isCoordinator()) { return equalsCoordinator(other); } return equalsLocal(other); } private: /// Identifying information for an edge documents valid on one server /// only used on a dbserver or single server struct LocalDocument { TRI_voc_cid_t cid; LocalDocumentId localDocumentId; ~LocalDocument() {} }; /// fixed size union, works for both single server and /// cluster case union TokenData { EdgeDocumentToken::LocalDocument document; uint8_t const* vpack; TokenData() noexcept { vpack = nullptr; } TokenData(velocypack::Slice const& edge) noexcept : vpack(edge.begin()) { TRI_ASSERT(!velocypack::Slice(vpack).isExternal()); } TokenData(TRI_voc_cid_t cid, LocalDocumentId tk) noexcept { document.cid = cid; document.localDocumentId = tk; } TokenData(TokenData const& other) noexcept : document(other.document) {} TokenData& operator=(TokenData const& other) noexcept { document = other.document; return *this; } ~TokenData() {} }; static_assert(sizeof(TokenData::document) >= sizeof(TokenData::vpack), "invalid TokenData struct"); TokenData _data; #ifdef ARANGODB_ENABLE_MAINTAINER_MODE enum TokenType : uint8_t { NONE, LOCAL, COORDINATOR }; TokenType _type; #endif }; } // namespace graph } // namespace arangodb #endif