19 std::byte* elemPtr(std::byte* rec,
const ColumnAccess& a, std::size_t element) {
23 const std::byte* elemPtr(
const std::byte* rec,
const ColumnAccess& a, std::size_t element) {
31 void storeInt(std::byte* rec,
const ColumnAccess& a, std::size_t element, std::int64_t v) {
33 case AccessKind::I8: {
34 auto x =
static_cast<std::int8_t
>(v);
35 std::memcpy(elemPtr(rec, a, element), &x,
sizeof x);
38 case AccessKind::U8: {
39 auto x =
static_cast<std::uint8_t
>(v);
40 std::memcpy(elemPtr(rec, a, element), &x,
sizeof x);
43 case AccessKind::I16: {
44 auto x =
static_cast<std::int16_t
>(v);
45 std::memcpy(elemPtr(rec, a, element), &x,
sizeof x);
48 case AccessKind::U16: {
49 auto x =
static_cast<std::uint16_t
>(v);
50 std::memcpy(elemPtr(rec, a, element), &x,
sizeof x);
53 case AccessKind::I32: {
54 auto x =
static_cast<std::int32_t
>(v);
55 std::memcpy(elemPtr(rec, a, element), &x,
sizeof x);
58 case AccessKind::U32: {
59 auto x =
static_cast<std::uint32_t
>(v);
60 std::memcpy(elemPtr(rec, a, element), &x,
sizeof x);
63 case AccessKind::I64: {
64 auto x =
static_cast<std::int64_t
>(v);
65 std::memcpy(elemPtr(rec, a, element), &x,
sizeof x);
68 case AccessKind::U64: {
69 auto x =
static_cast<std::uint64_t
>(v);
70 std::memcpy(elemPtr(rec, a, element), &x,
sizeof x);
73 case AccessKind::LocStr: {
74 auto x =
static_cast<std::uint32_t
>(v);
85 std::int64_t loadInt(
const std::byte* rec,
const ColumnAccess& a, std::size_t element) {
86 const std::byte* p = elemPtr(rec, a, element);
88 case AccessKind::I8: {
90 std::memcpy(&x, p,
sizeof x);
93 case AccessKind::U8: {
95 std::memcpy(&x, p,
sizeof x);
98 case AccessKind::I16: {
100 std::memcpy(&x, p,
sizeof x);
103 case AccessKind::U16: {
105 std::memcpy(&x, p,
sizeof x);
108 case AccessKind::I32: {
110 std::memcpy(&x, p,
sizeof x);
113 case AccessKind::U32: {
115 std::memcpy(&x, p,
sizeof x);
118 case AccessKind::I64:
119 case AccessKind::U64: {
121 std::memcpy(&x, p,
sizeof x);
124 case AccessKind::LocStr: {
129 case AccessKind::F32:
130 case AccessKind::Str:
138 std::string& stringAt(std::byte* rec,
const ColumnAccess& a, std::size_t element) {
139 return *
reinterpret_cast<std::string*
>(elemPtr(rec, a, element));
142 const std::string& stringAt(
const std::byte* rec,
const ColumnAccess& a, std::size_t element) {
143 return *
reinterpret_cast<const std::string*
>(elemPtr(rec, a, element));
148 std::uint32_t idOfRecord(
const RecordOps& ops,
const std::byte* rec) {
149 if (ops.
idColumn == SIZE_MAX)
return 0;
150 return static_cast<std::uint32_t
>(loadInt(rec, ops.
columns[ops.
idColumn], 0));
162 return idOfRecord(*_ops, _ops->cat(_vec, record));
166 storeInt(_ops->at(_vec, record), _ops->columns[column], element, value);
171 if (a.
kind == AccessKind::F32)
172 std::memcpy(elemPtr(_ops->at(_vec, record), a, element), &value,
sizeof value);
178 std::string_view value) {
180 if (a.
kind == AccessKind::Str || a.
kind == AccessKind::LocStr) stringAt(_ops->at(_vec, record), a, element) =
185 _ops->clonePush(_vec, src);
186 if (_ops->idColumn != SIZE_MAX)
187 storeInt(_ops->at(_vec, _ops->size(_vec) - 1), _ops->columns[_ops->idColumn], 0, newId);
191 const std::size_t n = _ops->size(_vec);
192 for (std::size_t i = 0; i < n; ++i)
193 if (idOfRecord(*_ops, _ops->cat(_vec, i)) == recordId)
return i;
202 return idOfRecord(*_ops, _ops->cat(_vec, record));
206 return loadInt(_ops->cat(_vec, record), _ops->columns[column], element);
211 const std::byte* rec = _ops->cat(_vec, record);
213 case AccessKind::F32: {
215 std::memcpy(&f, elemPtr(rec, a, element),
sizeof f);
216 return std::bit_cast<std::uint32_t>(f);
218 case AccessKind::Str:
219 case AccessKind::LocStr:
222 return static_cast<std::uint32_t
>(loadInt(rec, a, element));
228 if (a.
kind != AccessKind::Str && a.
kind != AccessKind::LocStr)
return {};
229 return stringAt(_ops->cat(_vec, record), a, element);
std::uint32_t idOf(std::size_t record) const override
void setInt(std::size_t record, std::size_t column, std::size_t element, std::int64_t value) override
void setFloat(std::size_t record, std::size_t column, std::size_t element, float value) override
std::size_t size() const override
void setString(std::size_t record, std::size_t column, std::size_t element, std::string_view value) override
void reserve(std::size_t n) override
std::size_t findById(std::uint32_t id) const override
The first record whose id equals id, or size() when none (copy source lookup).
void cloneWithId(std::size_t src, std::uint32_t newId) override
Clone record src into a fresh record and set its id column to newId (WDC copy-table materialization).
std::size_t add() override
std::string_view getString(std::size_t record, std::size_t column, std::size_t element) const override
std::uint32_t idOf(std::size_t record) const override
std::int64_t getInt(std::size_t record, std::size_t column, std::size_t element) const override
std::uint32_t getSlot(std::size_t record, std::size_t column, std::size_t element) const override
std::size_t size() const override
AccessKind
The storage kind of one record member, as the erased accessors see it: exact width and signedness for...
The record bridge: ErasedRecordSink / ErasedRecordSource implement the non-templated RecordSink / Rec...
Everything the erased core needs to touch one column of a record: where it lives, what it is,...
std::uint16_t elemStride
Bytes between array elements.
std::uint32_t offset
Member byte offset inside Record.
std::uint32_t flagsOffset
LocStr only: byte offset of .flags.
AccessKind kind
The element's storage kind.
The one thing that stays per-record: a table of thunks over the record VECTOR (only they know sizeof(...
std::size_t idColumn
Index of the $id$ column, or SIZE_MAX.
std::span< const ColumnAccess > columns
Per-column access facts.
Everything the erased core needs to touch one column of a record: where it lives, what it is,...
The one thing that stays per-record: a table of thunks over the record VECTOR (only they know sizeof(...