diff --git a/arangod/CMakeLists.txt b/arangod/CMakeLists.txt index 2257b33cdb..bf873bc569 100644 --- a/arangod/CMakeLists.txt +++ b/arangod/CMakeLists.txt @@ -259,7 +259,6 @@ add_executable(${BIN_ARANGOD} VocBase/ExampleMatcher.cpp VocBase/Graphs.cpp VocBase/KeyGenerator.cpp - VocBase/Legends.cpp VocBase/Shaper.cpp VocBase/Traverser.cpp VocBase/VocShaper.cpp diff --git a/arangod/V8Server/v8-collection.cpp b/arangod/V8Server/v8-collection.cpp index 784588c36f..008171c4bb 100644 --- a/arangod/V8Server/v8-collection.cpp +++ b/arangod/V8Server/v8-collection.cpp @@ -1923,6 +1923,7 @@ static void JS_InsertVocbaseVPack( auto transactionContext = std::make_shared(collection->_vocbase, true); SingleCollectionTransaction trx(transactionContext, collection->_cid, TRI_TRANSACTION_WRITE); + trx.addHint(TRI_TRANSACTION_HINT_SINGLE_OPERATION, false); res = trx.begin(); diff --git a/arangod/VocBase/Legends.cpp b/arangod/VocBase/Legends.cpp deleted file mode 100644 index fac7ad8d68..0000000000 --- a/arangod/VocBase/Legends.cpp +++ /dev/null @@ -1,334 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -/// 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 Max Neunhoeffer -//////////////////////////////////////////////////////////////////////////////// - -#include "Legends.h" - -using namespace arangodb; -using namespace arangodb::basics; - -//////////////////////////////////////////////////////////////////////////////// -/// Data format of a legend in memory: -/// -/// Rough overview description: -/// -/// - attribute-ID table -/// - shape table -/// - attribute-ID string data -/// - padding to achieve 8-byte alignment -/// - shape data -/// - padding to achieve 8-byte alignment -/// -/// Description of the attribute-ID table (actual binary types in -/// [square brackets]): -/// -/// - number of entries [TRI_shape_size_t] -/// - each entry consists of: -/// -/// - attribute ID (aid) [TRI_shape_aid_t] -/// - offset to string value, measured from the beginning of the legend -/// [TRI_shape_size_t] -/// -/// The entries in the attribute-ID table are sorted by ascending order of -/// shape IDs to allow for binary search if needed. -/// -/// Description of the shape table: -/// -/// - number of entries [TRI_shape_size_t] -/// - each entry consists of: -/// -/// - shape ID (sid) [TRI_shape_sid_t] -/// - offset to shape data, measured from the beginning of the legend -/// [TRI_shape_size_t] -/// - size in bytes of the shape data for this shape ID [TRI_shape_size_t] -/// -/// The entries in the shape table are sorted by ascending order of -/// shape IDs to allow for binary search if needed. -/// -/// The strings for the attribute IDs are stored one after another, each -/// including a terminating zero byte. At the end of the string data follow -/// zero bytes to pad to a total length that is divisible by 8. -/// -/// The actual entries of the shape data is stored one after another. Alignment -/// for each entry is automatically given by the length of the shape data. At -/// the end there is padding to make the length of the total legend divisible -/// by 8. -/// -/// Note that the builtin shapes are never dumped and that proper legends -/// contain all attribute IDs -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -/// @brief clear all data to build a new legend, keep shaper -//////////////////////////////////////////////////////////////////////////////// - -void JsonLegend::clear() { - _have_attribute.clear(); - _attribs.clear(); - _att_data.clear(); - _have_shape.clear(); - _shapes.clear(); - _shape_data.clear(); -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief add an attribute ID to the legend -//////////////////////////////////////////////////////////////////////////////// - -int JsonLegend::addAttributeId(TRI_shape_aid_t aid) { - auto it = _have_attribute.find(aid); - - if (it != _have_attribute.end()) { - return TRI_ERROR_NO_ERROR; - } - - char const* p = _shaper->lookupAttributeId(aid); - - if (nullptr == p) { - return TRI_ERROR_AID_NOT_FOUND; - } - - _have_attribute.insert(it, aid); - size_t len = strlen(p); - _attribs.emplace_back(aid, _att_data.length()); - _att_data.appendText(p, len + 1); // including the zero byte - - return TRI_ERROR_NO_ERROR; -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief add a shape to the legend -//////////////////////////////////////////////////////////////////////////////// - -int JsonLegend::addShape(TRI_shape_sid_t sid, char const* data, uint32_t len) { - // data and len must always be given, because in general we might have - // to sniff recursively into the subobjects. :-( - int res = TRI_ERROR_NO_ERROR; - - TRI_ASSERT(data != nullptr); - - TRI_shape_t const* shape = nullptr; - - // First the trivial cases: - if (sid < Shaper::firstCustomShapeId()) { - shape = Shaper::lookupSidBasicShape(sid); - - TRI_ASSERT(shape != nullptr); - } else { - shape = _shaper->lookupShapeId(sid); - - if (nullptr == shape) { - return TRI_ERROR_LEGEND_INCOMPLETE; - } - - auto it = _have_shape.find(sid); - - if (it == _have_shape.end()) { - _have_shape.insert(it, sid); - Shape sh(sid, _shape_data.length(), shape->_size); - _shapes.push_back(sh); - _shape_data.appendText(reinterpret_cast(shape), - static_cast(shape->_size)); - } - } - - // Now we have to add all attribute IDs and all shapes used by this - // one recursively, note that the data of this object is in a - // consistent state, such that we can call ourselves recursively. - - if (shape->_type == TRI_SHAPE_HOMOGENEOUS_SIZED_LIST) { - // Handle a homogeneous list with equal size entries. Note that - // this does not imply that no subobject contains any array or - // inhomogeneous list, because they could be lists that have the - // same size by sheer coincidence. Therefore we have to visit them - // all recursively. :-( - auto shape_spec = - reinterpret_cast(shape); - auto len = reinterpret_cast(data); - auto ptr = reinterpret_cast(len + 1); - res = TRI_ERROR_NO_ERROR; // just in case the length is 0 - TRI_shape_length_list_t i; - for (i = 0; i < *len; i++) { - res = addShape(shape_spec->_sidEntry, ptr, - static_cast(shape_spec->_sizeEntry)); - ptr += shape_spec->_sizeEntry; - if (res != TRI_ERROR_NO_ERROR) { - break; - } - } - } else if (shape->_type == TRI_SHAPE_HOMOGENEOUS_LIST) { - // Handle a homogeneous list: Only one sid, but the subobjects can - // contain inhomogeneous lists. - auto shape_spec = - reinterpret_cast(shape); - res = TRI_ERROR_NO_ERROR; // just in case the length is 0 - auto len = reinterpret_cast(data); - auto offsets = reinterpret_cast(len + 1); - TRI_shape_length_list_t i; - for (i = 0; i < *len; i++) { - res = addShape(shape_spec->_sidEntry, data + offsets[i], - static_cast(offsets[i + 1] - offsets[i])); - if (res != TRI_ERROR_NO_ERROR) { - break; - } - } - } else if (shape->_type == TRI_SHAPE_LIST) { - // Handle an inhomogeneous list: - // We have to scan recursively all entries of the list since they - // contain sids in the data area. - res = TRI_ERROR_NO_ERROR; // just in case the length is 0 - auto len = reinterpret_cast(data); - auto sids = reinterpret_cast(len + 1); - auto offsets = reinterpret_cast(sids + *len); - TRI_shape_length_list_t i; - - for (i = 0; i < *len; i++) { - res = addShape(sids[i], data + offsets[i], - static_cast(offsets[i + 1] - offsets[i])); - if (res != TRI_ERROR_NO_ERROR) { - break; - } - } - } else if (shape->_type == TRI_SHAPE_ARRAY) { - // Handle an array: - // Distinguish between fixed size subobjects and variable size - // subobjects. The fixed ones cannot contain inhomogeneous lists. - auto shape_spec = reinterpret_cast(shape); - auto sids = reinterpret_cast(shape_spec + 1); - auto aids = reinterpret_cast( - sids + (shape_spec->_fixedEntries + shape_spec->_variableEntries)); - auto offsetsF = reinterpret_cast( - aids + (shape_spec->_fixedEntries + shape_spec->_variableEntries)); - auto offsetsV = reinterpret_cast(data); - - TRI_shape_size_t i; - for (i = 0; - res == TRI_ERROR_NO_ERROR && - i < shape_spec->_fixedEntries + shape_spec->_variableEntries; - i++) { - res = addAttributeId(aids[i]); - } - for (i = 0; res == TRI_ERROR_NO_ERROR && i < shape_spec->_fixedEntries; - i++) { - // Fixed size subdocs cannot have inhomogeneous lists as subdocs: - res = addShape(sids[i], data + offsetsF[i], - static_cast(offsetsF[i + 1] - offsetsF[i])); - } - for (i = 0; res == TRI_ERROR_NO_ERROR && i < shape_spec->_variableEntries; - i++) { - addShape(sids[i + shape_spec->_fixedEntries], data + offsetsV[i], - static_cast(offsetsV[i + 1] - offsetsV[i])); - } - } - - return res; -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief round a value to the next multiple of 8 -//////////////////////////////////////////////////////////////////////////////// - -static inline TRI_shape_size_t roundup8(TRI_shape_size_t x) { - return (x + 7) - ((x + 7) & 7); -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief get the total size in bytes of the legend -//////////////////////////////////////////////////////////////////////////////// - -size_t JsonLegend::getSize() const { - // Add string pool size and shape pool size and add space for header - // and tables in bytes. - return sizeof(TRI_shape_size_t) // number of aids - + sizeof(AttributeId) * _attribs.size() // aid entries - + sizeof(TRI_shape_size_t) // number of sids - + sizeof(Shape) * _shapes.size() // sid entries - + static_cast( - roundup8(_att_data.length())) // string data, padded - + - static_cast( - roundup8(_shape_data.length())); // shape data, padded -} - -JsonLegend::AttributeComparerClass JsonLegend::AttributeComparerObject; -JsonLegend::ShapeComparerClass JsonLegend::ShapeComparerObject; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief dump the legend to the buffer pointed to by buf -//////////////////////////////////////////////////////////////////////////////// - -void JsonLegend::dump(void* buf) { - // Dump the resulting legend to a given buffer. - - // First sort the aids in ascending order: - sort(_attribs.begin(), _attribs.end(), AttributeComparerObject); - - // Then sort the sids in ascending order: - sort(_shapes.begin(), _shapes.end(), ShapeComparerObject); - - // Total length of table data to add to offsets: - TRI_shape_size_t socle = - sizeof(TRI_shape_size_t) + sizeof(AttributeId) * _attribs.size() + - sizeof(TRI_shape_size_t) + sizeof(Shape) * _shapes.size(); - - // Attribute ID table: - TRI_shape_size_t* p = reinterpret_cast(buf); - *p++ = _attribs.size(); - AttributeId* a = reinterpret_cast(p); - for (size_t i = 0; i < _attribs.size(); i++) { - _attribs[i].offset += socle; - *a++ = _attribs[i]; - _attribs[i].offset -= socle; - } - - // Add the length of the string data to socle for second table: - size_t const attDataLength = _att_data.length(); - socle += roundup8(attDataLength); - - // shape table: - size_t const n = _shapes.size(); - p = reinterpret_cast(a); - *p++ = n; - Shape* s = reinterpret_cast(p); - for (size_t i = 0; i < n; i++) { - _shapes[i].offset += socle; - *s++ = _shapes[i]; - _shapes[i].offset -= socle; - } - - // Attribute ID string data: - char* c = reinterpret_cast(s); - memcpy(c, _att_data.c_str(), attDataLength); - TRI_shape_size_t i = roundup8(attDataLength); - if (i > attDataLength) { - memset(c + attDataLength, 0, static_cast(i) - attDataLength); - } - c += i; - - // Shape data: - size_t const shapeDataLength = _shape_data.length(); - memcpy(c, _shape_data.c_str(), shapeDataLength); - i = roundup8(shapeDataLength); - if (i > shapeDataLength) { - memset(c + shapeDataLength, 0, static_cast(i) - shapeDataLength); - } -} diff --git a/arangod/VocBase/Legends.h b/arangod/VocBase/Legends.h deleted file mode 100644 index fc0904da44..0000000000 --- a/arangod/VocBase/Legends.h +++ /dev/null @@ -1,284 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -/// 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 Max Neunhoeffer -//////////////////////////////////////////////////////////////////////////////// - -#ifndef ARANGOD_VOC_BASE_LEGENDS_H -#define ARANGOD_VOC_BASE_LEGENDS_H 1 - -#include "Basics/Common.h" -#include "Basics/structures.h" -#include "Basics/StringBuffer.h" -#include "VocBase/shaped-json.h" -#include "VocBase/Shaper.h" - -namespace arangodb { -namespace basics { - -//////////////////////////////////////////////////////////////////////////////// -/// @brief one entry in the table of attribute IDs -//////////////////////////////////////////////////////////////////////////////// - -struct AttributeId { - TRI_shape_aid_t aid; - TRI_shape_size_t offset; - - AttributeId(TRI_shape_aid_t a, TRI_shape_size_t o) : aid(a), offset(o) {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief one entry in the table of shapes -//////////////////////////////////////////////////////////////////////////////// - -struct Shape { - TRI_shape_sid_t sid; - TRI_shape_size_t offset; - TRI_shape_size_t size; - - Shape(TRI_shape_sid_t sid, TRI_shape_size_t o, TRI_shape_size_t siz) - : sid(sid), offset(o), size(siz) {} -}; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief create a legend for one or more shaped json objects -//////////////////////////////////////////////////////////////////////////////// - -class JsonLegend { - ////////////////////////////////////////////////////////////////////////////// - /// @brief disable default constructor because we need a shaper - ////////////////////////////////////////////////////////////////////////////// - - JsonLegend() = delete; - - public: - ////////////////////////////////////////////////////////////////////////////// - /// @brief constructor, taking a shaper - ////////////////////////////////////////////////////////////////////////////// - - explicit JsonLegend(Shaper* shaper) - : _shaper(shaper), - _att_data(TRI_UNKNOWN_MEM_ZONE), - _shape_data(TRI_UNKNOWN_MEM_ZONE) {} - - ~JsonLegend() {} - - ////////////////////////////////////////////////////////////////////////////// - /// @brief clear all data and register a new shaper - ////////////////////////////////////////////////////////////////////////////// - - void reset(Shaper* shaper) { - clear(); - _shaper = shaper; - } - - ////////////////////////////////////////////////////////////////////////////// - /// @brief clear all data to build a new legend, keep shaper - ////////////////////////////////////////////////////////////////////////////// - - void clear(); - - ////////////////////////////////////////////////////////////////////////////// - /// @brief add an attribute ID to the legend - ////////////////////////////////////////////////////////////////////////////// - - int addAttributeId(TRI_shape_aid_t aid); - - ////////////////////////////////////////////////////////////////////////////// - /// @brief add a shape to the legend - ////////////////////////////////////////////////////////////////////////////// - - int addShape(TRI_shaped_json_t const* sh_json) { - return addShape(sh_json->_sid, sh_json->_data.data, sh_json->_data.length); - } - - int addShape(TRI_shape_sid_t sid, TRI_blob_t const* blob) { - return addShape(sid, blob->data, blob->length); - } - - int addShape(TRI_shape_sid_t sid, char const* data, uint32_t len); - - ////////////////////////////////////////////////////////////////////////////// - /// @brief get the total size in bytes of the legend - ////////////////////////////////////////////////////////////////////////////// - - size_t getSize() const; - - ////////////////////////////////////////////////////////////////////////////// - /// @brief dump the legend to the buffer pointed to by buf - ////////////////////////////////////////////////////////////////////////////// - - void dump(void* buf); - - private: - ////////////////////////////////////////////////////////////////////////////// - /// @brief the underlying shaper - ////////////////////////////////////////////////////////////////////////////// - - Shaper* _shaper; - - ////////////////////////////////////////////////////////////////////////////// - /// @brief used to sort attribute ID table by attribute ID - ////////////////////////////////////////////////////////////////////////////// - - static struct AttributeComparerClass { - bool operator()(AttributeId const& a, AttributeId const& b) { - return a.aid < b.aid; - } - } AttributeComparerObject; - - ////////////////////////////////////////////////////////////////////////////// - /// @brief used to sort shapes by shape ID - ////////////////////////////////////////////////////////////////////////////// - - static struct ShapeComparerClass { - bool operator()(Shape const& a, Shape const& b) { return a.sid < b.sid; } - } ShapeComparerObject; - - ////////////////////////////////////////////////////////////////////////////// - /// @brief remember which aids we already have - ////////////////////////////////////////////////////////////////////////////// - - std::unordered_set _have_attribute; - - ////////////////////////////////////////////////////////////////////////////// - /// @brief table of attribute IDs - ////////////////////////////////////////////////////////////////////////////// - - std::vector _attribs; - - ////////////////////////////////////////////////////////////////////////////// - /// @brief here we collect the string data for the attributes - ////////////////////////////////////////////////////////////////////////////// - - StringBuffer _att_data; - - ////////////////////////////////////////////////////////////////////////////// - /// @brief remember which sids we already have - ////////////////////////////////////////////////////////////////////////////// - - std::unordered_set _have_shape; - - ////////////////////////////////////////////////////////////////////////////// - /// @brief table of shapes - ////////////////////////////////////////////////////////////////////////////// - - std::vector _shapes; - - ////////////////////////////////////////////////////////////////////////////// - /// @brief here we collect the actual shape data - ////////////////////////////////////////////////////////////////////////////// - - StringBuffer _shape_data; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief a class to read a legend -//////////////////////////////////////////////////////////////////////////////// - -class LegendReader : public Shaper { - // This inherits from Shaper, note however, that at least - // for the time being it only implements lookupAttributeId and - // lookupShapeId. - - char const* _legend; - TRI_shape_size_t _numberAttributes; - AttributeId const* _aids; - TRI_shape_size_t _numberShapes; - Shape const* _shapes; - - public: - explicit LegendReader(char const* l) : Shaper(), _legend(l) { - auto p = reinterpret_cast(l); - _numberAttributes = *p++; - _aids = reinterpret_cast(p); - p = reinterpret_cast(_aids + _numberAttributes); - _numberShapes = *p++; - _shapes = reinterpret_cast(p); - } - - ~LegendReader() { - // nothing to do - } - - char const* lookupAttributeId(TRI_shape_aid_t aid) override final { - // binary search in AttributeIds - TRI_shape_size_t low = 0; - TRI_shape_size_t high = _numberAttributes; - TRI_shape_size_t mid; - - while (low < high) { - // at the beginning of the loop we always have: - // 0 <= low < high <= _numberAttributes - // thus 0 <= mid < _numberAttributes, so access is allowed - // and for ind (index of element to be found): - // low <= ind <= high - // Once low == high, we have either found it or found nothing - mid = (low + high) / 2; - if (_aids[mid].aid < aid) { - low = mid + 1; - } else { // Note: aids[mid].aid == aid possible, - // thus ind == high possible as well - high = mid; - } - } - if (low == high && high < _numberAttributes && _aids[low].aid == aid) { - return _legend + _aids[low].offset; - } - return nullptr; - } - - TRI_shape_t const* lookupShapeId(TRI_shape_sid_t sid) override final { - // Is it a builtin basic one? - if (sid < Shaper::firstCustomShapeId()) { - return Shaper::lookupSidBasicShape(sid); - } - - // binary search in Shapes - TRI_shape_size_t low = 0; - TRI_shape_size_t high = _numberShapes; - TRI_shape_size_t mid; - - while (low < high) { - // at the beginning of the loop we always have: - // 0 <= low < high <= _numberShapes - // thus 0 <= mid < _numberShapes, so access is allowed - // and for ind (index of element to be found): - // low <= ind <= high - // Once low == high, we have either found it or found nothing - mid = (low + high) / 2; - if (_shapes[mid].sid < sid) { - low = mid + 1; - } else { // Note: _shapes[mid].sid == sid possible, - // thus ind == high possible as well - high = mid; - } - } - if (low == high && high < _numberShapes && _shapes[low].sid == sid) { - return reinterpret_cast(_legend + - _shapes[low].offset); - } - return nullptr; - } -}; -} -} - -#endif diff --git a/arangod/VocBase/collection.cpp b/arangod/VocBase/collection.cpp index cb53451d20..dfc14acbf1 100644 --- a/arangod/VocBase/collection.cpp +++ b/arangod/VocBase/collection.cpp @@ -409,7 +409,7 @@ static bool CheckCollection(TRI_collection_t* collection, bool ignoreErrors) { char* ptr = datafile->_data; // skip the datafile header - ptr += TRI_DF_ALIGN_BLOCK(sizeof(TRI_df_header_marker_t)); + ptr += AlignedSize(sizeof(TRI_df_header_marker_t)); cm = (TRI_col_header_marker_t*)ptr; if (cm->base._type != TRI_COL_MARKER_HEADER) { diff --git a/arangod/VocBase/compactor.cpp b/arangod/VocBase/compactor.cpp index 5d8d2d3c49..9b13d35476 100644 --- a/arangod/VocBase/compactor.cpp +++ b/arangod/VocBase/compactor.cpp @@ -172,14 +172,6 @@ struct compaction_info_t { bool _keepDeletions; }; -//////////////////////////////////////////////////////////////////////////////// -/// @brief return a marker's size -//////////////////////////////////////////////////////////////////////////////// - -static inline int64_t AlignedSize(TRI_df_marker_t const* marker) { - return static_cast(TRI_DF_ALIGN_BLOCK(marker->_size)); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief creates a compactor file, based on a datafile //////////////////////////////////////////////////////////////////////////////// @@ -412,7 +404,7 @@ static bool Compactifier(TRI_df_marker_t const* marker, void* data, if (deleted) { // found a dead document context->_dfi.numberDead++; - context->_dfi.sizeDead += AlignedSize(marker); + context->_dfi.sizeDead += AlignedMarkerSize(marker); LOG_TOPIC(TRACE, Logger::COMPACTOR) << "found a stale document: " << key; return true; } @@ -441,7 +433,7 @@ static bool Compactifier(TRI_df_marker_t const* marker, void* data, } context->_dfi.numberAlive++; - context->_dfi.sizeAlive += AlignedSize(marker); + context->_dfi.sizeAlive += AlignedMarkerSize(marker); } // deletions @@ -564,13 +556,13 @@ static bool CalculateSize(TRI_df_marker_t const* marker, void* data, } context->_keepDeletions = true; - context->_targetSize += AlignedSize(marker); + context->_targetSize += AlignedMarkerSize(marker); } // deletions else if (marker->_type == TRI_DOC_MARKER_KEY_DELETION && context->_keepDeletions) { - context->_targetSize += AlignedSize(marker); + context->_targetSize += AlignedMarkerSize(marker); } return true; diff --git a/arangod/VocBase/datafile.cpp b/arangod/VocBase/datafile.cpp index f74e9ca55a..5bed9cd673 100644 --- a/arangod/VocBase/datafile.cpp +++ b/arangod/VocBase/datafile.cpp @@ -543,7 +543,7 @@ static TRI_df_scan_t ScanDatafile(TRI_datafile_t const* datafile) { entry._position = (TRI_voc_size_t)(ptr - datafile->_data); entry._size = marker->_size; - entry._realSize = TRI_DF_ALIGN_BLOCK(marker->_size); + entry._realSize = AlignedMarkerSize(marker); entry._tick = marker->_tick; entry._type = marker->_type; entry._status = 1; @@ -630,7 +630,7 @@ static TRI_df_scan_t ScanDatafile(TRI_datafile_t const* datafile) { TRI_PushBackVector(&scan._entries, &entry); - size = TRI_DF_ALIGN_BLOCK(marker->_size); + size = AlignedMarkerSize(marker); currentSize += (TRI_voc_size_t)size; if (marker->_type == TRI_DF_MARKER_FOOTER) { @@ -758,8 +758,8 @@ static bool TryRepairDatafile(TRI_datafile_t* datafile) { } } - size_t size = TRI_DF_ALIGN_BLOCK(marker->_size); - currentSize += (TRI_voc_size_t)size; + size_t size = AlignedMarkerSize(marker); + currentSize += size; if (marker->_type == TRI_DF_MARKER_FOOTER) { return true; @@ -975,8 +975,8 @@ static bool CheckDatafile(TRI_datafile_t* datafile, bool ignoreFailures) { maxTick = marker->_tick; } - size_t size = TRI_DF_ALIGN_BLOCK(marker->_size); - currentSize += (TRI_voc_size_t)size; + size_t size = AlignedMarkerSize(marker); + currentSize += size; if (marker->_type == TRI_DF_MARKER_FOOTER) { LOG(DEBUG) << "found footer, reached end of datafile '" << datafile->getName(datafile) << "', current size " << currentSize; @@ -1537,7 +1537,7 @@ int TRI_ReserveElementDatafile(TRI_datafile_t* datafile, TRI_voc_size_t size, TRI_df_marker_t** position, TRI_voc_size_t maximalJournalSize) { *position = nullptr; - size = TRI_DF_ALIGN_BLOCK(size); + size = AlignedSize(size); if (datafile->_state != TRI_DF_STATE_WRITE) { if (datafile->_state == TRI_DF_STATE_READ) { @@ -1723,8 +1723,7 @@ bool TRI_IterateDatafile(TRI_datafile_t* datafile, } while (ptr < end) { - TRI_df_marker_t const* marker = - reinterpret_cast(ptr); + auto const* marker = reinterpret_cast(ptr); if (marker->_size == 0) { return true; @@ -1737,8 +1736,7 @@ bool TRI_IterateDatafile(TRI_datafile_t* datafile, return false; } - size_t size = TRI_DF_ALIGN_BLOCK(marker->_size); - ptr += size; + ptr += AlignedMarkerSize(marker); } return true; diff --git a/arangod/VocBase/datafile.h b/arangod/VocBase/datafile.h index bc9be74a95..fd2679231e 100644 --- a/arangod/VocBase/datafile.h +++ b/arangod/VocBase/datafile.h @@ -89,13 +89,7 @@ struct TRI_datafile_t; /// @brief datafile version //////////////////////////////////////////////////////////////////////////////// -#define TRI_DF_VERSION (1) - -//////////////////////////////////////////////////////////////////////////////// -/// @brief alignment in datafile blocks -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_DF_BLOCK_ALIGNMENT (8) +#define TRI_DF_VERSION (2) //////////////////////////////////////////////////////////////////////////////// /// @brief maximum size of a single marker (in bytes) @@ -546,12 +540,23 @@ char const* TRI_NameMarkerDatafile(TRI_df_marker_t const*); void TRI_InitMarkerDatafile(char*, TRI_df_marker_type_e, TRI_voc_size_t); //////////////////////////////////////////////////////////////////////////////// -/// @brief aligns in datafile blocks +/// @brief returns the 8-byte aligned size for the value //////////////////////////////////////////////////////////////////////////////// -#define TRI_DF_ALIGN_BLOCK(a) \ - ((((a) + TRI_DF_BLOCK_ALIGNMENT - 1) / TRI_DF_BLOCK_ALIGNMENT) * \ - TRI_DF_BLOCK_ALIGNMENT) +template +static inline T AlignedSize(T value) { + return (value + 7) - ((value + 7) & 7); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the 8-byte aligned size for the marker +//////////////////////////////////////////////////////////////////////////////// + +template +static inline T AlignedMarkerSize(TRI_df_marker_t const* marker) { + size_t value = marker->_size; + return static_cast((value + 7) - ((value + 7) & 7)); +} //////////////////////////////////////////////////////////////////////////////// /// @brief returns the marker-specific offset to the vpack payload diff --git a/arangod/VocBase/document-collection.cpp b/arangod/VocBase/document-collection.cpp index 6f00fb2091..21f81fea7a 100644 --- a/arangod/VocBase/document-collection.cpp +++ b/arangod/VocBase/document-collection.cpp @@ -817,11 +817,11 @@ static int OpenIteratorHandleDocumentMarker(TRI_df_marker_t const* marker, TRI_document_collection_t* document = state->_document; arangodb::Transaction* trx = state->_trx; - VPackSlice const slice(reinterpret_cast(marker + sizeof(arangodb::wal::vpack_document_marker_t))); + VPackSlice const slice(reinterpret_cast(marker) + VPackOffset(TRI_WAL_MARKER_VPACK_DOCUMENT)); VPackSlice const keySlice = slice.get(TRI_VOC_ATTRIBUTE_KEY); std::string const key(keySlice.copyString()); TRI_voc_rid_t const rid = std::stoull(slice.get(TRI_VOC_ATTRIBUTE_REV).copyString()); - + SetRevision(document, rid, false); document->_keyGenerator->track(key); @@ -858,7 +858,7 @@ static int OpenIteratorHandleDocumentMarker(TRI_df_marker_t const* marker, if (res != TRI_ERROR_NO_ERROR) { document->_masterPointers.release(header, true); // ONLY IN OPENITERATOR - LOG(ERR) << "inserting document into indexes failed with error: " << TRI_errno_string(res); + LOG(ERR) << "inserting document into primary index failed with error: " << TRI_errno_string(res); return res; } @@ -867,7 +867,7 @@ static int OpenIteratorHandleDocumentMarker(TRI_df_marker_t const* marker, // update the datafile info state->_dfi->numberAlive++; - state->_dfi->sizeAlive += (int64_t)TRI_DF_ALIGN_BLOCK(marker->_size); + state->_dfi->sizeAlive += AlignedMarkerSize(marker); } // it is an update, but only if found has a smaller revision identifier @@ -877,9 +877,9 @@ static int OpenIteratorHandleDocumentMarker(TRI_df_marker_t const* marker, TRI_doc_mptr_t oldData = *found; // update the header info + found->_rid = rid; found->_fid = fid; found->setDataPtr(marker); - found->_rid = rid; document->_masterPointers.moveBack(found, &oldData); // ONLY IN OPENITERATOR @@ -892,17 +892,16 @@ static int OpenIteratorHandleDocumentMarker(TRI_df_marker_t const* marker, } if (oldData.getDataPtr() != nullptr) { - int64_t size = (int64_t)((TRI_df_marker_t const*)oldData.getDataPtr()) - ->_size; // ONLY IN OPENITERATOR, PROTECTED by RUNTIME + int64_t size = static_cast(oldData.getMarkerPtr()->_size); dfi->numberAlive--; - dfi->sizeAlive -= TRI_DF_ALIGN_BLOCK(size); + dfi->sizeAlive -= AlignedSize(size); dfi->numberDead++; - dfi->sizeDead += TRI_DF_ALIGN_BLOCK(size); + dfi->sizeDead += AlignedSize(size); } state->_dfi->numberAlive++; - state->_dfi->sizeAlive += (int64_t)TRI_DF_ALIGN_BLOCK(marker->_size); + state->_dfi->sizeAlive += AlignedMarkerSize(marker); } // it is a stale update @@ -910,9 +909,7 @@ static int OpenIteratorHandleDocumentMarker(TRI_df_marker_t const* marker, TRI_ASSERT(found->getDataPtr() != nullptr); state->_dfi->numberDead++; - state->_dfi->sizeDead += (int64_t)TRI_DF_ALIGN_BLOCK( - ((TRI_df_marker_t*)found->getDataPtr()) - ->_size); // ONLY IN OPENITERATOR, PROTECTED by RUNTIME + state->_dfi->sizeDead += AlignedSize(found->getMarkerPtr()->_size); } return TRI_ERROR_NO_ERROR; @@ -928,11 +925,11 @@ static int OpenIteratorHandleDeletionMarker(TRI_df_marker_t const* marker, TRI_document_collection_t* document = state->_document; arangodb::Transaction* trx = state->_trx; - VPackSlice const slice(reinterpret_cast(marker + sizeof(arangodb::wal::vpack_remove_marker_t))); + VPackSlice const slice(reinterpret_cast(marker) + VPackOffset(TRI_WAL_MARKER_VPACK_REMOVE)); VPackSlice const keySlice = slice.get(TRI_VOC_ATTRIBUTE_KEY); std::string const key(keySlice.copyString()); TRI_voc_rid_t const rid = std::stoull(slice.get(TRI_VOC_ATTRIBUTE_REV).copyString()); - + SetRevision(document, rid, false); document->_keyGenerator->track(key); @@ -966,16 +963,14 @@ static int OpenIteratorHandleDeletionMarker(TRI_df_marker_t const* marker, dfi = FindDatafileStats(state, found->_fid); } - TRI_ASSERT(found->getDataPtr() != - nullptr); // ONLY IN OPENITERATOR, PROTECTED by RUNTIME + TRI_ASSERT(found->getDataPtr() != nullptr); - int64_t size = (int64_t)((TRI_df_marker_t*)found->getDataPtr()) - ->_size; // ONLY IN OPENITERATOR, PROTECTED by RUNTIME + int64_t size = AlignedSize(found->getMarkerPtr()->_size); dfi->numberAlive--; - dfi->sizeAlive -= TRI_DF_ALIGN_BLOCK(size); + dfi->sizeAlive -= AlignedSize(size); dfi->numberDead++; - dfi->sizeDead += TRI_DF_ALIGN_BLOCK(size); + dfi->sizeDead += AlignedSize(size); state->_dfi->numberDeletions++; DeletePrimaryIndex(trx, document, found, false); @@ -1000,8 +995,6 @@ static bool OpenIterator(TRI_df_marker_t const* marker, void* data, int res; -LOG(INFO) << "scanning " << TRI_NameMarkerDatafile(marker); - if (marker->_type == TRI_WAL_MARKER_VPACK_DOCUMENT) { res = OpenIteratorHandleDocumentMarker(marker, datafile, static_cast(data)); diff --git a/arangod/VocBase/document-collection.h b/arangod/VocBase/document-collection.h index 073e50f883..62bfa03300 100644 --- a/arangod/VocBase/document-collection.h +++ b/arangod/VocBase/document-collection.h @@ -90,6 +90,14 @@ struct TRI_doc_mptr_t { _dataptr = that._dataptr; _hash = that._hash; } + + ////////////////////////////////////////////////////////////////////////////// + /// @brief return a pointer to the beginning of the marker + ////////////////////////////////////////////////////////////////////////////// + + inline struct TRI_df_marker_t const* getMarkerPtr() const { + return static_cast(_dataptr); + } ////////////////////////////////////////////////////////////////////////////// /// @brief return a pointer to the beginning of the marker diff --git a/arangod/VocBase/headers.cpp b/arangod/VocBase/headers.cpp index 7e73ab1bd5..33a6d86de1 100644 --- a/arangod/VocBase/headers.cpp +++ b/arangod/VocBase/headers.cpp @@ -41,12 +41,12 @@ static inline size_t GetBlockSize(size_t blockNumber) { if (blockNumber < 8) { // use a small block size in the beginning to save memory - return (size_t)(BLOCK_SIZE_UNIT << blockNumber); + return static_cast(BLOCK_SIZE_UNIT << blockNumber); } // use a block size of 32768 // this will use 32768 * sizeof(TRI_doc_mptr_t) bytes, i.e. 1.5 MB - return (size_t)(BLOCK_SIZE_UNIT << 8); + return static_cast(BLOCK_SIZE_UNIT << 8); } //////////////////////////////////////////////////////////////////////////////// @@ -99,15 +99,11 @@ void TRI_headers_t::moveBack(TRI_doc_mptr_t* header, TRI_doc_mptr_t const* old) TRI_ASSERT(old->getDataPtr() != nullptr); // ONLY IN HEADERS, PROTECTED by RUNTIME - int64_t newSize = - (int64_t)(((TRI_df_marker_t*)header->getDataPtr()) - ->_size); // ONLY IN HEADERS, PROTECTED by RUNTIME - int64_t oldSize = - (int64_t)(((TRI_df_marker_t*)old->getDataPtr()) - ->_size); // ONLY IN HEADERS, PROTECTED by RUNTIME + int64_t newSize = static_cast(header->getMarkerPtr()->_size); + int64_t oldSize = static_cast(old->getMarkerPtr()->_size); // we must adjust the size of the collection - _totalSize += (TRI_DF_ALIGN_BLOCK(newSize) - TRI_DF_ALIGN_BLOCK(oldSize)); + _totalSize += (AlignedSize(newSize) - AlignedSize(oldSize)); TRI_ASSERT(_totalSize > 0); } @@ -123,26 +119,19 @@ void TRI_headers_t::move(TRI_doc_mptr_t* header, TRI_doc_mptr_t const* old) { } TRI_ASSERT(_nrAllocated > 0); - TRI_ASSERT(header->getDataPtr() != - nullptr); // ONLY IN HEADERS, PROTECTED by RUNTIME - TRI_ASSERT(((TRI_df_marker_t*)header->getDataPtr())->_size > - 0); // ONLY IN HEADERS, PROTECTED by RUNTIME + TRI_ASSERT(header->getDataPtr() != nullptr); + TRI_ASSERT(header->getMarkerPtr()->_size > 0); TRI_ASSERT(old != nullptr); - TRI_ASSERT(old->getDataPtr() != - nullptr); // ONLY IN HEADERS, PROTECTED by RUNTIME + TRI_ASSERT(old->getDataPtr() != nullptr); - int64_t newSize = - (int64_t)(((TRI_df_marker_t*)header->getDataPtr()) - ->_size); // ONLY IN HEADERS, PROTECTED by RUNTIME - int64_t oldSize = - (int64_t)(((TRI_df_marker_t*)old->getDataPtr()) - ->_size); // ONLY IN HEADERS, PROTECTED by RUNTIME + int64_t newSize = static_cast(header->getMarkerPtr()->_size); + int64_t oldSize = static_cast(old->getMarkerPtr()->_size); // Please note the following: This operation is only used to revert an // update operation. The "new" document is removed again and the "old" // one is used once more. Therefore, the signs in the following statement // are actually OK: - _totalSize -= (TRI_DF_ALIGN_BLOCK(newSize) - TRI_DF_ALIGN_BLOCK(oldSize)); + _totalSize -= (AlignedSize(newSize) - AlignedSize(oldSize)); } //////////////////////////////////////////////////////////////////////////////// @@ -151,16 +140,14 @@ void TRI_headers_t::move(TRI_doc_mptr_t* header, TRI_doc_mptr_t const* old) { void TRI_headers_t::unlink(TRI_doc_mptr_t* header) { TRI_ASSERT(header != nullptr); - TRI_ASSERT(header->getDataPtr() != - nullptr); // ONLY IN HEADERS, PROTECTED by RUNTIME + TRI_ASSERT(header->getDataPtr() != nullptr); - int64_t size = (int64_t)((TRI_df_marker_t*)header->getDataPtr()) - ->_size; // ONLY IN HEADERS, PROTECTED by RUNTIME + int64_t size = static_cast(header->getMarkerPtr()->_size); TRI_ASSERT(size > 0); TRI_ASSERT(_nrLinked > 0); _nrLinked--; - _totalSize -= TRI_DF_ALIGN_BLOCK(size); + _totalSize -= AlignedSize(size); if (_nrLinked == 0) { TRI_ASSERT(_totalSize == 0); @@ -179,16 +166,13 @@ void TRI_headers_t::relink(TRI_doc_mptr_t* header, TRI_doc_mptr_t const* old) { return; } - TRI_ASSERT(header->getDataPtr() != - nullptr); // ONLY IN HEADERS, PROTECTED by RUNTIME - - int64_t size = (int64_t)((TRI_df_marker_t*)header->getDataPtr()) - ->_size; // ONLY IN HEADERS, PROTECTED by RUNTIME + TRI_ASSERT(header->getDataPtr() != nullptr); + int64_t size = static_cast(header->getMarkerPtr()->_size); TRI_ASSERT(size > 0); this->move(header, old); _nrLinked++; - _totalSize += TRI_DF_ALIGN_BLOCK(size); + _totalSize += AlignedSize(size); TRI_ASSERT(_totalSize > 0); } @@ -245,7 +229,7 @@ TRI_doc_mptr_t* TRI_headers_t::request(size_t size) { _nrAllocated++; _nrLinked++; - _totalSize += (int64_t)TRI_DF_ALIGN_BLOCK(size); + _totalSize += AlignedSize(size); return result; } @@ -294,7 +278,6 @@ void TRI_headers_t::release(TRI_doc_mptr_t* header, bool unlinkHeader) { void TRI_headers_t::adjustTotalSize(int64_t oldSize, int64_t newSize) { // oldSize = size of marker in WAL // newSize = size of marker in datafile - - _totalSize -= (TRI_DF_ALIGN_BLOCK(oldSize) - TRI_DF_ALIGN_BLOCK(newSize)); + _totalSize -= (AlignedSize(oldSize) - AlignedSize(newSize)); } diff --git a/arangod/VocBase/replication-dump.cpp b/arangod/VocBase/replication-dump.cpp index 51631d6db5..95ce2266b9 100644 --- a/arangod/VocBase/replication-dump.cpp +++ b/arangod/VocBase/replication-dump.cpp @@ -867,7 +867,7 @@ static int DumpCollection(TRI_replication_dump_t* dump, break; } - ptr += TRI_DF_ALIGN_BLOCK(marker->_size); + ptr += AlignedMarkerSize(marker); if (marker->_type == TRI_DF_MARKER_BLANK) { // fully ignore these marker types. they don't need to be replicated, @@ -1051,7 +1051,7 @@ int TRI_DumpLogReplication( break; } - ptr += TRI_DF_ALIGN_BLOCK(marker->_size); + ptr += AlignedMarkerSize(marker); // get the marker's tick and check whether we should include it TRI_voc_tick_t foundTick = marker->_tick; @@ -1180,7 +1180,7 @@ int TRI_DetermineOpenTransactionsReplication(TRI_replication_dump_t* dump, break; } - ptr += TRI_DF_ALIGN_BLOCK(marker->_size); + ptr += AlignedMarkerSize(marker); // get the marker's tick and check whether we should include it TRI_voc_tick_t foundTick = marker->_tick; diff --git a/arangod/VocBase/shaped-json.cpp b/arangod/VocBase/shaped-json.cpp index f919bd79b0..5828b8dc5a 100644 --- a/arangod/VocBase/shaped-json.cpp +++ b/arangod/VocBase/shaped-json.cpp @@ -29,7 +29,6 @@ #include "Basics/tri-strings.h" #include "Basics/vector.h" #include "Basics/VelocyPackHelper.h" -#include "VocBase/Legends.h" #include "VocBase/VocShaper.h" // #define DEBUG_JSON_SHAPER 1 @@ -2592,6 +2591,3 @@ void TRI_PrintShapeValues(TRI_shape_value_t* values, size_t n) { template bool TRI_StringifyArrayShapedJson( VocShaper*, struct TRI_string_buffer_t*, TRI_shaped_json_t const*, bool); -template bool TRI_StringifyArrayShapedJson( - arangodb::basics::LegendReader*, struct TRI_string_buffer_t*, - TRI_shaped_json_t const*, bool); diff --git a/arangod/VocBase/transaction.cpp b/arangod/VocBase/transaction.cpp index 98000ed0ce..617bd96599 100644 --- a/arangod/VocBase/transaction.cpp +++ b/arangod/VocBase/transaction.cpp @@ -208,11 +208,10 @@ static void FreeOperations(TRI_transaction_t* trx) { auto it2 = stats.find(fid); if (it2 == stats.end()) { - stats.emplace(fid, - std::make_pair(1, TRI_DF_ALIGN_BLOCK(marker->_size))); + stats.emplace(fid, std::make_pair(1, AlignedMarkerSize(marker))); } else { (*it2).second.first++; - (*it2).second.second += TRI_DF_ALIGN_BLOCK(marker->_size); + (*it2).second.second += AlignedMarkerSize(marker); } } } @@ -1141,8 +1140,7 @@ int TRI_AddOperationTransaction(TRI_transaction_t* trx, TRI_df_marker_t const* marker = static_cast( operation.oldHeader.getDataPtr()); // PROTECTED by trx from above document->_datafileStatistics.increaseDead( - operation.oldHeader._fid, 1, - static_cast(TRI_DF_ALIGN_BLOCK(marker->_size))); + operation.oldHeader._fid, 1, AlignedMarkerSize(marker)); } } else { // operation is buffered and might be rolled back diff --git a/arangod/Wal/CollectorThread.cpp b/arangod/Wal/CollectorThread.cpp index 1688d584db..b2ca59c6ed 100644 --- a/arangod/Wal/CollectorThread.cpp +++ b/arangod/Wal/CollectorThread.cpp @@ -163,12 +163,12 @@ static bool ScanMarker(TRI_df_marker_t const* marker, void* data, case TRI_DF_MARKER_PROLOGUE: { auto const* m = reinterpret_cast(marker); state->resetCollection(m->_databaseId, m->_collectionId); - return true; + break; } case TRI_WAL_MARKER_VPACK_DOCUMENT: { - TRI_voc_tick_t databaseId = state->lastDatabaseId; - TRI_voc_cid_t collectionId = state->lastCollectionId; + TRI_voc_tick_t const databaseId = state->lastDatabaseId; + TRI_voc_cid_t const collectionId = state->lastCollectionId; TRI_ASSERT(databaseId > 0); TRI_ASSERT(collectionId > 0); @@ -196,8 +196,8 @@ static bool ScanMarker(TRI_df_marker_t const* marker, void* data, } case TRI_WAL_MARKER_VPACK_REMOVE: { - TRI_voc_tick_t databaseId = state->lastDatabaseId; - TRI_voc_cid_t collectionId = state->lastCollectionId; + TRI_voc_tick_t const databaseId = state->lastDatabaseId; + TRI_voc_cid_t const collectionId = state->lastCollectionId; TRI_ASSERT(databaseId > 0); TRI_ASSERT(collectionId > 0); @@ -231,7 +231,7 @@ static bool ScanMarker(TRI_df_marker_t const* marker, void* data, case TRI_WAL_MARKER_VPACK_ABORT_TRANSACTION: { VPackSlice const slice(p + sizeof(TRI_df_marker_t)); - TRI_voc_tid_t tid = NumericValue(slice, "tid"); + TRI_voc_tid_t const tid = NumericValue(slice, "tid"); // note which abort markers we found state->handledTransactions.emplace(tid); @@ -240,42 +240,42 @@ static bool ScanMarker(TRI_df_marker_t const* marker, void* data, case TRI_WAL_MARKER_CREATE_COLLECTION: { VPackSlice const slice(p + sizeof(TRI_df_marker_t)); - TRI_voc_tid_t cid = NumericValue(slice, "cid"); + TRI_voc_tid_t const collectionId = NumericValue(slice, "cid"); // note that the collection is now considered not dropped - state->droppedCollections.erase(cid); + state->droppedCollections.erase(collectionId); break; } case TRI_WAL_MARKER_DROP_COLLECTION: { VPackSlice const slice(p + sizeof(TRI_df_marker_t)); - TRI_voc_tid_t cid = NumericValue(slice, "cid"); + TRI_voc_tid_t const collectionId = NumericValue(slice, "cid"); // note that the collection was dropped and doesn't need to be collected - state->droppedCollections.emplace(cid); - state->structuralOperations.erase(cid); - state->documentOperations.erase(cid); - state->operationsCount.erase(cid); - state->collections.erase(cid); + state->droppedCollections.emplace(collectionId); + state->structuralOperations.erase(collectionId); + state->documentOperations.erase(collectionId); + state->operationsCount.erase(collectionId); + state->collections.erase(collectionId); break; } case TRI_WAL_MARKER_CREATE_DATABASE: { VPackSlice const slice(p + sizeof(TRI_df_marker_t)); - TRI_voc_tick_t id = NumericValue(slice, "database"); + TRI_voc_tick_t database = NumericValue(slice, "database"); // note that the database is now considered not dropped - state->droppedDatabases.erase(id); + state->droppedDatabases.erase(database); break; } case TRI_WAL_MARKER_DROP_DATABASE: { VPackSlice const slice(p + sizeof(TRI_df_marker_t)); - TRI_voc_tick_t id = NumericValue(slice, "database"); + TRI_voc_tick_t database = NumericValue(slice, "database"); // note that the database was dropped and doesn't need to be collected - state->droppedDatabases.emplace(id); + state->droppedDatabases.emplace(database); // find all collections for the same database and erase their state, too for (auto it = state->collections.begin(); it != state->collections.end(); /* no hoisting */) { - if ((*it).second == id) { + if ((*it).second == database) { state->droppedCollections.emplace((*it).first); state->structuralOperations.erase((*it).first); state->documentOperations.erase((*it).first); @@ -305,7 +305,7 @@ static bool ScanMarker(TRI_df_marker_t const* marker, void* data, case TRI_DF_MARKER_FOOTER: { // new datafile or end of datafile. forget state! state->resetCollection(); - return true; + break; } default: { @@ -699,12 +699,12 @@ void CollectorThread::processCollectionMarker( // somebody inserted a new revision of the document or the revision // was already moved by the compactor dfi.numberDead++; - dfi.sizeDead += (int64_t)TRI_DF_ALIGN_BLOCK(datafileMarkerSize); + dfi.sizeDead += AlignedSize(datafileMarkerSize); } else { // update size info document->_masterPointers.adjustTotalSize( - TRI_DF_ALIGN_BLOCK(walMarker->_size), - TRI_DF_ALIGN_BLOCK(datafileMarkerSize)); + AlignedSize(walMarker->_size), + AlignedSize(datafileMarkerSize)); // we can safely update the master pointer's dataptr value found->setDataPtr( @@ -712,7 +712,7 @@ void CollectorThread::processCollectionMarker( found->_fid = fid; dfi.numberAlive++; - dfi.sizeAlive += (int64_t)TRI_DF_ALIGN_BLOCK(datafileMarkerSize); + dfi.sizeAlive += AlignedSize(datafileMarkerSize); } } else if (walMarker->_type == TRI_WAL_MARKER_VPACK_REMOVE) { auto& dfi = createDfi(cache, fid); @@ -729,7 +729,7 @@ void CollectorThread::processCollectionMarker( if (found != nullptr && found->_rid > revisionId) { // somebody re-created the document with a newer revision dfi.numberDead++; - dfi.sizeDead += (int64_t)TRI_DF_ALIGN_BLOCK(datafileMarkerSize); + dfi.sizeDead += AlignedSize(datafileMarkerSize); } } } @@ -1219,7 +1219,7 @@ char* CollectorThread::nextFreeMarkerPosition( TRI_document_collection_t* document, TRI_voc_tick_t tick, TRI_df_marker_type_e type, TRI_voc_size_t size, CollectorCache* cache) { TRI_collection_t* collection = document; - size = TRI_DF_ALIGN_BLOCK(size); + size = AlignedSize(size); char* dst = nullptr; TRI_datafile_t* datafile = nullptr; diff --git a/arangod/Wal/Logfile.cpp b/arangod/Wal/Logfile.cpp index f98943c5bf..62ffea631d 100644 --- a/arangod/Wal/Logfile.cpp +++ b/arangod/Wal/Logfile.cpp @@ -152,7 +152,7 @@ int Logfile::judge(std::string const& filename) { //////////////////////////////////////////////////////////////////////////////// char* Logfile::reserve(size_t size) { - size = TRI_DF_ALIGN_BLOCK(size); + size = AlignedSize(size); char* result = _df->_next; diff --git a/arangod/Wal/Marker.h b/arangod/Wal/Marker.h index c6808659d9..93272c6f25 100644 --- a/arangod/Wal/Marker.h +++ b/arangod/Wal/Marker.h @@ -150,10 +150,6 @@ class Marker { 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; } diff --git a/arangod/Wal/Slots.cpp b/arangod/Wal/Slots.cpp index 2a5a157aae..76f268cb47 100644 --- a/arangod/Wal/Slots.cpp +++ b/arangod/Wal/Slots.cpp @@ -131,7 +131,7 @@ SlotInfo Slots::nextUnused(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId static size_t const PrologueSize = sizeof(TRI_df_prologue_marker_t); // we need to use the aligned size for writing - uint32_t alignedSize = TRI_DF_ALIGN_BLOCK(size); + uint32_t alignedSize = AlignedSize(size); int iterations = 0; bool hasWaited = false; bool mustWritePrologue = false; @@ -231,7 +231,7 @@ SlotInfo Slots::nextUnused(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId // write prologue... // hand out the prologue slot and directly fill it - int res = writePrologue(slot, databaseId, collectionId); + int res = writePrologue(slot, mem, databaseId, collectionId); if (res != TRI_ERROR_NO_ERROR) { return SlotInfo(res); @@ -589,12 +589,10 @@ int Slots::writeHeader(Slot* slot) { TRI_df_header_marker_t header = _logfile->getHeaderMarker(); size_t const size = header.base._size; - TRI_df_marker_t* mem = - reinterpret_cast(_logfile->reserve(size)); + auto* mem = static_cast(_logfile->reserve(size)); TRI_ASSERT(mem != nullptr); - slot->setUsed(static_cast(mem), static_cast(size), - _logfile->id(), handout()); + slot->setUsed(mem, static_cast(size), _logfile->id(), handout()); slot->fill(&header.base, size); slot->setReturned(false); // no sync @@ -609,16 +607,13 @@ int Slots::writeHeader(Slot* slot) { /// @brief write a prologue marker //////////////////////////////////////////////////////////////////////////////// -int Slots::writePrologue(Slot* slot, TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId) { - TRI_df_header_marker_t header = _logfile->getHeaderMarker(); +int Slots::writePrologue(Slot* slot, void* mem, TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId) { + TRI_df_prologue_marker_t header = _logfile->getPrologueMarker(databaseId, collectionId); size_t const size = header.base._size; - TRI_df_marker_t* mem = - reinterpret_cast(_logfile->reserve(size)); TRI_ASSERT(mem != nullptr); - slot->setUsed(static_cast(mem), static_cast(size), - _logfile->id(), handout()); + slot->setUsed(mem, static_cast(size), _logfile->id(), handout()); slot->fill(&header.base, size); slot->setReturned(false); // no sync @@ -635,12 +630,10 @@ int Slots::writeFooter(Slot* slot) { TRI_df_footer_marker_t footer = _logfile->getFooterMarker(); size_t const size = footer.base._size; - TRI_df_marker_t* mem = - reinterpret_cast(_logfile->reserve(size)); + auto* mem = static_cast(_logfile->reserve(size)); TRI_ASSERT(mem != nullptr); - slot->setUsed(static_cast(mem), static_cast(size), - _logfile->id(), handout()); + slot->setUsed(mem, static_cast(size), _logfile->id(), handout()); slot->fill(&footer.base, size); slot->setReturned(true); // sync diff --git a/arangod/Wal/Slots.h b/arangod/Wal/Slots.h index a4f955f2fd..1d7fd6a470 100644 --- a/arangod/Wal/Slots.h +++ b/arangod/Wal/Slots.h @@ -165,7 +165,7 @@ class Slots { /// @brief writes a prologue for a document/remove marker ////////////////////////////////////////////////////////////////////////////// - int writePrologue(Slot*, TRI_voc_tick_t, TRI_voc_cid_t); + int writePrologue(Slot*, void*, TRI_voc_tick_t, TRI_voc_cid_t); ////////////////////////////////////////////////////////////////////////////// /// @brief write a footer marker