Skip to content

Commit

Permalink
improve builder memory reusability in optional
Browse files Browse the repository at this point in the history
  • Loading branch information
drexlerd committed Aug 27, 2024
1 parent 97ed848 commit 5668afc
Show file tree
Hide file tree
Showing 5 changed files with 401 additions and 141 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Flatmemory is a C++20 library for serialization and zero-cost deserialization. S

1. **Efficient Memory Management:** Flatmemory excels in scenarios where minimal memory allocations are critical. Builders reuse their memory, and serialized data can be efficiently written to large preallocated buffers. This minimizes the overhead typically associated with object creation and memory management.
2. **Cache-Friendly Data Layout:** Flatmemory stores data contiguously in memory, enhancing cache locality.
3. **Non-Trivial and Trivial Types:** Flatmemory supports a variety of non-trivial composite types like `Tuple`, `Vector`, and `Bitset`. Trivial types `T` that satisfy `std::is_trivially_copyable_v<T>` are stored in place, while non-trivial types are managed using offsets of type `uint32_t`.
3. **Non-Trivial and Trivial Types:** Flatmemory supports a variety of non-trivial composite types like `Tuple`, `Vector`, `Optional`, and `Bitset`. Trivial types `T` that satisfy `std::is_trivially_copyable_v<T>` are stored in place, while non-trivial types are managed using offsets of type `uint32_t`.
4. **Generic Programming:** Unlike other serialization libraries, Flatmemory does not rely on code generation tools. Instead, Flatmemory is purely based on templates, allowing serialization of generic types at ease.

## Limitations
Expand Down
25 changes: 10 additions & 15 deletions include/flatmemory/details/types/bitset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,14 @@
namespace flatmemory
{
/**
* ID class for non-trivial Bitset type.
* The optional tag can be used to disallow operations with bitsets with other non-default tags.
* ID class
*/

/// @brief `Bitset` implements a dynamic bitset with possibly infinite size.
/// The optional tag can be used to disallow operations with bitsets with other non-default tags.
/// There is no additional buffer size prefix because the buffer size is Vector<Block> + sizeof(bool).
/// @tparam Tag
/// @tparam Block
template<IsUnsignedIntegral Block, typename Tag>
struct Bitset : public NonTrivialType
{
Expand All @@ -57,8 +61,7 @@ template<IsUnsignedIntegral Block, typename Tag>
class Layout<Bitset<Block, Tag>>
{
public:
static constexpr size_t buffer_size_position = 0;
static constexpr size_t default_bit_value_position = buffer_size_position + sizeof(BufferSizeType);
static constexpr size_t default_bit_value_position = 0;
static constexpr size_t blocks_position = default_bit_value_position + sizeof(bool);

constexpr void print() const;
Expand Down Expand Up @@ -513,8 +516,7 @@ class ConstView<Bitset<Block, Tag>>
template<IsUnsignedIntegral Block, typename Tag>
constexpr void Layout<Bitset<Block, Tag>>::print() const
{
std::cout << "buffer_size_position: " << buffer_size_position << "\n"
<< "default_bit_value_position: " << default_bit_value_position << "\n"
std::cout << "default_bit_value_position: " << default_bit_value_position << "\n"
<< "blocks_position: " << blocks_position << std::endl;
}

Expand Down Expand Up @@ -826,9 +828,6 @@ size_t Builder<Bitset<Block, Tag>>::finish_impl(size_t pos, ByteBuffer& out)
/* Write the blocks inline because there is no other data. */
data_pos += m_blocks.finish(pos + data_pos, out);

/* Write the size of the buffer to the beginning. */
out.write(pos + BitsetLayout::buffer_size_position, static_cast<BufferSizeType>(data_pos));

return data_pos;
}

Expand Down Expand Up @@ -1273,9 +1272,7 @@ const uint8_t* View<Bitset<Block, Tag>>::buffer() const
template<IsUnsignedIntegral Block, typename Tag>
BufferSizeType View<Bitset<Block, Tag>>::buffer_size() const
{
assert(m_buf);
assert(test_correct_alignment<BufferSizeType>(m_buf + BitsetLayout::buffer_size_position));
return read_value<BufferSizeType>(m_buf + BitsetLayout::buffer_size_position);
return sizeof(bool) + get_blocks().buffer_size();
}

template<IsUnsignedIntegral Block, typename Tag>
Expand Down Expand Up @@ -1375,9 +1372,7 @@ const uint8_t* ConstView<Bitset<Block, Tag>>::buffer() const
template<IsUnsignedIntegral Block, typename Tag>
BufferSizeType ConstView<Bitset<Block, Tag>>::buffer_size() const
{
assert(m_buf);
assert(test_correct_alignment<BufferSizeType>(m_buf + BitsetLayout::buffer_size_position));
return read_value<BufferSizeType>(m_buf + BitsetLayout::buffer_size_position);
return sizeof(bool) + get_blocks().buffer_size();
}

template<IsUnsignedIntegral Block, typename Tag>
Expand Down
Loading

0 comments on commit 5668afc

Please sign in to comment.