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