1 /*
2 Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #ifndef NDB_VECTOR_HPP
26 #define NDB_VECTOR_HPP
27
28 #include <ndb_global.h>
29 #include <portlib/NdbMutex.h>
30
31 template<class T>
32 class Vector {
33 public:
34 Vector(int sz = 10);
35 ~Vector();
36
37 T& operator[](unsigned i);
38 const T& operator[](unsigned i) const;
size() const39 unsigned size() const { return m_size; };
40
41 int push_back(const T &);
42 void push(const T&, unsigned pos);
43 T& set(T&, unsigned pos, T& fill_obj);
44 T& back();
45
46 void erase(unsigned index);
47
48 void clear();
49
50 int fill(unsigned new_size, T & obj);
51
52 Vector<T>& operator=(const Vector<T>&);
53
54 /** Does deep copy.*/
55 Vector(const Vector&);
56 /**
57 * Shallow equal (i.e does memcmp)
58 */
59 bool equal(const Vector<T>& obj) const;
60
61 int assign(const T*, unsigned cnt);
assign(const Vector<T> & obj)62 int assign(const Vector<T>& obj) { return assign(obj.getBase(), obj.size());}
63
getBase()64 T* getBase() { return m_items;}
getBase() const65 const T* getBase() const { return m_items;}
66 private:
67 T * m_items;
68 unsigned m_size;
69 unsigned m_incSize;
70 unsigned m_arraySize;
71 };
72
73 template<class T>
Vector(int i)74 Vector<T>::Vector(int i){
75 m_items = new T[i];
76 if (m_items == NULL)
77 {
78 errno = ENOMEM;
79 m_size = 0;
80 m_arraySize = 0;
81 m_incSize = 0;
82 return;
83 }
84 m_size = 0;
85 m_arraySize = i;
86 m_incSize = 50;
87 }
88
89 template<class T>
Vector(const Vector & src)90 Vector<T>::Vector(const Vector& src):
91 m_items(new T[src.m_size]),
92 m_size(src.m_size),
93 m_incSize(src.m_incSize),
94 m_arraySize(src.m_size)
95
96 {
97 if (unlikely(m_items == NULL)){
98 errno = ENOMEM;
99 m_size = 0;
100 m_arraySize = 0;
101 m_incSize = 0;
102 return;
103 }
104 for(unsigned i = 0; i < m_size; i++){
105 m_items[i] = src.m_items[i];
106 }
107 }
108
109 template<class T>
~Vector()110 Vector<T>::~Vector(){
111 delete[] m_items;
112 // safety for placement new usage
113 m_items = 0;
114 m_size = 0;
115 m_arraySize = 0;
116 }
117
118 template<class T>
119 T &
operator [](unsigned i)120 Vector<T>::operator[](unsigned i){
121 if(i >= m_size)
122 abort();
123 return m_items[i];
124 }
125
126 template<class T>
127 const T &
operator [](unsigned i) const128 Vector<T>::operator[](unsigned i) const {
129 if(i >= m_size)
130 abort();
131 return m_items[i];
132 }
133
134 template<class T>
135 T &
back()136 Vector<T>::back(){
137 return (* this)[m_size - 1];
138 }
139
140 template<class T>
141 int
push_back(const T & t)142 Vector<T>::push_back(const T & t){
143 if(m_size == m_arraySize){
144 T * tmp = new T [m_arraySize + m_incSize];
145 if(tmp == NULL)
146 {
147 errno = ENOMEM;
148 return -1;
149 }
150 for (unsigned k = 0; k < m_size; k++)
151 tmp[k] = m_items[k];
152 delete[] m_items;
153 m_items = tmp;
154 m_arraySize = m_arraySize + m_incSize;
155 }
156 m_items[m_size] = t;
157 m_size++;
158 return 0;
159 }
160
161 template<class T>
162 void
push(const T & t,unsigned pos)163 Vector<T>::push(const T & t, unsigned pos)
164 {
165 push_back(t);
166 if (pos < m_size - 1)
167 {
168 for(unsigned i = m_size - 1; i > pos; i--)
169 {
170 m_items[i] = m_items[i-1];
171 }
172 m_items[pos] = t;
173 }
174 }
175
176 template<class T>
177 T&
set(T & t,unsigned pos,T & fill_obj)178 Vector<T>::set(T & t, unsigned pos, T& fill_obj)
179 {
180 fill(pos, fill_obj);
181 T& ret = m_items[pos];
182 m_items[pos] = t;
183 return ret;
184 }
185
186 template<class T>
187 void
erase(unsigned i)188 Vector<T>::erase(unsigned i){
189 if(i >= m_size)
190 abort();
191
192 for (unsigned k = i; k + 1 < m_size; k++)
193 m_items[k] = m_items[k + 1];
194 m_size--;
195 }
196
197 template<class T>
198 void
clear()199 Vector<T>::clear(){
200 m_size = 0;
201 }
202
203 template<class T>
204 int
fill(unsigned new_size,T & obj)205 Vector<T>::fill(unsigned new_size, T & obj){
206 while(m_size <= new_size)
207 if (push_back(obj))
208 return -1;
209 return 0;
210 }
211
212 template<class T>
213 Vector<T>&
operator =(const Vector<T> & obj)214 Vector<T>::operator=(const Vector<T>& obj){
215 if(this != &obj){
216 clear();
217 for(unsigned i = 0; i<obj.size(); i++){
218 push_back(obj[i]);
219 }
220 }
221 return * this;
222 }
223
224 template<class T>
225 int
assign(const T * src,unsigned cnt)226 Vector<T>::assign(const T* src, unsigned cnt)
227 {
228 clear();
229 for (unsigned i = 0; i<cnt; i++)
230 {
231 int ret;
232 if ((ret = push_back(src[i])))
233 return ret;
234 }
235 return 0;
236 }
237
238 template<class T>
239 bool
equal(const Vector<T> & obj) const240 Vector<T>::equal(const Vector<T>& obj) const
241 {
242 if (size() != obj.size())
243 return false;
244
245 return memcmp(getBase(), obj.getBase(), size() * sizeof(T)) == 0;
246 }
247
248 template<class T>
249 class MutexVector : public NdbLockable {
250 public:
251 MutexVector(int sz = 10);
252 ~MutexVector();
253
254 T& operator[](unsigned i);
255 const T& operator[](unsigned i) const;
size() const256 unsigned size() const { return m_size; };
257
258 int push_back(const T &);
259 int push_back(const T &, bool lockMutex);
260 T& back();
261
262 void erase(unsigned index);
263 void erase(unsigned index, bool lockMutex);
264
265 void clear();
266 void clear(bool lockMutex);
267
268 int fill(unsigned new_size, T & obj);
269 private:
270 T * m_items;
271 unsigned m_size;
272 unsigned m_incSize;
273 unsigned m_arraySize;
274 };
275
276 template<class T>
MutexVector(int i)277 MutexVector<T>::MutexVector(int i){
278 m_items = new T[i];
279 if (m_items == NULL)
280 {
281 errno = ENOMEM;
282 m_size = 0;
283 m_arraySize = 0;
284 m_incSize = 0;
285 return;
286 }
287 m_size = 0;
288 m_arraySize = i;
289 m_incSize = 50;
290 }
291
292 template<class T>
~MutexVector()293 MutexVector<T>::~MutexVector(){
294 delete[] m_items;
295 // safety for placement new usage
296 m_items = 0;
297 m_size = 0;
298 m_arraySize = 0;
299 }
300
301 template<class T>
302 T &
operator [](unsigned i)303 MutexVector<T>::operator[](unsigned i){
304 if(i >= m_size)
305 abort();
306 return m_items[i];
307 }
308
309 template<class T>
310 const T &
operator [](unsigned i) const311 MutexVector<T>::operator[](unsigned i) const {
312 if(i >= m_size)
313 abort();
314 return m_items[i];
315 }
316
317 template<class T>
318 T &
back()319 MutexVector<T>::back(){
320 return (* this)[m_size - 1];
321 }
322
323 template<class T>
324 int
push_back(const T & t)325 MutexVector<T>::push_back(const T & t){
326 lock();
327 if(m_size == m_arraySize){
328 T * tmp = new T [m_arraySize + m_incSize];
329 if (tmp == NULL)
330 {
331 errno = ENOMEM;
332 unlock();
333 return -1;
334 }
335 for (unsigned k = 0; k < m_size; k++)
336 tmp[k] = m_items[k];
337 delete[] m_items;
338 m_items = tmp;
339 m_arraySize = m_arraySize + m_incSize;
340 }
341 m_items[m_size] = t;
342 m_size++;
343 unlock();
344 return 0;
345 }
346
347 template<class T>
348 int
push_back(const T & t,bool lockMutex)349 MutexVector<T>::push_back(const T & t, bool lockMutex){
350 if(lockMutex)
351 lock();
352 if(m_size == m_arraySize){
353 T * tmp = new T [m_arraySize + m_incSize];
354 if (tmp == NULL)
355 {
356 errno = ENOMEM;
357 if(lockMutex)
358 unlock();
359 return -1;
360 }
361 for (unsigned k = 0; k < m_size; k++)
362 tmp[k] = m_items[k];
363 delete[] m_items;
364 m_items = tmp;
365 m_arraySize = m_arraySize + m_incSize;
366 }
367 m_items[m_size] = t;
368 m_size++;
369 if(lockMutex)
370 unlock();
371 return 0;
372 }
373
374 template<class T>
375 void
erase(unsigned i)376 MutexVector<T>::erase(unsigned i){
377 if(i >= m_size)
378 abort();
379
380 lock();
381 for (unsigned k = i; k + 1 < m_size; k++)
382 m_items[k] = m_items[k + 1];
383 m_size--;
384 unlock();
385 }
386
387 template<class T>
388 void
erase(unsigned i,bool _lock)389 MutexVector<T>::erase(unsigned i, bool _lock){
390 if(i >= m_size)
391 abort();
392
393 if(_lock)
394 lock();
395 for (unsigned k = i; k + 1 < m_size; k++)
396 m_items[k] = m_items[k + 1];
397 m_size--;
398 if(_lock)
399 unlock();
400 }
401
402 template<class T>
403 void
clear()404 MutexVector<T>::clear(){
405 lock();
406 m_size = 0;
407 unlock();
408 }
409
410 template<class T>
411 void
clear(bool l)412 MutexVector<T>::clear(bool l){
413 if(l) lock();
414 m_size = 0;
415 if(l) unlock();
416 }
417
418 template<class T>
419 int
fill(unsigned new_size,T & obj)420 MutexVector<T>::fill(unsigned new_size, T & obj){
421 while(m_size <= new_size)
422 if (push_back(obj))
423 return -1;
424 return 0;
425 }
426
427 #endif
428