NeoPZ
TPZChunkVector.h
Go to the documentation of this file.
1 
6 #ifndef PZCHUNK_H
7 #define PZCHUNK_H
8 
9 #include "pzmanvector.h"
10 #include "pzerror.h"
11 #include "Hash/TPZHash.h"
12 #include "TPZSavable.h"
13 #include <type_traits>
14 
15 
16 #include <stdlib.h>
17 #include <stddef.h>
18 
23 #define DEFAULTNUMBEROFCHUNKS 100
24 
29 #define DEFAULTCHUNKEXPONENT 10
30 
31 template<class T, int EXP>
32 class TPZChunkVector;
33 
34 template<bool is_const, class T, int EXP = DEFAULTCHUNKEXPONENT>
36 public:
37  typedef T valuetype;
38  typedef typename std::conditional<is_const, const TPZChunkVector<T, EXP>, TPZChunkVector<T, EXP>>::type vectype;
39  typedef typename std::conditional<is_const, const T&, T&>::type reference;
40  typedef typename std::conditional<is_const, const T*, T*>::type pointer;
41 
43  }
44 
46 
47  inline operator bool()const {
48  return (chunkVector && cur_index < chunkVector->NElements());
49  }
50 
52  return (chunkVector == other.chunkVector && cur_index == other.cur_index);
53  }
54 
56  return ! (* this == other);
57  }
58 
60  cur_index += movement;
61  return (*this);
62  }
63 
65  cur_index -= movement;
66  return (*this);
67  }
68 
70  ++cur_index;
71  return (*this);
72  }
73 
75  --cur_index;
76  return (*this);
77  }
78 
80  auto temp(*this);
81  ++cur_index;
82  return temp;
83  }
84 
86  auto temp(*this);
87  --cur_index;
88  return temp;
89  }
90 
91  TPZChunkVectorIterator<is_const, T, EXP> operator+(const ptrdiff_t& movement) const {
92  auto old_index = cur_index;
93  cur_index += movement;
94  auto temp(*this);
95  cur_index = old_index;
96  return temp;
97  }
98 
99  TPZChunkVectorIterator<is_const, T, EXP> operator-(const ptrdiff_t& movement) const {
100  auto old_index = cur_index;
101  cur_index -= movement;
102  auto temp(*this);
103  cur_index = old_index;
104  return temp;
105  }
106 
107  ptrdiff_t operator-(const TPZChunkVectorIterator<is_const, T, EXP>& other) const {
108  return std::distance(other.cur_index, this->cur_index);
109  }
110 
111  reference operator*() const {
112  return chunkVector->operator[](cur_index);
113  }
114 
115  pointer operator->() const {
116  return &chunkVector->operator[](cur_index);
117  }
118 
119  TPZChunkVectorIterator(const TPZChunkVectorIterator &other) = default;
120 
121 protected:
122 
123  vectype *chunkVector;
124  typename vectype::size_type cur_index;
125 
126  TPZChunkVectorIterator(vectype *chunkVector, typename vectype::size_type cur_index) : chunkVector(chunkVector), cur_index(cur_index) {
127 
128  }
129 
130 
131  friend class TPZChunkVector<T, EXP>;
132 };
133 
134 #include "TPZStream.h"
135 
141 template<typename T, typename std::enable_if<std::is_pointer<T>::value, int>::type * = nullptr>
142 void ReadInternal(T &output, TPZStream& buf, void* context){
143  output = dynamic_cast<T>(TPZPersistenceManager::GetInstance(&buf));
144 }
145 
146 template<typename T, typename std::enable_if<!std::is_pointer<T>::value && !is_arithmetic_pz<T>::value, int>::type * = nullptr>
147 void ReadInternal(T &output, TPZStream& buf, void* context){
148  output.Read(buf, context);
149 }
150 template<typename T, typename std::enable_if<!std::is_pointer<T>::value && is_arithmetic_pz<T>::value, int>::type * = nullptr>
151 void ReadInternal(T &output, TPZStream& buf, void* context){
152  buf.Read(&output, 1);
153 }
154 
155 template<typename T, typename std::enable_if<std::is_pointer<T>::value, int>::type * = nullptr>
156 void WriteInternal(const T& input, TPZStream& buf, int withclassid) {
158 }
159 
160 template<typename T, typename std::enable_if<!std::is_pointer<T>::value && !is_arithmetic_pz<T>::value, int>::type * = nullptr>
161 void WriteInternal(const T& input, TPZStream& buf, int withclassid) {
162  input.Write(buf, withclassid);
163 }
164 
165 template<typename T, typename std::enable_if<!std::is_pointer<T>::value && is_arithmetic_pz<T>::value, int>::type * = nullptr>
166 void WriteInternal(const T& input, TPZStream& buf, int withclassid) {
167  buf.Write(&input, withclassid);
168 }
169 
170 
175 template<class T, int EXP = DEFAULTCHUNKEXPONENT>
176 class TPZChunkVector : public TPZSavable {
177 public:
178 
179  typedef T value_type;
180  typedef value_type *pointer;
181  typedef const value_type *const_pointer;
184  typedef value_type &reference;
185  typedef const value_type &const_reference;
186  typedef int64_t size_type;
187 
193 
199 
204  TPZChunkVector(int64_t numberofchunks = DEFAULTNUMBEROFCHUNKS);
206  virtual ~TPZChunkVector();
207 
208  inline iterator begin() {
209  return iterator(this, 0);
210  }
211 
212  inline const_iterator begin() const {
213  return const_iterator(this, 0);
214  }
215 
216  inline const_iterator cbegin() const {
217  return const_iterator(this, 0);
218  }
219 
220  inline iterator end() {
221  return iterator(this, NElements());
222  }
223 
224  inline const_iterator end() const {
225  return const_iterator(this, NElements());
226  }
227 
228  inline const_iterator cend() const {
229  return const_iterator(this, NElements());
230  }
231 
236  inline int64_t NElements() const {
237  return fNElements;
238  }
239 
245  void Resize(const int64_t newsize);
246 
254  T &operator[](const int64_t nelem) const;
255 
257  int64_t FindObject(T *object);
258 
259  int ClassId() const override {
260  return Hash("TPZChunkVector") ^ ClassIdOrHash<T>() << 1 ^ (EXP << 2);
261  }
262 
263  void Read(TPZStream& buf, void* context) override{
264  uint64_t nObjects;
265  buf.Read(&nObjects);
266  this->Resize(nObjects);
267  for (uint64_t i = 0; i < nObjects; ++i) {
268  ReadInternal(this->operator [](i), buf, context);
269  }
270  }
271 
272  void Write(TPZStream& buf, int withclassid) const override{
273  uint64_t nObjects = this->NElements();
274  buf.Write(&nObjects);
275  for (uint64_t i = 0; i < nObjects; i++) {
276  WriteInternal(this->operator [](i), buf, withclassid);
277  }
278  }
279 
280 protected:
282  int64_t fNElements;
283 
286 
287 };
288 
289 //--| IMPLEMENTATION |----------------------------------------------------------
290 
291 template< class T, int EXP >
292 TPZChunkVector<T, EXP>::TPZChunkVector(int64_t numberofchunks) :
293 fVec(numberofchunks) {
294  fNElements = 0;
295 
296  for (int64_t i = 0; i < numberofchunks; i++) {
297  fVec[i] = NULL;
298  }
299 
300  fVec.Resize(0);
301 }
302 
303 template< class T, int EXP >
305  int64_t nchunks = fVec.NElements();
306 
307  for (int64_t i = 0; i < nchunks; i++) {
308  if (fVec[i]) delete[] fVec[i];
309  }
310 }
311 
312 // Increase the size of the chunk vector
313 
314 template< class T, int EXP>
315 void TPZChunkVector<T, EXP>::Resize(const int64_t newsize) {
316 #ifndef NODEBUG
317  if (newsize < 0) {
318  PZError << "TPZChunkVector::Resize. Bad parameter newsize." << std::endl;
319  PZError.flush();
320  return;
321  }
322 #endif
323  fNElements = newsize;
324 
325  int64_t nchunks = fVec.NElements();
326 
327  int64_t chunksneeded = ((newsize - 1) >> EXP) + 1;
328  if (chunksneeded == nchunks) return;
329 
330  T *NullPointer = 0;
331 
332  if (chunksneeded > nchunks)
333  fVec.Resize(chunksneeded, NullPointer);
334 
335  const int64_t sizechunk = 1 << EXP;
336  int64_t i;
337  for (i = 0; i < chunksneeded; ++i) {
338  if (!fVec[i])
339  fVec[i] = new T[sizechunk];
340  }
341 
342  for (; i < nchunks; ++i) {
343  if (fVec[i]) {
344  delete [] fVec[i];
345  fVec[i] = 0;
346  }
347  }
348 
349  fVec.Resize(chunksneeded);
350 }
351 
352 template<class T, int EXP>
354  int64_t nch = fVec.NElements();
355  int64_t ich;
356  int64_t index = 0;
357  // number of elements in a chunk
358  int64_t nelch = 1 << EXP;
359  for (ich = 0; ich < nch; ich++) {
360  if (fVec[ich] == 0) continue;
361  if (obj >= fVec[ich] && obj < fVec[ich] + nelch) {
362  return index + (obj - fVec[ich]);
363  } else {
364  index += nelch;
365  }
366  }
367  if (ich == nch) return -1;
368  return index;
369 }
370 
371 // Return a reference to the ith element of the vector
372 
373 template< class T, int EXP >
374 inline T &TPZChunkVector<T, EXP>::operator[](const int64_t nelem) const {
375 #ifndef NODEBUG
376  if (nelem < 0 || nelem >= NElements()) {
377  PZError << "TPZChunkVector::operator[]. "
378  << "Bad parameter nelem." << nelem << " NElements "
379  << NElements() << std::endl;
380  PZError.flush();
381  DebugStop();
382  exit(-1);
383  return fVec[0][0];
384  }
385 #endif
386 
387  const int64_t mask = (1 << EXP) - 1;
388 
389  return (fVec[nelem >> EXP])[nelem & mask];
390 }
391 
392 template< class T, int EXP >
394 fVec(TCh.fVec.NElements()) {
395 
396  fNElements = TCh.NElements();
397  int64_t nchunks = TCh.fVec.NElements();
398 
399  for (int64_t i = 0; i < nchunks; i++) {
400  if (!TCh.fVec[i]) {
401  fVec[i] = NULL;
402  } else {
403  int64_t j, k = 1 << EXP;
404  T* ptr = new T[1 << EXP];
405  fVec[i] = ptr;
406  T* ptrcp = TCh.fVec[i];
407  for (j = 0; j < k; j++) {
408  ptr[j] = ptrcp[j];
409  }
410  }
411  }
412 }
413 
414 template < class T, int EXP >
416  if (this == &TCh) return *this;
417  int64_t prvsz = fVec.NElements();
418  int64_t sz = TCh.fVec.NElements();
419  int64_t i;
420  for (i = sz; i < prvsz; i++)
421  if (fVec[i])
422  delete[] fVec[i];
423 
424  fVec.Resize(sz, 0);
425  fVec.Shrink();
426  fNElements = TCh.NElements();
427 
428  int64_t nchunks = sz;
429 
430  for (i = 0; i < nchunks; i++) {
431  if (!TCh.fVec[i]) {
432  fVec[i] = 0;
433  } else {
434  int64_t j, k = 1 << EXP;
435  fVec[i] = new T[1 << EXP];
436 
437  for (j = 0; j < k; j++)
438  fVec[i][j] = TCh.fVec[i][j];
439  }
440  }
441 
442  return *this;
443 }
444 
445 #endif // PZCHUNK_H
446 
447 //--| PZ |----------------------------------------------------------------------
pointer operator->() const
#define DEFAULTNUMBEROFCHUNKS
Default number of elements which will be allocated in the chunk vector.
TPZChunkVectorIterator(vectype *chunkVector, typename vectype::size_type cur_index)
TPZChunkVectorIterator< is_const, T, EXP > operator--(int)
void Read(TPZStream &buf, void *context) override
read objects from the stream
Contains declaration of the TPZSavable class which defines the interface to save and restore objects ...
virtual ~TPZChunkVector()
Destructor.
std::conditional< is_const, const TPZChunkVector< T, EXP >, TPZChunkVector< T, EXP > >::type vectype
Implements a vector class which allows to use external storage provided by the user. Utility.
Definition: pzquad.h:16
TPZChunkVectorIterator< is_const, T, EXP > & operator++()
T & operator[](const int64_t nelem) const
Returns a reference to the ith element of the vector.
void Write(TPZStream &buf, int withclassid) const override
Writes this object to the TPZStream buffer. Include the classid if withclassid = true.
TPZChunkVectorIterator< is_const, T, EXP > operator+(const ptrdiff_t &movement) const
void WriteInternal(const T &input, TPZStream &buf, int withclassid)
value_type * pointer
Defines PZError.
const_iterator cend() const
iterator begin()
reference operator*() const
TPZChunkVectorIterator< is_const, T, EXP > operator++(int)
clarg::argString input("-if", "input file", "cube1.txt")
int64_t NElements() const
Access method to query the number of elements of the vector.
const value_type * const_pointer
const_iterator begin() const
static TPZSavable * GetInstance(const int64_t &objId)
void Resize(const int64_t newsize)
Increase the size of the chunk vector.
int64_t FindObject(T *object)
Finds the index of an object by its pointer.
int64_t fNElements
Number of elements of the chunk vector.
virtual void Resize(const int64_t newsize, const T &object)
Resizes the vector object.
Definition: pzmanvector.h:426
TPZManVector< T * > fVec
Vector which points to each chunk of objects.
std::conditional< is_const, const T &, T & >::type reference
TPZChunkVectorIterator(const TPZChunkVectorIterator &other)=default
TPZChunkVector(const TPZChunkVector< T, EXP > &TCh)
Copy constructor.
virtual void Write(const bool val)
Definition: TPZStream.cpp:8
vectype::size_type cur_index
#define DebugStop()
Returns a message to user put a breakpoint in.
Definition: pzerror.h:20
Free store vector implementation.
TPZChunkVectorIterator< false, value_type, EXP > iterator
void ReadInternal(T &output, TPZStream &buf, void *context)
An object of this class implements a vector which allocates objects by chunks. Utility.
TPZChunkVectorIterator< is_const, T, EXP > & operator-=(const ptrdiff_t &movement)
const_iterator cbegin() const
void Shrink()
It reallocates storage to fit the necessary storage exactly.
Definition: pzmanvector.h:388
TPZChunkVector< T, EXP > & operator=(const TPZChunkVector< T, EXP > &TCh)
Assignment operator, copies all elements from the object TCh.
int32_t Hash(std::string str)
Definition: TPZHash.cpp:10
bool operator!=(const TPZChunkVectorIterator< is_const, T, EXP > &other) const
iterator end()
const value_type & const_reference
TPZChunkVectorIterator< true, value_type, EXP > const_iterator
ptrdiff_t operator-(const TPZChunkVectorIterator< is_const, T, EXP > &other) const
TPZChunkVectorIterator< is_const, T, EXP > & operator+=(const ptrdiff_t &movement)
std::conditional< is_const, const T *, T * >::type pointer
Contains declaration of the abstract TPZStream class. TPZStream defines the interface for saving and ...
Defines the interface for saving and reading data. Persistency.
Definition: TPZStream.h:50
int64_t NElements() const
Returns the number of elements of the vector.
Definition: pzvec.h:190
TPZChunkVectorIterator< is_const, T, EXP > operator-(const ptrdiff_t &movement) const
const_iterator end() const
TPZChunkVectorIterator< is_const, T, EXP > & operator=(const TPZChunkVectorIterator< is_const, T, EXP > &other)=default
TPZChunkVectorIterator< is_const, T, EXP > & operator--()
This class defines the interface to save and restore objects from TPZStream objects. Persistency.
Definition: TPZSavable.h:67
value_type & reference
static void WritePointer(const TPZSavable *obj, TPZStream *stream)
int ClassId() const override
Define the class id associated with the class.
bool operator==(const TPZChunkVectorIterator< is_const, T, EXP > &other) const
#define PZError
Defines the output device to error messages and the DebugStop() function.
Definition: pzerror.h:15
virtual void Read(bool &val)
Definition: TPZStream.cpp:91
obj
Definition: test.py:225