18#include <boost/core/demangle.hpp>
47 [[nodiscard]] std::size_t ColumnVectorHeader ::
54 auto& existingHeader =
m_elements.at(iter->second);
59 std::string uniqueName;
60 for (
unsigned suffix = 1; ; ++suffix)
62 uniqueName = columnInfo.
name +
"." + std::to_string(suffix);
67 renamedInfo.
name = std::move(uniqueName);
72 if (existingHeader.type != columnInfo.
type)
73 throw std::runtime_error(
"column " + columnInfo.
name +
" type mismatch");
74 if (existingHeader.offsetName != columnInfo.
offsetName)
75 throw std::runtime_error(
"column " + columnInfo.
name +
" offset name mismatch: " + existingHeader.offsetName +
" vs " + columnInfo.
offsetName);
76 if (existingHeader.isOffset != columnInfo.
isOffset)
77 throw std::runtime_error(
"column " + columnInfo.
name +
" isOffset mismatch");
79 throw std::runtime_error(
"column " + columnInfo.
name +
" fixed dimensions mismatch");
81 throw std::runtime_error(
"column " + columnInfo.
name +
" sole link target name mismatch");
83 throw std::runtime_error(
"column " + columnInfo.
name +
" isVariantLink mismatch");
85 throw std::runtime_error(
"column " + columnInfo.
name +
" variant link target names mismatch");
87 throw std::runtime_error(
"column " + columnInfo.
name +
" key column for variant link mismatch");
91 throw std::runtime_error(
"column " + columnInfo.
name +
" already registered as input, cannot register as output");
94 existingHeader.readOnly =
false;
128 header.isOptional =
false;
132 const std::size_t newIndex =
m_elements.size() - 1;
139 void ColumnVectorHeader ::
140 setOffsetColumn (std::size_t columnIndex, std::size_t offsetIndex)
143 throw std::logic_error (
"column index out of range");
145 throw std::logic_error (
"offset index out of range");
148 if (!offset.isOffset)
149 throw std::runtime_error (
"trying to set " + offset.debugName +
" as offset column for " + column.debugName +
", but it is not marked as offset column");
150 if (column.offsetIndex !=
unsetIndex && column.offsetIndex != offsetIndex)
151 throw std::runtime_error (
"trying to set " + offset.debugName +
" as offset column for " + column.debugName +
", but it is already set to " +
m_elements.at(column.offsetIndex).debugName);
152 column.offsetIndex = offsetIndex;
157 void ColumnVectorHeader ::
161 throw std::logic_error (
"header has too few m_elements, expected at least " + std::to_string(
numFixedColumns) +
" but got " + std::to_string(
m_elements.size()));
163 throw std::logic_error (
"size column has wrong array size, expected " + std::to_string(
m_elements.size()) +
" but got " + std::to_string(
m_elements[
sizeIndex].arraySize));
167 for (std::size_t columnIndex = 1u; columnIndex !=
m_elements.size(); ++ columnIndex)
170 if (column.debugName.empty())
171 throw std::logic_error (
"column " + std::to_string(columnIndex) +
" has no name");
172 if (column.type ==
nullptr)
173 throw std::logic_error (
"column " + column.debugName +
" has no type");
175 throw std::logic_error (
"column " + column.debugName +
" is an offset column that is of type " + boost::core::demangle(column.type->name()) +
" instead of ColumnarOffsetType");
178 for (std::size_t columnIndex = 1u; columnIndex !=
m_elements.size(); ++ columnIndex)
184 throw std::logic_error (
"column " + column.debugName +
" has an offset index that was never set");
186 throw std::logic_error (
"column " + column.debugName +
" has invalid offset index " + std::to_string(column.offsetIndex) +
" (max is " + std::to_string(
m_elements.size()-1) +
")");
187 const auto& offsetElement =
m_elements[column.offsetIndex];
188 if (!offsetElement.isOffset)
189 throw std::logic_error (
"column " + column.debugName +
" has offset index that is not marked as offset");
196 void ColumnVectorHeader ::
197 checkData (std::span<const void* const>
data)
const
200 throw std::logic_error (
"data vector has wrong size, expected " + std::to_string(
m_elements.size()) +
" but got " + std::to_string(
data.size()));
202 throw std::logic_error (
"null column is not set to a nullptr value");
203 const auto* sizeVector =
static_cast<const std::size_t*
>(
data[
sizeIndex]);
204 for (std::size_t columnIndex = 0u; columnIndex !=
m_elements.size(); ++ columnIndex)
207 if (
data[columnIndex] ==
nullptr)
209 if (column.isOptional)
211 if (column.offsetIndex !=
nullIndex &&
data[column.offsetIndex] ==
nullptr)
213 throw std::logic_error (
"column " + column.debugName +
" was not set");
217 const auto size = sizeVector[columnIndex];
219 throw std::runtime_error (
"offset column " + column.debugName +
" has size " + std::to_string(size) +
", but needs at least 1 element");
222 throw std::runtime_error (
"offset column doesn't start with 0: " + column.debugName);
223 for (std::size_t i = 1u; i != size; ++ i)
225 if (offsets[i] < offsets[i-1])
226 throw std::runtime_error (
"offset column " + column.debugName +
" is not monotonically increasing at index " + std::to_string(i) +
": " + std::to_string(offsets[i-1]) +
" > " + std::to_string(offsets[i]));
230 for (std::size_t columnIndex = 0u; columnIndex !=
m_elements.size(); ++ columnIndex)
232 if (
data[columnIndex] ==
nullptr)
235 std::size_t expectedSize = 1u;
238 if (
data[column.offsetIndex] ==
nullptr)
239 throw std::runtime_error (
"column " + column.debugName +
" uses offset column " +
m_elements[column.offsetIndex].debugName +
" that is not set");
240 const auto offsetIndex = column.offsetIndex;
242 expectedSize = offsetsPtr[sizeVector[offsetIndex]-1];
244 expectedSize *= column.arraySize;
249 if (sizeVector[columnIndex] != expectedSize)
250 throw std::runtime_error (
"column size doesn't match expected size: " + column.debugName +
", found " + std::to_string (sizeVector[columnIndex]) +
" vs exptected=" + std::to_string (expectedSize) +
" isOffset=" + std::to_string (column.isOffset));
259 m_data (val_header->numColumns(), nullptr),
267 void ColumnVectorData ::
268 setColumnVoid (std::size_t columnIndex, std::size_t size,
const void *dataPtr,
const std::type_info&
type,
bool isConst)
271 throw std::logic_error (
"cannot set the null column");
272 if (columnIndex >=
m_header->numColumns())
273 throw std::logic_error (
"invalid column index: " + std::to_string(columnIndex) +
" (max is " + std::to_string(
m_header->numColumns()-1) +
")");
280 if (dataPtr ==
nullptr)
283 throw std::logic_error (
"dataPtr is null but size is not zero for column: " +
header.debugName);
284 static const unsigned dummyValue = 0;
285 dataPtr = &dummyValue;
289 throw std::runtime_error (
"invalid type for column: " +
header.debugName);
290 if (isConst && !
header.readOnly)
291 throw std::runtime_error (
"assigning const vector to a column that is not read-only: " +
header.debugName);
292 if (
m_data[columnIndex] !=
nullptr)
293 throw std::runtime_error (
"column filled multiple times: " +
header.debugName);
295 m_data[columnIndex] = castDataPtr;
301 std::pair<std::size_t,const void*> ColumnVectorData ::
302 getColumnVoid (std::size_t columnIndex,
const std::type_info *
type,
bool isConst)
const
304 if (columnIndex >=
m_header->numColumns())
305 throw std::runtime_error (
"invalid column index: " + std::to_string(columnIndex) +
" (max is " + std::to_string(
m_header->numColumns()-1) +
")");
309 throw std::runtime_error (
"invalid type for column: " +
header.debugName);
310 if (!isConst &&
header.readOnly)
311 throw std::runtime_error (
"retrieving non-const vector from a read-only column: " +
header.debugName);
312 if (
m_data[columnIndex] !=
nullptr)
315 return std::make_pair (0u,
nullptr);
320 void ColumnVectorData ::
323 tool.callVoid (
m_data.data());
328 std::unordered_map<std::string, ColumnInfo> ColumnVectorHeader ::
329 getAllColumnInfo ()
const
331 std::unordered_map<std::string, ColumnInfo> result;
337 info.name =
header.debugName;
338 info.index =
static_cast<unsigned>(i);
340 info.accessMode =
header.accessMode;
341 info.offsetName =
header.offsetName;
342 info.fixedDimensions =
header.fixedDimensions;
343 info.isOffset =
header.isOffset;
344 info.isOptional =
header.isOptional;
345 info.soleLinkTargetName =
header.soleLinkTargetName;
346 info.isVariantLink =
header.isVariantLink;
347 info.variantLinkTargetNames =
header.variantLinkTargetNames;
348 info.keyColumnForVariantLink =
header.keyColumnForVariantLink;
349 result.emplace(info.name, std::move(info));
char data[hepevt_bytes_allocation_ATLAS]
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
const ColumnVectorHeader * m_header
std::vector< void * > m_data
void setColumn(std::size_t columnIndex, std::size_t size, CT *dataPtr)
set the data for the given column
std::vector< std::size_t > m_dataSize
the header information for the entire columnar data vector
std::size_t addColumn(const ColumnInfo &columnInfo)
add a column for the given ColumnInfo, returning its index
static constexpr std::size_t nullIndex
the index used for an invalid index (always has to be 0)
static constexpr std::size_t numFixedColumns
the number of fix elements in the columnar data vector
std::unordered_map< std::string, std::size_t > m_nameToIndex
map from column name to index for deduplication
static constexpr std::size_t unsetIndex
the number used for an unset but non-null index
std::vector< ColumnVectorElementHeader > m_elements
the elements in the columnar data vector
static constexpr std::size_t sizeIndex
the index used for the column size column
@ update
an updateable column
std::size_t ColumnarOffsetType
the type used for the size and offsets in the columnar data
a struct that contains meta-information about each column that's needed to interface the column with ...
std::string offsetName
the name of the offset column used for this column (or empty string for none)
std::string soleLinkTargetName
for simple link columns: the name of the target container
std::string keyColumnForVariantLink
if this is a key column for a variant link, the name of the associated link column
std::vector< unsigned > fixedDimensions
the fixed dimensions this column has (if any)
bool isOptional
whether this column is optional
std::vector< std::string > variantLinkTargetNames
for variant link key columns: the names of the containers we can link to
std::string name
the name of the column
bool isOffset
whether this is an offset column
ColumnAccessMode accessMode
the access mode for the column
bool isVariantLink
whether this is a variant link column
const std::type_info * type
the type of the individual entries in the column