Implement endianness-independent serialization for UUIDs

This commit is contained in:
ltrk2 2023-08-23 11:14:34 -07:00
parent 7f31258956
commit 8d8490ac58

View File

@ -7,6 +7,7 @@
#include <IO/WriteHelpers.h>
#include <Common/assert_cast.h>
#include <ranges>
namespace DB
{
@ -136,23 +137,31 @@ void SerializationUUID::deserializeBinary(IColumn & column, ReadBuffer & istr, c
void SerializationUUID::serializeBinaryBulk(const IColumn & column, WriteBuffer & ostr, size_t offset, size_t limit) const
{
const typename ColumnVector<UUID>::Container & x = typeid_cast<const ColumnVector<UUID> &>(column).getData();
size_t size = x.size();
if (limit == 0 || offset + limit > size)
if (const size_t size = x.size(); limit == 0 || offset + limit > size)
limit = size - offset;
if (limit)
if (limit == 0)
return;
if constexpr (std::endian::native == std::endian::big)
{
std::ranges::for_each(
x | std::views::drop(offset) | std::views::take(limit), [&ostr](const auto & uuid) { writeBinaryLittleEndian(uuid, ostr); });
}
else
ostr.write(reinterpret_cast<const char *>(&x[offset]), sizeof(UUID) * limit);
}
void SerializationUUID::deserializeBinaryBulk(IColumn & column, ReadBuffer & istr, size_t limit, double /*avg_value_size_hint*/) const
{
typename ColumnVector<UUID>::Container & x = typeid_cast<ColumnVector<UUID> &>(column).getData();
size_t initial_size = x.size();
const size_t initial_size = x.size();
x.resize(initial_size + limit);
size_t size = istr.readBig(reinterpret_cast<char*>(&x[initial_size]), sizeof(UUID) * limit);
const size_t size = istr.readBig(reinterpret_cast<char *>(&x[initial_size]), sizeof(UUID) * limit);
x.resize(initial_size + size / sizeof(UUID));
}
if constexpr (std::endian::native == std::endian::big)
std::ranges::for_each(
x | std::views::drop(initial_size), [](auto & uuid) { transformEndianness<std::endian::big, std::endian::little>(uuid); });
}
}