4#include <pixie/storage/read_only_view.h>
17inline constexpr std::size_t kAlignedStorageLineBytes = 64;
18inline constexpr std::size_t kAlignedStorageLineBits =
19 kAlignedStorageLineBytes * 8;
20inline constexpr std::size_t kAlignedStorageLineWords64 =
21 kAlignedStorageLineBytes /
sizeof(std::uint64_t);
22inline constexpr std::size_t kAlignedStorageLineWords16 =
23 kAlignedStorageLineBytes /
sizeof(std::uint16_t);
27 std::array<std::byte, kAlignedStorageLineBytes> data{};
30static_assert(
alignof(
CacheLine) == kAlignedStorageLineBytes);
31static_assert(
sizeof(
CacheLine) == kAlignedStorageLineBytes);
43 AlignedStorage() =
default;
47 : logical_size_bytes_(bytes_for_bits(
size_bits)),
52 : AlignedStorage(bit_size_for_words(words.size())) {
70 return data_.size() * kAlignedStorageLineBytes;
81 std::as_bytes(std::span<const CacheLine>(data_)));
86 return std::as_bytes(std::span<const CacheLine>(data_))
87 .first(logical_size_bytes_);
92 std::size_t count_bytes)
const {
98 std::size_t count_bytes) {
104 std::size_t count_bytes)
const {
107 throw std::out_of_range(
"Storage view is outside the allocation");
116 logical_size_bytes_ = bytes_for_bits(
size_bits);
121 return std::as_writable_bytes(std::span<CacheLine>(data_))
122 .first(logical_size_bytes_);
127 return {
reinterpret_cast<std::uint16_t*
>(data_.data()),
128 logical_size_bytes_ /
sizeof(std::uint16_t)};
133 return {
reinterpret_cast<std::uint64_t*
>(data_.data()),
134 logical_size_bytes_ /
sizeof(std::uint64_t)};
139 return data_.capacity() * kAlignedStorageLineBytes;
149 std::span<const CacheLine>
as_lines()
const {
return data_; }
153 const std::size_t size = reader.
read_size();
154 if (size > std::numeric_limits<std::size_t>::max() / 8) {
155 throw std::length_error(
"Serialized aligned storage is too large");
157 AlignedStorage result(size * 8);
158 const std::span<const std::byte> bytes = reader.
read_bytes(size);
164 static std::size_t bit_size_for_words(std::size_t word_count) {
165 constexpr std::size_t kWordBits =
166 std::numeric_limits<std::uint64_t>::digits;
167 if (word_count > std::numeric_limits<std::size_t>::max() / kWordBits) {
168 throw std::length_error(
"Aligned storage word sequence is too large");
170 return word_count * kWordBits;
173 static constexpr std::size_t bytes_for_bits(std::size_t size_bits) {
174 return size_bits / 8 + (size_bits % 8 != 0);
177 static constexpr std::size_t lines_for_bits(std::size_t size_bits) {
178 return size_bits / kAlignedStorageLineBits +
179 (size_bits % kAlignedStorageLineBits != 0);
182 std::size_t logical_size_bytes_ = 0;
183 std::vector<CacheLine> data_;
std::span< CacheLine > as_lines()
Return mutable cache-line blocks.
Definition aligned.h:146
std::size_t logical_size_bytes() const
Return the logical number of exposed bytes.
Definition aligned.h:66
static AlignedStorage deserialize_impl(BinaryReader &reader)
Restore an owning copy of one size-prefixed byte sequence.
Definition aligned.h:152
void shrink_to_fit_impl()
Request release of unused vector capacity.
Definition aligned.h:143
std::size_t padded_size_bytes() const
Return the cache-line-rounded backing size in bytes.
Definition aligned.h:69
AlignedStorage(std::size_t size_bits)
Construct storage for at least size_bits bits.
Definition aligned.h:46
std::span< const CacheLine > as_lines() const
Return read-only cache-line blocks.
Definition aligned.h:149
std::size_t size_bytes_impl() const
Return the logical number of exposed bytes.
Definition aligned.h:57
void resize_impl(std::size_t size_bits)
Resize to hold at least size_bits bits.
Definition aligned.h:114
AlignedStorage(std::span< const std::uint64_t > words)
Copy complete 64-bit words into aligned owning storage.
Definition aligned.h:51
std::size_t allocated_bytes_impl() const
Return bytes reserved by the underlying vector.
Definition aligned.h:138
SplitSpan< std::byte > segments_impl(std::size_t offset_bytes, std::size_t count_bytes)
Return a checked logical byte range as one writable segment.
Definition aligned.h:97
std::span< const std::byte > as_bytes_impl() const
Return the logical bytes as a read-only span.
Definition aligned.h:85
std::span< std::byte > writable_bytes_impl()
Return writable logical bytes.
Definition aligned.h:120
ReadOnlyStorageView view_impl(std::size_t offset_bytes, std::size_t count_bytes) const
Return a checked read-only byte subrange.
Definition aligned.h:103
std::span< std::uint64_t > writable_words64_impl()
Return writable logical storage as 64-bit words.
Definition aligned.h:132
ReadOnlyStorageView padded_view() const
Return a non-owning view of the complete cache-line backing.
Definition aligned.h:79
std::span< std::uint16_t > writable_words16_impl()
Return writable logical storage as 16-bit words.
Definition aligned.h:126
SplitSpan< const std::byte > segments_impl(std::size_t offset_bytes, std::size_t count_bytes) const
Return a checked logical byte range as one physical segment.
Definition aligned.h:91
position_type end_position_impl() const
Return the position one past the final logical byte.
Definition aligned.h:63
position_type begin_position_impl() const
Return the first logical byte position.
Definition aligned.h:60
Bounds-checked reader for canonical little-endian binary data.
Definition serialization.h:526
std::span< const std::byte > read_bytes(std::size_t count)
Read exactly count uninterpreted bytes.
Definition serialization.h:604
std::size_t read_size()
Read an unsigned 64-bit size and convert it to size_t.
Definition serialization.h:587
A non-owning, read-only view of a byte sequence.
Definition read_only_view.h:15
A logical contiguous sequence stored in at most two physical spans.
Definition split_span.h:25
CRTP facade for byte-addressable storage.
Definition storage.h:65
std::size_t size_bits() const
Definition storage.h:78
std::uint64_t position_type
Definition storage.h:68
auto writable_bytes()
Return writable storage bytes.
Definition storage.h:228
Common interface for byte-addressable storage.
A 64-byte aligned storage block.
Definition aligned.h:26