2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
5 /** @file ElementLinkVectorCnv_p1.icc
6 * @brief This file contains the implementation for the ElementLinkVectorCnv_p1 template methods.
7 * @author Marcin.Nowak@cern.ch
12 #include "AthLinks/ElementLinkVector.h"
13 #include "AthenaKernel/ThinningCache.h"
14 #include "AthenaKernel/ThinningDecisionBase.h"
15 #include "AthenaKernel/getThinningCache.h"
18 //using namespace std;
23 template <typename LINK_TYPE>
25 ElementLinkVectorCnv_p1<LINK_TYPE>::transToPers(const LinkVect_t& trans,
27 const SG::ThinningCache* cache,
30 pers.m_elementRefs.clear();
33 LinkVect_t tmpTrans = trans;
38 std::vector<typename LinkVect_t::DataLinkVector::size_type> shortrefs;
39 tmpTrans.toPersistent(shortrefs);
40 // copy the container keys
41 m_DLinkVectorCnv.transToPers(&tmpTrans.hostDObjs(), &pers.m_links, msg);
43 // copy the element links in the compact form
44 size_t link_n = tmpTrans.size();
45 pers.m_elementRefs.reserve(link_n);
46 for ( std::size_t i=0; i!=link_n; ++i ) {
47 typedef typename PersLinkVect_t::ElementRef PElemRef_t;
48 size_t idx = SG::ThinningDecisionBase::RemovedIdx;
49 if (shortrefs[i] != SG::ThinningDecisionBase::RemovedIdx)
50 idx = tmpTrans.elementIndex(i);
51 pers.m_elementRefs.push_back( PElemRef_t (idx, shortrefs[i]) );
56 // the not so easy case: thinning occured...
58 // Note: we can't use ElementLinkVector::toPersistent.
59 // we have to first handle the DataLinks and then the elementlink refs
61 // - corrupt the ElementLinks
62 // - generate many-many ERRORs (when the EL points at a thinned away elmt)
64 // set all DataLinks to persistent state
65 tmpTrans.toPersistentDL();
67 // copy the container keys
68 m_DLinkVectorCnv.transToPers(&tmpTrans.hostDObjs(), &pers.m_links, msg);
69 //std::cout << "*** -- ElementLinkVectorCnv: KEY=" << *iter << std::endl;
71 // copy the element links in the compact form
72 size_t link_n = tmpTrans.size();
73 pers.m_elementRefs.reserve(link_n);
74 typedef typename LinkVect_t::ElemLink EL;
75 for ( std::size_t ilink = 0; ilink != link_n; ++ilink ) {
76 // note the _copy_ of the original
77 // (needed for multi-stream thinning)
78 EL el = tmpTrans[ilink];
79 // here is the problem: in case the ElementLink was directly created w/
80 // only a pointer to the element, _and_ if the the pointed-at element
81 // has been thinned away, EL::index() will throw b/c
82 // IndexingPolicy::setIndex will fail.
83 std::size_t orig_idx = SG::ThinningDecisionBase::RemovedIdx;
85 orig_idx = el.index();
86 } catch ( const SG::maybe_thinning_error& err ) {
87 // ok. that's the corner case we talked about above.
89 << "caught a maybe_thinning_error: [" << err.what() << "]"
91 << "(this is an expected case of the EL-state-phase-space "
92 << "when thinning is active)"
95 std::size_t idx = orig_idx;
97 const SG::ThinningDecisionBase* dec = cache->thinning (el.key());
99 idx = dec->index (idx);
103 typename LinkVect_t::size_type shortref = 0;
104 if ( idx == SG::ThinningDecisionBase::RemovedIdx ) {
105 // that element has been thinned away.
106 shortref = idx; //< 'special' well-known value
108 // element not thinned away
109 typename LinkVect_t::DataLinkVector::iterator ihost =
110 tmpTrans.findHostDObj (el);
111 if (ihost != tmpTrans.endHostDObjs())
112 shortref = std::distance (tmpTrans.beginHostDObjs(), ihost);
115 << "link not found in ElemLinkVector" << endmsg;
118 typedef typename PersLinkVect_t::ElementRef PersELRef;
119 pers.m_elementRefs.push_back( PersELRef (idx, shortref) );
124 template <typename LINK_TYPE>
125 void ElementLinkVectorCnv_p1<LINK_TYPE>::transToPers(const LinkVect_t& trans,
126 PersLinkVect_t& pers,
127 MsgStream& msg) const
129 transToPers (trans, pers,
130 SG::getThinningCache(),
135 template <typename LINK_TYPE >
136 void ElementLinkVectorCnv_p1< LINK_TYPE >::persToTrans(const PersLinkVect_t& pers, LinkVect_t& trans, MsgStream& msg) const
138 // copy the container keys
139 typename LinkVect_t::DataLinkVector dl;
140 m_DLinkVectorCnv.persToTrans(&pers.m_links, &dl, msg);
142 trans.moveHostDObjs (dl);
144 // cout << "*** -- ElementLinkVectorCnv: KEY=" << *iter << endl;
145 // copy the element links in the compact form
146 size_t link_n = pers.m_elementRefs.size();
147 trans.reserve(link_n);
148 typename PersLinkVect_t::ElementRefVector::const_iterator link_iter = pers.m_elementRefs.begin();
150 // This test needed for 32/64 bit compatibility.
151 if ( link_iter->m_nameIndex == static_cast<uint32_t>(SG::ThinningDecisionBase::RemovedIdx) &&
152 link_iter->m_elementIndex == static_cast<Index_t>(SG::ThinningDecisionBase::RemovedIdx) )
154 // thinned-away element...
155 trans.push_back (SG::ThinningDecisionBase::RemovedIdx,
156 SG::ThinningDecisionBase::RemovedIdx);
159 trans.push_back (link_iter->m_nameIndex, link_iter->m_elementIndex);
163 << "ElementLinkVectorCnv_p1::PersToTrans(): KEY="
164 << pers->m_links[link_iter->m_nameIndex].m_link
165 << ", IDX=" << link_iter->m_elementIndex
175 template <typename LINK_TYPE>
178 ElementLinkVectorCnv_p1<LINK_TYPE>
179 ::transToPers(const LinkVect_t* trans, PersLinkVect_t* pers, MsgStream& msg) const
181 this->transToPers(*trans, *pers, msg);
185 template <typename LINK_TYPE >
188 ElementLinkVectorCnv_p1< LINK_TYPE >
189 ::persToTrans(const PersLinkVect_t* pers, LinkVect_t* trans, MsgStream& msg) const
191 this->persToTrans(*pers, *trans, msg);