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 124 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.soleLinkTargetClid != columnInfo.soleLinkTargetClid)
83 throw std::runtime_error("column " + columnInfo.name + " sole link target clid mismatch");
84 if (existingHeader.isVariantLink != columnInfo.isVariantLink)
85 throw std::runtime_error("column " + columnInfo.name + " isVariantLink mismatch");
86 if (existingHeader.variantLinkTargetNames != columnInfo.variantLinkTargetNames)
87 throw std::runtime_error("column " + columnInfo.name + " variant link target names mismatch");
88 if (existingHeader.keyColumnForVariantLink != columnInfo.keyColumnForVariantLink)
89 throw std::runtime_error("column " + columnInfo.name + " key column for variant link mismatch");
90
91 // Handle access mode conflicts
92 if (columnInfo.accessMode == ColumnAccessMode::output && existingHeader.readOnly)
93 throw std::runtime_error("column " + columnInfo.name + " already registered as input, cannot register as output");
94 // Promote to read-write if new column needs write access (update mode)
95 if (columnInfo.accessMode == ColumnAccessMode::update)
96 existingHeader.readOnly = false;
97 // If existing is already non-readOnly (output or update), keep it that way
98 return iter->second;
99 }
100
101 m_elements.emplace_back();
102 m_elements.at(sizeIndex).arraySize = m_elements.size();
103
104 auto& header = m_elements.back();
105 header.debugName = columnInfo.name;
106 header.type = columnInfo.type;
107 header.accessMode = columnInfo.accessMode;
108 header.offsetName = columnInfo.offsetName;
109 header.soleLinkTargetName = columnInfo.soleLinkTargetName;
110 header.soleLinkTargetClid = columnInfo.soleLinkTargetClid;
111 header.isVariantLink = columnInfo.isVariantLink;
112 header.variantLinkTargetNames = columnInfo.variantLinkTargetNames;
113 header.keyColumnForVariantLink = columnInfo.keyColumnForVariantLink;
114 header.fixedDimensions = columnInfo.fixedDimensions;
115
116 switch (columnInfo.accessMode)
117 {
119 break;
121 header.readOnly = false;
122 break;
124 header.readOnly = false;
125 break;
126 }
127 for (unsigned dim : columnInfo.fixedDimensions)
128 header.arraySize *= dim;
129 header.isOffset = columnInfo.isOffset;
130 if (!columnInfo.isOptional)
131 header.isOptional = false;
132 if (!columnInfo.offsetName.empty())
133 header.offsetIndex = unsetIndex;
134
135 const std::size_t newIndex = m_elements.size() - 1;
136 m_nameToIndex.emplace(columnInfo.name, newIndex);
137 return newIndex;
138 }
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:28
@ output
an output column
Definition ColumnInfo.h:25
@ input
an input column
Definition ColumnInfo.h:22

◆ checkData()

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

do a basic check of the data vector

Definition at line 199 of file ColumnVectorWrapper.cxx.

201 {
202 if (data.size() != m_elements.size())
203 throw std::logic_error ("data vector has wrong size, expected " + std::to_string(m_elements.size()) + " but got " + std::to_string(data.size()));
204 if (data[nullIndex] != nullptr)
205 throw std::logic_error ("null column is not set to a nullptr value");
206 const auto* sizeVector = static_cast<const std::size_t*>(data[sizeIndex]);
207 for (std::size_t columnIndex = 0u; columnIndex != m_elements.size(); ++ columnIndex)
208 {
209 const auto& column = m_elements[columnIndex];
210 if (data[columnIndex] == nullptr)
211 {
212 if (column.isOptional)
213 continue;
214 if (column.offsetIndex != nullIndex && data[column.offsetIndex] == nullptr)
215 continue;
216 throw std::logic_error ("column " + column.debugName + " was not set");
217 }
218 if (column.isOffset)
219 {
220 const auto size = sizeVector[columnIndex];
221 if (size < 1)
222 throw std::runtime_error ("offset column " + column.debugName + " has size " + std::to_string(size) + ", but needs at least 1 element");
223 auto *offsets = static_cast<const ColumnarOffsetType*>(data[columnIndex]);
224 if (offsets[0] != 0)
225 throw std::runtime_error ("offset column doesn't start with 0: " + column.debugName);
226 for (std::size_t i = 1u; i != size; ++ i)
227 {
228 if (offsets[i] < offsets[i-1])
229 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 }
231 }
232 }
233 for (std::size_t columnIndex = 0u; columnIndex != m_elements.size(); ++ columnIndex)
234 {
235 if (data[columnIndex] == nullptr)
236 continue;
237 const auto& column = m_elements[columnIndex];
238 std::size_t expectedSize = 1u;
239 if (column.offsetIndex != ColumnVectorHeader::nullIndex)
240 {
241 if (data[column.offsetIndex] == nullptr)
242 throw std::runtime_error ("column " + column.debugName + " uses offset column " + m_elements[column.offsetIndex].debugName + " that is not set");
243 const auto offsetIndex = column.offsetIndex;
244 auto *offsetsPtr = static_cast<const ColumnarOffsetType*>(data[offsetIndex]);
245 expectedSize = offsetsPtr[sizeVector[offsetIndex]-1];
246 }
247 expectedSize *= column.arraySize;
248
249 if (column.isOffset)
250 expectedSize += 1u;
251
252 if (sizeVector[columnIndex] != expectedSize)
253 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));
254 }
255 }
size_t size() const
Number of registered mappings.
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 160 of file ColumnVectorWrapper.cxx.

162 {
163 if (m_elements.size() < numFixedColumns)
164 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()));
165 if (m_elements[sizeIndex].arraySize != m_elements.size())
166 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
168 // skipping the first column, which is always the null column
169 // and behaves in a funny manner
170 for (std::size_t columnIndex = 1u; columnIndex != m_elements.size(); ++ columnIndex)
171 {
172 const auto& column = m_elements[columnIndex];
173 if (column.debugName.empty())
174 throw std::logic_error ("column " + std::to_string(columnIndex) + " has no name");
175 if (column.type == nullptr)
176 throw std::logic_error ("column " + column.debugName + " has no type");
177 if (column.isOffset && *column.type != typeid(ColumnarOffsetType))
178 throw std::logic_error ("column " + column.debugName + " is an offset column that is of type " + boost::core::demangle(column.type->name()) + " instead of ColumnarOffsetType");
179 }
180
181 for (std::size_t columnIndex = 1u; columnIndex != m_elements.size(); ++ columnIndex)
182 {
183 const auto& column = m_elements[columnIndex];
184 if (column.offsetIndex != nullIndex)
185 {
186 if (column.offsetIndex == unsetIndex)
187 throw std::logic_error ("column " + column.debugName + " has an offset index that was never set");
188 if (column.offsetIndex >= m_elements.size())
189 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) + ")");
190 const auto& offsetElement = m_elements[column.offsetIndex];
191 if (!offsetElement.isOffset)
192 throw std::logic_error ("column " + column.debugName + " has offset index that is not marked as offset");
193 }
194 }
195 }

◆ 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 331 of file ColumnVectorWrapper.cxx.

333 {
334 std::unordered_map<std::string, ColumnInfo> result;
335 // Skip the fixed columns (null and size)
336 for (std::size_t i = numFixedColumns; i < m_elements.size(); ++i)
337 {
338 const auto& header = m_elements[i];
339 ColumnInfo info;
340 info.name = header.debugName;
341 info.index = static_cast<unsigned>(i);
342 info.type = header.type;
343 info.accessMode = header.accessMode;
344 info.offsetName = header.offsetName;
345 info.fixedDimensions = header.fixedDimensions;
346 info.isOffset = header.isOffset;
347 info.isOptional = header.isOptional;
348 info.soleLinkTargetName = header.soleLinkTargetName;
349 info.soleLinkTargetClid = header.soleLinkTargetClid;
350 info.isVariantLink = header.isVariantLink;
351 info.variantLinkTargetNames = header.variantLinkTargetNames;
352 info.keyColumnForVariantLink = header.keyColumnForVariantLink;
353 result.emplace(info.name, std::move(info));
354 }
355 return result;
356 }

◆ getColumn()

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

get the column for the given index

Definition at line 159 of file ColumnVectorWrapper.h.

159 {
160 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 164 of file ColumnVectorWrapper.h.

164 {
165 auto iter = m_nameToIndex.find(name);
166 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 154 of file ColumnVectorWrapper.h.

154 {
155 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 142 of file ColumnVectorWrapper.cxx.

144 {
145 if (columnIndex >= m_elements.size())
146 throw std::logic_error ("column index out of range");
147 if (offsetIndex >= m_elements.size())
148 throw std::logic_error ("offset index out of range");
149 auto& column = m_elements.at(columnIndex);
150 auto& offset = m_elements.at(offsetIndex);
151 if (!offset.isOffset)
152 throw std::runtime_error ("trying to set " + offset.debugName + " as offset column for " + column.debugName + ", but it is not marked as offset column");
153 if (column.offsetIndex != unsetIndex && column.offsetIndex != offsetIndex)
154 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);
155 column.offsetIndex = offsetIndex;
156 }

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 184 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 187 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 131 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 140 of file ColumnVectorWrapper.h.

◆ sizeIndex

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

the index used for the column size column

Definition at line 134 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 137 of file ColumnVectorWrapper.h.


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