CompactListList.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2019-2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "CompactListList.H"
30 #include "labelRange.H"
31 
32 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
33 
34 template<class T>
36 (
37  const label idx,
38  const labelUList& localLens
39 )
40 {
42  << "Overflow : sum of sizes exceeds labelMax ("
43  << labelMax << ") after index " << idx;
44 
45  if (!localLens.empty())
46  {
47  FatalError << " of " << flatOutput(localLens);
48  }
49 
51  << nl
52  << "Please recompile with larger datatype for label." << nl
54 }
55 
56 
57 template<class T>
58 template<class ListListType>
60 (
61  const ListListType& lists,
62  const bool checkOverflow
63 )
64 {
65  CompactListList<T> compact;
66 
67  auto& newOffsets = compact.offsets_;
68  auto& newValues = compact.values_;
69 
70  label total = 0;
71  const label len = lists.size();
72 
73  if (len)
74  {
75  newOffsets.resize(len+1, Zero);
76 
77  for (label i = 0; i < len; ++i)
78  {
79  newOffsets[i] = total;
80  total += lists[i].size();
81 
82  if (checkOverflow && total < newOffsets[i])
83  {
84  reportOverflowAndExit(i);
85  }
86  }
87  newOffsets[len] = total;
88  }
89 
90  if (total)
91  {
92  // Copy in the data
93  newValues.resize(total);
94 
95  auto outIter = newValues.begin();
96 
97  for (const auto& list : lists)
98  {
99  forAll(list, i)
100  {
101  *outIter = list[i];
102  ++outIter;
103  }
104  }
105  }
106 
107  return compact;
108 }
109 
110 
111 template<class T>
112 template<class SubListType>
114 (
115  const UList<SubListType>& lists,
116  const bool checkOverflow
117 )
118 {
120  (
121  lists,
122  checkOverflow
123  );
124 }
125 
126 
127 template<class T>
128 template<class SubListType, class Addr>
130 (
132  const bool checkOverflow
133 )
134 {
136  (
137  lists,
138  checkOverflow
139  );
140 }
141 
142 
143 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
144 
145 template<class T>
147 {
148  const label len = listSizes.size();
149 
150  if (len)
151  {
152  offsets_.resize(len+1);
153 
154  label total = 0;
155  for (label i = 0; i < len; ++i)
156  {
157  offsets_[i] = total;
158  total += listSizes[i];
159 
160 #ifdef FULLDEBUG
161  if (total < offsets_[i])
162  {
163  reportOverflowAndExit(i, listSizes);
164  }
165 #endif
166  }
167 
168  offsets_[len] = total;
169  values_.resize(total);
170  }
171 }
172 
173 
174 template<class T>
176 (
177  const labelUList& listSizes,
178  const T& val
179 )
180 {
181  const label len = listSizes.size();
182 
183  if (len)
184  {
185  offsets_.resize(len+1);
186 
187  label total = 0;
188  for (label i = 0; i < len; ++i)
189  {
190  offsets_[i] = total;
191  total += listSizes[i];
192 
193 #ifdef FULLDEBUG
194  if (total < offsets_[i])
195  {
196  reportOverflowAndExit(i, listSizes);
197  }
198 #endif
199  }
200 
201  offsets_[len] = total;
202  values_.resize(total, val);
203  }
204 }
205 
206 
207 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
208 
209 template<class T>
210 Foam::label Foam::CompactListList<T>::maxNonLocalSize(const label rowi) const
211 {
212  const label len = (offsets_.size() - 1);
213 
214  if (len < 1)
215  {
216  return 0;
217  }
218 
219  label maxLen = 0;
220 
221  for (label i=0; i < len; ++i)
222  {
223  if (i != rowi)
224  {
225  const label localLen = (offsets_[i+1] - offsets_[i]);
226  maxLen = max(maxLen, localLen);
227  }
228  }
229 
230  return maxLen;
231 }
232 
233 
234 template<class T>
235 std::streamsize Foam::CompactListList<T>::byteSize() const
236 {
237  if (!is_contiguous<T>::value)
238  {
240  << "Invalid for non-contiguous data types"
242  }
243  return this->size_bytes();
244 }
245 
246 
247 template<class T>
249 {
250  return labelRange(offsets_[i], offsets_[i+1] - offsets_[i]);
251 }
252 
253 
254 template<class T>
257 {
259 
260  const label len = (offsets_.size() - 1);
261 
262  if (len < 1)
263  {
264  return values;
265  }
266 
267  values.resize(len);
268 
269  for (label i=0; i < len; ++i)
270  {
271  values[i].reset(offsets_[i], (offsets_[i+1] - offsets_[i]));
272  }
273 
274  return values;
275 }
276 
277 
278 template<class T>
279 void Foam::CompactListList<T>::resize(const labelUList& listSizes)
280 {
281  const label len = listSizes.size();
282 
283  if (len)
284  {
285  offsets_.resize(len+1);
286 
287  label total = 0;
288  for (label i = 0; i < len; ++i)
289  {
290  offsets_[i] = total;
291  total += listSizes[i];
292 #if 0
293  if (checkOverflow && total < offsets_[i])
294  {
295  reportOverflowAndExit(i, listSizes);
296  }
297 #endif
298  }
299 
300  offsets_[len] = total;
301  values_.resize(total);
302  }
303  else
304  {
305  clear();
306  }
307 }
308 
309 
310 template<class T>
311 void Foam::CompactListList<T>::setLocalSize(const label rowi, const label len)
312 {
313  if (rowi >= 0 && rowi+1 < offsets_.size() && len >= 0)
314  {
315  const label delta = (len - (offsets_[rowi+1] - offsets_[rowi]));
316 
317  // TBD: additional overflow check
318  if (delta)
319  {
320  for (label i = rowi+1; i < offsets_.size(); ++i)
321  {
322  offsets_[i] += delta;
323  }
324  }
325  }
326 }
327 
328 
329 template<class T>
331 {
333 
334  const label len = (offsets_.size() - 1);
335 
336  if (len < 1)
337  {
338  return values;
339  }
340 
341  values.resize(len);
342 
343  for (label i=0; i < len; ++i)
344  {
345  values[i] = offsets_[i+1] - offsets_[i];
346  }
348  return values;
349 }
350 
351 
352 template<class T>
354 (
355  CompactListList<T>& other
356 )
357 {
358  if (this == &other)
359  {
360  return; // Self-swap is a no-op
361  }
362 
363  offsets_.swap(other.offsets_);
364  values_.swap(other.values_);
365 }
366 
367 
368 template<class T>
370 (
371  CompactListList<T>& list
372 )
373 {
374  if (this == &list)
375  {
376  return; // Self-assignment is a no-op
377  }
378 
379  offsets_.transfer(list.offsets_);
380  values_.transfer(list.values_);
381 }
382 
383 
384 template<class T>
385 template<class SubListType>
388 {
389  List<SubListType> lists(size());
390 
391  forAll(lists, i)
392  {
393  lists[i] = SubListType(this->localList(i));
394  }
395 
396  return lists;
397 }
398 
399 
400 template<class T>
401 template<class SubListType>
404 {
405  List<SubListType> lists(range.size());
406 
407  auto outIter = lists.begin();
408 
409  for (const label i : range)
410  {
411  *outIter = SubListType(this->localList(i));
412  ++outIter;
413  }
414 
415  return lists;
416 }
417 
418 
419 // ************************************************************************* //
scalar delta
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:118
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:51
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
void swap(CompactListList< T > &other)
Swap contents.
static CompactListList< T > pack(const UList< SubListType > &lists, const bool checkOverflow=false)
Construct by packing together the list of lists.
Base for lists with indirect addressing, templated on the list contents type and the addressing type...
scalar range
UList< label > labelUList
A UList of labels.
Definition: UList.H:80
void transfer(CompactListList< T > &list)
Transfer contents into this and annul the argument.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:413
void setLocalSize(const label rowi, const label len)
Alter local addressing size for given row, does not change content.
List< labelRange > ranges() const
Return start/size ranges for all sub-lists.
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:164
List< SubListType > unpack() const
Return non-compact list of lists.
labelRange range(const label i) const
Return start/size range for given sub-list.
CompactListList() noexcept=default
Default construct.
patchWriters clear()
void resize(const label mRows)
Reset size of CompactListList.
errorManip< error > abort(error &err)
Definition: errorManip.H:139
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:322
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:99
std::streamsize byteSize() const
Number of contiguous bytes for the values data, runtime FatalError if type is not contiguous...
A packed storage unstructured matrix of objects of type <T> using an offset table for access...
const volScalarField & T
labelList localSizes() const
The local row sizes.
constexpr label labelMax
Definition: label.H:55
List< label > labelList
A List of labels.
Definition: List.H:62
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:157