From d151dcbb9d2ddc892c4b843ae35c2335730b057b Mon Sep 17 00:00:00 2001 From: Derek Bailey Date: Wed, 19 May 2021 10:53:46 -0700 Subject: [PATCH] Revert "[C++] Removed most heap allocations in builder (#6620)" (#6659) This reverts commit 72730ecd8ae62a67fe3d4fd83522537424924b74. --- include/flatbuffers/base.h | 5 --- include/flatbuffers/flatbuffers.h | 72 ++++++++----------------------- 2 files changed, 19 insertions(+), 58 deletions(-) diff --git a/include/flatbuffers/base.h b/include/flatbuffers/base.h index 4efa42ada..cc9e22dcc 100644 --- a/include/flatbuffers/base.h +++ b/include/flatbuffers/base.h @@ -247,11 +247,6 @@ namespace flatbuffers { #endif // __has_include #endif // !FLATBUFFERS_HAS_STRING_VIEW -#ifndef FLATBUFFERS_GENERAL_HEAP_ALLOC_OK - // Allow heap allocations to be used - #define FLATBUFFERS_GENERAL_HEAP_ALLOC_OK 1 -#endif // !FLATBUFFERS_GENERAL_HEAP_ALLOC_OK - #ifndef FLATBUFFERS_HAS_NEW_STRTOD // Modern (C++11) strtod and strtof functions are available for use. // 1) nan/inf strings as argument of strtod; diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index 180bf740b..ee34d54ed 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -1356,8 +1356,9 @@ class FlatBufferBuilder { // Write a single aligned scalar to the buffer template uoffset_t PushElement(T element) { AssertScalarT(); + T litle_endian_element = EndianScalar(element); Align(sizeof(T)); - buf_.push_small(EndianScalar(element)); + buf_.push_small(litle_endian_element); return GetSize(); } @@ -1600,13 +1601,11 @@ class FlatBufferBuilder { /// @brief Store a string in the buffer, which can contain any binary data. /// If a string with this exact contents has already been serialized before, - /// instead simply returns the offset of the existing string. This uses a map - /// stored on the heap, but only stores the numerical offsets. + /// instead simply returns the offset of the existing string. /// @param[in] str A const char pointer to the data to be stored as a string. /// @param[in] len The number of bytes that should be stored from `str`. /// @return Returns the offset in the buffer where the string starts. Offset CreateSharedString(const char *str, size_t len) { - FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK); if (!string_pool) string_pool = new StringOffsetMap(StringOffsetCompare(buf_)); auto size_before_string = buf_.size(); @@ -1628,8 +1627,7 @@ class FlatBufferBuilder { #ifdef FLATBUFFERS_HAS_STRING_VIEW /// @brief Store a string in the buffer, which can contain any binary data. /// If a string with this exact contents has already been serialized before, - /// instead simply returns the offset of the existing string. This uses a map - /// stored on the heap, but only stores the numerical offsets. + /// instead simply returns the offset of the existing string. /// @param[in] str A const std::string_view to store in the buffer. /// @return Returns the offset in the buffer where the string starts Offset CreateSharedString(const flatbuffers::string_view str) { @@ -1638,8 +1636,7 @@ class FlatBufferBuilder { #else /// @brief Store a string in the buffer, which null-terminated. /// If a string with this exact contents has already been serialized before, - /// instead simply returns the offset of the existing string. This uses a map - /// stored on the heap, but only stores the numerical offsets. + /// instead simply returns the offset of the existing string. /// @param[in] str A const char pointer to a C-string to add to the buffer. /// @return Returns the offset in the buffer where the string starts. Offset CreateSharedString(const char *str) { @@ -1648,8 +1645,7 @@ class FlatBufferBuilder { /// @brief Store a string in the buffer, which can contain any binary data. /// If a string with this exact contents has already been serialized before, - /// instead simply returns the offset of the existing string. This uses a map - /// stored on the heap, but only stores the numerical offsets. + /// instead simply returns the offset of the existing string. /// @param[in] str A const reference to a std::string to store in the buffer. /// @return Returns the offset in the buffer where the string starts. Offset CreateSharedString(const std::string &str) { @@ -1659,8 +1655,7 @@ class FlatBufferBuilder { /// @brief Store a string in the buffer, which can contain any binary data. /// If a string with this exact contents has already been serialized before, - /// instead simply returns the offset of the existing string. This uses a map - /// stored on the heap, but only stores the numerical offsets. + /// instead simply returns the offset of the existing string. /// @param[in] str A const pointer to a `String` struct to add to the buffer. /// @return Returns the offset in the buffer where the string starts Offset CreateSharedString(const String *str) { @@ -1767,18 +1762,15 @@ class FlatBufferBuilder { /// where the vector is stored. template Offset> CreateVector(size_t vector_size, const std::function &f) { - FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK); std::vector elems(vector_size); for (size_t i = 0; i < vector_size; i++) elems[i] = f(i); return CreateVector(elems); } - #endif // FLATBUFFERS_CPP98_STL + #endif // clang-format on /// @brief Serialize values returned by a function into a FlatBuffer `vector`. - /// This is a convenience function that takes care of iteration for you. This - /// uses a vector stored on the heap to store the intermediate results of the - /// iteration. + /// This is a convenience function that takes care of iteration for you. /// @tparam T The data type of the `std::vector` elements. /// @param f A function that takes the current iteration 0..vector_size-1, /// and the state parameter returning any type that you can construct a @@ -1788,7 +1780,6 @@ class FlatBufferBuilder { /// where the vector is stored. template Offset> CreateVector(size_t vector_size, F f, S *state) { - FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK); std::vector elems(vector_size); for (size_t i = 0; i < vector_size; i++) elems[i] = f(i, state); return CreateVector(elems); @@ -1802,34 +1793,9 @@ class FlatBufferBuilder { /// where the vector is stored. Offset>> CreateVectorOfStrings( const std::vector &v) { - return CreateVectorOfStrings(v.cbegin(), v.cend()); - } - - /// @brief Serialize a collection of Strings into a FlatBuffer `vector`. - /// This is a convenience function for a common case. - /// @param begin The begining iterator of the collection - /// @param end The ending iterator of the collection - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset>> CreateVectorOfStrings(It begin, It end) { - auto size = std::distance(begin, end); - auto scratch_buffer_usage = size * sizeof(Offset); - // If there is not enough space to store the offsets, there definitely won't - // be enough space to store all the strings. So ensuring space for the - // scratch region is OK, for it it fails, it would have failed later. - buf_.ensure_space(scratch_buffer_usage); - for (auto it = begin; it != end; ++it) { - buf_.scratch_push_small(CreateString(*it)); - } - StartVector(size, sizeof(Offset)); - for (auto it = buf_.scratch_end(); - it > buf_.scratch_end() - scratch_buffer_usage;) { - it -= sizeof(Offset); - PushElement(*reinterpret_cast *>(it)); - } - buf_.scratch_pop(scratch_buffer_usage); - return Offset>>(EndVector(size)); + std::vector> offsets(v.size()); + for (size_t i = 0; i < v.size(); i++) offsets[i] = CreateString(v[i]); + return CreateVector(offsets); } /// @brief Serialize an array of structs into a FlatBuffer `vector`. @@ -1860,9 +1826,9 @@ class FlatBufferBuilder { Offset> CreateVectorOfNativeStructs( const S *v, size_t len, T((*const pack_func)(const S &))) { FLATBUFFERS_ASSERT(pack_func); - auto structs = StartVectorOfStructs(len); - for (size_t i = 0; i < len; i++) { structs[i] = pack_func(v[i]); } - return EndVectorOfStructs(len); + std::vector vv(len); + std::transform(v, v + len, vv.begin(), pack_func); + return CreateVectorOfStructs(data(vv), vv.size()); } /// @brief Serialize an array of native structs into a FlatBuffer `vector`. @@ -2028,10 +1994,10 @@ class FlatBufferBuilder { Offset> CreateVectorOfSortedNativeStructs(S *v, size_t len) { extern T Pack(const S &); - auto structs = StartVectorOfStructs(len); - for (size_t i = 0; i < len; i++) { structs[i] = Pack(v[i]); } - std::sort(structs, structs + len, StructKeyComparator()); - return EndVectorOfStructs(len); + typedef T (*Pack_t)(const S &); + std::vector vv(len); + std::transform(v, v + len, vv.begin(), static_cast(Pack)); + return CreateVectorOfSortedStructs(vv, len); } /// @cond FLATBUFFERS_INTERNAL