ATLAS Offline Software
ElementLinkCnv_p1.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /** @file ElementLinkCnv_p1.icc
6  * @brief This file contains the implementation for the ElementLinkCnv_p1 template methods.
7  * @author Marcin.Nowak@cern.ch
8  **/
9 
10 #include <stdexcept>
11 
12 #include "AthLinks/ElementLink.h"
13 #include "AthenaKernel/ThinningCache.h"
14 #include "AthenaKernel/ThinningDecisionBase.h"
15 #include "AthenaKernel/getThinningCache.h"
16 //#define ELLINK_DEBUG
17 
18 
19 template <typename LINK_TYPE>
20 void ElementLinkCnv_p1<LINK_TYPE>::
21 transToPers(const Link_t& trans, PersLink_t& pers,
22  const SG::ThinningCache* cache,
23  [[maybe_unused]] MsgStream& msg) const
24 {
25 #ifdef ELLINK_DEBUG
26 // trans.printState();
27 #endif
28  if( trans.isDefault() ) {
29  // pers.m_contName <- empty string (default value)
30  pers.m_elementIndex = 0; // value not used, but 0 compresses better
31  return;
32  }
33 
34  // Check for thinning.
35  if (cache) {
36  const SG::ThinningDecisionBase* dec = cache->thinning (trans.key());
37  if (dec) {
38  // here is the problem: in case the ElementLink was directly created w/
39  // only a pointer to the element, _and_ if the the pointed at element
40  // has been thinned away, EL::index() will throw b/c
41  // IndexingPolicy::setIndex will fail.
42  std::size_t idx = SG::ThinningDecisionBase::RemovedIdx;
43  try {
44  idx = trans.index();
45  } catch ( const SG::maybe_thinning_error& err ) {
46  // ok. that's the corner case we talked about above.
47 #ifdef ELLINK_DEBUG
48  msg << MSG::DEBUG << "caught a maybe_thinning_error: ["
49  << err.what() << "]"
50  << endmsg
51  << "(this is an expected case of the EL-state-phase-space "
52  << "when thinning is active)"
53  << endmsg;
54 #endif
55  }
56  // Get the updated index:
57  const std::size_t persIdx = dec->index( idx );
58  if (SG::ThinningDecisionBase::RemovedIdx == persIdx) {
59  // this element has been thinned away. So the persistent equivalent
60  // of a null pointer is a default persistent pointer.
61  pers = PersLink_t();
62  pers.m_elementIndex = 0; // value not used, but 0 compresses better
63  }
64  else {
65  Link_t tmp = trans;
66  tmp.toPersistent();
67  pers.m_SGKeyHash = tmp.key();
68  pers.m_elementIndex = persIdx;
69  }
70 #ifdef ELLINK_DEBUG
71  msg << MSG::INFO << "ElementLinkCnv_p1::transToPers(): SG Container="
72  << ", Key Hash=" << pers.m_SGKeyHash
73  << ", IDX=" << pers.m_elementIndex << endmsg;
74 #endif
75  return;
76  }
77  }
78 
79  // No thinning.
80  Link_t tmp = trans;
81  tmp.toPersistent();
82  // pers.m_contName = tmp.dataID();
83  pers.m_SGKeyHash = tmp.key();
84  pers.m_elementIndex = tmp.index();
85 #ifdef ELLINK_DEBUG
86  msg << MSG::INFO << "ElementLinkCnv_p1::transToPers(): SG Container="
87  << pers->m_contName << ", Key Hash=" << pers->m_SGKeyHash
88  << ", IDX=" << pers->m_elementIndex << endmsg;
89 #endif
90 }
91 
92 
93 template <typename LINK_TYPE>
94 void ElementLinkCnv_p1<LINK_TYPE>::
95 transToPers(const Link_t& trans, PersLink_t& pers,
96  MsgStream& msg) const
97 {
98  transToPers (trans, pers,
99  SG::getThinningCache(),
100  msg);
101 }
102 
103 
104 template <typename LINK_TYPE >
105 void ElementLinkCnv_p1< LINK_TYPE >
106 ::persToTrans(const PersLink_t& pers, Link_t& trans,
107  [[maybe_unused]] MsgStream& msg) const
108 {
109  if( !pers.m_contName.empty() ) {
110 #ifdef ELLINK_DEBUG
111  msg << MSG::DEBUG << "ElementLinkCnv_p1::PersToTrans(): SGContainer="
112  << pers.m_contName << ", IDX=" << pers.m_elementIndex << endmsg;
113 #endif
114  trans = Link_t(pers.m_contName, pers.m_elementIndex);
115  }
116  else if( pers.m_SGKeyHash != 0 ) {
117 #ifdef ELLINK_DEBUG
118  msg << MSG::DEBUG << "ElementLinkCnv_p1::PersToTrans(): SGContainer hash="
119  << pers.m_SGKeyHash << ", IDX=" << pers.m_elementIndex << endmsg;
120 #endif
121  trans = Link_t( (typename Link_t::sgkey_t)pers.m_SGKeyHash, pers.m_elementIndex);
122  }
123  else {
124 #ifdef ELLINK_DEBUG
125  msg << MSG::DEBUG << "ElementLinkCnv_p1::PersToTrans(): reading EL in Default state" << endmsg;
126 #endif
127  // set the transient ELink to the default state.
128  trans.reset();
129  }
130 }
131 
132 
133 
134 template <typename LINK_TYPE >
135 inline
136 void ElementLinkCnv_p1< LINK_TYPE >::
137 transToPers(const Link_t* trans, PersLink_t* pers, MsgStream& log) const {
138  transToPers( *trans, *pers, log);
139 }
140 
141 
142 template <typename LINK_TYPE >
143 inline
144 void ElementLinkCnv_p1< LINK_TYPE >::
145 persToTrans(const PersLink_t* pers, Link_t* trans, MsgStream& log) const {
146  persToTrans( *pers, *trans, log);
147 }