2 * Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
5 * @file AthContainers/tools/PackedLinkVectorFactory.icc
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief Factory object that creates vectors using @c AuxTypeVector,
9 * specialized for PackedLink.
13 #include "AthContainers/tools/AuxTypeVector.h"
14 #include "AthContainers/AuxTypeRegistry.h"
21 * @brief Create a vector object of this type.
22 * @param auxid ID for the variable being created.
23 * @param size Initial size of the new vector.
24 * @param capacity Initial capacity of the new vector.
25 * @param isLinked True if this variable is linked from another one.
28 template <class CONT, class ALLOC>
29 std::unique_ptr<IAuxTypeVector>
30 PackedLinkVectorFactory<CONT, ALLOC>::create (SG::auxid_t auxid,
31 size_t size, size_t capacity,
32 [[maybe_unused]] bool isLinked) const
35 const AuxTypeRegistry& r = AuxTypeRegistry::instance();
36 auxid_t linked_id = r.linkedVariable (auxid);
38 using linkedAlloc = typename std::allocator_traits<ALLOC>::template rebind_alloc<DataLink<CONT> >;
40 std::make_unique<AuxTypeVector<DataLink<CONT>, linkedAlloc> > (linked_id,
42 return std::make_unique<AuxTypeVector_t> (auxid, size, capacity,
43 std::move (linkedVec));
48 * @brief Create a vector object of this type from a data blob.
49 * @param auxid ID for the variable being created.
50 * @param data The vector object.
51 * @param linkedVector The interface for another variable linked to this one.
52 * (We do not take ownership.)
53 * @param isPacked If true, @c data is a @c PackedContainer.
54 * @param ownFlag If true, the newly-created IAuxTypeVector object
55 * will take ownership of @c data.
56 * @param isLinked True if this variable is linked from another one.
58 * @c data should be a pointer to a
59 * std::vector<SG::PackedLink<CONT>, ALLOC<...> > object obtained with new.
60 * For this method, isPacked and isLinked must both be false.
62 template <class CONT, class ALLOC>
63 std::unique_ptr<IAuxTypeVector>
64 PackedLinkVectorFactory<CONT, ALLOC>::createFromData (SG::auxid_t auxid,
66 IAuxTypeVector* linkedVector,
67 [[maybe_unused]] bool isPacked,
69 [[maybe_unused]] bool isLinked) const
71 assert (!isPacked && !isLinked && linkedVector != nullptr);
72 using Holder = SG::PackedLinkVectorHolder<CONT, ALLOC>;
73 using vector_type = typename Holder::vector_type;
74 return std::make_unique<Holder>
75 (auxid, reinterpret_cast<vector_type*>(data), linkedVector, ownFlag);
80 * @brief Copy elements between vectors.
81 * @param auxid The aux data item being operated on.
82 * @param dst Container for the destination vector.
83 * @param dst_index Index of the first destination element in the vector.
84 * @param src Container for the source vector.
85 * @param src_index Index of the first source element in the vector.
86 * @param n Number of elements to copy.
88 * @c dst and @ src can be either the same or different.
90 template <class CONT, class ALLOC>
91 void PackedLinkVectorFactory<CONT, ALLOC>::copy (SG::auxid_t auxid,
94 const AuxVectorData& src,
99 Base::copy (auxid, dst, dst_index, src, src_index, n);
100 if (&dst != &src && src.getDataArrayAllowMissing (auxid) != nullptr) {
101 IAuxTypeVector& dstlv = *dst.getStore()->linkedVector (auxid);
102 if (!Helper::updateLinks (dstlv,
103 reinterpret_cast<vector_value_type*>(dst.getDataArray (auxid)) + dst_index,
105 *src.getConstStore()->linkedVector (auxid),
108 dst.clearCache (dstlv.auxid());
115 * @brief Copy elements between vectors, possibly applying thinning.
116 * @param auxid The aux data item being operated on.
117 * @param dst Container for the destination vector.
118 * @param dst_index Index of the first destination element in the vector.
119 * @param src Container for the source vector.
120 * @param src_index Index of source element in the vector.
121 * @param src_index Index of the first source element in the vector.
122 * @param n Number of elements to copy.
124 * @c dst and @ src can be either the same or different.
126 template <class CONT, class ALLOC>
127 void PackedLinkVectorFactory<CONT, ALLOC>::copyForOutput
129 AuxVectorData& dst, size_t dst_index,
130 const AuxVectorData& src, size_t src_index,
134 copy (auxid, dst, dst_index, src, src_index, n);
135 #ifndef XAOD_STANDALONE
136 auto dstptr = reinterpret_cast<vector_value_type*>(dst.getDataArray (auxid)) + dst_index;
137 IAuxTypeVector& dstlv = *dst.getStore()->linkedVector (auxid);
138 typename Helper::DataLinkBase_span links = Helper::getLinkBaseSpan (dstlv);
139 const SG::ThinningCache* tc = SG::getThinningCache();
140 IProxyDict* sg = Helper::storeFromSpan (links);
141 bool cacheValid = Helper::applyThinning (dstlv, dstptr, n, links, tc, sg);
142 if (!cacheValid) dst.clearCache (dstlv.auxid());
148 * @brief Swap elements between vectors.
149 * @param auxid The aux data item being operated on.
150 * @param a Container for the first vector.
151 * @param aindex Index of the first element in the first vector.
152 * @param b Container for the second vector.
153 * @param bindex Index of the first element in the second vector.
154 * @param n Number of elements to swap.
156 * @c a and @ b can be either the same or different.
157 * However, the ranges should not overlap.
159 template <class CONT, class ALLOC>
160 void PackedLinkVectorFactory<CONT, ALLOC>::swap (SG::auxid_t auxid,
161 AuxVectorData& a, size_t aindex,
162 AuxVectorData& b, size_t bindex,
166 Base::swap (auxid, a, aindex, b, bindex, n);
168 IAuxTypeVector& alv = *a.getStore()->linkedVector (auxid);
169 IAuxTypeVector& blv = *b.getStore()->linkedVector (auxid);
171 if (!Helper::updateLinks (alv,
172 reinterpret_cast<vector_value_type*>(a.getDataArray (auxid)) + aindex,
175 a.clearCache (alv.auxid());
178 if (!Helper::updateLinks (blv,
179 reinterpret_cast<vector_value_type*>(b.getDataArray (auxid)) + bindex,
182 b.clearCache (blv.auxid());
188 //**************************************************************************
192 * @brief Create a vector object of this type.
193 * @param auxid ID for the variable being created.
194 * @param size Initial size of the new vector.
195 * @param capacity Initial capacity of the new vector.
196 * @param isLinked True if this variable is linked from another one.
199 template <class CONT, class VALLOC, class VELT, class ALLOC>
200 std::unique_ptr<IAuxTypeVector>
201 PackedLinkVVectorFactory<CONT, VALLOC, VELT, ALLOC>::
202 create (SG::auxid_t auxid,
203 size_t size, size_t capacity,
204 [[maybe_unused]] bool isLinked) const
207 const AuxTypeRegistry& r = AuxTypeRegistry::instance();
208 auxid_t linked_id = r.linkedVariable (auxid);
210 using linkedAlloc = typename std::allocator_traits<ALLOC>::template rebind_alloc<DataLink<CONT> >;
212 std::make_unique<AuxTypeVector<DataLink<CONT>, linkedAlloc> > (linked_id,
214 return std::make_unique<AuxTypeVector_t> (auxid, size, capacity,
215 std::move (linkedVec));
220 * @brief Create a vector object of this type from a data blob.
221 * @param auxid ID for the variable being created.
222 * @param data The vector object.
223 * @param linkedVector The interface for another variable linked to this one.
224 * (We do not take ownership.)
225 * @param isPacked If true, @c data is a @c PackedContainer.
226 * @param ownFlag If true, the newly-created IAuxTypeVector object
227 * will take ownership of @c data.
228 * @param isLinked True if this variable is linked from another one.
230 * @c data should be a pointer to a
231 * std::vector<std::vector<SG::PackedLink<CONT>, VALLOC<...> > >, ALLOC<...> > object obtained with new.
232 * For this method, isPacked and isLinked must both be false.
234 template <class CONT, class VALLOC, class VELT, class ALLOC>
235 std::unique_ptr<IAuxTypeVector>
236 PackedLinkVVectorFactory<CONT, VALLOC, VELT, ALLOC>::
237 createFromData (SG::auxid_t auxid,
239 IAuxTypeVector* linkedVector,
240 [[maybe_unused]] bool isPacked,
242 [[maybe_unused]] bool isLinked) const
244 assert (!isPacked && !isLinked && linkedVector != nullptr);
245 using Holder = SG::PackedLinkVVectorHolder<CONT, VALLOC, VELT, ALLOC>;
246 using vector_type = typename Holder::vector_type;
247 return std::make_unique<Holder>
248 (auxid, reinterpret_cast<vector_type*>(data), linkedVector, ownFlag);
253 * @brief Copy elements between vectors.
254 * @param auxid The aux data item being operated on.
255 * @param dst Container for the destination vector.
256 * @param dst_index Index of the first destination element in the vector.
257 * @param src Container for the source vector.
258 * @param src_index Index of the first source element in the vector.
259 * @param n Number of elements to copy.
261 * @c dst and @ src can be either the same or different.
263 template <class CONT, class VALLOC, class VELT, class ALLOC>
264 void PackedLinkVVectorFactory<CONT, VALLOC, VELT, ALLOC>::
265 copy (SG::auxid_t auxid,
268 const AuxVectorData& src,
273 Base::copy (auxid, dst, dst_index, src, src_index, n);
274 if (&dst != &src && src.getDataArrayAllowMissing (auxid) != nullptr) {
275 IAuxTypeVector& dstlv = *dst.getStore()->linkedVector (auxid);
276 if (!Helper::updateLinks (dstlv,
277 reinterpret_cast<vector_value_type*>(dst.getDataArray (auxid)) + dst_index,
279 *src.getConstStore()->linkedVector (auxid),
282 dst.clearCache (dstlv.auxid());
289 * @brief Copy elements between vectors, possibly applying thinning.
290 * @param auxid The aux data item being operated on.
291 * @param dst Container for the destination vector.
292 * @param dst_index Index of the first destination element in the vector.
293 * @param src Container for the source vector.
294 * @param src_index Index of source element in the vector.
295 * @param src_index Index of the first source element in the vector.
296 * @param n Number of elements to copy.
298 * @c dst and @ src can be either the same or different.
300 template <class CONT, class VALLOC, class VELT, class ALLOC>
301 void PackedLinkVVectorFactory<CONT, VALLOC, VELT, ALLOC>::copyForOutput
303 AuxVectorData& dst, size_t dst_index,
304 const AuxVectorData& src, size_t src_index,
308 copy (auxid, dst, dst_index, src, src_index, n);
309 #ifndef XAOD_STANDALONE
310 using DataLinkBase_span = typename Helper::DataLinkBase_span;
311 auto dstptr = reinterpret_cast<vector_value_type*>(dst.getDataArray (auxid)) + dst_index;
312 IAuxTypeVector& dstlv = *dst.getStore()->linkedVector (auxid);
313 DataLinkBase_span links = Helper::getLinkBaseSpan (dstlv);
314 const SG::ThinningCache* tc = SG::getThinningCache();
315 IProxyDict* sg = Helper::storeFromSpan (links);
316 bool cacheValid = true;
317 for (size_t i = 0; i < n; i++) {
319 cacheValid &= Helper::applyThinning (dstlv, v.data(), v.size(),
322 if (!cacheValid) dst.clearCache (dstlv.auxid());
328 * @brief Swap elements between vectors.
329 * @param auxid The aux data item being operated on.
330 * @param a Container for the first vector.
331 * @param aindex Index of the first element in the first vector.
332 * @param b Container for the second vector.
333 * @param bindex Index of the first element in the second vector.
334 * @param n Number of elements to swap.
336 * @c a and @ b can be either the same or different.
337 * However, the ranges should not overlap.
339 template <class CONT, class VALLOC, class VELT, class ALLOC>
340 void PackedLinkVVectorFactory<CONT, VALLOC, VELT, ALLOC>::
341 swap (SG::auxid_t auxid,
342 AuxVectorData& a, size_t aindex,
343 AuxVectorData& b, size_t bindex,
347 Base::swap (auxid, a, aindex, b, bindex, n);
349 IAuxTypeVector& alv = *a.getStore()->linkedVector (auxid);
350 IAuxTypeVector& blv = *b.getStore()->linkedVector (auxid);
352 if (!Helper::updateLinks (alv,
353 reinterpret_cast<vector_value_type*>(a.getDataArray (auxid)) + aindex,
356 a.clearCache (alv.auxid());
359 if (!Helper::updateLinks (blv,
360 reinterpret_cast<vector_value_type*>(b.getDataArray (auxid)) + bindex,
363 b.clearCache (blv.auxid());