Make packed bool vector datafiles match in-memory layout for vector_view.
This commit is contained in:
parent
49e09294bf
commit
cb5d596a5a
@ -30,22 +30,29 @@ namespace serialization
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template <typename T, typename BlockT = unsigned char>
|
template <typename T, typename BlockT = unsigned char>
|
||||||
inline BlockT packBits(const T &data, std::size_t index, std::size_t count)
|
inline BlockT packBits(const T &data, std::size_t base_index, const std::size_t count)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<typename T::value_type, bool>::value, "value_type is not bool");
|
static_assert(std::is_same<typename T::value_type, bool>::value, "value_type is not bool");
|
||||||
|
|
||||||
|
// Note: if this packing is changed, be sure to update vector_view<bool>
|
||||||
|
// as well, so that on-disk and in-memory layouts match.
|
||||||
BlockT value = 0;
|
BlockT value = 0;
|
||||||
for (std::size_t bit = 0; bit < count; ++bit, ++index)
|
for (std::size_t bit = 0; bit < count; ++bit)
|
||||||
value = (value << 1) | data[index];
|
{
|
||||||
|
value |= (data[base_index + bit] ? BlockT{1} : BlockT{0}) << bit;
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename BlockT = unsigned char>
|
template <typename T, typename BlockT = unsigned char>
|
||||||
inline void unpackBits(T &data, std::size_t index, std::size_t count, BlockT value)
|
inline void
|
||||||
|
unpackBits(T &data, const std::size_t base_index, const std::size_t count, const BlockT value)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<typename T::value_type, bool>::value, "value_type is not bool");
|
static_assert(std::is_same<typename T::value_type, bool>::value, "value_type is not bool");
|
||||||
const BlockT mask = BlockT{1} << (count - 1);
|
for (std::size_t bit = 0; bit < count; ++bit)
|
||||||
for (std::size_t bit = 0; bit < count; value <<= 1, ++bit, ++index)
|
{
|
||||||
data[index] = value & mask;
|
data[base_index + bit] = value & (BlockT{1} << bit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VectorT>
|
template <typename VectorT>
|
||||||
|
@ -195,6 +195,8 @@ template <> class vector_view<bool>
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
||||||
const std::size_t bucket = index / WORD_BITS;
|
const std::size_t bucket = index / WORD_BITS;
|
||||||
|
// Note: ordering of bits here should match packBits in storage/serialization.hpp
|
||||||
|
// so that directly mmap-ing data is possible
|
||||||
const auto offset = index % WORD_BITS;
|
const auto offset = index % WORD_BITS;
|
||||||
return m_ptr[bucket] & (static_cast<Word>(1) << offset);
|
return m_ptr[bucket] & (static_cast<Word>(1) << offset);
|
||||||
}
|
}
|
||||||
@ -224,11 +226,22 @@ template <> class vector_view<bool>
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT(index < m_size);
|
BOOST_ASSERT(index < m_size);
|
||||||
const auto bucket = index / WORD_BITS;
|
const auto bucket = index / WORD_BITS;
|
||||||
|
// Note: ordering of bits here should match packBits in storage/serialization.hpp
|
||||||
|
// so that directly mmap-ing data is possible
|
||||||
const auto offset = index % WORD_BITS;
|
const auto offset = index % WORD_BITS;
|
||||||
return reference{m_ptr + bucket, static_cast<Word>(1) << offset};
|
return reference{m_ptr + bucket, static_cast<Word>(1) << offset};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> friend void swap(vector_view<T> &, vector_view<T> &) noexcept;
|
template <typename T> friend void swap(vector_view<T> &, vector_view<T> &) noexcept;
|
||||||
|
|
||||||
|
friend std::ostream &operator<<(std::ostream &os, const vector_view<bool> &rhs)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < rhs.size(); ++i)
|
||||||
|
{
|
||||||
|
os << (i > 0 ? " " : "") << rhs.at(i);
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Both vector_view<T> and the vector_view<bool> specializations share this impl.
|
// Both vector_view<T> and the vector_view<bool> specializations share this impl.
|
||||||
|
Loading…
Reference in New Issue
Block a user