ATLAS Offline Software
Loading...
Searching...
No Matches
columnar::TestUtils::LinkColumnVector Class Referencefinal
Collaboration diagram for columnar::TestUtils::LinkColumnVector:

Public Types

using CM = ColumnarModeArray

Public Member Functions

 ~LinkColumnVector () noexcept
std::vector< std::string > connect (const ColumnInfo &columnInfo, const std::unordered_map< std::string, const std::vector< ColumnarOffsetType > * > &offsetColumns, const std::unordered_map< std::string, ColumnInfo > &requestedColumns)
void clear ()
void checkOffsets (unsigned eventIndex)
template<typename T>
void addLink (const ElementLink< T > &element, unsigned eventIndex)
void addEmptyLink ()
void addSplitLink (std::size_t linkIndex, SG::sgkey_t linkKey, unsigned eventIndex)
std::size_t size () const noexcept
const CM::LinkIndexTypedata () const noexcept
auto begin () const noexcept
auto end () const noexcept
const std::vector< typename CM::LinkKeyType > & keysColumn (std::size_t index) const

Private Member Functions

void addTarget (const std::string &name, const std::unordered_map< std::string, const std::vector< ColumnarOffsetType > * > &offsetColumns, std::uint32_t clid=0)

Private Attributes

std::vector< typename CM::LinkIndexTypem_columnData
std::string m_columnName
std::vector< std::string > m_targetNames
std::vector< SG::sgkey_tm_targetKeys
std::vector< const std::vector< ColumnarOffsetType > * > m_targetOffsetColumns
std::vector< std::vector< typename CM::LinkKeyType > > m_keysColumns
std::unordered_map< SG::sgkey_t, std::unordered_set< std::size_t > > m_unknownKeysAllowedTargets

Detailed Description

Definition at line 301 of file ColumnarPhysliteTest.cxx.

Member Typedef Documentation

◆ CM

Constructor & Destructor Documentation

◆ ~LinkColumnVector()

columnar::TestUtils::LinkColumnVector::~LinkColumnVector ( )
inlinenoexcept

Definition at line 309 of file ColumnarPhysliteTest.cxx.

310 {
311 if (!m_unknownKeysAllowedTargets.empty())
312 {
313 std::cout << "found unknown keys for " << m_columnName << ":";
314 for (auto& [key, allowedSet] : m_unknownKeysAllowedTargets)
315 {
316 std::cout << " " << std::hex << key << std::dec << " (allowed targets:";
317 for (auto index : allowedSet)
318 std::cout << " " << m_targetNames.at(index);
319 std::cout << ")";
320 }
321 }
322 }
std::unordered_map< SG::sgkey_t, std::unordered_set< std::size_t > > m_unknownKeysAllowedTargets

Member Function Documentation

◆ addEmptyLink()

void columnar::TestUtils::LinkColumnVector::addEmptyLink ( )
inline

Definition at line 376 of file ColumnarPhysliteTest.cxx.

377 {
379 }
std::vector< typename CM::LinkIndexType > m_columnData
constexpr ColumnarOffsetType invalidObjectIndex
the value for an invalid element index

◆ addLink()

template<typename T>
void columnar::TestUtils::LinkColumnVector::addLink ( const ElementLink< T > & element,
unsigned eventIndex )
inline

Definition at line 365 of file ColumnarPhysliteTest.cxx.

366 {
367 if (element.isDefault())
368 {
369 addEmptyLink();
370 return;
371 }
372
373 addSplitLink (element.index(), element.key(), eventIndex);
374 }
bool isDefault() const
Test to see if this link is in the default state.
void addSplitLink(std::size_t linkIndex, SG::sgkey_t linkKey, unsigned eventIndex)

◆ addSplitLink()

void columnar::TestUtils::LinkColumnVector::addSplitLink ( std::size_t linkIndex,
SG::sgkey_t linkKey,
unsigned eventIndex )
inline

Definition at line 381 of file ColumnarPhysliteTest.cxx.

382 {
383 if (linkIndex == 0 && linkKey == 0)
384 {
385 addEmptyLink();
386 return;
387 }
388
389 unsigned targetIndex = 0u;
390 while (targetIndex < m_targetKeys.size() && m_targetKeys.at(targetIndex) != linkKey)
391 ++ targetIndex;
392
393 // We didn't find the key, so we try to figure out which of the
394 // targets it could be. The idea is that you wouldn't rely on
395 // this for real tests, but that you then go and fill in those
396 // keys in the central lookup table. It will always record and
397 // report, that means if there is a variant link with extra
398 // targets you didn't declare you will get a diagnostic. This
399 // may be overly cautious, but it gives an extra diagnostic if
400 // maybe you missed a target.
401 if (targetIndex == m_targetKeys.size())
402 {
403 if (!m_unknownKeysAllowedTargets.contains (linkKey))
404 {
405 auto& allowedSet = m_unknownKeysAllowedTargets[linkKey];
406 for (std::size_t i = 0; i < m_targetKeys.size(); ++ i)
407 {
408 if (m_targetKeys.at(i) == 0)
409 allowedSet.insert(i);
410 }
411 }
412 auto& allowedSet = m_unknownKeysAllowedTargets[linkKey];
413 for (auto iter = allowedSet.begin(); iter != allowedSet.end();)
414 {
415 auto index = *iter;
416 auto& targetOffsetColumn = *m_targetOffsetColumns.at(index);
417 if (eventIndex + 1 >= targetOffsetColumn.size())
418 throw std::runtime_error ("target offset column not yet filled for: " + m_targetNames.at(index));
419 if (targetOffsetColumn.at(eventIndex) + linkIndex >= targetOffsetColumn.at(eventIndex + 1))
420 iter = allowedSet.erase(iter);
421 else
422 ++ iter;
423 }
424 // Not quite sure whether it is safer to use or not use one of
425 // the targets from the allowed set in this case. In general
426 // tools are expected to handle invalid links gracefully,
427 // worst case they throw an exception when trying to access
428 // it. So what I came up with is that for variant links we
429 // assume it invalid, but for non-variant links the tool
430 // expects exactly one target and we either found it or throw
431 // an exception.
432 if (m_keysColumns.empty())
433 {
434 if (allowedSet.size() == 1 && m_targetKeys.at(*allowedSet.begin()) == 0 && m_unknownKeysAllowedTargets.size() == 1)
435 targetIndex = *allowedSet.begin();
436 else
437 {
438 std::ostringstream error;
439 error << "target key mismatch: read sgkey " << std::hex << linkKey << std::dec;
440 error << " for column " << m_columnName << " with element index " << linkIndex << " targeting " << m_targetNames.at(0);
441 if (m_targetKeys.at(0) != 0u)
442 {
443 error << ", expected sgkey " << std::hex << m_targetKeys.at(0) << std::dec;
444 } else if (m_unknownKeysAllowedTargets.size() > 1)
445 {
446 error << ", alternate key found for non-variant link:";
447 for (auto& [key, allowedSet] : m_unknownKeysAllowedTargets)
448 {
449 if (key != linkKey)
450 error << " " << std::hex << key << std::dec;
451 }
452 } else
453 {
454 error << ", no expected sgkey configured but the maximum allowed index for the target is " << m_targetOffsetColumns.at(0)->at(eventIndex + 1) - m_targetOffsetColumns.at(0)->at(eventIndex) - 1;
455 }
456 throw std::runtime_error (std::move (error).str());
457 }
458 }
459 }
460
461 if (targetIndex == m_targetKeys.size())
462 {
463 // this creates a link with an unknown key, which the user
464 // will ignore
465 m_columnData.push_back (CM::mergeLinkKeyIndex (0xff, linkIndex));
466 return;
467 }
468
469 auto& targetOffsetColumn = *m_targetOffsetColumns.at(targetIndex);
470 if (eventIndex + 1 >= targetOffsetColumn.size())
471 throw std::runtime_error ("target offset column not yet filled for: " + m_targetNames.at(targetIndex));
472 auto myLinkIndex = linkIndex + targetOffsetColumn.at(eventIndex);
473 if (myLinkIndex >= targetOffsetColumn.at(eventIndex + 1))
474 throw std::runtime_error ("index out of range for link: " + m_columnName + " with element index " + std::to_string(linkIndex) + " targeting " + m_targetNames.at(targetIndex) + " with offset " + std::to_string(targetOffsetColumn.at(eventIndex)) + " and next offset " + std::to_string(targetOffsetColumn.at(eventIndex + 1)));
475
476 m_columnData.push_back (CM::mergeLinkKeyIndex (targetIndex, myLinkIndex));
477 }
std::vector< const std::vector< ColumnarOffsetType > * > m_targetOffsetColumns
std::vector< std::vector< typename CM::LinkKeyType > > m_keysColumns
str index
Definition DeMoScan.py:362
@ u
Enums for curvilinear frames.
Definition ParamDefs.h:77
@ linkIndex
link index for multiple track and vertex matches
static LinkIndexType mergeLinkKeyIndex(LinkIndexType key, LinkIndexType index)
merge a key and index value into a link value

◆ addTarget()

void columnar::TestUtils::LinkColumnVector::addTarget ( const std::string & name,
const std::unordered_map< std::string, const std::vector< ColumnarOffsetType > * > & offsetColumns,
std::uint32_t clid = 0 )
inlineprivate

Definition at line 519 of file ColumnarPhysliteTest.cxx.

520 {
521 unsigned targetIndex = 0;
522 while (targetIndex < m_targetNames.size() && m_targetNames.at(targetIndex) != name)
523 ++ targetIndex;
524 if (targetIndex == m_targetNames.size())
525 {
526 m_targetNames.push_back(name);
527 if (auto offsetIter = offsetColumns.find (name); offsetIter != offsetColumns.end())
528 m_targetOffsetColumns.push_back (offsetIter->second);
529 else
530 throw std::runtime_error ("missing offset column: " + name);
531 if (clid != 0)
532 m_targetKeys.push_back (computeSgKey (name, clid));
533 else if (auto keyIter = knownSgKeys.find (name); keyIter != knownSgKeys.end())
534 m_targetKeys.push_back (keyIter->second);
535 else
536 m_targetKeys.push_back (0);
537 }
538 if (!m_keysColumns.empty())
539 m_keysColumns.back().push_back (targetIndex);
540 }
const std::unordered_map< std::string, SG::sgkey_t > knownSgKeys
lookup table from container name to its sgkey hash
Definition KnownSgKeys.h:32
SG::sgkey_t computeSgKey(const std::string &name, std::uint32_t clid)
compute the StoreGate hashed key for a container

◆ begin()

auto columnar::TestUtils::LinkColumnVector::begin ( ) const
inlinenodiscardnoexcept

Definition at line 489 of file ColumnarPhysliteTest.cxx.

489{ return m_columnData.begin(); }

◆ checkOffsets()

void columnar::TestUtils::LinkColumnVector::checkOffsets ( unsigned eventIndex)
inline

Definition at line 354 of file ColumnarPhysliteTest.cxx.

355 {
356 for (std::size_t i = 0; i < m_targetNames.size(); ++ i)
357 {
358 auto& targetOffsetColumn = *m_targetOffsetColumns.at(i);
359 if (eventIndex + 1 >= targetOffsetColumn.size())
360 throw std::runtime_error ("target offset column not yet filled for: " + m_targetNames.at(i) + " when checking link column " + m_columnName);
361 }
362 }

◆ clear()

void columnar::TestUtils::LinkColumnVector::clear ( )
inline

Definition at line 349 of file ColumnarPhysliteTest.cxx.

350 {
351 m_columnData.clear();
352 }

◆ connect()

std::vector< std::string > columnar::TestUtils::LinkColumnVector::connect ( const ColumnInfo & columnInfo,
const std::unordered_map< std::string, const std::vector< ColumnarOffsetType > * > & offsetColumns,
const std::unordered_map< std::string, ColumnInfo > & requestedColumns )
inlinenodiscard

Definition at line 324 of file ColumnarPhysliteTest.cxx.

325 {
326 m_columnName = columnInfo.name;
327 std::vector<std::string> keyColumnNames;
328 if (!columnInfo.soleLinkTargetName.empty())
329 {
330 addTarget (columnInfo.soleLinkTargetName, offsetColumns, columnInfo.soleLinkTargetClid);
331 } else
332 {
333 for (auto& [requestedName, requestedInfo] : requestedColumns)
334 {
335 if (requestedInfo.keyColumnForVariantLink == m_columnName)
336 {
337 keyColumnNames.push_back (requestedName);
338 m_keysColumns.emplace_back();
339 for (const auto& targetName : requestedInfo.variantLinkTargetNames)
340 addTarget (targetName, offsetColumns);
341 }
342 }
343 if (m_keysColumns.empty())
344 throw std::runtime_error ("no key column found for variant link: " + m_columnName);
345 }
346 return keyColumnNames;
347 }
void addTarget(const std::string &name, const std::unordered_map< std::string, const std::vector< ColumnarOffsetType > * > &offsetColumns, std::uint32_t clid=0)

◆ data()

const CM::LinkIndexType * columnar::TestUtils::LinkColumnVector::data ( ) const
inlinenodiscardnoexcept

Definition at line 484 of file ColumnarPhysliteTest.cxx.

485 {
486 return m_columnData.data();
487 }

◆ end()

auto columnar::TestUtils::LinkColumnVector::end ( ) const
inlinenodiscardnoexcept

Definition at line 490 of file ColumnarPhysliteTest.cxx.

490{ return m_columnData.end(); }

◆ keysColumn()

const std::vector< typename CM::LinkKeyType > & columnar::TestUtils::LinkColumnVector::keysColumn ( std::size_t index) const
inlinenodiscard

Definition at line 492 of file ColumnarPhysliteTest.cxx.

493 {
494 return m_keysColumns.at(index);
495 }

◆ size()

std::size_t columnar::TestUtils::LinkColumnVector::size ( ) const
inlinenodiscardnoexcept

Definition at line 479 of file ColumnarPhysliteTest.cxx.

480 {
481 return m_columnData.size();
482 }

Member Data Documentation

◆ m_columnData

std::vector<typename CM::LinkIndexType> columnar::TestUtils::LinkColumnVector::m_columnData
private

Private Members

Definition at line 503 of file ColumnarPhysliteTest.cxx.

◆ m_columnName

std::string columnar::TestUtils::LinkColumnVector::m_columnName
private

Definition at line 505 of file ColumnarPhysliteTest.cxx.

◆ m_keysColumns

std::vector<std::vector<typename CM::LinkKeyType> > columnar::TestUtils::LinkColumnVector::m_keysColumns
private

Definition at line 513 of file ColumnarPhysliteTest.cxx.

◆ m_targetKeys

std::vector<SG::sgkey_t> columnar::TestUtils::LinkColumnVector::m_targetKeys
private

Definition at line 508 of file ColumnarPhysliteTest.cxx.

◆ m_targetNames

std::vector<std::string> columnar::TestUtils::LinkColumnVector::m_targetNames
private

Definition at line 507 of file ColumnarPhysliteTest.cxx.

◆ m_targetOffsetColumns

std::vector<const std::vector<ColumnarOffsetType>*> columnar::TestUtils::LinkColumnVector::m_targetOffsetColumns
private

Definition at line 509 of file ColumnarPhysliteTest.cxx.

◆ m_unknownKeysAllowedTargets

std::unordered_map<SG::sgkey_t,std::unordered_set<std::size_t> > columnar::TestUtils::LinkColumnVector::m_unknownKeysAllowedTargets
private

Definition at line 515 of file ColumnarPhysliteTest.cxx.


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