A platform for high-performance distributed tool and library development written in C++. It can be deployed in two different cluster modes: standalone or distributed. API for v0.5.0, released on June 13, 2018.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Array.cc
Go to the documentation of this file.
1 /*****************************************************************************
2  * *
3  * Copyright 2018 Rice University *
4  * *
5  * Licensed under the Apache License, Version 2.0 (the "License"); *
6  * you may not use this file except in compliance with the License. *
7  * You may obtain a copy of the License at *
8  * *
9  * http://www.apache.org/licenses/LICENSE-2.0 *
10  * *
11  * Unless required by applicable law or agreed to in writing, software *
12  * distributed under the License is distributed on an "AS IS" BASIS, *
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
14  * See the License for the specific language governing permissions and *
15  * limitations under the License. *
16  * *
17  *****************************************************************************/
18 
19 #ifndef ARRAY_CC
20 #define ARRAY_CC
21 
22 #include <cstddef>
23 #include <iostream>
24 #include <vector>
25 #include <algorithm>
26 #include <iterator>
27 #include <type_traits>
28 #include <cstring>
29 
30 #include "Handle.h"
31 #include "Object.h"
32 #include "InterfaceFunctions.h"
33 
34 // Note: we need to write all operations in constructors, destructors, and assignment operators
35 // WITHOUT using
36 // the underlying type in any way (including assignment, initialization, destruction, size).
37 //
38 namespace pdb {
39 
40 template <class TypeContained>
41 void Array<TypeContained>::setUpAndCopyFrom(void* target, void* source) const {
42 
43  new (target) Array<TypeContained>();
44  Array<TypeContained>& fromMe = *((Array<TypeContained>*)source);
45  Array<TypeContained>& toMe = *((Array<TypeContained>*)target);
46 
47  // copy the number of slots
48  toMe.numSlots = fromMe.numSlots;
49  toMe.usedSlots = fromMe.usedSlots;
50 
51  // copy the type info
52  toMe.typeInfo = fromMe.typeInfo;
53  if (toMe.typeInfo.getTypeCode() == 0) {
54  std::cout << "Array::setUpAndCopyFrom: typeInfo=0 before getSizeOfConsitituentObject"
55  << std::endl;
56  }
57  // copy everything over... use memmove on primitive type, or properly do the assignment on
58  // everything else
59  char* newLoc = (char*)toMe.data;
60  char* data = (char*)fromMe.data;
61 
62  // get the type code for our child from the RHS
63  // get the size of the constituent object
64  uint32_t dataSize = 0;
65  if (fromMe.usedSlots > 0)
66 #ifdef DEBUG_DEEP_COPY
67  PDB_COUT << "fromMe.usedSlots=" << fromMe.usedSlots << std::endl;
68 #endif
69  dataSize = toMe.typeInfo.getSizeOfConstituentObject(data);
70 
71 #ifdef DEBUG_DEEP_COPY
72  PDB_COUT << "dataSize=" << dataSize << std::endl;
73 #endif
74 
75  if (!toMe.typeInfo.descendsFromObject()) {
76  // in this case, we might have a fundmanetal type... regardless, just do a simple bitwise
77  // copy
78  memmove(newLoc, data, dataSize * fromMe.usedSlots);
79  } else {
80  for (uint32_t i = 0; i < fromMe.usedSlots; i++) {
81  try {
82  toMe.typeInfo.setUpAndCopyFromConstituentObject(newLoc + dataSize * i,
83  data + dataSize * i);
84  } catch (NotEnoughSpace& n) {
85  // JiaNote: handle exception here
86  PDB_COUT << "exception in array copy" << std::endl;
87  toMe.usedSlots = i;
88  throw n;
89  }
90  }
91  }
92 }
93 
94 // just use setUpAndCopyFrom to do a deep copy... this assumes that we have enough space!!
95 template <class TypeContained>
97  setUpAndCopyFrom(this, &toMe);
98 }
99 
100 template <class TypeContained>
101 Array<TypeContained>::Array(uint32_t numSlotsIn, uint32_t numUsedSlots) {
102  typeInfo.setup<TypeContained>();
103  usedSlots = numUsedSlots;
104  numSlots = numSlotsIn;
105  if (typeInfo.descendsFromObject()) {
106  // std :: cout << "numUsedSlots=" << numUsedSlots << std :: endl;
107  // run the constructor on each object
108  // std :: cout << "Calling object constructor.\n";
109  for (uint32_t i = 0; i < numUsedSlots; i++) {
110  new ((void*)&(((TypeContained*)(data))[i])) TypeContained();
111  }
112  } else {
113  // std :: cout << "numUsedSlots=" << numUsedSlots << std :: endl;
114  // std :: cout << "sizeof(TypeContained)=" << sizeof(TypeContained) << std :: endl;
115  // zero out everything
116  // std :: cout << "Just b-zeroing everything.\n";
117  bzero(data, numUsedSlots * sizeof(TypeContained));
118  }
119 }
120 template <class TypeContained>
121 Array<TypeContained>::Array(uint32_t numSlotsIn) {
122  typeInfo.setup<TypeContained>();
123  usedSlots = 0;
124  numSlots = numSlotsIn;
125 }
126 
127 template <class TypeContained>
129  return resize(numSlots * 2);
130 }
131 
132 template <class TypeContained>
134  typeInfo.setup<TypeContained>();
135  return usedSlots == numSlots;
136 }
137 
138 template <class TypeContained>
140  typeInfo.setup<TypeContained>();
141  usedSlots = 0;
142  numSlots = 0;
143 }
144 
145 // Note: because this can be called by Object.deleteObject (), it must be written so as to not use
146 // TypeContained
147 template <class TypeContained>
149  if (typeInfo.getTypeCode() == 0) {
150  std::cout << "Array::~Array: typeInfo = 0 before getSizeOfConstituentObject" << std::endl;
151  }
152  // do no work if the guys we store do not come from pdb :: Object
153  if (!typeInfo.descendsFromObject())
154  return;
155 
156  // loop through and explicitly call the destructor on everything
157  char* location = (char*)data;
158 
159  // get the size of the constituent object
160  uint32_t objSize = 0;
161  if (usedSlots > 0)
162  objSize = typeInfo.getSizeOfConstituentObject(location);
163 
164  // now, delete each of the objects in there, if we have got an object type
165  for (uint32_t i = 0; i < usedSlots; i++) {
166  typeInfo.deleteConstituentObject(location + i * objSize);
167  }
168 }
169 
170 template <class TypeContained>
172 
173  // allocate the new Array
174  Handle<Array<TypeContained>> tempArray =
175  makeObjectWithExtraStorage<Array<TypeContained>>(sizeof(TypeContained) * howMany, howMany);
176 
177  // copy everything over
178  TypeContained* newLoc = (TypeContained*)(tempArray->data);
179 
180  uint32_t max = usedSlots;
181  if (max < howMany)
182  max = howMany;
183 
184  uint32_t min = usedSlots;
185  if (min > howMany)
186  min = howMany;
187 
188  tempArray->usedSlots = min;
189 
190  // JiaNote: deep copy may cause exception, and cause usedSlots inconsistent
191  size_t myUsedSlots = usedSlots;
192 
193  for (uint32_t i = 0; i < min || i < myUsedSlots; i++) {
194 
195  if (i < min) {
196  new ((void*)&(newLoc[i])) TypeContained();
197  newLoc[i] = ((TypeContained*)(data))[i];
198  } else if (i < myUsedSlots) {
199  ((TypeContained*)(data))[i].~TypeContained();
200  // JiaNote: we need make usedSlots consistent in cases of exception
201  usedSlots--;
202  }
203  }
204 
205  // empty out this guy
206  return tempArray;
207 }
208 
209 template <class TypeContained>
210 TypeContained& Array<TypeContained>::getObj(uint32_t which) {
211  return ((TypeContained*)(data))[which];
212 }
213 
214 template <class TypeContained>
215 void Array<TypeContained>::assign(uint32_t which, const TypeContained& val) {
216  if (which > usedSlots) {
217  std::cerr << "Bad: you are writing past the end of the vector!\n";
218  return;
219  }
220  ((TypeContained*)(data))[which] = val;
221 }
222 
223 template <class TypeContained>
224 void Array<TypeContained>::push_back(const TypeContained& val) {
225  // need a placement new to correctly initialize before the copy
226  new ((void*)&(((TypeContained*)(data))[usedSlots])) TypeContained();
227  ((((TypeContained*)(data))[usedSlots])) = val;
228  usedSlots++;
229 }
230 
231 
232 template <class TypeContained>
234 
235  // need a placement new
236  new ((void*)&(((TypeContained*)(data))[usedSlots])) TypeContained();
237  usedSlots++;
238 }
239 
240 
241 template <class TypeContained>
242 TypeContained* Array<TypeContained>::c_ptr() {
243  return ((TypeContained*)(data));
244 }
245 
246 template <class TypeContained>
248  if (usedSlots != 0) {
249  ((TypeContained*)(data))[usedSlots - 1].~TypeContained();
250  usedSlots--;
251  }
252 }
253 
254 template <class TypeContained>
256  return usedSlots;
257 }
258 
259 template <class TypeContained>
260 void Array<TypeContained>::setUsed(uint32_t toMe) {
261  usedSlots = toMe;
262 }
263 
264 template <class TypeContained>
266  deleter(deleteMe, this);
267 }
268 
269 template <class TypeContained>
270 size_t Array<TypeContained>::getSize(void* forMe) {
271  if (((Array<TypeContained>*)forMe)->typeInfo.getTypeCode() == 0) {
272  std::cout << "Array::getSize: typeInfo = 0 before getSizeOfConstituent" << std::endl;
273  }
274  return sizeof(Array<TypeContained>) +
275  ((Array<TypeContained>*)forMe)->typeInfo.getSizeOfConstituentObject(forMe) *
276  ((Array<TypeContained>*)forMe)->numSlots;
277 }
278 }
279 
280 #endif
size_t getSizeOfConstituentObject(void *forMe) const
void push_back()
Definition: Array.cc:233
Handle< Array< TypeContained > > doubleSize()
Definition: Array.cc:128
PDBTemplateBase typeInfo
Definition: Array.h:68
void deleter(void *deleteMe, ObjType *dummy)
Definition: DeepCopy.h:48
uint32_t numSlots
Definition: Array.h:74
uint32_t numUsedSlots()
Definition: Array.cc:255
void setUpAndCopyFrom(void *target, void *source) const
Definition: Array.cc:41
TypeContained * c_ptr()
Definition: Array.cc:242
TypeContained & getObj(uint32_t which)
Definition: Array.cc:210
bool isFull()
Definition: Array.cc:133
int16_t getTypeCode() const
void setUpAndCopyFromConstituentObject(void *target, void *source) const
#define PDB_COUT
Definition: PDBDebug.h:31
Handle< Array< TypeContained > > resize(uint32_t howMany)
Definition: Array.cc:171
void assign(uint32_t which, const TypeContained &val)
Definition: Array.cc:215
~Array()
Definition: Array.cc:148
Nothing data[0]
Definition: Array.h:77
uint32_t usedSlots
Definition: Array.h:71
bool descendsFromObject() const
size_t getSize(void *forMe)
Definition: Array.cc:270
void setUsed(uint32_t toMe)
Definition: Array.cc:260
void deleteObject(void *deleteMe)
Definition: Array.cc:265
void pop_back()
Definition: Array.cc:247