diff --git a/UnitTests/Basics/structure-size-test.cpp b/UnitTests/Basics/structure-size-test.cpp index 6ca59b8a9a..37c527e4d9 100644 --- a/UnitTests/Basics/structure-size-test.cpp +++ b/UnitTests/Basics/structure-size-test.cpp @@ -30,6 +30,7 @@ #include "arangod/VocBase/datafile.h" #include "arangod/VocBase/primary-collection.h" #include "arangod/VocBase/voc-shaper.h" +#include "arangod/Wal/Marker.h" // ----------------------------------------------------------------------------- // --SECTION-- setup / tear-down @@ -137,58 +138,58 @@ BOOST_AUTO_TEST_CASE (tst_col_header_marker) { } //////////////////////////////////////////////////////////////////////////////// -/// @brief test sizeof TRI_wal_document_marker_t +/// @brief test sizeof document_marker_t //////////////////////////////////////////////////////////////////////////////// BOOST_AUTO_TEST_CASE (tst_wal_document_marker) { - size_t s = sizeof(TRI_wal_document_marker_t); + size_t s = sizeof(triagens::wal::document_marker_t); BOOST_CHECK_EQUAL(24 + 48, s); // base + own size BOOST_CHECK_EQUAL(true, s % 8 == 0); - BOOST_CHECK_EQUAL( 0, offsetof(struct TRI_wal_document_marker_s, base)); - BOOST_CHECK_EQUAL(24, offsetof(struct TRI_wal_document_marker_s, _databaseId)); - BOOST_CHECK_EQUAL(32, offsetof(struct TRI_wal_document_marker_s, _collectionId)); - BOOST_CHECK_EQUAL(40, offsetof(struct TRI_wal_document_marker_s, _rid)); - BOOST_CHECK_EQUAL(48, offsetof(struct TRI_wal_document_marker_s, _tid)); - BOOST_CHECK_EQUAL(56, offsetof(struct TRI_wal_document_marker_s, _shape)); - BOOST_CHECK_EQUAL(64, offsetof(struct TRI_wal_document_marker_s, _offsetKey)); - BOOST_CHECK_EQUAL(66, offsetof(struct TRI_wal_document_marker_s, _offsetLegend)); - BOOST_CHECK_EQUAL(68, offsetof(struct TRI_wal_document_marker_s, _offsetJson)); + BOOST_CHECK_EQUAL( 0, offsetof(triagens::wal::document_marker_t, base)); + BOOST_CHECK_EQUAL(24, offsetof(triagens::wal::document_marker_t, _databaseId)); + BOOST_CHECK_EQUAL(32, offsetof(triagens::wal::document_marker_t, _collectionId)); + BOOST_CHECK_EQUAL(40, offsetof(triagens::wal::document_marker_t, _rid)); + BOOST_CHECK_EQUAL(48, offsetof(triagens::wal::document_marker_t, _tid)); + BOOST_CHECK_EQUAL(56, offsetof(triagens::wal::document_marker_t, _shape)); + BOOST_CHECK_EQUAL(64, offsetof(triagens::wal::document_marker_t, _offsetKey)); + BOOST_CHECK_EQUAL(66, offsetof(triagens::wal::document_marker_t, _offsetLegend)); + BOOST_CHECK_EQUAL(68, offsetof(triagens::wal::document_marker_t, _offsetJson)); } //////////////////////////////////////////////////////////////////////////////// -/// @brief test sizeof TRI_wal_edge_marker_t +/// @brief test sizeof edge_marker_t //////////////////////////////////////////////////////////////////////////////// BOOST_AUTO_TEST_CASE (tst_wal_edge_marker) { - size_t s = sizeof(TRI_wal_edge_marker_t); + size_t s = sizeof(triagens::wal::edge_marker_t); BOOST_CHECK_EQUAL(24 + 48 + 24, s); // base + own size BOOST_CHECK_EQUAL(true, s % 8 == 0); - BOOST_CHECK_EQUAL( 0, offsetof(struct TRI_wal_edge_marker_s, base)); - BOOST_CHECK_EQUAL(72, offsetof(struct TRI_wal_edge_marker_s, _toCid)); - BOOST_CHECK_EQUAL(80, offsetof(struct TRI_wal_edge_marker_s, _fromCid)); - BOOST_CHECK_EQUAL(88, offsetof(struct TRI_wal_edge_marker_s, _offsetToKey)); - BOOST_CHECK_EQUAL(90, offsetof(struct TRI_wal_edge_marker_s, _offsetFromKey)); + BOOST_CHECK_EQUAL( 0, offsetof(triagens::wal::edge_marker_t, base)); + BOOST_CHECK_EQUAL(72, offsetof(triagens::wal::edge_marker_t, _toCid)); + BOOST_CHECK_EQUAL(80, offsetof(triagens::wal::edge_marker_t, _fromCid)); + BOOST_CHECK_EQUAL(88, offsetof(triagens::wal::edge_marker_t, _offsetToKey)); + BOOST_CHECK_EQUAL(90, offsetof(triagens::wal::edge_marker_t, _offsetFromKey)); } //////////////////////////////////////////////////////////////////////////////// -/// @brief test sizeof TRI_wal_remove_marker_t +/// @brief test sizeof remove_marker_t //////////////////////////////////////////////////////////////////////////////// BOOST_AUTO_TEST_CASE (tst_wal_remove_marker) { - size_t s = sizeof(TRI_wal_remove_marker_t); + size_t s = sizeof(triagens::wal::remove_marker_t); BOOST_CHECK_EQUAL(24 + 32, s); // base + own size BOOST_CHECK_EQUAL(true, s % 8 == 0); - BOOST_CHECK_EQUAL( 0, offsetof(struct TRI_wal_remove_marker_s, base)); - BOOST_CHECK_EQUAL(24, offsetof(struct TRI_wal_remove_marker_s, _databaseId)); - BOOST_CHECK_EQUAL(32, offsetof(struct TRI_wal_remove_marker_s, _collectionId)); - BOOST_CHECK_EQUAL(40, offsetof(struct TRI_wal_remove_marker_s, _rid)); - BOOST_CHECK_EQUAL(48, offsetof(struct TRI_wal_remove_marker_s, _tid)); + BOOST_CHECK_EQUAL( 0, offsetof(triagens::wal::remove_marker_t, base)); + BOOST_CHECK_EQUAL(24, offsetof(triagens::wal::remove_marker_t, _databaseId)); + BOOST_CHECK_EQUAL(32, offsetof(triagens::wal::remove_marker_t, _collectionId)); + BOOST_CHECK_EQUAL(40, offsetof(triagens::wal::remove_marker_t, _rid)); + BOOST_CHECK_EQUAL(48, offsetof(triagens::wal::remove_marker_t, _tid)); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Utils/Transaction.h b/arangod/Utils/Transaction.h index 7ad1150f9c..5d1c78578a 100644 --- a/arangod/Utils/Transaction.h +++ b/arangod/Utils/Transaction.h @@ -896,6 +896,7 @@ namespace triagens { false); } else { + // edge res = primary->insertEdge(trxCollection, key, rid, diff --git a/arangod/VocBase/document-collection.cpp b/arangod/VocBase/document-collection.cpp index 4519f28de7..52fd09b0b3 100644 --- a/arangod/VocBase/document-collection.cpp +++ b/arangod/VocBase/document-collection.cpp @@ -1626,9 +1626,9 @@ static int InsertDocumentShapedJson (TRI_transaction_collection_t* trxCollection triagens::wal::DocumentMarker marker(primary->base._vocbase->_id, primary->base._info._cid, + rid, TRI_GetMarkerIdTransaction(trxCollection->_transaction), keyString, - rid, shaped); // insert into WAL first @@ -1648,11 +1648,14 @@ static int InsertDocumentShapedJson (TRI_transaction_collection_t* trxCollection if (header == NULL) { return TRI_ERROR_OUT_OF_MEMORY; } + + triagens::wal::document_marker_t const* m = static_cast(slotInfo.mem); header->_rid = rid; header->_fid = 0; // TODO: use WAL fid - header->_data = slotInfo.mem; // let header point to WAL location - header->_key = const_cast(static_cast(slotInfo.mem) + marker.offsetKey); + // let header point to WAL location + header->_data = (void*) m; + header->_key = (char*) m + m->_offsetKey; int res = InsertIndexes(trxCollection, header, forceSync); diff --git a/arangod/VocBase/primary-collection.h b/arangod/VocBase/primary-collection.h index 5b414f07c6..d6971f1d71 100644 --- a/arangod/VocBase/primary-collection.h +++ b/arangod/VocBase/primary-collection.h @@ -343,61 +343,6 @@ typedef struct TRI_primary_collection_s { } TRI_primary_collection_t; -//////////////////////////////////////////////////////////////////////////////// -/// @brief wal document marker -//////////////////////////////////////////////////////////////////////////////// - -typedef struct TRI_wal_document_marker_s { - TRI_df_marker_t base; - - TRI_voc_tick_t _databaseId; - TRI_voc_cid_t _collectionId; - - TRI_voc_rid_t _rid; // this is the tick for a create and update - TRI_voc_tid_t _tid; - - TRI_shape_sid_t _shape; - - uint16_t _offsetKey; - uint16_t _offsetLegend; - uint32_t _offsetJson; -} -TRI_wal_document_marker_t; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief wal edge marker -//////////////////////////////////////////////////////////////////////////////// - -typedef struct TRI_wal_edge_marker_s { - TRI_wal_document_marker_t base; - - 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 -} -TRI_wal_edge_marker_t; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief wal remove marker -//////////////////////////////////////////////////////////////////////////////// - -typedef struct TRI_wal_remove_marker_s { - TRI_df_marker_t base; - - TRI_voc_tick_t _databaseId; - TRI_voc_cid_t _collectionId; - - TRI_voc_rid_t _rid; // this is the tick for the deletion - TRI_voc_tid_t _tid; -} -TRI_wal_remove_marker_t; - //////////////////////////////////////////////////////////////////////////////// /// @brief document datafile marker with key //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Wal/Marker.h b/arangod/Wal/Marker.h index 820c818600..c9b4f00cdb 100644 --- a/arangod/Wal/Marker.h +++ b/arangod/Wal/Marker.h @@ -37,11 +37,100 @@ namespace triagens { static_assert(sizeof(TRI_df_marker_t) == 24, "invalid base marker size"); +//////////////////////////////////////////////////////////////////////////////// +/// @brief wal transaction begin marker +//////////////////////////////////////////////////////////////////////////////// + + struct transaction_begin_marker_t { + TRI_df_marker_t base; + + TRI_voc_tick_t _databaseId; + TRI_voc_tid_t _transactionId; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief wal transaction commit marker +//////////////////////////////////////////////////////////////////////////////// + + struct transaction_commit_marker_t { + TRI_df_marker_t base; + + TRI_voc_tick_t _databaseId; + TRI_voc_tid_t _transactionId; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief wal transaction abort marker +//////////////////////////////////////////////////////////////////////////////// + + struct transaction_abort_marker_t { + TRI_df_marker_t base; + + TRI_voc_tick_t _databaseId; + TRI_voc_tid_t _transactionId; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief wal document marker +//////////////////////////////////////////////////////////////////////////////// + + struct document_marker_t { + TRI_df_marker_t base; + + TRI_voc_tick_t _databaseId; + TRI_voc_cid_t _collectionId; + + TRI_voc_rid_t _rid; // this is the tick for a create and update + TRI_voc_tid_t _tid; + + TRI_shape_sid_t _shape; + + uint16_t _offsetKey; + uint16_t _offsetLegend; + uint32_t _offsetJson; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief wal edge marker +//////////////////////////////////////////////////////////////////////////////// + + struct edge_marker_t { + document_marker_t base; + + 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 + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief wal remove marker +//////////////////////////////////////////////////////////////////////////////// + + struct remove_marker_t { + TRI_df_marker_t base; + + TRI_voc_tick_t _databaseId; + TRI_voc_cid_t _collectionId; + + TRI_voc_rid_t _rid; // this is the tick for the deletion + TRI_voc_tid_t _tid; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief wal marker class +//////////////////////////////////////////////////////////////////////////////// + struct Marker { Marker (TRI_df_marker_type_e type, - size_t payloadSize) - : buffer(new char[sizeof(TRI_df_marker_t) + payloadSize]), - size(sizeof(TRI_df_marker_t) + payloadSize) { + size_t size) + : buffer(new char[size]), + size(size) { std::cout << "CREATING MARKER OF TYPE: " << type << "\n"; @@ -59,7 +148,7 @@ namespace triagens { } } - inline size_t alignedSize (size_t size) const { + static inline size_t alignedSize (size_t size) { return TRI_DF_ALIGN_BLOCK(size); } @@ -67,22 +156,12 @@ namespace triagens { return (TRI_df_marker_t*) buffer; } - inline char* data () const { - return (char*) buffer + sizeof(TRI_df_marker_t); + inline char* base () const { + return (char*) buffer; } - - inline void advance (char*& ptr, size_t length) { - ptr += length; - } - - template void store (char*& ptr, T value) { - *((T*) ptr) = value; - advance(ptr, sizeof(T)); - } - - void store (char*& ptr, char const* src, size_t length) { - memcpy(ptr, src, length); - advance(ptr, length); + + inline char* payload () const { + return base() + sizeof(TRI_df_marker_t); } char* buffer; @@ -93,11 +172,12 @@ namespace triagens { BeginTransactionMarker (TRI_voc_tick_t databaseId, TRI_voc_tid_t transactionId) : Marker(TRI_WAL_MARKER_BEGIN_TRANSACTION, - sizeof(TRI_voc_tick_t) + sizeof(TRI_voc_tid_t)) { + sizeof(transaction_begin_marker_t)) { + + transaction_begin_marker_t* m = reinterpret_cast(base()); - char* p = data(); - store(p, databaseId); - store(p, transactionId); + m->_databaseId = databaseId; + m->_transactionId = transactionId; } ~BeginTransactionMarker () { @@ -109,11 +189,12 @@ namespace triagens { CommitTransactionMarker (TRI_voc_tick_t databaseId, TRI_voc_tid_t transactionId) : Marker(TRI_WAL_MARKER_COMMIT_TRANSACTION, - sizeof(TRI_voc_tick_t) + sizeof(TRI_voc_tid_t)) { - - char* p = data(); - store(p, databaseId); - store(p, transactionId); + sizeof(transaction_commit_marker_t)) { + + transaction_commit_marker_t* m = reinterpret_cast(base()); + + m->_databaseId = databaseId; + m->_transactionId = transactionId; } ~CommitTransactionMarker () { @@ -125,11 +206,12 @@ namespace triagens { AbortTransactionMarker (TRI_voc_tick_t databaseId, TRI_voc_tid_t transactionId) : Marker(TRI_WAL_MARKER_ABORT_TRANSACTION, - sizeof(TRI_voc_tick_t) + sizeof(TRI_voc_tid_t)) { - - char* p = data(); - store(p, databaseId); - store(p, transactionId); + sizeof(transaction_abort_marker_t)) { + + transaction_abort_marker_t* m = reinterpret_cast(base()); + + m->_databaseId = databaseId; + m->_transactionId = transactionId; } ~AbortTransactionMarker () { @@ -140,67 +222,51 @@ namespace triagens { struct DocumentMarker : public Marker { DocumentMarker (TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + TRI_voc_rid_t revisionId, TRI_voc_tid_t transactionId, std::string const& key, - TRI_voc_rid_t revision, TRI_shaped_json_t const* shapedJson) : Marker(TRI_WAL_MARKER_DOCUMENT, - fixedSize() + alignedSize(key.size() + 2) + shapedJson->_data.length) { + sizeof(document_marker_t) + alignedSize(key.size() + 2) + shapedJson->_data.length) { - char* p = data(); - store(p, databaseId); - store(p, collectionId); - store(p, transactionId); - store(p, revision); + document_marker_t* m = reinterpret_cast(base()); + m->_databaseId = databaseId; + m->_collectionId = collectionId; + m->_rid = revisionId; + m->_tid = transactionId; + m->_shape = shapedJson->_sid; + m->_offsetKey = sizeof(document_marker_t); // start position of key + m->_offsetLegend = m->_offsetKey + alignedSize(key.size() + 2); + m->_offsetJson = m->_offsetLegend; // TODO: account for legendSize // + alignedSize(legendSize) - // sid - store(p, shapedJson->_sid); + { + // store key + size_t const n = key.size(); + char* p = static_cast(base()) + m->_offsetKey; - // offset to key - offsetKey = static_cast(sizeof(TRI_df_marker_t) + fixedSize()); - store(p, offsetKey); - - // offset to legend - offsetLegend = static_cast(offsetKey + alignedSize(key.size() + 2)); - store(p, offsetLegend); - - // offset to shapedJson - offsetShapedJson = static_cast(offsetLegend + 8); // TODO - store(p, offsetShapedJson); - - // store key - size_t const n = key.size(); - store(p, (uint8_t) n); // length of key - store(p, key.c_str(), n); - - // pad key with \0 - for (size_t i = n + 1; i < 8 + ((n + 1) / 8) * 8; ++i) { - store(p, '\0'); + // init key buffer + memset(p, '\0', (1 + ((n + 1) / 8)) * 8); + + // store length of key + *p = (uint8_t) n; + // store actual key + memcpy(p + 1, key.c_str(), n); } - // store shaped json - store(p, (char const*) shapedJson->_data.data, static_cast(shapedJson->_data.length)); + // store legend // TODO + + // store shapedJson + { + char* p = static_cast(base()) + m->_offsetJson; + memcpy(p, shapedJson->_data.data, static_cast(shapedJson->_data.length)); + } } ~DocumentMarker () { } - size_t fixedSize () const { - return sizeof(TRI_voc_tick_t) + - sizeof(TRI_voc_cid_t) + - sizeof(TRI_voc_tid_t) + - sizeof(TRI_voc_rid_t) + - sizeof(TRI_shape_sid_t) + - sizeof(uint16_t) + - sizeof(uint16_t) + - sizeof(uint32_t); - } - - uint16_t offsetKey; - uint16_t offsetLegend; - uint32_t offsetShapedJson; - }; + /* struct RemoveMarker : public Marker { RemoveMarker (TRI_voc_tick_t databaseId,