1 // Dear emacs, this is -*- c++ -*-
4 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
7 #include "GaudiKernel/System.h"
8 #include "AthenaKernel/errorcheck.h"
12 /* #define __ELVDEBUG */
14 template <typename DOBJ>
15 typename ElementLinkVector<DOBJ>::DataLinkVector::const_iterator
16 ElementLinkVector<DOBJ>::findHostDObj(const ElemLink& link) const
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;
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;
31 template <typename DOBJ>
32 typename ElementLinkVector<DOBJ>::DataLinkVector::iterator
33 ElementLinkVector<DOBJ>::findHostDObj(const ElemLink& link)
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;
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;
49 template <typename DOBJ>
50 typename ElementLinkVector<DOBJ>::iterator
51 ElementLinkVector<DOBJ>::insert(iterator position, const ElemLink& link)
54 std::cout << "insert of link "
55 << link.dataID() << "/" << link.index() << " after "
56 << position->dataID() << "/" << position->index() <<endl;
59 return iterator(m_shortRefs.insert(shortIterFromLong(position), ElemLinkRef( link)),
63 template <typename DOBJ>
65 ElementLinkVector<DOBJ>::insert(iterator position, size_type n, const ElemLink& link)
68 m_shortRefs.insert(shortIterFromLong(position), n, ElemLinkRef(link));
71 template <typename DOBJ>
72 typename ElementLinkVector<DOBJ>::iterator
73 ElementLinkVector<DOBJ>::erase(iterator position)
75 const ElemLink& save(*position);
76 iterator ret(m_shortRefs.erase(shortIterFromLong(position)), Short2LongRef());
81 template <typename DOBJ>
82 typename ElementLinkVector<DOBJ>::iterator
83 ElementLinkVector<DOBJ>::erase(iterator first, iterator last)
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)),
92 template <typename DOBJ>
94 ElementLinkVector<DOBJ>::
95 resize(size_type sz, const ElemLink& link)
97 if (sz > size()) { insert(end(), sz-size(), link); }
98 else if (sz < size()) { erase(begin()+sz, end()); }
101 template <typename DOBJ>
103 ElementLinkVector<DOBJ>::toTransient()
105 // Call the appropriate function for making use of the persistent data
106 // if we're doing direct ROOT I/O:
109 toTransient( dummy );
110 m_isDirectIO = false;
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;
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;
132 template <typename DOBJ>
134 ElementLinkVector<DOBJ>::toPersistentDL()
138 //set all DataLinks to persistent state
140 typename DataLinkVector::iterator iter = beginHostDObjs();
141 for (; iter!= endHostDObjs(); ++iter) {
142 if (! (*iter).toPersistentNoRemap()) success = false;
149 template <typename DOBJ>
151 ElementLinkVector<DOBJ>::toPersistent()
153 bool success = toPersistentDL();
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;
161 // WARNING: The code doesn't take thinning into account at the
164 // Reset the base class's variables:
166 m_persIndices.clear();
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() );
180 template <typename DOBJ>
182 ElementLinkVector<DOBJ>::toPersistent
183 (std::vector<typename DataLinkVector::size_type>& shortrefs)
185 bool success = toPersistentDL();
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);
200 template <typename DOBJ>
202 ElementLinkVector<DOBJ>::doRemap()
204 bool remapping = false;
205 typename RefVector::iterator refIter = m_shortRefs.begin();
206 for (; refIter!= m_shortRefs.end(); ++refIter) {
207 if (refIter->doRemap()) {
210 typename RefVector::iterator ri2 = m_shortRefs.begin();
211 for (; ri2 != refIter; ++ri2) {
212 addHostDObj (ri2->elementLink());
218 addHostDObj (refIter->elementLink());
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.
226 template <typename DOBJ>
228 ElementLinkVector<DOBJ>::moveHostDObjs
229 (DataLinkVector& dobjs)
231 if (!this->empty()) {
232 MsgStream log(Athena::getMessageSvc(), "ElementLink");
234 << "ElementLinkVector::moveHostDObjs called on non-empty vector."
236 throw std::runtime_error("ElementLinkVector::moveHistDObjs : vector not empty");
238 m_hostDObjs.swap (dobjs);
242 template <typename DOBJ>
244 ElementLinkVector<DOBJ>::push_back
245 (typename DataLinkVector::size_type nameIndex,
246 typename ElemLinkRef::index_type elementIndex)
248 m_shortRefs.push_back (ElemLinkRef (nameIndex, elementIndex, *this));
251 template< typename DOBJ >
252 void ElementLinkVector< DOBJ >::
253 toTransient( uint64_t& /*dummy*/ ) {
255 // A little sanity check:
256 assert( m_persKeys.size() == m_persIndices.size() );
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 ] ) );
269 template< typename DOBJ >
270 void ElementLinkVector< DOBJ >::
271 toTransient( uint32_t& /*dummy*/ ) {
273 // A little sanity check:
274 assert( m_persKeys.size() == m_persIndices.size() );
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 ] ) );
287 template< typename DOBJ >
288 template< typename INDEX_TYPE >
289 void ElementLinkVector< DOBJ >::
290 toTransient( INDEX_TYPE& /*dummy*/ ) {
292 REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "ElementLinkVector" )
293 << "Using direct ROOT I/O for type "
294 << System::typeinfoName( typeid( this ) )
300 template< typename DOBJ >
301 void ElementLinkVector< DOBJ >::
302 addHostDObj( const ElemLink& link ) {
304 // Check if we already have it:
305 if( endHostDObjs() != findHostDObj( link ) ) {
309 //DataLink< DOBJ > dl( link.storagePolicy() );
310 DataLink< DOBJ > dl( link.key() );
311 if( ! dl.isDefault() ) {
312 m_hostDObjs.push_back( dl );
314 std::cout << "addHostDObj added link "
315 << link.dataID() << "/" << link.index() << std::endl;