From d57328e0f2e948e5dfd707467e3942ecf2690179 Mon Sep 17 00:00:00 2001 From: Julia CP Date: Wed, 13 Aug 2025 11:31:41 -0300 Subject: [PATCH 1/8] Introduce supervised buffer template, must fix Builder.cpp to accomodate it --- include/velocypack/Buffer.h | 4 +- include/velocypack/Builder.h | 29 ++++---- src/Builder.cpp | 128 ++++++++++++++++++++--------------- 3 files changed, 90 insertions(+), 71 deletions(-) diff --git a/include/velocypack/Buffer.h b/include/velocypack/Buffer.h index 71d7b9f3..aacc2702 100644 --- a/include/velocypack/Buffer.h +++ b/include/velocypack/Buffer.h @@ -194,7 +194,7 @@ class Buffer { // Steal external memory; only allowed when the buffer is not local, // i.e. !usesLocalMemory() - T* steal() noexcept { + virtual T* steal() noexcept { VELOCYPACK_ASSERT(!usesLocalMemory()); auto buffer = _buffer; @@ -284,7 +284,7 @@ class Buffer { inline void poison(T*, ValueLength) noexcept {} #endif - void grow(ValueLength len) { + virtual void grow(ValueLength len) { VELOCYPACK_ASSERT(_size + len >= sizeof(_local)); // need reallocation diff --git a/include/velocypack/Builder.h b/include/velocypack/Builder.h index 9e10e81c..02d17bf7 100644 --- a/include/velocypack/Builder.h +++ b/include/velocypack/Builder.h @@ -50,6 +50,7 @@ namespace arangodb::velocypack { class ArrayIterator; class ObjectIterator; +template> class Builder { friend class Parser; // The parser needs access to internals. @@ -74,12 +75,12 @@ class Builder { // buffer. Whenever the stack is empty, one can use the start, // size and slice methods to get out the ready built VPack // object(s). + public: + using buffer_type = BufferType; private: - // Here we collect the result - std::shared_ptr> _buffer; - // used for quicker access than shared_ptr - Buffer* _bufferPtr; + std::shared_ptr _buffer; + BufferType* _bufferPtr; // Always points to the start of _buffer uint8_t* _start; // the append position @@ -114,19 +115,19 @@ class Builder { explicit Builder(Options const* options); // create an empty Builder, using an existing buffer and default Options - explicit Builder(std::shared_ptr> buffer); + explicit Builder(std::shared_ptr buffer); // create an empty Builder, using an existing buffer and Options - explicit Builder(std::shared_ptr> buffer, + explicit Builder(std::shared_ptr buffer, Options const* options); // create a Builder that uses an existing Buffer and default Options. // the Builder will not claim ownership for its Buffer - explicit Builder(Buffer& buffer) noexcept; + explicit Builder(BufferType& buffer) noexcept; // create a Builder that uses an existing Buffer. the Builder will not // claim ownership for this Buffer - explicit Builder(Buffer& buffer, Options const* options); + explicit Builder(BufferType& buffer, Options const* options); // populate a Builder from a Slice explicit Builder(Slice slice, Options const* options = &Options::Defaults); @@ -141,9 +142,9 @@ class Builder { // get a reference to the Builder's Buffer object // note: this object may be a nullptr if the buffer was already stolen // from the Builder, or if the Builder has no ownership for the Buffer - std::shared_ptr> const& buffer() const { return _buffer; } + std::shared_ptr const& buffer() const { return _buffer; } - Buffer& bufferRef() const { + BufferType& bufferRef() const { if (_bufferPtr == nullptr) { throw Exception(Exception::InternalError, "Builder has no Buffer"); } @@ -153,9 +154,9 @@ class Builder { // steal the Builder's Buffer object. afterwards the Builder // is unusable - note: this may return a nullptr if the Builder does not // own the Buffer! - std::shared_ptr> steal() { + std::shared_ptr steal() { // After a steal the Builder is broken! - std::shared_ptr> res(std::move(_buffer)); + std::shared_ptr res(std::move(_buffer)); _bufferPtr = nullptr; _start = nullptr; clear(); @@ -613,7 +614,7 @@ class Builder { close(); return *this; } - + void resetTo(std::size_t value) { _pos = value; VELOCYPACK_ASSERT(_bufferPtr != nullptr); @@ -1145,7 +1146,7 @@ struct ArrayBuilder final : public BuilderContainer, } // namespace arangodb::velocypack -using VPackBuilder = arangodb::velocypack::Builder; +using VPackBuilder = arangodb::velocypack::Builder>; using VPackBuilderNonDeleter = arangodb::velocypack::BuilderNonDeleter; using VPackBuilderContainer = arangodb::velocypack::BuilderContainer; using VPackObjectBuilder = arangodb::velocypack::ObjectBuilder; diff --git a/src/Builder.cpp b/src/Builder.cpp index a75ae5e5..1a2422c2 100644 --- a/src/Builder.cpp +++ b/src/Builder.cpp @@ -33,20 +33,20 @@ #include "velocypack/Iterator.h" #include "velocypack/Sink.h" -using namespace arangodb::velocypack; + namespace { // checks whether a memmove operation is allowed to get rid of the padding -bool isAllowedToMemmove(Options const* options, uint8_t const* start, - std::vector::iterator indexStart, - std::vector::iterator indexEnd, - ValueLength offsetSize) { +bool isAllowedToMemmove(arangodb::velocypack::Options const* options, uint8_t const* start, + std::vector::iterator indexStart, + std::vector::iterator indexEnd, + arangodb::velocypack::ValueLength offsetSize) { VELOCYPACK_ASSERT(offsetSize == 1 || offsetSize == 2); - if (options->paddingBehavior == Options::PaddingBehavior::NoPadding || + if (options->paddingBehavior == arangodb::velocypack::Options::PaddingBehavior::NoPadding || (offsetSize == 1 && - options->paddingBehavior == Options::PaddingBehavior::Flexible)) { + options->paddingBehavior == arangodb::velocypack::Options::PaddingBehavior::Flexible)) { std::size_t const distance = std::distance(indexStart, indexEnd); std::size_t const n = (std::min)(std::size_t(8 - 2 * offsetSize), distance); for (std::size_t i = 0; i < n; i++) { @@ -60,7 +60,7 @@ bool isAllowedToMemmove(Options const* options, uint8_t const* start, return false; } -uint8_t determineArrayType(bool needIndexTable, ValueLength offsetSize) { +uint8_t determineArrayType(bool needIndexTable, arangodb::velocypack::ValueLength offsetSize) { uint8_t type; // Now build the table: if (needIndexTable) { @@ -79,7 +79,7 @@ uint8_t determineArrayType(bool needIndexTable, ValueLength offsetSize) { return type; } -constexpr ValueLength linearAttributeUniquenessCutoff = 4; +constexpr arangodb::velocypack::ValueLength linearAttributeUniquenessCutoff = 4; // struct used when sorting index tables for objects: struct SortEntry { @@ -129,16 +129,16 @@ uint8_t const* findAttrName(uint8_t const* base, uint64_t& len) { return findAttrName(arangodb::velocypack::Slice(base).makeKey().start(), len); } -bool checkAttributeUniquenessUnsortedBrute(ObjectIterator& it) { +bool checkAttributeUniquenessUnsortedBrute(arangodb::velocypack::ObjectIterator& it) { std::array keys; do { // key(true) guarantees a String as returned type std::string_view key = it.key(true).stringView(); - ValueLength index = it.index(); + arangodb::velocypack::ValueLength index = it.index(); // compare with all other already looked-at keys - for (ValueLength i = 0; i < index; ++i) { + for (arangodb::velocypack::ValueLength i = 0; i < index; ++i) { if (VELOCYPACK_UNLIKELY(keys[i] == key)) { return false; } @@ -151,7 +151,7 @@ bool checkAttributeUniquenessUnsortedBrute(ObjectIterator& it) { return true; } -bool checkAttributeUniquenessUnsortedSet(ObjectIterator& it) { +bool checkAttributeUniquenessUnsortedSet(arangodb::velocypack::ObjectIterator& it) { #ifndef VELOCYPACK_NO_THREADLOCALS std::unique_ptr>& tmp = ::duplicateKeys; @@ -165,7 +165,7 @@ bool checkAttributeUniquenessUnsortedSet(ObjectIterator& it) { #endif do { - Slice key = it.key(true); + arangodb::velocypack::Slice key = it.key(true); // key(true) guarantees a String as returned type VELOCYPACK_ASSERT(key.isString()); if (VELOCYPACK_UNLIKELY(!tmp->emplace(key.stringView()).second)) { @@ -181,8 +181,9 @@ bool checkAttributeUniquenessUnsortedSet(ObjectIterator& it) { } // namespace // create an empty Builder, using default Options -Builder::Builder() - : _buffer(std::make_shared>()), +template +arangodb::velocypack::Builder::Builder() + : _buffer(std::make_shared()), _bufferPtr(_buffer.get()), _start(_bufferPtr->data()), _pos(0), @@ -195,7 +196,8 @@ Builder::Builder() } // create an empty Builder, using Options -Builder::Builder(Options const* opts) : Builder() { +template +arangodb::velocypack::Builder::Builder(arangodb::velocypack::Options const* opts) : Builder() { if (VELOCYPACK_UNLIKELY(opts == nullptr)) { throw Exception(Exception::InternalError, "Options cannot be a nullptr"); } @@ -203,7 +205,8 @@ Builder::Builder(Options const* opts) : Builder() { } // create an empty Builder, using an existing buffer and default Options -Builder::Builder(std::shared_ptr> buffer) +template +arangodb::velocypack::Builder::Builder(std::shared_ptr buffer) : _buffer(std::move(buffer)), _bufferPtr(_buffer.get()), _start(nullptr), @@ -223,7 +226,9 @@ Builder::Builder(std::shared_ptr> buffer) } // create an empty Builder, using an existing buffer -Builder::Builder(std::shared_ptr> buffer, Options const* opts) +template +arangodb::velocypack::Builder::Builder(std::shared_ptr buffer, + Options const* opts) : Builder(std::move(buffer)) { if (VELOCYPACK_UNLIKELY(opts == nullptr)) { throw Exception(Exception::InternalError, "Options cannot be a nullptr"); @@ -233,7 +238,8 @@ Builder::Builder(std::shared_ptr> buffer, Options const* opts) // create a Builder that uses an existing Buffer and options. // the Builder will not claim ownership for its Buffer -Builder::Builder(Buffer& buffer) noexcept +template +arangodb::velocypack::Builder::Builder(BufferType& buffer) noexcept : _bufferPtr(&buffer), _start(_bufferPtr->data()), _pos(buffer.size()), @@ -247,7 +253,8 @@ Builder::Builder(Buffer& buffer) noexcept // create a Builder that uses an existing Buffer. the Builder will not // claim ownership for its Buffer -Builder::Builder(Buffer& buffer, Options const* opts) +template +arangodb::velocypack::Builder::Builder(BufferType& buffer, Options const* opts) : Builder(buffer) { if (VELOCYPACK_UNLIKELY(opts == nullptr)) { throw Exception(Exception::InternalError, "Options cannot be a nullptr"); @@ -256,11 +263,13 @@ Builder::Builder(Buffer& buffer, Options const* opts) } // populate a Builder from a Slice -Builder::Builder(Slice slice, Options const* options) : Builder(options) { +arangodb::velocypack::Builder::Builder(Slice slice, Options const* options) + : Builder(options) { add(slice); } -Builder::Builder(Builder const& that) +template +arangodb::velocypack::Builder::Builder(Builder const& that) : _bufferPtr(nullptr), _start(nullptr), _pos(that._pos), @@ -276,7 +285,7 @@ Builder::Builder(Builder const& that) if (that._buffer == nullptr) { _bufferPtr = that._bufferPtr; } else { - _buffer = std::make_shared>(*that._buffer); + _buffer = std::make_shared(*that._buffer); _bufferPtr = _buffer.get(); } @@ -288,13 +297,14 @@ Builder::Builder(Builder const& that) _stack.reserve(arenaSize / sizeof(decltype(_stack)::value_type)); } -Builder& Builder::operator=(Builder const& that) { +template +arangodb::velocypack::Builder& arangodb::velocypack::Builder::operator=(Builder const& that) { if (this != &that) { if (that._buffer == nullptr) { _buffer.reset(); _bufferPtr = that._bufferPtr; } else { - _buffer = std::make_shared>(*that._buffer); + _buffer = std::make_shared(*that._buffer); _bufferPtr = _buffer.get(); } if (_bufferPtr == nullptr) { @@ -312,7 +322,8 @@ Builder& Builder::operator=(Builder const& that) { return *this; } -Builder::Builder(Builder&& that) noexcept +template +arangodb::velocypack::Builder::Builder(Builder&& that) noexcept : _buffer(std::move(that._buffer)), _bufferPtr(nullptr), _start(nullptr), @@ -339,7 +350,8 @@ Builder::Builder(Builder&& that) noexcept that.clear(); } -Builder& Builder::operator=(Builder&& that) noexcept { +template +arangodb::velocypack::Builder& Builder::operator=(arangodb::velocypack::Builder&& that) noexcept { if (this != &that) { _buffer = std::move(that._buffer); if (_buffer != nullptr) { @@ -366,7 +378,7 @@ Builder& Builder::operator=(Builder&& that) noexcept { return *this; } -std::string Builder::toString() const { +std::string Builder::toString() const { Options opts; opts.prettyPrint = true; @@ -376,14 +388,14 @@ std::string Builder::toString() const { return buffer; } -std::string Builder::toJson() const { +std::string Builder::toJson() const { std::string buffer; StringSink sink(&buffer); Dumper::dump(slice(), &sink); return buffer; } -void Builder::sortObjectIndexShort( +void Builder::sortObjectIndexShort( uint8_t* objBase, std::vector::iterator indexStart, std::vector::iterator indexEnd) const { std::sort(indexStart, indexEnd, @@ -407,7 +419,7 @@ void Builder::sortObjectIndexShort( }); } -void Builder::sortObjectIndexLong( +void Builder::sortObjectIndexLong( uint8_t* objBase, std::vector::iterator indexStart, std::vector::iterator indexEnd) const { #ifndef VELOCYPACK_NO_THREADLOCALS @@ -456,7 +468,8 @@ void Builder::sortObjectIndexLong( } } -Builder& Builder::closeEmptyArrayOrObject(ValueLength pos, bool isArray) { +Builder& Builder::closeEmptyArrayOrObject(ValueLength pos, + bool isArray) { // empty Array or Object _start[pos] = (isArray ? 0x01 : 0x0a); VELOCYPACK_ASSERT(_pos == pos + 9); @@ -465,7 +478,7 @@ Builder& Builder::closeEmptyArrayOrObject(ValueLength pos, bool isArray) { return *this; } -bool Builder::closeCompactArrayOrObject( +bool Builder::closeCompactArrayOrObject( ValueLength pos, bool isArray, std::vector::iterator indexStart, std::vector::iterator indexEnd) { @@ -523,9 +536,9 @@ bool Builder::closeCompactArrayOrObject( return false; } -Builder& Builder::closeArray(ValueLength pos, - std::vector::iterator indexStart, - std::vector::iterator indexEnd) { +Builder& Builder::closeArray( + ValueLength pos, std::vector::iterator indexStart, + std::vector::iterator indexEnd) { std::size_t const n = std::distance(indexStart, indexEnd); VELOCYPACK_ASSERT(n > 0); @@ -672,7 +685,7 @@ Builder& Builder::closeArray(ValueLength pos, return *this; } -Builder& Builder::close() { +Builder& Builder::close() { if (VELOCYPACK_UNLIKELY(isClosed())) { throw Exception(Exception::BuilderNeedOpenCompound); } @@ -854,12 +867,12 @@ Builder& Builder::close() { } // checks whether an Object value has a specific key attribute -bool Builder::hasKey(std::string_view key) const { +bool Builder::hasKey(std::string_view key) const { return !getKey(key).isNone(); } // return the value for a specific key of an Object value -Slice Builder::getKey(std::string_view key) const { +Slice Builder::getKey(std::string_view key) const { if (VELOCYPACK_UNLIKELY(_stack.empty())) { throw Exception(Exception::BuilderNeedOpenObject); } @@ -882,7 +895,7 @@ Slice Builder::getKey(std::string_view key) const { return Slice(); } -void Builder::appendTag(uint64_t tag) { +void Builder::appendTag(uint64_t tag) { if (options->disallowTags) { // Tagged values explicitly disallowed throw Exception(Exception::BuilderTagsDisallowed); @@ -898,7 +911,7 @@ void Builder::appendTag(uint64_t tag) { } } -uint8_t* Builder::set(Value const& item) { +uint8_t* Builder::set(Value const& item) { auto const oldPos = _pos; auto ctype = item.cType(); @@ -1165,7 +1178,7 @@ uint8_t* Builder::set(Value const& item) { return _start + oldPos; } -uint8_t* Builder::set(Slice const& item) { +uint8_t* Builder::set(Slice const& item) { checkKeyHasValidType(item); if (VELOCYPACK_UNLIKELY(options->disallowCustom && item.isCustom())) { @@ -1183,7 +1196,7 @@ uint8_t* Builder::set(Slice const& item) { return _start + _pos - l; } -uint8_t* Builder::set(ValuePair const& pair) { +uint8_t* Builder::set(ValuePair const& pair) { // This method builds a single further VPack item at the current // append position. This is the case for ValueType::String, // ValueType::Binary, or ValueType::Custom, which can be built @@ -1242,7 +1255,7 @@ uint8_t* Builder::set(ValuePair const& pair) { "ValueType::Custom are valid for ValuePair argument"); } -uint8_t* Builder::set(IStringFromParts const& parts) { +uint8_t* Builder::set(IStringFromParts const& parts) { // This method builds a single VPack String item composed of the 2 parts. auto const oldPos = _pos; @@ -1269,13 +1282,13 @@ uint8_t* Builder::set(IStringFromParts const& parts) { return _start + oldPos; } -void Builder::cleanupAdd() noexcept { +void Builder::cleanupAdd() noexcept { VELOCYPACK_ASSERT(!_stack.empty()); VELOCYPACK_ASSERT(!_indexes.empty()); _indexes.pop_back(); } -void Builder::reportAdd() { +void Builder::reportAdd() { VELOCYPACK_ASSERT(!_stack.empty()); if (_indexes.capacity() == 0) { // make an initial reservation for several items at @@ -1286,14 +1299,14 @@ void Builder::reportAdd() { _indexes.push_back(_pos - _stack.back().startPos); } -void Builder::closeLevel() noexcept { +void Builder::closeLevel() noexcept { VELOCYPACK_ASSERT(!_stack.empty()); ValueLength const indexStartPos = _stack.back().indexStartPos; _stack.pop_back(); _indexes.erase(_indexes.begin() + indexStartPos, _indexes.end()); } -bool Builder::checkAttributeUniqueness(Slice obj) const { +bool Builder::checkAttributeUniqueness(Slice obj) const { VELOCYPACK_ASSERT(options->checkAttributeUniqueness == true); VELOCYPACK_ASSERT(obj.isObject()); VELOCYPACK_ASSERT(obj.length() >= 2); @@ -1306,7 +1319,7 @@ bool Builder::checkAttributeUniqueness(Slice obj) const { return checkAttributeUniquenessUnsorted(obj); } -bool Builder::checkAttributeUniquenessSorted(Slice obj) const { +bool Builder::checkAttributeUniquenessSorted(Slice obj) const { ObjectIterator it(obj, false); // fetch initial key @@ -1338,7 +1351,7 @@ bool Builder::checkAttributeUniquenessSorted(Slice obj) const { return true; } -bool Builder::checkAttributeUniquenessUnsorted(Slice obj) const { +bool Builder::checkAttributeUniquenessUnsorted(Slice obj) const { // cutoff value for linear attribute uniqueness scan // unsorted objects with this amount of attributes (or less) will // be validated using a non-allocating scan over the attributes @@ -1355,7 +1368,7 @@ bool Builder::checkAttributeUniquenessUnsorted(Slice obj) const { // Add all subkeys and subvalues into an object from an ObjectIterator // and leaves open the object intentionally -uint8_t* Builder::add(ObjectIterator&& sub) { +uint8_t* Builder::add(ObjectIterator&& sub) { if (VELOCYPACK_UNLIKELY(_stack.empty())) { throw Exception(Exception::BuilderNeedOpenObject); } @@ -1378,7 +1391,7 @@ uint8_t* Builder::add(ObjectIterator&& sub) { // Add all subkeys and subvalues into an object from an ArrayIterator // and leaves open the array intentionally -uint8_t* Builder::add(ArrayIterator&& sub) { +uint8_t* Builder::add(ArrayIterator&& sub) { if (VELOCYPACK_UNLIKELY(_stack.empty())) { throw Exception(Exception::BuilderNeedOpenArray); } @@ -1394,16 +1407,21 @@ uint8_t* Builder::add(ArrayIterator&& sub) { return _start + oldPos; } -ValueLength Builder::effectivePaddingForOneByteMembers() const noexcept { +ValueLength Builder::effectivePaddingForOneByteMembers() + const noexcept { // 8 bytes - object length (1 byte) - number of items (1 byte) = 6 bytes return (options->paddingBehavior == Options::PaddingBehavior::UsePadding ? 6 : 0); } -ValueLength Builder::effectivePaddingForTwoByteMembers() const noexcept { +ValueLength Builder::effectivePaddingForTwoByteMembers() + const noexcept { // 8 bytes - object length (2 bytes) - number of items (2 bytes) = 4 bytes return (options->paddingBehavior == Options::PaddingBehavior::UsePadding ? 4 : 0); } static_assert(sizeof(double) == 8, "double is not 8 bytes"); +// remember instantiate template + +template class arangodb::velocypack::Builder>; From 87909e19bb4155fd67270df8951288db55c13bfc Mon Sep 17 00:00:00 2001 From: Julia CP Date: Wed, 13 Aug 2025 11:48:55 -0300 Subject: [PATCH 2/8] Intermediate commit of the supervised buffer, must fix template errors still --- include/velocypack/Builder.h | 2 +- src/Builder.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/velocypack/Builder.h b/include/velocypack/Builder.h index 02d17bf7..e2450220 100644 --- a/include/velocypack/Builder.h +++ b/include/velocypack/Builder.h @@ -1146,7 +1146,7 @@ struct ArrayBuilder final : public BuilderContainer, } // namespace arangodb::velocypack -using VPackBuilder = arangodb::velocypack::Builder>; +using VPackBuilder = arangodb::velocypack::Builder>; using VPackBuilderNonDeleter = arangodb::velocypack::BuilderNonDeleter; using VPackBuilderContainer = arangodb::velocypack::BuilderContainer; using VPackObjectBuilder = arangodb::velocypack::ObjectBuilder; diff --git a/src/Builder.cpp b/src/Builder.cpp index 1a2422c2..bfb9873f 100644 --- a/src/Builder.cpp +++ b/src/Builder.cpp @@ -298,7 +298,8 @@ arangodb::velocypack::Builder::Builder(Builder const& that) } template -arangodb::velocypack::Builder& arangodb::velocypack::Builder::operator=(Builder const& that) { +arangodb::velocypack::Builder& +arangodb::velocypack::Builder::operator=(arangodb::velocypack::Builder const& that) { if (this != &that) { if (that._buffer == nullptr) { _buffer.reset(); From e953ea5d2472eaf29b764a5a6d08f12c27313103 Mon Sep 17 00:00:00 2001 From: Julia CP Date: Wed, 13 Aug 2025 12:09:45 -0300 Subject: [PATCH 3/8] Make destructor virtual --- include/velocypack/Buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/velocypack/Buffer.h b/include/velocypack/Buffer.h index aacc2702..b1f12080 100644 --- a/include/velocypack/Buffer.h +++ b/include/velocypack/Buffer.h @@ -132,7 +132,7 @@ class Buffer { return *this; } - ~Buffer() { + virtual ~Buffer() { if (_buffer != _local) { velocypack_free(_buffer); } From 852e6eebb2886e0ad31475f9426c8b2f97cff31e Mon Sep 17 00:00:00 2001 From: Julia CP Date: Thu, 14 Aug 2025 13:49:34 -0300 Subject: [PATCH 4/8] Restore files to their original state from main branch so just Buffer is changed --- include/velocypack/Builder.h | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/include/velocypack/Builder.h b/include/velocypack/Builder.h index e2450220..9e10e81c 100644 --- a/include/velocypack/Builder.h +++ b/include/velocypack/Builder.h @@ -50,7 +50,6 @@ namespace arangodb::velocypack { class ArrayIterator; class ObjectIterator; -template> class Builder { friend class Parser; // The parser needs access to internals. @@ -75,12 +74,12 @@ class Builder { // buffer. Whenever the stack is empty, one can use the start, // size and slice methods to get out the ready built VPack // object(s). - public: - using buffer_type = BufferType; private: - std::shared_ptr _buffer; - BufferType* _bufferPtr; + // Here we collect the result + std::shared_ptr> _buffer; + // used for quicker access than shared_ptr + Buffer* _bufferPtr; // Always points to the start of _buffer uint8_t* _start; // the append position @@ -115,19 +114,19 @@ class Builder { explicit Builder(Options const* options); // create an empty Builder, using an existing buffer and default Options - explicit Builder(std::shared_ptr buffer); + explicit Builder(std::shared_ptr> buffer); // create an empty Builder, using an existing buffer and Options - explicit Builder(std::shared_ptr buffer, + explicit Builder(std::shared_ptr> buffer, Options const* options); // create a Builder that uses an existing Buffer and default Options. // the Builder will not claim ownership for its Buffer - explicit Builder(BufferType& buffer) noexcept; + explicit Builder(Buffer& buffer) noexcept; // create a Builder that uses an existing Buffer. the Builder will not // claim ownership for this Buffer - explicit Builder(BufferType& buffer, Options const* options); + explicit Builder(Buffer& buffer, Options const* options); // populate a Builder from a Slice explicit Builder(Slice slice, Options const* options = &Options::Defaults); @@ -142,9 +141,9 @@ class Builder { // get a reference to the Builder's Buffer object // note: this object may be a nullptr if the buffer was already stolen // from the Builder, or if the Builder has no ownership for the Buffer - std::shared_ptr const& buffer() const { return _buffer; } + std::shared_ptr> const& buffer() const { return _buffer; } - BufferType& bufferRef() const { + Buffer& bufferRef() const { if (_bufferPtr == nullptr) { throw Exception(Exception::InternalError, "Builder has no Buffer"); } @@ -154,9 +153,9 @@ class Builder { // steal the Builder's Buffer object. afterwards the Builder // is unusable - note: this may return a nullptr if the Builder does not // own the Buffer! - std::shared_ptr steal() { + std::shared_ptr> steal() { // After a steal the Builder is broken! - std::shared_ptr res(std::move(_buffer)); + std::shared_ptr> res(std::move(_buffer)); _bufferPtr = nullptr; _start = nullptr; clear(); @@ -614,7 +613,7 @@ class Builder { close(); return *this; } - + void resetTo(std::size_t value) { _pos = value; VELOCYPACK_ASSERT(_bufferPtr != nullptr); @@ -1146,7 +1145,7 @@ struct ArrayBuilder final : public BuilderContainer, } // namespace arangodb::velocypack -using VPackBuilder = arangodb::velocypack::Builder>; +using VPackBuilder = arangodb::velocypack::Builder; using VPackBuilderNonDeleter = arangodb::velocypack::BuilderNonDeleter; using VPackBuilderContainer = arangodb::velocypack::BuilderContainer; using VPackObjectBuilder = arangodb::velocypack::ObjectBuilder; From 7467ac98b530f05a25a6a6eb91e7ca41ed89080d Mon Sep 17 00:00:00 2001 From: Julia CP Date: Fri, 15 Aug 2025 10:55:28 -0300 Subject: [PATCH 5/8] Restored Builder to its original state --- src/Builder.cpp | 129 +++++++++++++++++++++--------------------------- 1 file changed, 55 insertions(+), 74 deletions(-) diff --git a/src/Builder.cpp b/src/Builder.cpp index bfb9873f..a75ae5e5 100644 --- a/src/Builder.cpp +++ b/src/Builder.cpp @@ -33,20 +33,20 @@ #include "velocypack/Iterator.h" #include "velocypack/Sink.h" - +using namespace arangodb::velocypack; namespace { // checks whether a memmove operation is allowed to get rid of the padding -bool isAllowedToMemmove(arangodb::velocypack::Options const* options, uint8_t const* start, - std::vector::iterator indexStart, - std::vector::iterator indexEnd, - arangodb::velocypack::ValueLength offsetSize) { +bool isAllowedToMemmove(Options const* options, uint8_t const* start, + std::vector::iterator indexStart, + std::vector::iterator indexEnd, + ValueLength offsetSize) { VELOCYPACK_ASSERT(offsetSize == 1 || offsetSize == 2); - if (options->paddingBehavior == arangodb::velocypack::Options::PaddingBehavior::NoPadding || + if (options->paddingBehavior == Options::PaddingBehavior::NoPadding || (offsetSize == 1 && - options->paddingBehavior == arangodb::velocypack::Options::PaddingBehavior::Flexible)) { + options->paddingBehavior == Options::PaddingBehavior::Flexible)) { std::size_t const distance = std::distance(indexStart, indexEnd); std::size_t const n = (std::min)(std::size_t(8 - 2 * offsetSize), distance); for (std::size_t i = 0; i < n; i++) { @@ -60,7 +60,7 @@ bool isAllowedToMemmove(arangodb::velocypack::Options const* options, uint8_t co return false; } -uint8_t determineArrayType(bool needIndexTable, arangodb::velocypack::ValueLength offsetSize) { +uint8_t determineArrayType(bool needIndexTable, ValueLength offsetSize) { uint8_t type; // Now build the table: if (needIndexTable) { @@ -79,7 +79,7 @@ uint8_t determineArrayType(bool needIndexTable, arangodb::velocypack::ValueLengt return type; } -constexpr arangodb::velocypack::ValueLength linearAttributeUniquenessCutoff = 4; +constexpr ValueLength linearAttributeUniquenessCutoff = 4; // struct used when sorting index tables for objects: struct SortEntry { @@ -129,16 +129,16 @@ uint8_t const* findAttrName(uint8_t const* base, uint64_t& len) { return findAttrName(arangodb::velocypack::Slice(base).makeKey().start(), len); } -bool checkAttributeUniquenessUnsortedBrute(arangodb::velocypack::ObjectIterator& it) { +bool checkAttributeUniquenessUnsortedBrute(ObjectIterator& it) { std::array keys; do { // key(true) guarantees a String as returned type std::string_view key = it.key(true).stringView(); - arangodb::velocypack::ValueLength index = it.index(); + ValueLength index = it.index(); // compare with all other already looked-at keys - for (arangodb::velocypack::ValueLength i = 0; i < index; ++i) { + for (ValueLength i = 0; i < index; ++i) { if (VELOCYPACK_UNLIKELY(keys[i] == key)) { return false; } @@ -151,7 +151,7 @@ bool checkAttributeUniquenessUnsortedBrute(arangodb::velocypack::ObjectIterator& return true; } -bool checkAttributeUniquenessUnsortedSet(arangodb::velocypack::ObjectIterator& it) { +bool checkAttributeUniquenessUnsortedSet(ObjectIterator& it) { #ifndef VELOCYPACK_NO_THREADLOCALS std::unique_ptr>& tmp = ::duplicateKeys; @@ -165,7 +165,7 @@ bool checkAttributeUniquenessUnsortedSet(arangodb::velocypack::ObjectIterator& i #endif do { - arangodb::velocypack::Slice key = it.key(true); + Slice key = it.key(true); // key(true) guarantees a String as returned type VELOCYPACK_ASSERT(key.isString()); if (VELOCYPACK_UNLIKELY(!tmp->emplace(key.stringView()).second)) { @@ -181,9 +181,8 @@ bool checkAttributeUniquenessUnsortedSet(arangodb::velocypack::ObjectIterator& i } // namespace // create an empty Builder, using default Options -template -arangodb::velocypack::Builder::Builder() - : _buffer(std::make_shared()), +Builder::Builder() + : _buffer(std::make_shared>()), _bufferPtr(_buffer.get()), _start(_bufferPtr->data()), _pos(0), @@ -196,8 +195,7 @@ arangodb::velocypack::Builder::Builder() } // create an empty Builder, using Options -template -arangodb::velocypack::Builder::Builder(arangodb::velocypack::Options const* opts) : Builder() { +Builder::Builder(Options const* opts) : Builder() { if (VELOCYPACK_UNLIKELY(opts == nullptr)) { throw Exception(Exception::InternalError, "Options cannot be a nullptr"); } @@ -205,8 +203,7 @@ arangodb::velocypack::Builder::Builder(arangodb::velocypack::Options } // create an empty Builder, using an existing buffer and default Options -template -arangodb::velocypack::Builder::Builder(std::shared_ptr buffer) +Builder::Builder(std::shared_ptr> buffer) : _buffer(std::move(buffer)), _bufferPtr(_buffer.get()), _start(nullptr), @@ -226,9 +223,7 @@ arangodb::velocypack::Builder::Builder(std::shared_ptr b } // create an empty Builder, using an existing buffer -template -arangodb::velocypack::Builder::Builder(std::shared_ptr buffer, - Options const* opts) +Builder::Builder(std::shared_ptr> buffer, Options const* opts) : Builder(std::move(buffer)) { if (VELOCYPACK_UNLIKELY(opts == nullptr)) { throw Exception(Exception::InternalError, "Options cannot be a nullptr"); @@ -238,8 +233,7 @@ arangodb::velocypack::Builder::Builder(std::shared_ptr b // create a Builder that uses an existing Buffer and options. // the Builder will not claim ownership for its Buffer -template -arangodb::velocypack::Builder::Builder(BufferType& buffer) noexcept +Builder::Builder(Buffer& buffer) noexcept : _bufferPtr(&buffer), _start(_bufferPtr->data()), _pos(buffer.size()), @@ -253,8 +247,7 @@ arangodb::velocypack::Builder::Builder(BufferType& buffer) noexcept // create a Builder that uses an existing Buffer. the Builder will not // claim ownership for its Buffer -template -arangodb::velocypack::Builder::Builder(BufferType& buffer, Options const* opts) +Builder::Builder(Buffer& buffer, Options const* opts) : Builder(buffer) { if (VELOCYPACK_UNLIKELY(opts == nullptr)) { throw Exception(Exception::InternalError, "Options cannot be a nullptr"); @@ -263,13 +256,11 @@ arangodb::velocypack::Builder::Builder(BufferType& buffer, Options c } // populate a Builder from a Slice -arangodb::velocypack::Builder::Builder(Slice slice, Options const* options) - : Builder(options) { +Builder::Builder(Slice slice, Options const* options) : Builder(options) { add(slice); } -template -arangodb::velocypack::Builder::Builder(Builder const& that) +Builder::Builder(Builder const& that) : _bufferPtr(nullptr), _start(nullptr), _pos(that._pos), @@ -285,7 +276,7 @@ arangodb::velocypack::Builder::Builder(Builder const& that) if (that._buffer == nullptr) { _bufferPtr = that._bufferPtr; } else { - _buffer = std::make_shared(*that._buffer); + _buffer = std::make_shared>(*that._buffer); _bufferPtr = _buffer.get(); } @@ -297,15 +288,13 @@ arangodb::velocypack::Builder::Builder(Builder const& that) _stack.reserve(arenaSize / sizeof(decltype(_stack)::value_type)); } -template -arangodb::velocypack::Builder& -arangodb::velocypack::Builder::operator=(arangodb::velocypack::Builder const& that) { +Builder& Builder::operator=(Builder const& that) { if (this != &that) { if (that._buffer == nullptr) { _buffer.reset(); _bufferPtr = that._bufferPtr; } else { - _buffer = std::make_shared(*that._buffer); + _buffer = std::make_shared>(*that._buffer); _bufferPtr = _buffer.get(); } if (_bufferPtr == nullptr) { @@ -323,8 +312,7 @@ arangodb::velocypack::Builder::operator=(arangodb::velocypack::Build return *this; } -template -arangodb::velocypack::Builder::Builder(Builder&& that) noexcept +Builder::Builder(Builder&& that) noexcept : _buffer(std::move(that._buffer)), _bufferPtr(nullptr), _start(nullptr), @@ -351,8 +339,7 @@ arangodb::velocypack::Builder::Builder(Builder&& that) noexcept that.clear(); } -template -arangodb::velocypack::Builder& Builder::operator=(arangodb::velocypack::Builder&& that) noexcept { +Builder& Builder::operator=(Builder&& that) noexcept { if (this != &that) { _buffer = std::move(that._buffer); if (_buffer != nullptr) { @@ -379,7 +366,7 @@ arangodb::velocypack::Builder& Builder::operator=(arangodb::velocypa return *this; } -std::string Builder::toString() const { +std::string Builder::toString() const { Options opts; opts.prettyPrint = true; @@ -389,14 +376,14 @@ std::string Builder::toString() const { return buffer; } -std::string Builder::toJson() const { +std::string Builder::toJson() const { std::string buffer; StringSink sink(&buffer); Dumper::dump(slice(), &sink); return buffer; } -void Builder::sortObjectIndexShort( +void Builder::sortObjectIndexShort( uint8_t* objBase, std::vector::iterator indexStart, std::vector::iterator indexEnd) const { std::sort(indexStart, indexEnd, @@ -420,7 +407,7 @@ void Builder::sortObjectIndexShort( }); } -void Builder::sortObjectIndexLong( +void Builder::sortObjectIndexLong( uint8_t* objBase, std::vector::iterator indexStart, std::vector::iterator indexEnd) const { #ifndef VELOCYPACK_NO_THREADLOCALS @@ -469,8 +456,7 @@ void Builder::sortObjectIndexLong( } } -Builder& Builder::closeEmptyArrayOrObject(ValueLength pos, - bool isArray) { +Builder& Builder::closeEmptyArrayOrObject(ValueLength pos, bool isArray) { // empty Array or Object _start[pos] = (isArray ? 0x01 : 0x0a); VELOCYPACK_ASSERT(_pos == pos + 9); @@ -479,7 +465,7 @@ Builder& Builder::closeEmptyArrayOrObject(ValueLength pos, return *this; } -bool Builder::closeCompactArrayOrObject( +bool Builder::closeCompactArrayOrObject( ValueLength pos, bool isArray, std::vector::iterator indexStart, std::vector::iterator indexEnd) { @@ -537,9 +523,9 @@ bool Builder::closeCompactArrayOrObject( return false; } -Builder& Builder::closeArray( - ValueLength pos, std::vector::iterator indexStart, - std::vector::iterator indexEnd) { +Builder& Builder::closeArray(ValueLength pos, + std::vector::iterator indexStart, + std::vector::iterator indexEnd) { std::size_t const n = std::distance(indexStart, indexEnd); VELOCYPACK_ASSERT(n > 0); @@ -686,7 +672,7 @@ Builder& Builder::closeArray( return *this; } -Builder& Builder::close() { +Builder& Builder::close() { if (VELOCYPACK_UNLIKELY(isClosed())) { throw Exception(Exception::BuilderNeedOpenCompound); } @@ -868,12 +854,12 @@ Builder& Builder::close() { } // checks whether an Object value has a specific key attribute -bool Builder::hasKey(std::string_view key) const { +bool Builder::hasKey(std::string_view key) const { return !getKey(key).isNone(); } // return the value for a specific key of an Object value -Slice Builder::getKey(std::string_view key) const { +Slice Builder::getKey(std::string_view key) const { if (VELOCYPACK_UNLIKELY(_stack.empty())) { throw Exception(Exception::BuilderNeedOpenObject); } @@ -896,7 +882,7 @@ Slice Builder::getKey(std::string_view key) const { return Slice(); } -void Builder::appendTag(uint64_t tag) { +void Builder::appendTag(uint64_t tag) { if (options->disallowTags) { // Tagged values explicitly disallowed throw Exception(Exception::BuilderTagsDisallowed); @@ -912,7 +898,7 @@ void Builder::appendTag(uint64_t tag) { } } -uint8_t* Builder::set(Value const& item) { +uint8_t* Builder::set(Value const& item) { auto const oldPos = _pos; auto ctype = item.cType(); @@ -1179,7 +1165,7 @@ uint8_t* Builder::set(Value const& item) { return _start + oldPos; } -uint8_t* Builder::set(Slice const& item) { +uint8_t* Builder::set(Slice const& item) { checkKeyHasValidType(item); if (VELOCYPACK_UNLIKELY(options->disallowCustom && item.isCustom())) { @@ -1197,7 +1183,7 @@ uint8_t* Builder::set(Slice const& item) { return _start + _pos - l; } -uint8_t* Builder::set(ValuePair const& pair) { +uint8_t* Builder::set(ValuePair const& pair) { // This method builds a single further VPack item at the current // append position. This is the case for ValueType::String, // ValueType::Binary, or ValueType::Custom, which can be built @@ -1256,7 +1242,7 @@ uint8_t* Builder::set(ValuePair const& pair) { "ValueType::Custom are valid for ValuePair argument"); } -uint8_t* Builder::set(IStringFromParts const& parts) { +uint8_t* Builder::set(IStringFromParts const& parts) { // This method builds a single VPack String item composed of the 2 parts. auto const oldPos = _pos; @@ -1283,13 +1269,13 @@ uint8_t* Builder::set(IStringFromParts const& parts) { return _start + oldPos; } -void Builder::cleanupAdd() noexcept { +void Builder::cleanupAdd() noexcept { VELOCYPACK_ASSERT(!_stack.empty()); VELOCYPACK_ASSERT(!_indexes.empty()); _indexes.pop_back(); } -void Builder::reportAdd() { +void Builder::reportAdd() { VELOCYPACK_ASSERT(!_stack.empty()); if (_indexes.capacity() == 0) { // make an initial reservation for several items at @@ -1300,14 +1286,14 @@ void Builder::reportAdd() { _indexes.push_back(_pos - _stack.back().startPos); } -void Builder::closeLevel() noexcept { +void Builder::closeLevel() noexcept { VELOCYPACK_ASSERT(!_stack.empty()); ValueLength const indexStartPos = _stack.back().indexStartPos; _stack.pop_back(); _indexes.erase(_indexes.begin() + indexStartPos, _indexes.end()); } -bool Builder::checkAttributeUniqueness(Slice obj) const { +bool Builder::checkAttributeUniqueness(Slice obj) const { VELOCYPACK_ASSERT(options->checkAttributeUniqueness == true); VELOCYPACK_ASSERT(obj.isObject()); VELOCYPACK_ASSERT(obj.length() >= 2); @@ -1320,7 +1306,7 @@ bool Builder::checkAttributeUniqueness(Slice obj) const { return checkAttributeUniquenessUnsorted(obj); } -bool Builder::checkAttributeUniquenessSorted(Slice obj) const { +bool Builder::checkAttributeUniquenessSorted(Slice obj) const { ObjectIterator it(obj, false); // fetch initial key @@ -1352,7 +1338,7 @@ bool Builder::checkAttributeUniquenessSorted(Slice obj) const { return true; } -bool Builder::checkAttributeUniquenessUnsorted(Slice obj) const { +bool Builder::checkAttributeUniquenessUnsorted(Slice obj) const { // cutoff value for linear attribute uniqueness scan // unsorted objects with this amount of attributes (or less) will // be validated using a non-allocating scan over the attributes @@ -1369,7 +1355,7 @@ bool Builder::checkAttributeUniquenessUnsorted(Slice obj) const { // Add all subkeys and subvalues into an object from an ObjectIterator // and leaves open the object intentionally -uint8_t* Builder::add(ObjectIterator&& sub) { +uint8_t* Builder::add(ObjectIterator&& sub) { if (VELOCYPACK_UNLIKELY(_stack.empty())) { throw Exception(Exception::BuilderNeedOpenObject); } @@ -1392,7 +1378,7 @@ uint8_t* Builder::add(ObjectIterator&& sub) { // Add all subkeys and subvalues into an object from an ArrayIterator // and leaves open the array intentionally -uint8_t* Builder::add(ArrayIterator&& sub) { +uint8_t* Builder::add(ArrayIterator&& sub) { if (VELOCYPACK_UNLIKELY(_stack.empty())) { throw Exception(Exception::BuilderNeedOpenArray); } @@ -1408,21 +1394,16 @@ uint8_t* Builder::add(ArrayIterator&& sub) { return _start + oldPos; } -ValueLength Builder::effectivePaddingForOneByteMembers() - const noexcept { +ValueLength Builder::effectivePaddingForOneByteMembers() const noexcept { // 8 bytes - object length (1 byte) - number of items (1 byte) = 6 bytes return (options->paddingBehavior == Options::PaddingBehavior::UsePadding ? 6 : 0); } -ValueLength Builder::effectivePaddingForTwoByteMembers() - const noexcept { +ValueLength Builder::effectivePaddingForTwoByteMembers() const noexcept { // 8 bytes - object length (2 bytes) - number of items (2 bytes) = 4 bytes return (options->paddingBehavior == Options::PaddingBehavior::UsePadding ? 4 : 0); } static_assert(sizeof(double) == 8, "double is not 8 bytes"); -// remember instantiate template - -template class arangodb::velocypack::Builder>; From f1b811ba8003f00ca61973bc7a64173fee6d8578 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Mon, 18 Aug 2025 15:45:15 +0200 Subject: [PATCH 6/8] Updated the github actions --- .github/workflows/codeql-analysis.yml | 8 ++-- .github/workflows/github-ci.yml | 54 +++++++++++---------------- 2 files changed, 25 insertions(+), 37 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 9071a676..cbc4d1a9 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -31,7 +31,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. @@ -44,7 +44,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -55,7 +55,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v3 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -69,4 +69,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml index b83443e5..29a9ebf1 100644 --- a/.github/workflows/github-ci.yml +++ b/.github/workflows/github-ci.yml @@ -14,39 +14,36 @@ env: jobs: build: runs-on: ${{ matrix.os }} + timeout-minutes: 60 strategy: matrix: include: # GCC builds - - {os: ubuntu-latest, compiler: gcc, version: '10', - build_type: Release, hash_type: fasthash } - {os: ubuntu-latest, compiler: gcc, version: '11', - build_type: Release, hash_type: xxhash } + build_type: Release, hash_type: fasthash } - {os: ubuntu-latest, compiler: gcc, version: '12', + build_type: Release, hash_type: xxhash } + - {os: ubuntu-latest, compiler: gcc, version: '13', build_type: Release, hash_type: fasthash } - - {os: ubuntu-latest, compiler: gcc, version: '10', + - {os: ubuntu-latest, compiler: gcc, version: '11', build_type: Debug, hash_type: xxhash, flags: '-O0 -fno-inline --coverage', coverage: true} - - {os: ubuntu-latest, compiler: gcc, version: '10', + - {os: ubuntu-latest, compiler: gcc, version: '11', build_type: Debug, hash_type: xxhash, sanitizer: true, flags: '-fsanitize=address -fsanitize=leak -fsanitize=undefined -fsanitize-address-use-after-scope -fno-omit-frame-pointer', - ld_flags: '-fsanitize=address -fsanitize=leak -fsanitize=undefined -fsanitize=address-use-after-scope -fno-omit-frame-pointer'} + ld_flags: '-fsanitize=address -fsanitize=leak -fsanitize=undefined -fsanitize-address-use-after-scope -fno-omit-frame-pointer'} # Clang builds - - {os: ubuntu-20.04, compiler: clang, version: '10', + - {os: ubuntu-latest, compiler: clang, version: '14', build_type: Release, hash_type: xxhash } - - {os: ubuntu-latest, compiler: clang, version: '11', + - {os: ubuntu-latest, compiler: clang, version: '15', build_type: Release, hash_type: fasthash } - - {os: ubuntu-latest, compiler: clang, version: '12', + - {os: ubuntu-latest, compiler: clang, version: '16', build_type: Release, hash_type: xxhash } - - {os: ubuntu-latest, compiler: clang, version: '13', + - {os: ubuntu-latest, compiler: clang, version: '17', build_type: Release, hash_type: fasthash } - - {os: ubuntu-latest, compiler: clang, version: '14', - build_type: Release, hash_type: xxhash } - # Windows builds - - {os: windows-2019, compiler: msvc, - build_type: Release, hash_type: xxhash } + # Windows builds (removed windows-2019 as it's deprecated) - {os: windows-latest, compiler: msvc, build_type: Release, hash_type: xxhash } @@ -54,47 +51,38 @@ jobs: - {os: macos-latest, compiler: clang, build_type: Release, hash_type: xxhash } - # This seems to trigger a bug, so re-enable it after it is - # fixed - # - {os: macos-latest, compiler: clang, - # build_type: Release, hash_type: xxhash, - # flags: '-O0 -fno-inline --coverage', coverage: true} - fail-fast: false steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup environment run: | echo "SANITIZER=${{ matrix.sanitizer }}" >> ${GITHUB_ENV} - name: Install gcc if: startsWith(matrix.os, 'ubuntu-') && matrix.compiler == 'gcc' run: | - sudo add-apt-repository ppa:ubuntu-toolchain-r/test + sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y sudo apt-get update - sudo apt-get install g++-${{ matrix.version }} + sudo apt-get install g++-${{ matrix.version }} -y echo "CXX=g++-${{ matrix.version }}" >> ${GITHUB_ENV} echo "CC=gcc-${{ matrix.version }}" >> ${GITHUB_ENV} - name: Install clang if: startsWith(matrix.os, 'ubuntu-') && matrix.compiler == 'clang' run: | sudo apt-get update - sudo apt-get install libunwind-dev + sudo apt-get install libunwind-dev -y sudo wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - version=${{ matrix.version }} - if [[ $version -ge 13 ]]; then - sudo add-apt-repository "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-$version main" + if [[ $version -ge 14 ]]; then + sudo add-apt-repository "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-$version main" -y fi sudo apt-get update - sudo apt-get install clang-$version lld libc++-$version-dev libc++abi-$version-dev + sudo apt-get install clang-$version lld libc++-$version-dev libc++abi-$version-dev -y echo "CC=clang-$version" >> ${GITHUB_ENV} echo "CXX=clang++-$version" >> ${GITHUB_ENV} - echo "CC=clang-$version" >> ${GITHUB_ENV} echo "LDFLAGS=-fuse-ld=lld" >> ${GITHUB_ENV} - - name: Initialize MSVC ${{ matrix.version }} + - name: Initialize MSVC if: startsWith(matrix.os, 'windows-') uses: ilammy/msvc-dev-cmd@v1 - with: - toolset: ${{ matrix.version }} - name: Configure CMake # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type @@ -111,7 +99,7 @@ jobs: - name: Coverage if: matrix.coverage == true run: | - sudo apt-get install lcov + sudo apt-get install lcov -y CXX=g++-${{ matrix.version }} scripts/collect-coverage.sh - name: Coveralls Upload From 16461ccb209655b5fbe67b1fd165011c001bf130 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Mon, 18 Aug 2025 16:32:13 +0200 Subject: [PATCH 7/8] Removed teimout again --- .github/workflows/github-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml index 29a9ebf1..9873d19f 100644 --- a/.github/workflows/github-ci.yml +++ b/.github/workflows/github-ci.yml @@ -14,7 +14,6 @@ env: jobs: build: runs-on: ${{ matrix.os }} - timeout-minutes: 60 strategy: matrix: include: From f7802d735b9a418bdc4cc9cd55c656c1851a08c6 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Mon, 18 Aug 2025 16:56:15 +0200 Subject: [PATCH 8/8] Bumped clang and gcc versions to what is actually supported by arangodb --- .github/workflows/github-ci.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml index 9873d19f..f7f05d9c 100644 --- a/.github/workflows/github-ci.yml +++ b/.github/workflows/github-ci.yml @@ -18,29 +18,29 @@ jobs: matrix: include: # GCC builds - - {os: ubuntu-latest, compiler: gcc, version: '11', + - {os: ubuntu-latest, compiler: gcc, version: '13', build_type: Release, hash_type: fasthash } - - {os: ubuntu-latest, compiler: gcc, version: '12', + - {os: ubuntu-latest, compiler: gcc, version: '14', build_type: Release, hash_type: xxhash } - - {os: ubuntu-latest, compiler: gcc, version: '13', + - {os: ubuntu-latest, compiler: gcc, version: '15', build_type: Release, hash_type: fasthash } - - {os: ubuntu-latest, compiler: gcc, version: '11', + - {os: ubuntu-latest, compiler: gcc, version: '13', build_type: Debug, hash_type: xxhash, flags: '-O0 -fno-inline --coverage', coverage: true} - - {os: ubuntu-latest, compiler: gcc, version: '11', + - {os: ubuntu-latest, compiler: gcc, version: '13', build_type: Debug, hash_type: xxhash, sanitizer: true, flags: '-fsanitize=address -fsanitize=leak -fsanitize=undefined -fsanitize-address-use-after-scope -fno-omit-frame-pointer', ld_flags: '-fsanitize=address -fsanitize=leak -fsanitize=undefined -fsanitize-address-use-after-scope -fno-omit-frame-pointer'} # Clang builds - - {os: ubuntu-latest, compiler: clang, version: '14', - build_type: Release, hash_type: xxhash } - - {os: ubuntu-latest, compiler: clang, version: '15', - build_type: Release, hash_type: fasthash } - {os: ubuntu-latest, compiler: clang, version: '16', build_type: Release, hash_type: xxhash } - {os: ubuntu-latest, compiler: clang, version: '17', build_type: Release, hash_type: fasthash } + - {os: ubuntu-latest, compiler: clang, version: '18', + build_type: Release, hash_type: xxhash } + - {os: ubuntu-latest, compiler: clang, version: '19', + build_type: Release, hash_type: fasthash } # Windows builds (removed windows-2019 as it's deprecated) - {os: windows-latest, compiler: msvc,