ATLAS Offline Software
Loading...
Searching...
No Matches
columnar::ColumnVectorHeader Class Referencefinal

the header information for the entire columnar data vector More...

#include <ColumnVectorWrapper.h>

Collaboration diagram for columnar::ColumnVectorHeader:

Public Member Functions

 ColumnVectorHeader ()
 standard contructor
std::size_t addColumn (const ColumnInfo &columnInfo)
 add a column for the given ColumnInfo, returning its index
void setOffsetColumn (std::size_t columnIndex, std::size_t offsetIndex)
 set the index of the offset column for the given column
std::size_t numColumns () const noexcept
 the number of columns in the columnar data vector
const ColumnVectorElementHeadergetColumn (std::size_t index) const
 get the column for the given index
std::size_t getColumnIndex (const std::string &name) const noexcept
 get the column index for the given name, or nullIndex if not found
std::unordered_map< std::string, ColumnInfogetAllColumnInfo () const
 get all columns as a map of ColumnInfo for use with IColumnData::connect
void checkSelf () const
 check the self-consistency of the header
void checkData (std::span< const void *const > data) const
 do a basic check of the data vector

Static Public Attributes

static constexpr std::size_t nullIndex = 0u
 the index used for an invalid index (always has to be 0)
static constexpr std::size_t sizeIndex = 1u
 the index used for the column size column
static constexpr std::size_t unsetIndex = static_cast<std::size_t>(-1)
 the number used for an unset but non-null index
static constexpr std::size_t numFixedColumns = 2u
 the number of fix elements in the columnar data vector

Private Attributes

std::vector< ColumnVectorElementHeaderm_elements
 the elements in the columnar data vector
std::unordered_map< std::string, std::size_t > m_nameToIndex
 map from column name to index for deduplication

Detailed Description

the header information for the entire columnar data vector

At its core this is just a vector of ColumnVectorElementHeader, with some extra helper functions. Note that this is completely independent of the tool used, and can indeed be used with multiple tools.

Definition at line 120 of file ColumnVectorWrapper.h.

Constructor & Destructor Documentation

◆ ColumnVectorHeader()

columnar::ColumnVectorHeader::ColumnVectorHeader ( )

standard contructor

Definition at line 29 of file ColumnVectorWrapper.cxx.

31 {
33
34 // we always reserve the first column as having a null value
35 m_elements.at(nullIndex).debugName = "<null>";
36 m_elements.at(nullIndex).isOptional = true;
37
38 // we always reserve the second column as the size column
39 m_elements.at(sizeIndex).debugName = "<size>";
40 m_elements.at(sizeIndex).type = &typeid(std::size_t);
41 m_elements.at(sizeIndex).isOptional = false;
42 m_elements.at(sizeIndex).readOnly = true;
43 }
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::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

Member Function Documentation

◆ addColumn()

std::size_t columnar::ColumnVectorHeader::addColumn ( const ColumnInfo & columnInfo)
nodiscard

add a column for the given ColumnInfo, returning its index

Definition at line 47 of file ColumnVectorWrapper.cxx.

49 {
50 // Check for existing column with the same name (deduplication for multi-tool support)
51 auto iter = m_nameToIndex.find(columnInfo.name);
52 if (iter != m_nameToIndex.end())
53 {
54 auto& existingHeader = m_elements.at(iter->second);
55
56 // Variant link key columns with different targets get auto-renamed
57 if (!columnInfo.keyColumnForVariantLink.empty() && !existingHeader.keyColumnForVariantLink.empty() && existingHeader.variantLinkTargetNames != columnInfo.variantLinkTargetNames)
58 {
59 std::string uniqueName;
60 for (unsigned suffix = 1; ; ++suffix)
61 {
62 uniqueName = columnInfo.name + "." + std::to_string(suffix);
63 if (m_nameToIndex.find(uniqueName) == m_nameToIndex.end())
64 break;
65 }
66 ColumnInfo renamedInfo = columnInfo;
67 renamedInfo.name = std::move(uniqueName);
68 return addColumn(renamedInfo);
69 }
70
71 // Check that relevant fields match
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");
78 if (existingHeader.fixedDimensions != columnInfo.fixedDimensions)
79 throw std::runtime_error("column " + columnInfo.name + " fixed dimensions mismatch");
80 if (existingHeader.soleLinkTargetName != columnInfo.soleLinkTargetName)
81 throw std::runtime_error("column " + columnInfo.name + " sole link target name mismatch");
82 if (existingHeader.isVariantLink != columnInfo.isVariantLink)
83 throw std::runtime_error("column " + columnInfo.name + " isVariantLink mismatch");
84 if (existingHeader.variantLinkTargetNames != columnInfo.variantLinkTargetNames)
85 throw std::runtime_error("column " + columnInfo.name + " variant link target names mismatch");
86 if (existingHeader.keyColumnForVariantLink != columnInfo.keyColumnForVariantLink)
87 throw std::runtime_error("column " + columnInfo.name + " key column for variant link mismatch");
88
89 // Handle access mode conflicts
90 if (columnInfo.accessMode == ColumnAccessMode::output && existingHeader.readOnly)
91 throw std::runtime_error("column " + columnInfo.name + " already registered as input, cannot register as output");
92 // Promote to read-write if new column needs write access (update mode)
93 if (columnInfo.accessMode == ColumnAccessMode::update)
94 existingHeader.readOnly = false;
95 // If existing is already non-readOnly (output or update), keep it that way
96 return iter->second;
97 }
98
99 m_elements.emplace_back();
100 m_elements.at(sizeIndex).arraySize = m_elements.size();
101
102 auto& header = m_elements.back();
103 header.debugName = columnInfo.name;
104 header.type = columnInfo.type;
105 header.accessMode = columnInfo.accessMode;
106 header.offsetName = columnInfo.offsetName;
107 header.soleLinkTargetName = columnInfo.soleLinkTargetName;
108 header.isVariantLink = columnInfo.isVariantLink;
109 header.variantLinkTargetNames = columnInfo.variantLinkTargetNames;
110 header.keyColumnForVariantLink = columnInfo.keyColumnForVariantLink;
111 header.fixedDimensions = columnInfo.fixedDimensions;
112
113 switch (columnInfo.accessMode)
114 {
116 break;
118 header.readOnly = false;
119 break;
121 header.readOnly = false;
122 break;
123 }
124 for (unsigned dim : columnInfo.fixedDimensions)
125 header.arraySize *= dim;
126 header.isOffset = columnInfo.isOffset;
127 if (!columnInfo.isOptional)
128 header.isOptional = false;
129 if (!columnInfo.offsetName.empty())
130 header.offsetIndex = unsetIndex;
131
132 const std::size_t newIndex = m_elements.size() - 1;
133 m_nameToIndex.emplace(columnInfo.name, newIndex);
134 return newIndex;
135 }
std::size_t addColumn(const ColumnInfo &columnInfo)
add a column for the given ColumnInfo, returning its index
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
@ update
an updateable column
Definition ColumnInfo.h:27
@ output
an output column
Definition ColumnInfo.h:24
@ input
an input column
Definition ColumnInfo.h:21

◆ checkData()

void columnar::ColumnVectorHeader::checkData ( std::span< const void *const > data) const

do a basic check of the data vector

Definition at line 196 of file ColumnVectorWrapper.cxx.

198 {
199 if (data.size() != m_elements.size())
200 throw std::logic_error ("data vector has wrong size, expected " + std::to_string(m_elements.size()) + " but got " + std::to_string(data.size()));
201 if (data[nullIndex] != nullptr)
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)
205 {
206 const auto& column = m_elements[columnIndex];
207 if (data[columnIndex] == nullptr)
208 {
209 if (column.isOptional)
210 continue;
211 if (column.offsetIndex != nullIndex && data[column.offsetIndex] == nullptr)
212 continue;
213 throw std::logic_error ("column " + column.debugName + " was not set");
214 }
215 if (column.isOffset)
216 {
217 const auto size = sizeVector[columnIndex];
218 if (size < 1)
219 throw std::runtime_error ("offset column " + column.debugName + " has size " + std::to_string(size) + ", but needs at least 1 element");
220 auto *offsets = static_cast<const ColumnarOffsetType*>(data[columnIndex]);
221 if (offsets[0] != 0)
222 throw std::runtime_error ("offset column doesn't start with 0: " + column.debugName);
223 for (std::size_t i = 1u; i != size; ++ i)
224 {
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]));
227 }
228 }
229 }
230 for (std::size_t columnIndex = 0u; columnIndex != m_elements.size(); ++ columnIndex)
231 {
232 if (data[columnIndex] == nullptr)
233 continue;
234 const auto& column = m_elements[columnIndex];
235 std::size_t expectedSize = 1u;
236 if (column.offsetIndex != ColumnVectorHeader::nullIndex)
237 {
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;
241 auto *offsetsPtr = static_cast<const ColumnarOffsetType*>(data[offsetIndex]);
242 expectedSize = offsetsPtr[sizeVector[offsetIndex]-1];
243 }
244 expectedSize *= column.arraySize;
245
246 if (column.isOffset)
247 expectedSize += 1u;
248
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));
251 }
252 }
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
std::size_t ColumnarOffsetType
the type used for the size and offsets in the columnar data

◆ checkSelf()

void columnar::ColumnVectorHeader::checkSelf ( ) const

check the self-consistency of the header

Definition at line 157 of file ColumnVectorWrapper.cxx.

159 {
160 if (m_elements.size() < numFixedColumns)
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()));
162 if (m_elements[sizeIndex].arraySize != 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));
164
165 // skipping the first column, which is always the null column
166 // and behaves in a funny manner
167 for (std::size_t columnIndex = 1u; columnIndex != m_elements.size(); ++ columnIndex)
168 {
169 const auto& column = m_elements[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");
174 if (column.isOffset && *column.type != typeid(ColumnarOffsetType))
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");
176 }
177
178 for (std::size_t columnIndex = 1u; columnIndex != m_elements.size(); ++ columnIndex)
179 {
180 const auto& column = m_elements[columnIndex];
181 if (column.offsetIndex != nullIndex)
182 {
183 if (column.offsetIndex == unsetIndex)
184 throw std::logic_error ("column " + column.debugName + " has an offset index that was never set");
185 if (column.offsetIndex >= m_elements.size())
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");
190 }
191 }
192 }

◆ getAllColumnInfo()

std::unordered_map< std::string, ColumnInfo > columnar::ColumnVectorHeader::getAllColumnInfo ( ) const
nodiscard

get all columns as a map of ColumnInfo for use with IColumnData::connect

Definition at line 328 of file ColumnVectorWrapper.cxx.

330 {
331 std::unordered_map<std::string, ColumnInfo> result;
332 // Skip the fixed columns (null and size)
333 for (std::size_t i = numFixedColumns; i < m_elements.size(); ++i)
334 {
335 const auto& header = m_elements[i];
336 ColumnInfo info;
337 info.name = header.debugName;
338 info.index = static_cast<unsigned>(i);
339 info.type = header.type;
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));
350 }
351 return result;
352 }

◆ getColumn()

const ColumnVectorElementHeader & columnar::ColumnVectorHeader::getColumn ( std::size_t index) const
inlinenodiscard

get the column for the given index

Definition at line 155 of file ColumnVectorWrapper.h.

155 {
156 return m_elements.at (index); }

◆ getColumnIndex()

std::size_t columnar::ColumnVectorHeader::getColumnIndex ( const std::string & name) const
inlinenodiscardnoexcept

get the column index for the given name, or nullIndex if not found

Definition at line 160 of file ColumnVectorWrapper.h.

160 {
161 auto iter = m_nameToIndex.find(name);
162 return (iter != m_nameToIndex.end()) ? iter->second : nullIndex; }

◆ numColumns()

std::size_t columnar::ColumnVectorHeader::numColumns ( ) const
inlinenodiscardnoexcept

the number of columns in the columnar data vector

Definition at line 150 of file ColumnVectorWrapper.h.

150 {
151 return m_elements.size(); }

◆ setOffsetColumn()

void columnar::ColumnVectorHeader::setOffsetColumn ( std::size_t columnIndex,
std::size_t offsetIndex )

set the index of the offset column for the given column

Definition at line 139 of file ColumnVectorWrapper.cxx.

141 {
142 if (columnIndex >= m_elements.size())
143 throw std::logic_error ("column index out of range");
144 if (offsetIndex >= m_elements.size())
145 throw std::logic_error ("offset index out of range");
146 auto& column = m_elements.at(columnIndex);
147 auto& offset = m_elements.at(offsetIndex);
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;
153 }

Member Data Documentation

◆ m_elements

std::vector<ColumnVectorElementHeader> columnar::ColumnVectorHeader::m_elements
private

the elements in the columnar data vector

Private Members

Definition at line 180 of file ColumnVectorWrapper.h.

◆ m_nameToIndex

std::unordered_map<std::string, std::size_t> columnar::ColumnVectorHeader::m_nameToIndex
private

map from column name to index for deduplication

Definition at line 183 of file ColumnVectorWrapper.h.

◆ nullIndex

std::size_t columnar::ColumnVectorHeader::nullIndex = 0u
staticconstexpr

the index used for an invalid index (always has to be 0)

Public Members

Definition at line 127 of file ColumnVectorWrapper.h.

◆ numFixedColumns

std::size_t columnar::ColumnVectorHeader::numFixedColumns = 2u
staticconstexpr

the number of fix elements in the columnar data vector

Definition at line 136 of file ColumnVectorWrapper.h.

◆ sizeIndex

std::size_t columnar::ColumnVectorHeader::sizeIndex = 1u
staticconstexpr

the index used for the column size column

Definition at line 130 of file ColumnVectorWrapper.h.

◆ unsetIndex

std::size_t columnar::ColumnVectorHeader::unsetIndex = static_cast<std::size_t>(-1)
staticconstexpr

the number used for an unset but non-null index

Definition at line 133 of file ColumnVectorWrapper.h.


The documentation for this class was generated from the following files: