ATLAS Offline Software
SGELVRef.icc
Go to the documentation of this file.
1 // Dear emacs, this is -*- c++ -*-
2 
3 /*
4  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 
8 #include <cassert>
9 
10 #include "AthenaKernel/getMessageSvc.h"
11 #include "AthenaKernel/ThinningDecisionBase.h"
12 #include "GaudiKernel/MsgStream.h"
13 
14 /* #define __ELVDEBUG */
15 
16 // Standard Constructor
17 template <typename DOBJ>
18 SG::ELVRef<DOBJ>::ELVRef ( const ElemLink& link ) :
19  m_link( link ), m_shortRef( 0 ), m_index(link.index())
20 {
21 }
22 
23 // copy constructor
24 template <typename DOBJ>
25 SG::ELVRef<DOBJ>::ELVRef(const ELVRef& rhs) :
26  m_link(rhs.m_link),
27  m_shortRef(rhs.m_shortRef),
28  m_index (rhs.m_index)
29 { }
30 
31 // constructor from indices.
32 template <typename DOBJ>
33 SG::ELVRef<DOBJ>::ELVRef
34  (typename DataLinkVector::size_type hostIndex,
35  index_type elementIndex,
36  const ElemLinkVec& owner)
37  : m_shortRef (hostIndex),
38  m_index(elementIndex)
39 {
40  toTransient (owner);
41 }
42 
43 // return the index
44 template <typename DOBJ>
45 typename SG::ELVRef<DOBJ>::index_type
46 SG::ELVRef<DOBJ>::elementIndex() const
47 {
48  return m_link.index();
49 }
50 
51 // return the key
52 template <typename DOBJ>
53 typename SG::ELVRef<DOBJ>::ID_type
54 SG::ELVRef<DOBJ>::dataID() const {
55  return m_link.dataID();
56 }
57 
58 // Move to persistent state
59 template <typename DOBJ>
60 bool
61 SG::ELVRef<DOBJ>::toPersistent
62  (const ElemLinkVec& owner)
63 {
64  // Handle null reference.
65  if (m_link.isDefault())
66  return true;
67 
68  // Do the contained EL.
69  if (!m_link.toPersistent())
70  return false;
71 
72  // Transfer the index.
73  m_index = this->m_link.index();
74 
75  // Calculate the distance in DataLinkVector
76  typename DataLinkVector::const_iterator iHost(owner.findHostDObj(m_link));
77 
78  if ( iHost != owner.endHostDObjs() ) {
79  m_shortRef = std::distance(owner.beginHostDObjs(), iHost);
80  }
81  else {
82  MsgStream log(Athena::getMessageSvc(), "SG::ELVRef");
83  log << MSG::WARNING
84  << "link not found in ElemLinkVector" << endmsg;
85  return false;
86  }
87 
88  return true;
89 }
90 
91 // Move to persistent state and return shortref.
92 template <typename DOBJ>
93 inline
94 bool
95 SG::ELVRef<DOBJ>::toPersistent
96  (const ElemLinkVec& owner,
97  typename DataLinkVector::size_type& shortref)
98 {
99  bool ret = toPersistent (owner);
100  shortref = m_shortRef;
101  return ret;
102 }
103 
104 
105 // Move to transient state
106 template <typename DOBJ>
107 bool
108 SG::ELVRef<DOBJ>::toTransient
109  (const ElemLinkVec& owner)
110 {
111  bool success = true;
112 
113  // locate DataLink
114  typename DataLinkVector::const_iterator iHost(owner.beginHostDObjs());
115 
116  // handle thinned-away/null elements
117  if ( m_shortRef == SG::ThinningDecisionBase::RemovedIdx ||
118  !IndexingPolicy::isValid(m_index))
119  {
120  m_link = ElemLink();
121  return success;
122  }
123 
124  if (m_shortRef >= (unsigned)(owner.endHostDObjs() - iHost)) {
125  MsgStream log(Athena::getMessageSvc(), "ElementLinkVector");
126  log << MSG::ERROR
127  << "ELVRef::toTransient: shortref index of " << m_shortRef
128  << " is beyond the end of the host container (size "
129  << owner.endHostDObjs() - iHost << ")" << endmsg;
130  m_link = ElemLink();
131  return false;
132  }
133 
134  std::advance(iHost, m_shortRef);
135  assert(iHost != owner.endHostDObjs());
136 
137  // create a new ElementLink
138  m_link = ElemLink(iHost->key(), this->index());
139 
140  return success;
141 }
142 
143 template <typename DOBJ>
144 bool
145 SG::ELVRef<DOBJ>::doRemap()
146 {
147  SG::sgkey_t new_key;
148  index_type new_index;
149  if (this->m_link.isDefault())
150  return false;
151  index_type index = this->m_link.index();
152 
153  if (SG_detail::checkForRemap (this->m_link.source(),
154  this->m_link.key(),
155  index,
156  new_key,
157  new_index))
158  {
159  this->m_link.resetWithKeyAndIndex (new_key, new_index);
160  return true;
161  }
162  return false;
163 }
164 
165 
166 // operator =
167 template <typename DOBJ>
168 SG::ELVRef<DOBJ>&
169 SG::ELVRef<DOBJ>::operator=(const ELVRef& rhs) {
170 #ifdef __ELVDEBUG
171  MsgStream log(Athena::getMessageSvc(), "SG::ELVRef");
172  log << MSG::DEBUG
173  << "operator= called on " << dataID() << '/' << index()
174  << " with rhs " << rhs.dataID() << '/' << rhs.index()
175  << std::endl;
176 #endif
177 
178  if (&rhs != this) {
179  m_index = rhs.m_index;
180  m_link = rhs.m_link;
181  m_shortRef = rhs.m_shortRef;
182  }
183 #ifdef __ELVDEBUG
184  MsgStream log(Athena::getMessageSvc(), "SG::ELVRef");
185  log << MSG::DEBUG
186  << "operator= result is " << dataID() << '/' << index()
187  << std::endl;
188 #endif
189 
190  return *this;
191 }
192