//////////////////////////////////////////////////////////////////////////////// /// 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 Jan Steemann //////////////////////////////////////////////////////////////////////////////// #ifndef ARANGOD_WAL_MARKER_H #define ARANGOD_WAL_MARKER_H 1 #include "Basics/Common.h" #include "Basics/tri-strings.h" #include "VocBase/datafile.h" #include "VocBase/Legends.h" #include "VocBase/shaped-json.h" #include "VocBase/voc-types.h" #include #include namespace arangodb { namespace wal { static_assert(sizeof(TRI_df_marker_t) == 24, "invalid base marker size"); //////////////////////////////////////////////////////////////////////////////// /// @brief wal attribute marker //////////////////////////////////////////////////////////////////////////////// struct attribute_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_cid_t _collectionId; TRI_shape_aid_t _attributeId; // char* name }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal shape marker //////////////////////////////////////////////////////////////////////////////// struct shape_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_cid_t _collectionId; // char* shape }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal create database marker //////////////////////////////////////////////////////////////////////////////// struct database_create_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; // char* properties }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal drop database marker //////////////////////////////////////////////////////////////////////////////// struct database_drop_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal create collection marker //////////////////////////////////////////////////////////////////////////////// struct collection_create_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_cid_t _collectionId; // char* properties }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal drop collection marker //////////////////////////////////////////////////////////////////////////////// struct collection_drop_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_cid_t _collectionId; }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal rename collection marker //////////////////////////////////////////////////////////////////////////////// struct collection_rename_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_cid_t _collectionId; // char* name }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal change collection marker //////////////////////////////////////////////////////////////////////////////// struct collection_change_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_cid_t _collectionId; // char* properties }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal create index marker //////////////////////////////////////////////////////////////////////////////// struct index_create_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_cid_t _collectionId; TRI_idx_iid_t _indexId; // char* properties }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal drop index marker //////////////////////////////////////////////////////////////////////////////// struct index_drop_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_cid_t _collectionId; TRI_idx_iid_t _indexId; }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal transaction begin marker //////////////////////////////////////////////////////////////////////////////// struct transaction_begin_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_tid_t _transactionId; }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal transaction commit marker //////////////////////////////////////////////////////////////////////////////// struct transaction_commit_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_tid_t _transactionId; }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal transaction abort marker //////////////////////////////////////////////////////////////////////////////// struct transaction_abort_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_tid_t _transactionId; }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal remote transaction begin marker //////////////////////////////////////////////////////////////////////////////// struct transaction_remote_begin_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_tid_t _transactionId; TRI_voc_tid_t _externalId; }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal remote transaction commit marker //////////////////////////////////////////////////////////////////////////////// struct transaction_remote_commit_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_tid_t _transactionId; TRI_voc_tid_t _externalId; }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal remote transaction abort marker //////////////////////////////////////////////////////////////////////////////// struct transaction_remote_abort_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_tid_t _transactionId; TRI_voc_tid_t _externalId; }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal document marker //////////////////////////////////////////////////////////////////////////////// struct document_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_cid_t _collectionId; TRI_voc_rid_t _revisionId; // this is the tick for a create and update TRI_voc_tid_t _transactionId; TRI_shape_sid_t _shape; uint16_t _offsetKey; uint16_t _offsetLegend; uint32_t _offsetJson; // char* key // char* shapedJson }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal vpack document marker //////////////////////////////////////////////////////////////////////////////// struct vpack_document_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_cid_t _collectionId; TRI_voc_tid_t _transactionId; // uint8_t* vpack }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal vpack remove marker //////////////////////////////////////////////////////////////////////////////// struct vpack_remove_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_cid_t _collectionId; TRI_voc_tid_t _transactionId; // uint8_t* vpack }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal edge marker //////////////////////////////////////////////////////////////////////////////// struct edge_marker_t : document_marker_t { TRI_voc_cid_t _toCid; TRI_voc_cid_t _fromCid; uint16_t _offsetToKey; uint16_t _offsetFromKey; #ifdef TRI_PADDING_32 char _padding_df_marker[4]; #endif // char* key // char* toKey // char* fromKey // char* shapedJson }; //////////////////////////////////////////////////////////////////////////////// /// @brief wal remove marker //////////////////////////////////////////////////////////////////////////////// struct remove_marker_t : TRI_df_marker_t { TRI_voc_tick_t _databaseId; TRI_voc_cid_t _collectionId; TRI_voc_rid_t _revisionId; // this is the tick for the deletion TRI_voc_tid_t _transactionId; // char* key }; class Marker { protected: Marker& operator=(Marker const&) = delete; Marker(Marker&&) = delete; Marker(Marker const&) = delete; ////////////////////////////////////////////////////////////////////////////// /// @brief create a marker from a marker existing in memory ////////////////////////////////////////////////////////////////////////////// Marker(TRI_df_marker_t const*, TRI_voc_fid_t); ////////////////////////////////////////////////////////////////////////////// /// @brief create a marker that manages its own memory ////////////////////////////////////////////////////////////////////////////// Marker(TRI_df_marker_type_e, size_t); public: virtual ~Marker(); inline void freeBuffer() { if (_buffer != nullptr && _mustFree) { delete[] _buffer; _buffer = nullptr; _mustFree = false; } } inline char* steal() { char* buffer = _buffer; _buffer = nullptr; _mustFree = false; return buffer; } inline TRI_voc_fid_t fid() const { return _fid; } static inline size_t alignedSize(size_t size) { return TRI_DF_ALIGN_BLOCK(size); } inline void* mem() const { return static_cast(_buffer); } inline char* begin() const { return _buffer; } inline char* end() const { return _buffer + _size; } ////////////////////////////////////////////////////////////////////////////// /// @brief return the size of the marker ////////////////////////////////////////////////////////////////////////////// inline uint32_t size() const { return _size; } ////////////////////////////////////////////////////////////////////////////// /// @brief return a hex representation of a marker part ////////////////////////////////////////////////////////////////////////////// std::string hexifyPart(char const*, size_t) const; ////////////////////////////////////////////////////////////////////////////// /// @brief return a printable string representation of a marker part ////////////////////////////////////////////////////////////////////////////// std::string stringifyPart(char const*, size_t) const; ////////////////////////////////////////////////////////////////////////////// /// @brief print the marker in binary form ////////////////////////////////////////////////////////////////////////////// void dumpBinary() const; protected: ////////////////////////////////////////////////////////////////////////////// /// @brief store a null-terminated string inside the marker ////////////////////////////////////////////////////////////////////////////// void storeSizedString(size_t, std::string const&); ////////////////////////////////////////////////////////////////////////////// /// @brief store a null-terminated string inside the marker ////////////////////////////////////////////////////////////////////////////// void storeSizedString(size_t, char const*, size_t); protected: ////////////////////////////////////////////////////////////////////////////// /// @brief pointer to marker data ////////////////////////////////////////////////////////////////////////////// char* _buffer; ////////////////////////////////////////////////////////////////////////////// /// @brief size of marker data ////////////////////////////////////////////////////////////////////////////// uint32_t const _size; ////////////////////////////////////////////////////////////////////////////// /// @brief whether or not the destructor must free the memory ////////////////////////////////////////////////////////////////////////////// bool _mustFree; ////////////////////////////////////////////////////////////////////////////// /// @brief id of the logfile the marker is stored in ////////////////////////////////////////////////////////////////////////////// TRI_voc_fid_t _fid; }; class EnvelopeMarker : public Marker { public: EnvelopeMarker(TRI_df_marker_t const*, TRI_voc_fid_t); ~EnvelopeMarker(); }; class AttributeMarker : public Marker { public: AttributeMarker(TRI_voc_tick_t, TRI_voc_cid_t, TRI_shape_aid_t, std::string const&); ~AttributeMarker(); public: inline char* attributeName() const { // pointer to attribute name return begin() + sizeof(attribute_marker_t); } void setType(TRI_df_marker_type_t); void dump() const; }; class ShapeMarker : public Marker { public: ShapeMarker(TRI_voc_tick_t, TRI_voc_cid_t, TRI_shape_t const*); ~ShapeMarker(); public: inline char* shape() const { return begin() + sizeof(shape_marker_t); } inline TRI_shape_sid_t shapeId() const { return reinterpret_cast(shape())->_sid; } void dump() const; }; class CreateDatabaseMarker : public Marker { public: CreateDatabaseMarker(TRI_voc_tick_t, std::string const&); ~CreateDatabaseMarker(); public: inline char* properties() const { return begin() + sizeof(database_create_marker_t); } void dump() const; }; class DropDatabaseMarker : public Marker { public: explicit DropDatabaseMarker(TRI_voc_tick_t); ~DropDatabaseMarker(); public: void dump() const; }; class CreateCollectionMarker : public Marker { public: CreateCollectionMarker(TRI_voc_tick_t, TRI_voc_cid_t, std::string const&); ~CreateCollectionMarker(); public: inline char* properties() const { return begin() + sizeof(collection_create_marker_t); } void dump() const; }; class DropCollectionMarker : public Marker { public: DropCollectionMarker(TRI_voc_tick_t, TRI_voc_cid_t); ~DropCollectionMarker(); public: void dump() const; }; class RenameCollectionMarker : public Marker { public: RenameCollectionMarker(TRI_voc_tick_t, TRI_voc_cid_t, std::string const&); ~RenameCollectionMarker(); public: inline char* name() const { return begin() + sizeof(collection_rename_marker_t); } void dump() const; }; class ChangeCollectionMarker : public Marker { public: ChangeCollectionMarker(TRI_voc_tick_t, TRI_voc_cid_t, std::string const&); ~ChangeCollectionMarker(); public: inline char* properties() const { return begin() + sizeof(collection_change_marker_t); } void dump() const; }; class CreateIndexMarker : public Marker { public: CreateIndexMarker(TRI_voc_tick_t, TRI_voc_cid_t, TRI_idx_iid_t, std::string const&); ~CreateIndexMarker(); public: inline char* properties() const { return begin() + sizeof(index_create_marker_t); } void dump() const; }; class DropIndexMarker : public Marker { public: DropIndexMarker(TRI_voc_tick_t, TRI_voc_cid_t, TRI_idx_iid_t); ~DropIndexMarker(); public: void dump() const; }; class BeginTransactionMarker : public Marker { public: BeginTransactionMarker(TRI_voc_tick_t, TRI_voc_tid_t); ~BeginTransactionMarker(); public: void dump() const; }; class CommitTransactionMarker : public Marker { public: CommitTransactionMarker(TRI_voc_tick_t, TRI_voc_tid_t); ~CommitTransactionMarker(); public: void dump() const; }; class AbortTransactionMarker : public Marker { public: AbortTransactionMarker(TRI_voc_tick_t, TRI_voc_tid_t); ~AbortTransactionMarker(); public: void dump() const; }; class BeginRemoteTransactionMarker : public Marker { public: BeginRemoteTransactionMarker(TRI_voc_tick_t, TRI_voc_tid_t, TRI_voc_tid_t); ~BeginRemoteTransactionMarker(); public: void dump() const; }; class CommitRemoteTransactionMarker : public Marker { public: CommitRemoteTransactionMarker(TRI_voc_tick_t, TRI_voc_tid_t, TRI_voc_tid_t); ~CommitRemoteTransactionMarker(); public: void dump() const; }; class AbortRemoteTransactionMarker : public Marker { public: AbortRemoteTransactionMarker(TRI_voc_tick_t, TRI_voc_tid_t, TRI_voc_tid_t); ~AbortRemoteTransactionMarker(); public: void dump() const; }; class VPackDocumentMarker : public Marker { public: VPackDocumentMarker(TRI_voc_tick_t, TRI_voc_cid_t, TRI_voc_tid_t, VPackSlice const*); ~VPackDocumentMarker(); public: inline TRI_voc_tid_t transactionId() const { auto const* m = reinterpret_cast(begin()); return m->_transactionId; } inline uint8_t* vpack() const { // pointer to vpack return reinterpret_cast(begin()) + sizeof(vpack_document_marker_t); } inline size_t vpackLength() const { VPackSlice slice(vpack()); return slice.byteSize(); } }; class VPackRemoveMarker : public Marker { public: VPackRemoveMarker(TRI_voc_tick_t, TRI_voc_cid_t, TRI_voc_tid_t, VPackSlice const*); ~VPackRemoveMarker(); public: inline TRI_voc_tid_t transactionId() const { auto const* m = reinterpret_cast(begin()); return m->_transactionId; } inline uint8_t* vpack() const { // pointer to vpack return reinterpret_cast(begin()) + sizeof(vpack_remove_marker_t); } inline size_t vpackLength() const { VPackSlice slice(vpack()); return slice.byteSize(); } }; class DocumentMarker : public Marker { public: DocumentMarker(TRI_voc_tick_t, TRI_voc_cid_t, TRI_voc_rid_t, TRI_voc_tid_t, std::string const&, size_t, TRI_shaped_json_t const*); ~DocumentMarker(); public: inline TRI_voc_rid_t revisionId() const { document_marker_t const* m = reinterpret_cast(begin()); return m->_revisionId; } inline TRI_voc_tid_t transactionId() const { document_marker_t const* m = reinterpret_cast(begin()); return m->_transactionId; } inline char* key() const { // pointer to key return begin() + sizeof(document_marker_t); } inline char const* legend() const { // pointer to legend document_marker_t const* m = reinterpret_cast(begin()); return begin() + m->_offsetLegend; } inline size_t legendLength() const { document_marker_t const* m = reinterpret_cast(begin()); return static_cast(m->_offsetJson - m->_offsetLegend); } inline char const* json() const { // pointer to json document_marker_t const* m = reinterpret_cast(begin()); return begin() + m->_offsetJson; } inline size_t jsonLength() const { document_marker_t const* m = reinterpret_cast(begin()); return static_cast(size() - m->_offsetJson); } void storeLegend(arangodb::basics::JsonLegend&); void dump() const; static DocumentMarker* clone(TRI_df_marker_t const*, TRI_voc_tick_t, TRI_voc_cid_t, TRI_voc_rid_t, TRI_voc_tid_t, size_t, TRI_shaped_json_t const*); }; class EdgeMarker : public Marker { public: EdgeMarker(TRI_voc_tick_t, TRI_voc_cid_t, TRI_voc_rid_t, TRI_voc_tid_t, std::string const&, TRI_document_edge_t const*, size_t, TRI_shaped_json_t const*); ~EdgeMarker(); inline TRI_voc_rid_t revisionId() const { edge_marker_t const* m = reinterpret_cast(begin()); return m->_revisionId; } inline TRI_voc_rid_t transactionId() const { edge_marker_t const* m = reinterpret_cast(begin()); return m->_transactionId; } inline char const* key() const { // pointer to key return begin() + sizeof(edge_marker_t); } inline char const* fromKey() const { // pointer to _from key edge_marker_t const* m = reinterpret_cast(begin()); return begin() + m->_offsetFromKey; } inline char const* toKey() const { // pointer to _to key edge_marker_t const* m = reinterpret_cast(begin()); return begin() + m->_offsetToKey; } inline char const* legend() const { // pointer to legend edge_marker_t const* m = reinterpret_cast(begin()); return begin() + m->_offsetLegend; } inline size_t legendLength() const { edge_marker_t const* m = reinterpret_cast(begin()); return static_cast(m->_offsetJson - m->_offsetLegend); } inline char const* json() const { // pointer to json edge_marker_t const* m = reinterpret_cast(begin()); return begin() + m->_offsetJson; } inline size_t jsonLength() const { edge_marker_t const* m = reinterpret_cast(begin()); return static_cast(size() - m->_offsetJson); } void storeLegend(arangodb::basics::JsonLegend&); void dump() const; static EdgeMarker* clone(TRI_df_marker_t const*, TRI_voc_tick_t, TRI_voc_cid_t, TRI_voc_rid_t, TRI_voc_tid_t, size_t, TRI_shaped_json_t const*); }; class RemoveMarker : public Marker { public: RemoveMarker(TRI_voc_tick_t, TRI_voc_cid_t, TRI_voc_rid_t, TRI_voc_tid_t, std::string const&); ~RemoveMarker(); public: inline char const* key() const { // pointer to key return begin() + sizeof(remove_marker_t); } inline TRI_voc_tid_t transactionId() const { remove_marker_t const* m = reinterpret_cast(begin()); return m->_transactionId; } inline TRI_voc_rid_t revisionId() const { remove_marker_t const* m = reinterpret_cast(begin()); return m->_revisionId; } void dump() const; }; } } #endif