ATLAS Offline Software
AthLinks/ElementLinkVector.icc
Go to the documentation of this file.
1 // Dear emacs, this is -*- c++ -*-
2 
3 /*
4  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 
8 #ifndef GAUDIKERNEL_SYSTEM_H
9 #include "GaudiKernel/System.h"
10 #endif
11 
12 #ifndef ATHENAKERNEL_ERRORCHECK_H
13 #include "AthenaKernel/errorcheck.h"
14 #endif
15 
16 #include <cassert>
17 #include <stdexcept>
18 /* #define __ELVDEBUG */
19 
20 template <typename DOBJ>
21 typename ElementLinkVector<DOBJ>::DataLinkVector::const_iterator
22 ElementLinkVector<DOBJ>::findHostDObj(const ElemLink& link) const
23 {
24  //DataLink<DOBJ> dl (link.storagePolicy());
25  DataLink<DOBJ> dl = link.getDataLink();
26  typename DataLinkVector::const_iterator iHost(beginHostDObjs()), eHost(endHostDObjs());
27  while ((eHost != iHost) && (*iHost != dl)) ++iHost;
28 #ifdef __ELVDEBUG
29  std::cout << "findHostDObj (const version) called for link "
30  << link.dataID() << "/" << link.index()
31  << " - which is " << ((iHost != eHost) ? "" : " NOT ")
32  << " in ELV host dobjs list " << std::endl;
33 #endif
34  return iHost;
35 }
36 
37 template <typename DOBJ>
38 typename ElementLinkVector<DOBJ>::DataLinkVector::iterator
39 ElementLinkVector<DOBJ>::findHostDObj(const ElemLink& link)
40 {
41  //DataLink<DOBJ> dl (link.storagePolicy());
42  DataLink<DOBJ> dl (link.key());
43  typename DataLinkVector::iterator iHost(beginHostDObjs()), eHost(endHostDObjs());
44  while ((eHost != iHost) && (*iHost != dl)) ++iHost;
45 #ifdef __ELVDEBUG
46  std::cout << "findHostDObj (non-const version) called for link "
47  << link.dataID() << "/" << link.index()
48  << " - which is " << ((iHost != eHost) ? "" : " NOT ")
49  << " in ELV host dobjs list " << std::endl;
50 #endif
51  return iHost;
52 }
53 
54 
55 template <typename DOBJ>
56 typename ElementLinkVector<DOBJ>::iterator
57 ElementLinkVector<DOBJ>::insert(iterator position, const ElemLink& link)
58 {
59 #ifdef __ELVDEBUG
60  std::cout << "insert of link "
61  << link.dataID() << "/" << link.index() << " after "
62  << position->dataID() << "/" << position->index() <<endl;
63 #endif
64  addHostDObj(link);
65  return iterator(m_shortRefs.insert(shortIterFromLong(position), ElemLinkRef( link)),
66  Short2LongRef());
67 }
68 
69 template <typename DOBJ>
70 void
71 ElementLinkVector<DOBJ>::insert(iterator position, size_type n, const ElemLink& link)
72 {
73  addHostDObj(link);
74  m_shortRefs.insert(shortIterFromLong(position), n, ElemLinkRef(link));
75 }
76 
77 template <typename DOBJ>
78 typename ElementLinkVector<DOBJ>::iterator
79 ElementLinkVector<DOBJ>::erase(iterator position)
80 {
81  const ElemLink& save(*position);
82  iterator ret(m_shortRefs.erase(shortIterFromLong(position)), Short2LongRef());
83  removeHostObj(save);
84  return ret;
85 }
86 
87 template <typename DOBJ>
88 typename ElementLinkVector<DOBJ>::iterator
89 ElementLinkVector<DOBJ>::erase(iterator first, iterator last)
90 {
91  iterator i(first);
92  while (i != last) removeHostObj(*i++); //FIXME won't work in ELVDEBUG as such
93  return iterator(m_shortRefs.erase(shortIterFromLong(first),
94  shortIterFromLong(last)),
95  Short2LongRef());
96 }
97 
98 template <typename DOBJ>
99 void
100 ElementLinkVector<DOBJ>::
101 resize(size_type sz, const ElemLink& link)
102 {
103  if (sz > size()) { insert(end(), sz-size(), link); }
104  else if (sz < size()) { erase(begin()+sz, end()); }
105 }
106 
107 template <typename DOBJ>
108 bool
109 ElementLinkVector<DOBJ>::toTransient()
110 {
111  // Call the appropriate function for making use of the persistent data
112  // if we're doing direct ROOT I/O:
113  if( m_isDirectIO ) {
114  index_type dummy;
115  toTransient( dummy );
116  m_isDirectIO = false;
117  }
118 
119  bool success = true;
120  // set the proper state of all DataLinks
121  typename DataLinkVector::iterator iter = beginHostDObjs();
122  for (; iter!= endHostDObjs(); ++iter) {
123  if (! (*iter).toTransient()) success = false;
124  }
125 
126  // set the refVector's to transient mode. Note that RefVector would
127  // need the owner (this) as it is constructed from persistency using
128  // the default constructor
129  typename RefVector::iterator refIter = m_shortRefs.begin();
130  for (; refIter!= m_shortRefs.end(); ++refIter) {
131  if (! (*refIter).toTransient(*this)) success = false;
132  }
133 
134  return success;
135 }
136 
137 
138 template <typename DOBJ>
139 bool
140 ElementLinkVector<DOBJ>::toPersistentDL()
141 {
142  doRemap();
143 
144  //set all DataLinks to persistent state
145  bool success = true;
146  typename DataLinkVector::iterator iter = beginHostDObjs();
147  for (; iter!= endHostDObjs(); ++iter) {
148  if (! (*iter).toPersistentNoRemap()) success = false;
149  }
150 
151  return success;
152 }
153 
154 
155 template <typename DOBJ>
156 bool
157 ElementLinkVector<DOBJ>::toPersistent()
158 {
159  bool success = toPersistentDL();
160 
161  // set all ElementLink Refs to persistent state
162  typename RefVector::iterator refIter = m_shortRefs.begin();
163  for (; refIter!= m_shortRefs.end(); ++refIter) {
164  if (! (*refIter).toPersistent(*this)) success = false;
165  }
166 
167  // WARNING: The code doesn't take thinning into account at the
168  // moment!!!
169 
170  // Reset the base class's variables:
171  m_persKeys.clear();
172  m_persIndices.clear();
173 
174  // Copy the info into the base class:
175  typename RefVector::const_iterator ref_itr = m_shortRefs.begin();
176  typename RefVector::const_iterator ref_end = m_shortRefs.end();
177  for( ; ref_itr != ref_end; ++ref_itr ) {
178  m_persKeys.push_back( ref_itr->elementLink().persKey() );
179  m_persIndices.push_back( ref_itr->elementLink().persIndex() );
180  }
181 
182  return success;
183 }
184 
185 
186 template <typename DOBJ>
187 bool
188 ElementLinkVector<DOBJ>::toPersistent
189  (std::vector<typename DataLinkVector::size_type>& shortrefs)
190 {
191  bool success = toPersistentDL();
192 
193  // set all ElementLink Refs to persistent state
194  shortrefs.reserve (m_shortRefs.size());
195  typename RefVector::iterator refIter = m_shortRefs.begin();
196  for (; refIter!= m_shortRefs.end(); ++refIter) {
197  typename DataLinkVector::size_type shortref;
198  if (! (*refIter).toPersistent(*this, shortref)) success = false;
199  shortrefs.push_back (shortref);
200  }
201 
202  return success;
203 }
204 
205 
206 template <typename DOBJ>
207 void
208 ElementLinkVector<DOBJ>::doRemap()
209 {
210  bool remapping = false;
211  typename RefVector::iterator refIter = m_shortRefs.begin();
212  for (; refIter!= m_shortRefs.end(); ++refIter) {
213  if (refIter->doRemap()) {
214  if (!remapping) {
215  m_hostDObjs.clear();
216  typename RefVector::iterator ri2 = m_shortRefs.begin();
217  for (; ri2 != refIter; ++ri2) {
218  addHostDObj (ri2->elementLink());
219  }
220  remapping = true;
221  }
222  }
223  if (remapping)
224  addHostDObj (refIter->elementLink());
225  }
226 }
227 
228 
229 // Set the vector of host data objects from @a dobjs.
230 // @a dobjs is destroyed.
231 // This is an error if the vector is not empty.
232 template <typename DOBJ>
233 void
234 ElementLinkVector<DOBJ>::moveHostDObjs
235  (DataLinkVector& dobjs)
236 {
237  if (!this->empty()) {
238  MsgStream log(Athena::getMessageSvc(), "ElementLink");
239  log << MSG::ERROR
240  << "ElementLinkVector::moveHostDObjs called on non-empty vector."
241  << endmsg;
242  throw std::runtime_error("ElementLinkVector::moveHistDObjs : vector not empty");
243  }
244  m_hostDObjs.swap (dobjs);
245 }
246 
247 
248 template <typename DOBJ>
249 void
250 ElementLinkVector<DOBJ>::push_back
251  (typename DataLinkVector::size_type nameIndex,
252  typename ElemLinkRef::index_type elementIndex)
253 {
254  m_shortRefs.push_back (ElemLinkRef (nameIndex, elementIndex, *this));
255 }
256 
257 template< typename DOBJ >
258 void ElementLinkVector< DOBJ >::
259 toTransient( uint64_t& /*dummy*/ ) {
260 
261  // A little sanity check:
262  assert( m_persKeys.size() == m_persIndices.size() );
263 
264  // Clear the object:
265  clear();
266 
267  // Now re-create the links based on the persistent info:
268  for( size_t i = 0; i < m_persKeys.size(); ++i ) {
269  push_back( ElemLink( m_persKeys[ i ], m_persIndices[ i ] ) );
270  }
271 
272  return;
273 }
274 
275 template< typename DOBJ >
276 void ElementLinkVector< DOBJ >::
277 toTransient( uint32_t& /*dummy*/ ) {
278 
279  // A little sanity check:
280  assert( m_persKeys.size() == m_persIndices.size() );
281 
282  // Clear the object:
283  clear();
284 
285  // Now re-create the links based on the persistent info:
286  for( size_t i = 0; i < m_persKeys.size(); ++i ) {
287  push_back( ElemLink( m_persKeys[ i ], m_persIndices[ i ] ) );
288  }
289 
290  return;
291 }
292 
293 template< typename DOBJ >
294 template< typename INDEX_TYPE >
295 void ElementLinkVector< DOBJ >::
296 toTransient( INDEX_TYPE& /*dummy*/ ) {
297 
298  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "ElementLinkVector" )
299  << "Using direct ROOT I/O for type "
300  << System::typeinfoName( typeid( this ) )
301  << " not supported";
302 
303  return;
304 }
305 
306 template< typename DOBJ >
307 void ElementLinkVector< DOBJ >::
308 addHostDObj( const ElemLink& link ) {
309 
310  // Check if we already have it:
311  if( endHostDObjs() != findHostDObj( link ) ) {
312  return;
313  }
314 
315  //DataLink< DOBJ > dl( link.storagePolicy() );
316  DataLink< DOBJ > dl( link.key() );
317  if( ! dl.isDefault() ) {
318  m_hostDObjs.push_back( dl );
319 #ifdef __ELVDEBUG
320  std::cout << "addHostDObj added link "
321  << link.dataID() << "/" << link.index() << std::endl;
322 #endif
323  }
324 
325  return;
326 }