ATLAS Offline Software
Loading...
Searching...
No Matches
SG::RootAuxVectorFactory Class Reference

Dynamic implementation of IAuxVectorFactory, relying on root's vector proxy. More...

#include <RootAuxVectorFactory.h>

Inheritance diagram for SG::RootAuxVectorFactory:
Collaboration diagram for SG::RootAuxVectorFactory:

Public Member Functions

 RootAuxVectorFactory (TClass *objClass)
 Constructor.
virtual ~RootAuxVectorFactory () override
 Destructor.
const RootUtils::TyperootType () const
 Return the ROOT type wrapper.
TClass *objClass ATLAS_NOT_CONST_THREAD_SAFE () const
 Return the TClass for the overall object.
TClass *vecClass ATLAS_NOT_CONST_THREAD_SAFE () const
 Return the TClass for the std::vector.
size_t offset () const
 Return the offset of the vector within the object.
virtual std::unique_ptr< SG::IAuxTypeVectorcreate (SG::auxid_t auxid, size_t size, size_t capacity, bool isLinked) const override
 Create a vector object of this type.
virtual std::unique_ptr< SG::IAuxTypeVectorcreateFromData (SG::auxid_t auxid, void *data, IAuxTypeVector *linkedVector, bool isPacked, bool ownFlag, bool isLinked) const override
 Create a vector object of this type from a data blob.
virtual void copy (SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const override
 Copy elements between vectors.
virtual void copyForOutput (SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const override
 Copy elements between vectors, possibly applying thinning.
virtual void swap (SG::auxid_t auxid, AuxVectorData &a, size_t aindex, AuxVectorData &b, size_t bindex, size_t n) const override
 Swap elements between vectors.
virtual void clear (SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, size_t n) const override
 Clear a range of elements within a vector.
virtual size_t getEltSize () const override
 Return the size of an element of this vector type.
virtual const std::type_info * tiVec () const override
 Return the type_info of the overall object.
virtual bool isDynamic () const override
 True if the vectors created by this factory work by dynamic emulation (via TVirtualCollectionProxy or similar); false if the std::vector code is used directly.
virtual const std::type_info * tiAlloc () const override
 Return the type_info of the vector allocator.
virtual std::string tiAllocName () const override
 Return the (demangled) name of the vector allocator.
void toTransient (const EventContext &ctx, RootAuxVector &vec) const
 Perform post-read processing for one variable.
void copy (SG::auxid_t auxid, AuxVectorData &&dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const
 Copy elements between vectors.

Private Types

enum  {
  NONE , ELEMENT_LINK , ELEMENT_LINK_VECTOR , ELEMENT_LINK_NONPOINTER ,
  DATA_LINK , DATA_LINK_VECTOR
}
 Flag to tell whether we need to do thinning / toTrasnsient. More...

Private Member Functions

char * copyImpl (SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const
 Helper for copy; returns a pointer to the first destination object, or nullptr if the destination was cleared rather than copied.

Private Attributes

TClass * m_objClass
 The TClass for the overall object.
TClass * m_vecClass
 The TClass for the std::vector.
size_t m_offset
 Offset of the STL vector within the overall object.
RootUtils::Type m_type
 Wrapper for the ROOT type of the element.
enum SG::RootAuxVectorFactory:: { ... }  m_isEL
 Flag to tell whether we need to do thinning / toTrasnsient.

Detailed Description

Dynamic implementation of IAuxVectorFactory, relying on root's vector proxy.

This is used for the case when we need to manipulate an aux data vector present in an input data file but we have neither a proper template instantiation for the factory (because the variable was never explicitly referenced), nor can we find a dictionary entry for the factory.j

This implementation works by relying entirely on the root dictionary information.

We may either be dealing directly with an STL vector class, or with embedded in another class (as for PackedContainer). Here, vecClass is the class of the STL vector and objClass is the overall object class. In the case of a direct STL vector, these are identical.

Definition at line 285 of file RootAuxVectorFactory.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
private

Flag to tell whether we need to do thinning / toTrasnsient.

Enumerator
NONE 
ELEMENT_LINK 
ELEMENT_LINK_VECTOR 
ELEMENT_LINK_NONPOINTER 
DATA_LINK 
DATA_LINK_VECTOR 

Definition at line 510 of file RootAuxVectorFactory.h.

510 { NONE,
513 } m_isEL;
enum SG::RootAuxVectorFactory::@071257101107162132204103261125230107154016006205 m_isEL
Flag to tell whether we need to do thinning / toTrasnsient.

Constructor & Destructor Documentation

◆ RootAuxVectorFactory()

SG::RootAuxVectorFactory::RootAuxVectorFactory ( TClass * objClass)

Constructor.

Parameters
vecClassThe TClass for the vector object.

Definition at line 384 of file RootAuxVectorFactory.cxx.

385 : m_objClass (objClass),
386 m_vecClass (objClass),
387 m_offset (0),
388 m_isEL (NONE)
389{
390 TVirtualCollectionProxy* proxy = m_vecClass->GetCollectionProxy();
391
392 if (!proxy) {
393 TClass* vecClass = lookupVectorType (objClass);
394 if (vecClass) {
395 m_vecClass = vecClass;
396 Int_t offs = objClass->GetBaseClassOffset (vecClass);
397 if (offs >= 0) {
398 m_offset = offs;
399 proxy = vecClass->GetCollectionProxy();
400 }
401 else {
402 ATHCONTAINERS_ERROR("RootAuxVectorFactory::RootAuxVectorFactory",
403 std::string("Can't find vector base class in ") +
404 objClass->GetName());
405 }
406 }
407 }
408
409 if (!proxy) {
410 std::string err = "Can't find collection proxy for ";
411 err += m_vecClass->GetName();
412 throw std::runtime_error (err.c_str());
413 }
414
415 if (m_vecClass->GetTypeInfo() == 0) {
416 ATHCONTAINERS_ERROR("RootAuxVectorFactory::RootAuxVectorFactory",
417 std::string("No type_info available for class ") +
418 m_vecClass->GetName() +
419 std::string(". There is probably a missing dictionary. We will likely crash further on."));
420 }
421
422 TClass* eltClass = proxy->GetValueClass();
423 if (eltClass) {
424 m_type.init (eltClass);
425
426 const std::type_info* ti = eltClass->GetTypeInfo();
427 if (ti) {
428
429 static const CxxUtils::ClassName pat1 ("ElementLink<$T>");
430 static const CxxUtils::ClassName pat2 ("std::vector<ElementLink<$T> >");
431 static const CxxUtils::ClassName pat3 ("DataLink<$T>");
432 static const CxxUtils::ClassName pat4 ("std::vector<DataLink<$T> >");
433
435 CxxUtils::ClassName::match_t matches;
436 if (clname.match (pat1, matches)) {
438 if (eltClass->GetBaseClass ("ElementLinkBase") == nullptr) {
440 }
441 }
442 else if (clname.match (pat2, matches)) {
444
445 TVirtualCollectionProxy* proxy2 = eltClass->GetCollectionProxy();
446 if (proxy2) {
447 TClass* innerEltClass = proxy2->GetValueClass();
448 if (innerEltClass) {
449 if (innerEltClass->GetBaseClass ("ElementLinkBase") == nullptr) {
451 }
452 }
453 }
454 }
455 else if (clname.match (pat3, matches)) {
457 }
458 else if (clname.match (pat4, matches)) {
460 }
461 }
462 }
463 else
464 m_type.init (proxy->GetType());
465}
RootUtils::Type m_type
Wrapper for the ROOT type of the element.
size_t m_offset
Offset of the STL vector within the overall object.
TClass * m_objClass
The TClass for the overall object.
TClass * m_vecClass
The TClass for the std::vector.
#define ATHCONTAINERS_ERROR(ctx, msg)
Definition error.h:54
ClassName()
Default constructor.
std::string normalizedTypeinfoName(const std::type_info &info)
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
TClass * lookupVectorType(TClass &cl)
Internal function used by xAOD::TAuxStore and xAOD::RAuxStore.

◆ ~RootAuxVectorFactory()

SG::RootAuxVectorFactory::~RootAuxVectorFactory ( )
overridevirtual

Destructor.

Definition at line 471 of file RootAuxVectorFactory.cxx.

472{
473}

Member Function Documentation

◆ ATLAS_NOT_CONST_THREAD_SAFE() [1/2]

TClass *vecClass SG::RootAuxVectorFactory::ATLAS_NOT_CONST_THREAD_SAFE ( ) const
inline

Return the TClass for the std::vector.

(Returning non-const TClass* ok here; TClass is internally thread-safe.)

Definition at line 321 of file RootAuxVectorFactory.h.

321{ return m_vecClass; }

◆ ATLAS_NOT_CONST_THREAD_SAFE() [2/2]

TClass *objClass SG::RootAuxVectorFactory::ATLAS_NOT_CONST_THREAD_SAFE ( ) const
inline

Return the TClass for the overall object.

(Returning non-const TClass* ok here; TClass is internally thread-safe.)

Definition at line 313 of file RootAuxVectorFactory.h.

313{ return m_objClass; }

◆ clear()

void SG::RootAuxVectorFactory::clear ( SG::auxid_t auxid,
AuxVectorData & dst,
size_t dst_index,
size_t n ) const
overridevirtual

Clear a range of elements within a vector.

Parameters
auxidThe aux data item being operated on.
dstContainer holding the element
dst_indexIndex of the first element in the vector.
nNumber of elements to clear.

Implements SG::IAuxTypeVectorFactory.

Definition at line 657 of file RootAuxVectorFactory.cxx.

660{
661 if (n == 0) return;
662 m_type.clearRange (dst.getDataArray (auxid), dst_index, n);
663}
SG::auxid_t auxid() const
Return the aux id for this variable.

◆ copy() [1/2]

void SG::IAuxTypeVectorFactory::copy ( SG::auxid_t auxid,
AuxVectorData && dst,
size_t dst_index,
const AuxVectorData & src,
size_t src_index,
size_t n ) const
inlineinherited

Copy elements between vectors.

Parameters
auxidThe aux data item being operated on.
dstContainer for the destination vector. Declared as a rvalue reference to allow passing a temporary here (such as from AuxVectorInterface).
dst_indexIndex of the first destination element in the vector.
srcContainer for the source vector.
src_indexIndex of the first source element in the vector.
nNumber of elements to copy.

dst and @ src can be either the same or different.

Definition at line 132 of file IAuxTypeVectorFactory.h.

136 {
137 copy (auxid, dst, dst_index, src, src_index, n);
138 }
virtual void copy(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const =0
Copy elements between vectors.

◆ copy() [2/2]

void SG::RootAuxVectorFactory::copy ( SG::auxid_t auxid,
AuxVectorData & dst,
size_t dst_index,
const AuxVectorData & src,
size_t src_index,
size_t n ) const
overridevirtual

Copy elements between vectors.

Parameters
auxidThe aux data item being operated on.
dstContainer for the destination vector.
dst_indexIndex of the first destination element in the vector.
srcContainer for the source vector.
src_indexIndex of the first source element in the vector.
nNumber of elements to copy.

dst and @ src can be either the same or different.

Implements SG::IAuxTypeVectorFactory.

Definition at line 572 of file RootAuxVectorFactory.cxx.

578{
579 (void)copyImpl (auxid, dst, dst_index, src, src_index, n);
580}
char * copyImpl(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const
Helper for copy; returns a pointer to the first destination object, or nullptr if the destination was...

◆ copyForOutput()

void SG::RootAuxVectorFactory::copyForOutput ( SG::auxid_t auxid,
AuxVectorData & dst,
size_t dst_index,
const AuxVectorData & src,
size_t src_index,
size_t n ) const
overridevirtual

Copy elements between vectors, possibly applying thinning.

Parameters
auxidThe aux data item being operated on.
dstContainer for the destination vector.
dst_indexIndex of the first destination element in the vector.
srcContainer for the source vector.
src_indexIndex of source element in the vector.
src_indexIndex of the first source element in the vector.
nNumber of elements to copy.

dst and @ src can be either the same or different.

Implements SG::IAuxTypeVectorFactory.

Definition at line 595 of file RootAuxVectorFactory.cxx.

599{
600 char* dstptr = copyImpl (auxid, dst, dst_index, src, src_index, n);
601
602 if (m_isEL == ELEMENT_LINK) {
603 size_t eltsz = m_type.getSize();
604 for (size_t i = 0; i < n; i++) {
605 reinterpret_cast<ElementLinkBase*>(dstptr + i*eltsz)->thin();
606 }
607 }
608 else if (m_isEL == ELEMENT_LINK_VECTOR) {
609 size_t eltsz = m_type.getSize();
610 for (size_t i = 0; i < n; i++) {
611 std::vector<ElementLinkBase>& v =
612 *reinterpret_cast<std::vector<ElementLinkBase>* > (dstptr +i*eltsz);
613 for (ElementLinkBase& el : v) {
614 el.thin();
615 }
616 }
617 }
618 else if (m_isEL == ELEMENT_LINK_NONPOINTER) {
619 ATHCONTAINERS_ERROR("RootAuxVectorFactory::copyForOutput",
620 std::string("Cannot apply thinning for ElementLink with non-pointer element: ") +
621 m_vecClass->GetName());
622 }
623}

◆ copyImpl()

char * SG::RootAuxVectorFactory::copyImpl ( SG::auxid_t auxid,
AuxVectorData & dst,
size_t dst_index,
const AuxVectorData & src,
size_t src_index,
size_t n ) const
private

Helper for copy; returns a pointer to the first destination object, or nullptr if the destination was cleared rather than copied.

Definition at line 530 of file RootAuxVectorFactory.cxx.

536{
537 if (n == 0) return nullptr;
538 size_t eltsz = m_type.getSize();
539 char* dstptr = reinterpret_cast<char*> (dst.getDataArray (auxid));
540 if (&src == &dst) {
541 // Source and destination containers are the same,
542 // so we don't need to bother with fetching the src pointer.
543 // copyRange properly handles overlapping regions.
544 m_type.copyRange (dstptr + eltsz*dst_index, dstptr + eltsz*src_index, n);
545 return dstptr + eltsz*dst_index;
546 }
547 else {
548 const char* srcptr = reinterpret_cast<const char*>(src.getDataArrayAllowMissing (auxid));
549 if (srcptr) {
550 m_type.copyRange (dstptr + eltsz*dst_index, srcptr + eltsz*src_index, n);
551 return dstptr + eltsz*dst_index;
552 }
553 else {
554 m_type.clearRange (dstptr + eltsz*dst_index, n);
555 return nullptr;
556 }
557 }
558}

◆ create()

std::unique_ptr< SG::IAuxTypeVector > SG::RootAuxVectorFactory::create ( SG::auxid_t auxid,
size_t size,
size_t capacity,
bool isLinked ) const
overridevirtual

Create a vector object of this type.

Parameters
auxidID for the variable being created.
sizeInitial size of the new vector.
capacityInitial capacity of the new vector.
isLinkedTrue if this variable is linked from another one.

Returns a newly-allocated object.

Parameters
auxidID for the variable being created.
sizeInitial size of the new vector.
capacityInitial capacity of the new vector.
isLinkedTrue if this variable is linked from another one.

Implements SG::IAuxTypeVectorFactory.

Definition at line 484 of file RootAuxVectorFactory.cxx.

488{
489 return std::make_unique<RootAuxVector> (this, auxid, size, capacity,
490 isLinked);
491}
virtual size_t size() const override
Return the number of elements in the store.

◆ createFromData()

std::unique_ptr< SG::IAuxTypeVector > SG::RootAuxVectorFactory::createFromData ( SG::auxid_t auxid,
void * data,
IAuxTypeVector * linkedVector,
bool isPacked,
bool ownFlag,
bool isLinked ) const
overridevirtual

Create a vector object of this type from a data blob.

Parameters
auxidID for the variable being created.
dataThe vector object.
linkedVectorThe interface for another variable linked to this one, or nullptr if there isn't one. (We do not take ownership.)
isPackedIf true, data is a PackedContainer.
ownFlagIf true, the newly-created IAuxTypeVector object will take ownership of data.
isLinkedTrue if this variable is linked from another one.

If the element type is T, then data should be a pointer to a std::vector<T> object, which was obtained with new.

This version does not support packed containers, so isPacked must be false.

Returns a newly-allocated object.

Implements SG::IAuxTypeVectorFactory.

Definition at line 515 of file RootAuxVectorFactory.cxx.

521{
522 if (linkedVector) std::abort();
523 return std::make_unique<RootAuxVector> (this, auxid, data, isPacked, ownFlag,
524 isLinked);
525}
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
virtual IAuxTypeVector * linkedVector(SG::auxid_t auxid) override
Return interface for a linked variable.

◆ getEltSize()

size_t SG::RootAuxVectorFactory::getEltSize ( ) const
overridevirtual

Return the size of an element of this vector type.

Implements SG::IAuxTypeVectorFactory.

Definition at line 669 of file RootAuxVectorFactory.cxx.

670{
671 return m_type.getSize();
672}

◆ isDynamic()

bool SG::RootAuxVectorFactory::isDynamic ( ) const
overridevirtual

True if the vectors created by this factory work by dynamic emulation (via TVirtualCollectionProxy or similar); false if the std::vector code is used directly.

Implements SG::IAuxTypeVectorFactory.

Definition at line 689 of file RootAuxVectorFactory.cxx.

690{
691 return true;
692}

◆ offset()

size_t SG::RootAuxVectorFactory::offset ( ) const
inline

Return the offset of the vector within the object.

Definition at line 327 of file RootAuxVectorFactory.h.

327{ return m_offset; }

◆ rootType()

const RootUtils::Type & SG::RootAuxVectorFactory::rootType ( ) const
inline

Return the ROOT type wrapper.

Definition at line 305 of file RootAuxVectorFactory.h.

305{ return m_type; }

◆ swap()

void SG::RootAuxVectorFactory::swap ( SG::auxid_t auxid,
AuxVectorData & a,
size_t aindex,
AuxVectorData & b,
size_t bindex,
size_t n ) const
overridevirtual

Swap elements between vectors.

Parameters
auxidThe aux data item being operated on.
aContainer for the first vector.
aindexIndex of the first element in the first vector.
bContainer for the second vector.
bindexIndex of the first element in the second vector.
nNumber of elements to swap.

a and @ b can be either the same or different. However, the ranges should not overlap.

Implements SG::IAuxTypeVectorFactory.

Definition at line 638 of file RootAuxVectorFactory.cxx.

642{
643 if (n == 0) return;
644 void* aptr = a.getDataArray (auxid);
645 void* bptr = &a == &b ? aptr : b.getDataArray (auxid);
646 m_type.swapRange (aptr, aindex, bptr, bindex, n);
647}
static Double_t a

◆ tiAlloc()

const std::type_info * SG::RootAuxVectorFactory::tiAlloc ( ) const
overridevirtual

Return the type_info of the vector allocator.

May be nullptr for a dynamic vector.

Implements SG::IAuxTypeVectorFactory.

Definition at line 700 of file RootAuxVectorFactory.cxx.

701{
702 return nullptr;
703}

◆ tiAllocName()

std::string SG::RootAuxVectorFactory::tiAllocName ( ) const
overridevirtual

Return the (demangled) name of the vector allocator.

Implements SG::IAuxTypeVectorFactory.

Definition at line 709 of file RootAuxVectorFactory.cxx.

710{
711 std::string name = SG::normalizedTypeinfoName (*m_vecClass->GetTypeInfo());
712 CxxUtils::ClassName cn (name);
713 std::string alloc_name;
714 if (cn.ntargs() >= 2) {
715 alloc_name = cn.targ(1).fullName();
716 }
717 else if (cn.ntargs() == 1) {
718 alloc_name = "std::allocator<" + cn.targ(0).fullName();
719 if (alloc_name[alloc_name.size()-1] == '>') alloc_name += " ";
720 alloc_name += ">";
721 }
722 return alloc_name;
723}

◆ tiVec()

const std::type_info * SG::RootAuxVectorFactory::tiVec ( ) const
overridevirtual

Return the type_info of the overall object.

Implements SG::IAuxTypeVectorFactory.

Definition at line 678 of file RootAuxVectorFactory.cxx.

679{
680 return m_objClass->GetTypeInfo();
681}

◆ toTransient()

void SG::RootAuxVectorFactory::toTransient ( const EventContext & ctx,
RootAuxVector & vec ) const

Perform post-read processing for one variable.

Parameters
ctxThe current event context.
vecThe variable to process.

Some object types require some processing after being read before they are usable. This can be indicated by specializing SG::ToTransient for the vector type containing the variable. This method will call such a ToTransient method on the contents, if one is defined.

Definition at line 736 of file RootAuxVectorFactory.cxx.

738{
739 if (m_isEL == NONE) {
740 return;
741 }
743 ATHCONTAINERS_ERROR("RootAuxVectorFactory::toTransient",
744 std::string("Cannot call toTransient for ElementLink with non-pointer element: ") +
745 m_vecClass->GetName());
746 return;
747 }
748
749 char* ptr = reinterpret_cast<char*> (vec.toPtr());
750 size_t n = vec.size();
751 IProxyDict* pdict = Atlas::proxyDictFromEventContext (ctx);
752 size_t eltsz = m_type.getSize();
753
754 if (m_isEL == ELEMENT_LINK) {
755 for (size_t i = 0; i < n; i++) {
756 reinterpret_cast<ElementLinkBase*>(ptr + i*eltsz)->toTransient (pdict);
757 }
758 }
759 else if (m_isEL == ELEMENT_LINK_VECTOR) {
760 for (size_t i = 0; i < n; i++) {
761 std::vector<ElementLinkBase>& v =
762 *reinterpret_cast<std::vector<ElementLinkBase>* > (ptr +i*eltsz);
763 for (ElementLinkBase& el : v) {
764 el.toTransient (pdict);
765 }
766 }
767 }
768 else if (m_isEL == DATA_LINK) {
769 for (size_t i = 0; i < n; i++) {
770 reinterpret_cast<DataLinkBase*>(ptr + i*eltsz)->toTransient (pdict);
771 }
772 }
773 else if (m_isEL == DATA_LINK_VECTOR) {
774 for (size_t i = 0; i < n; i++) {
775 std::vector<DataLinkBase>& v =
776 *reinterpret_cast<std::vector<DataLinkBase>* > (ptr +i*eltsz);
777 for (DataLinkBase& dl : v) {
778 dl.toTransient (pdict);
779 }
780 }
781 }
782}
std::vector< size_t > vec
void toTransient(const EventContext &ctx, RootAuxVector &vec) const
Perform post-read processing for one variable.
IProxyDict * proxyDictFromEventContext()
Return the IProxyDict for this thread's current context.
void * ptr(T *p)
Definition SGImplSvc.cxx:74

Member Data Documentation

◆ []

enum { ... } SG::RootAuxVectorFactory::m_isEL

Flag to tell whether we need to do thinning / toTrasnsient.

◆ m_objClass

TClass* SG::RootAuxVectorFactory::m_objClass
private

The TClass for the overall object.

Definition at line 498 of file RootAuxVectorFactory.h.

◆ m_offset

size_t SG::RootAuxVectorFactory::m_offset
private

Offset of the STL vector within the overall object.

Definition at line 504 of file RootAuxVectorFactory.h.

◆ m_type

RootUtils::Type SG::RootAuxVectorFactory::m_type
private

Wrapper for the ROOT type of the element.

Definition at line 507 of file RootAuxVectorFactory.h.

◆ m_vecClass

TClass* SG::RootAuxVectorFactory::m_vecClass
private

The TClass for the std::vector.

Definition at line 501 of file RootAuxVectorFactory.h.


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