ATLAS Offline Software
Loading...
Searching...
No Matches
SG::JaggedVecVectorFactoryFuncs Namespace Reference

Functions

void fillTrailingZeros (JaggedVecEltBase *elts, size_t index, size_t sz, IAuxTypeVector *lv)
 Fill in trailing zeros in a range.
void copyImpl (SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n, bool for_output)
 Copy elements between vectors: out-of-line portion.
void swap (SG::auxid_t auxid, AuxVectorData &a, size_t aindex, AuxVectorData &b, size_t bindex, size_t n)
 Swap elements between vectors.
void clear (JaggedVecEltBase *v, auxid_t auxid, AuxVectorData &dst, size_t dst_index, size_t n)
 Clear a range of elements within a vector.

Function Documentation

◆ clear()

void SG::JaggedVecVectorFactoryFuncs::clear ( JaggedVecEltBase * v,
auxid_t auxid,
AuxVectorData & dst,
size_t dst_index,
size_t n )

Clear a range of elements within a vector.

Parameters
vPointer to the vector being operated on.
auxidThe aux data item being operated on.
dstContainer holding the element
dst_indexIndex of the first element in the vector.
nNumber of elements to clear.

Definition at line 281 of file JaggedVecVectorFactory.cxx.

286{
287 const size_t dst_sz = dst.size_v();
289
290 // Make sure there are no trailing zeros in the destination.
291 fillTrailingZeros (v, dst_sz, dst_sz, lv);
292
293 size_t begin = v[dst_index].begin(dst_index);
294 size_t end = v[dst_index+n-1].end();
295
296 size_t n_payload = end - begin;
297
298 // Erase the payload elements.
299 lv->shift (end, - n_payload);
300
301 // Adjust indices for following elements.
302 std::for_each (v+dst_index+n, v+dst_sz, Shift (-n_payload));
303 // Clear out the given range.
304 std::fill_n (v+dst_index, n, JaggedVecEltBase(begin));
305}
@ Shift
virtual size_t size_v() const =0
Return the size of the container.
SG::IAuxStore * getStore()
Return the current store, as a non-const interface.
virtual IAuxTypeVector * linkedVector(SG::auxid_t)
Definition IAuxStore.h:187
Abstract interface for manipulating vectors of arbitrary types.
virtual bool shift(size_t pos, ptrdiff_t offs)=0
Shift the elements of the vector.
Describe one element of a jagged vector (base class).
void fillTrailingZeros(JaggedVecEltBase *elts, size_t index, size_t sz, IAuxTypeVector *lv)
Fill in trailing zeros in a range.
SG::auxid_t auxid() const
Return the aux id for this variable.

◆ copyImpl()

void SG::JaggedVecVectorFactoryFuncs::copyImpl ( SG::auxid_t auxid,
AuxVectorData & dst,
size_t dst_index,
const AuxVectorData & src,
size_t src_index,
size_t n,
bool for_output )

Copy elements between vectors: out-of-line portion.

Parameters
auxidThe aux data item being operated on.
dstContainer for the destination vector.
dst_indexIndex of the first destination element in the vector.
srcContainer for the source vector.
src_indexIndex of the first source element in the vector.
nNumber of elements to copy.
for_outputIf true, then need to use copyForOutput on the payload, to update links due to thinning.

dst and @ src can be either the same or different.

Definition at line 47 of file JaggedVecVectorFactory.cxx.

54{
55 using vector_value_type = JaggedVecEltBase;
56
57 if (n == 0) return;
58
59 // Check for overlaps.
60 if (&src == &dst) {
61 size_t src_end = src_index + n;
62 size_t dst_end = dst_index + n;
63 if ((src_end > dst_index && src_end <= dst_end) ||
64 (dst_end > src_index && dst_end <= src_end))
65 {
66 // Overlapping copies not implemented for jagged vectors.
67 // Talk to core software if this is an issue.
69 }
70 }
71
72 vector_value_type* v_dst = reinterpret_cast<vector_value_type*> (dst.getDataArray (auxid));
73 const vector_value_type* v_src = &dst==&src ? v_dst : reinterpret_cast<const vector_value_type*> (src.getDataArray (auxid));
74 IAuxTypeVector* dst_lv = dst.getStore()->linkedVector (auxid);
75 const SG::auxid_t payload_auxid = dst_lv->auxid();
76 const AuxTypeRegistry& r = AuxTypeRegistry::instance();
77 const IAuxTypeVectorFactory* payload_fac = r.getFactory (payload_auxid);
78 const size_t dst_sz = dst.size_v();
79
80 // Make sure there are no trailing zeros in the destination within the
81 fillTrailingZeros (v_dst, dst_index+n, dst_sz, dst_lv);
82
83 const size_t dst_first = v_dst[dst_index].begin(dst_index);
84 size_t src_first = v_src[src_index].begin(src_index);
85 size_t src_first_orig = src_first;
86 const size_t n_dst = v_dst[dst_index+n-1].end() - dst_first;
87 size_t n_src = v_src[src_index+n-1].end() - src_first;
88
89 // First copy the Elt elements. We'll fix up the indices below.
90 std::copy_n (v_src+src_index, n, v_dst+dst_index);
91
92 // If the source had trailing zeros, fix them up here.
93 if (v_dst[dst_index+n-1].end() == 0) {
94 const size_t src_sz = src.size_v();
95 if (v_src[src_sz-1].end() == 0) {
96 const IAuxTypeVector* src_lv = src.getConstStore()->linkedVector (auxid);
97 if (size_t src_n_payload = src_lv->getDataSpan().size) {
98
99 bool adjust = true;
100 for (size_t i = src_index+n; i < src_sz; ++i) {
101 if (v_src[i].end() != 0) {
102 adjust = false;
103 break;
104 }
105 }
106 if (adjust) {
107 Shift shift (src_n_payload);
108 for (size_t i = dst_index+n-1; v_dst[i].end() == 0; --i) {
109 shift (v_dst[i]);
110 if (i == dst_index) break;
111 }
112 if (src_first == 0 && src_index > 0) {
113 src_first = v_src[src_index-1].end();
114 src_first_orig = src_first;
115 }
116 n_src = src_n_payload - src_first;
117 }
118 }
119 }
120 }
121
122 // Adjust the size of the destination payload container.
123 if (n_src != n_dst) {
124 if (!dst_lv->shift (dst_first+n_dst, n_src - n_dst)) {
125 dst.clearCache (payload_auxid);
126 }
127 if (&dst == &src && src_first > dst_first) {
128 src_first += (n_src - n_dst);
129 }
130 }
131
132 // Copy the payload elements.
133 if (for_output) {
134 payload_fac->copyForOutput (payload_auxid, dst, dst_first, src, src_first, n_src);
135 }
136 else {
137 payload_fac->copy (payload_auxid, dst, dst_first, src, src_first, n_src);
138 }
139
140 // Fix up the Elt entries --- first the ones we copied, then the following
141 // ones in the destination container.
142 std::for_each_n (v_dst+dst_index, n, Shift (dst_first - src_first_orig));
143 // Avoid N^2.
144 if (dst_index+n < dst_sz && !(v_dst[dst_index+n].end() == 0 && v_dst[dst_sz-1].end() == 0))
145 {
146 std::for_each (v_dst+dst_index+n, v_dst+dst_sz, Shift (n_src - n_dst));
147 }
148}
static AuxTypeRegistry & instance()
Return the singleton registry instance.
void clearCache()
Clear the cached aux data pointers.
const void * getDataArray(SG::auxid_t auxid) const
Return a const pointer to the start of an aux data vector.
int r
Definition globals.cxx:22
virtual void shift(size_t pos, ptrdiff_t offs) override
Shift the elements of the container.
void throwJaggedVecOverlappingCopy()
Throw a SG::ExcJaggedVecOverlappingCopy exception.
size_t auxid_t
Identifier for a particular aux data item.
Definition AuxTypes.h:27

◆ fillTrailingZeros()

void SG::JaggedVecVectorFactoryFuncs::fillTrailingZeros ( JaggedVecEltBase * elts,
size_t index,
size_t sz,
IAuxTypeVector * lv )

Fill in trailing zeros in a range.

Parameters
eltsPointer to the vector on which to operate.
indexIndex of the last element to fill.
szSize of the vector.
lvCorresponding linked vector.

Fill fill in trailing zeros working backwards from index.

Definition at line 17 of file JaggedVecVectorFactory.cxx.

21{
22 if (index > 0 && elts[index-1].end() == 0 && elts[sz-1].end() == 0) {
23 if (size_t n_payload = lv->getDataSpan().size) {
24 Shift shift (n_payload);
25 for (--index; elts[index].end() == 0; --index) {
26 shift (elts[index]);
27 if (index == 0) break;
28 }
29 }
30 }
31}
static Double_t sz
const AuxDataSpanBase & getDataSpan() const
Return a reference to a description of this vector's start+size.
index_type end() const
Return the index of the end of the range.
Definition index.py:1
size_t size
The length of the variable's vector.
Definition AuxDataSpan.h:57

◆ swap()

void SG::JaggedVecVectorFactoryFuncs::swap ( SG::auxid_t auxid,
AuxVectorData & a,
size_t aindex,
AuxVectorData & b,
size_t bindex,
size_t n )

Swap elements between vectors.

Parameters
auxidThe aux data item being operated on.
aContainer for the first vector.
aindexIndex of the first element in the first vector.
bContainer for the second vector.
bindexIndex of the first element in the second vector.
nNumber of elements to swap.

a and @ b can be either the same or different. However, the ranges should not overlap.

Definition at line 163 of file JaggedVecVectorFactory.cxx.

167{
168 using vector_value_type = JaggedVecEltBase;
169
170 if (n == 0) return;
171
172 vector_value_type* v_a = reinterpret_cast<vector_value_type*> (a.getDataArray (auxid));
173 vector_value_type* v_b = &a==&b ? v_a : reinterpret_cast<vector_value_type*> (b.getDataArray (auxid));
174 IAuxTypeVector* alv = a.getStore()->linkedVector (auxid);
175 IAuxTypeVector* blv = &a==&b ? alv : b.getStore()->linkedVector (auxid);
176 const SG::auxid_t payload_auxid = alv->auxid();
178 const IAuxTypeVectorFactory* payload_fac = r.getFactory (payload_auxid);
179 const size_t a_sz = a.size_v();
180 const size_t b_sz = b.size_v();
181
182 // Make sure there are no trailing zeros in the ranges we're looking at.
183 fillTrailingZeros (v_a, a_sz, a_sz, alv);
184 fillTrailingZeros (v_b, b_sz, b_sz, blv);
185
186 size_t a_first = v_a[aindex].begin(aindex);
187 size_t b_first = v_b[bindex].begin(bindex);
188 const size_t a_first_orig = a_first;
189 const size_t b_first_orig = b_first;
190 const size_t n_a = v_a[aindex+n-1].end() - a_first;
191 const size_t n_b = v_b[bindex+n-1].end() - b_first;
192
193 // First swap the Elt entries. We'll fix up the indices below.
194 std::swap_ranges (v_a+aindex, v_a+aindex+n, v_b+bindex);
195
196 // We have two payload ranges to swap, a and b.
197 // One is probably longer than the other, so we'll need to adjust the
198 // payload vector lengths.
199 // But first, swap the common part of the payloads.
200 const size_t n_common = std::min (n_a, n_b);
201 payload_fac->swap (payload_auxid, a, a_first, b, b_first, n_common);
202
203 // Now we move the tail; that is, the piece of one payload range
204 // that is not in the other. Define a function to reduce duplicate
205 // code. Here, 1 is the range that is longer and 2 the range
206 // that is shorter.
207 auto shiftTail = [payload_fac, n_common, payload_auxid]
208 (AuxVectorData& vd1,
209 IAuxTypeVector* lv1,
210 size_t& first1,
211 const size_t n1,
212 AuxVectorData& vd2,
213 IAuxTypeVector* lv2,
214 size_t& first2)
215 {
216 // Lengthen the shorter payload to receive the extra elements from
217 // the longer one.
218 if (!lv2->shift (first2 + n_common, n1 - n_common)) {
219 vd2.clearCache (payload_auxid);
220 }
221 if (&vd1 == &vd2 && first1 > first2) {
222 // Special case for self-swapping: keep indices consistent.
223 first1 += (n1 - n_common);
224 }
225 // Copy the extra elements.
226 payload_fac->copy (payload_auxid,
227 vd2, first2 + n_common, vd1, first1 + n_common,
228 n1 - n_common);
229 // Now remove those elements from the longer one.
230 lv1->shift (first1 + n1, - (n1 - n_common));
231 if (&vd1 == &vd2 && first2 > first1) {
232 // Special case for self-swapping: keep indices consistent.
233 first2 -= (n1 - n_common);
234 }
235 };
236
237 // Now move the tail, depending on which is larger.
238 if (n_a > n_b) {
239 shiftTail (a, alv, a_first, n_a, b, blv, b_first);
240 }
241 else if (n_b > n_a) {
242 shiftTail (b, blv, b_first, n_b, a, alv, a_first);
243 }
244
245 // Now adjust the indices in the Elt ranges that were swapped.
246 // In the case of self-swapping, the _first indices may have changed,
247 // so need to remember to use the original values.
248 std::for_each_n (v_a+aindex, n, Shift (a_first - b_first_orig));
249 std::for_each_n (v_b+bindex, n, Shift (b_first - a_first_orig));
250
251 if (n_a != n_b) {
252 if (&a == &b) {
253 // Self-swapping case.
254 // Adjust the indices between the two ranges that were swapped
255 // (but we needn't do anything if the number of payload items
256 // was the same).
257 if (aindex < bindex) {
258 std::for_each (v_a+aindex+n, v_a+bindex, Shift (n_b - n_a));
259 }
260 else {
261 std::for_each (v_a+bindex+n, v_a+aindex, Shift (n_a - n_b));
262 }
263 }
264 else {
265 // Distinct container case. Adjust indices after the swapped ranges.
266 std::for_each (v_a+aindex+n, v_a+a_sz, Shift (n_b - n_a));
267 std::for_each (v_b+bindex+n, v_b+b_sz, Shift (n_a - n_b));
268 }
269 }
270}
static Double_t a
Handle mappings between names and auxid_t.
Manage lookup of vectors of auxiliary data.
Interface for factory objects that create vectors.
virtual void copy(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const =0
Copy elements between vectors.
virtual void swap(SG::auxid_t auxid, AuxVectorData &a, size_t aindex, AuxVectorData &b, size_t bindex, size_t n) const =0
Swap elements between vectors.
auxid_t auxid() const
Return the auxid of the variable this vector represents.
DataModel_detail::iterator< DV > swap_ranges(DataModel_detail::iterator< DV > first1, DataModel_detail::iterator< DV > last1, DataModel_detail::iterator< DV > first2)
Specialization of swap_ranges for DataVector/DataList.