18#include <boost/core/demangle.hpp>
47 [[nodiscard]] std::size_t ColumnVectorHeader ::
54 auto& existingHeader =
m_elements.at(iter->second);
57 if (existingHeader.type != columnInfo.
type)
58 throw std::runtime_error(
"column " + columnInfo.
name +
" type mismatch");
59 if (existingHeader.offsetName != columnInfo.
offsetName)
60 throw std::runtime_error(
"column " + columnInfo.
name +
" offset name mismatch: " + existingHeader.offsetName +
" vs " + columnInfo.
offsetName);
61 if (existingHeader.isOffset != columnInfo.
isOffset)
62 throw std::runtime_error(
"column " + columnInfo.
name +
" isOffset mismatch");
64 throw std::runtime_error(
"column " + columnInfo.
name +
" fixed dimensions mismatch");
66 throw std::runtime_error(
"column " + columnInfo.
name +
" link target names mismatch");
68 throw std::runtime_error(
"column " + columnInfo.
name +
" variant link key column mismatch");
72 throw std::runtime_error(
"column " + columnInfo.
name +
" already registered as input, cannot register as output");
75 existingHeader.readOnly =
false;
107 header.isOptional =
false;
111 const std::size_t newIndex =
m_elements.size() - 1;
118 void ColumnVectorHeader ::
119 setOffsetColumn (std::size_t columnIndex, std::size_t offsetIndex)
122 throw std::logic_error (
"column index out of range");
124 throw std::logic_error (
"offset index out of range");
127 if (!offset.isOffset)
128 throw std::runtime_error (
"trying to set " + offset.debugName +
" as offset column for " + column.debugName +
", but it is not marked as offset column");
129 if (column.offsetIndex !=
unsetIndex && column.offsetIndex != offsetIndex)
130 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);
131 column.offsetIndex = offsetIndex;
136 void ColumnVectorHeader ::
140 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()));
142 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));
146 for (std::size_t columnIndex = 1u; columnIndex !=
m_elements.size(); ++ columnIndex)
149 if (column.debugName.empty())
150 throw std::logic_error (
"column " + std::to_string(columnIndex) +
" has no name");
151 if (column.type ==
nullptr)
152 throw std::logic_error (
"column " + column.debugName +
" has no type");
154 throw std::logic_error (
"column " + column.debugName +
" is an offset column that is of type " + boost::core::demangle(column.type->name()) +
" instead of ColumnarOffsetType");
157 for (std::size_t columnIndex = 1u; columnIndex !=
m_elements.size(); ++ columnIndex)
163 throw std::logic_error (
"column " + column.debugName +
" has an offset index that was never set");
165 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) +
")");
166 const auto& offsetElement =
m_elements[column.offsetIndex];
167 if (!offsetElement.isOffset)
168 throw std::logic_error (
"column " + column.debugName +
" has offset index that is not marked as offset");
175 void ColumnVectorHeader ::
176 checkData (std::span<const void* const>
data)
const
179 throw std::logic_error (
"data vector has wrong size, expected " + std::to_string(
m_elements.size()) +
" but got " + std::to_string(
data.size()));
181 throw std::logic_error (
"null column is not set to a nullptr value");
182 const auto* sizeVector =
static_cast<const std::size_t*
>(
data[
sizeIndex]);
183 for (std::size_t columnIndex = 0u; columnIndex !=
m_elements.size(); ++ columnIndex)
186 if (
data[columnIndex] ==
nullptr)
188 if (column.isOptional)
190 if (column.offsetIndex !=
nullIndex &&
data[column.offsetIndex] ==
nullptr)
192 throw std::logic_error (
"column " + column.debugName +
" was not set");
196 const auto size = sizeVector[columnIndex];
198 throw std::runtime_error (
"offset column " + column.debugName +
" has size " + std::to_string(size) +
", but needs at least 1 element");
201 throw std::runtime_error (
"offset column doesn't start with 0: " + column.debugName);
202 for (std::size_t i = 1u; i != size; ++ i)
204 if (offsets[i] < offsets[i-1])
205 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]));
209 for (std::size_t columnIndex = 0u; columnIndex !=
m_elements.size(); ++ columnIndex)
211 if (
data[columnIndex] ==
nullptr)
214 std::size_t expectedSize = 1u;
217 if (
data[column.offsetIndex] ==
nullptr)
218 throw std::runtime_error (
"column " + column.debugName +
" uses offset column " +
m_elements[column.offsetIndex].debugName +
" that is not set");
219 const auto offsetIndex = column.offsetIndex;
221 expectedSize = offsetsPtr[sizeVector[offsetIndex]-1];
223 expectedSize *= column.arraySize;
228 if (sizeVector[columnIndex] != expectedSize)
229 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));
238 m_data (val_header->numColumns(), nullptr),
246 void ColumnVectorData ::
247 setColumnVoid (std::size_t columnIndex, std::size_t size,
const void *dataPtr,
const std::type_info&
type,
bool isConst)
250 throw std::logic_error (
"cannot set the null column");
251 if (columnIndex >=
m_header->numColumns())
252 throw std::logic_error (
"invalid column index: " + std::to_string(columnIndex) +
" (max is " + std::to_string(
m_header->numColumns()-1) +
")");
259 if (dataPtr ==
nullptr)
262 throw std::logic_error (
"dataPtr is null but size is not zero for column: " +
header.debugName);
263 static const unsigned dummyValue = 0;
264 dataPtr = &dummyValue;
268 throw std::runtime_error (
"invalid type for column: " +
header.debugName);
269 if (isConst && !
header.readOnly)
270 throw std::runtime_error (
"assigning const vector to a column that is not read-only: " +
header.debugName);
271 if (
m_data[columnIndex] !=
nullptr)
272 throw std::runtime_error (
"column filled multiple times: " +
header.debugName);
274 m_data[columnIndex] = castDataPtr;
280 std::pair<std::size_t,const void*> ColumnVectorData ::
281 getColumnVoid (std::size_t columnIndex,
const std::type_info *
type,
bool isConst)
283 if (columnIndex >=
m_header->numColumns())
284 throw std::runtime_error (
"invalid column index: " + std::to_string(columnIndex) +
" (max is " + std::to_string(
m_header->numColumns()-1) +
")");
288 throw std::runtime_error (
"invalid type for column: " +
header.debugName);
289 if (!isConst &&
header.readOnly)
290 throw std::runtime_error (
"retrieving non-const vector from a read-only column: " +
header.debugName);
291 if (
m_data[columnIndex] !=
nullptr)
294 return std::make_pair (0u,
nullptr);
299 void ColumnVectorData ::
302 tool.callVoid (
m_data.data());
307 std::unordered_map<std::string, ColumnInfo> ColumnVectorHeader ::
308 getAllColumnInfo ()
const
310 std::unordered_map<std::string, ColumnInfo>
result;
316 info.name =
header.debugName;
317 info.index =
static_cast<unsigned>(i);
319 info.accessMode =
header.accessMode;
320 info.offsetName =
header.offsetName;
321 info.fixedDimensions =
header.fixedDimensions;
322 info.isOffset =
header.isOffset;
323 info.isOptional =
header.isOptional;
324 info.linkTargetNames =
header.linkTargetNames;
325 info.variantLinkKeyColumn =
header.variantLinkKeyColumn;
326 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
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::vector< unsigned > fixedDimensions
the fixed dimensions this column has (if any)
bool isOptional
whether this column is optional
std::string variantLinkKeyColumn
if this is a variant link column, this is the name of the column with the container keys
std::string name
the name of the column
std::vector< std::string > linkTargetNames
for link columns: the name(s) of the container(s) we link to
bool isOffset
whether this is an offset column
ColumnAccessMode accessMode
the access mode for the column
const std::type_info * type
the type of the individual entries in the column