/* * Copyright (c) 2020 Huawei Technologies Co.,Ltd. * * openGauss is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: * * http://license.coscl.org.cn/MulanPSL2 * * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. * --------------------------------------------------------------------------------------- * * dfs_vector.h * * * * IDENTIFICATION * src/include/utils/dfs_vector.h * * --------------------------------------------------------------------------------------- */ #ifndef VECTOR_H_ #define VECTOR_H_ #include "postgres.h" #include "securec.h" #include "securec_check.h" #include /* stands for non-int type */ struct __type_true {}; /* stands for int type */ struct __type_false {}; template struct _type_traits { typedef __type_false is_POD_type; }; template <> struct _type_traits { typedef __type_true is_POD_type; }; /* * Afford the dynamic array function. */ template class Vector { public: typedef T value_type; typedef value_type* iterator; typedef typename _type_traits::is_POD_type is_POD; /* Return the start iterator. */ iterator begin() { if (currentSize == 0) { return 0; } return iterator(vectorHead); } /* Return the last iterator. */ iterator end() { return iterator(vectorHead + currentSize); } /* constructor */ Vector(int n = 0) : currentSize(n), currentCapacity(n > VECTOR_INIT_SIZE ? n : VECTOR_INIT_SIZE) { vectorHead = allocateMemory(is_POD()); } /* constructor */ Vector(int n, T val) : currentSize(n), currentCapacity(n > VECTOR_INIT_SIZE ? n : VECTOR_INIT_SIZE) { vectorHead = allocateMemory(is_POD()); for (int i = 0; i < n; i++) vectorHead[i] = val; } /* constructor */ Vector(const Vector& b) : currentSize(b.currentSize), currentCapacity(b.currentCapacity) { errno_t rc = EOK; vectorHead = allocateMemory(is_POD()); if (NULL == vectorHead) { elog(ERROR, "memory alloc failed!\n"); } rc = memcpy_s(vectorHead, currentCapacity * sizeof(T), b.vectorHead, currentSize * sizeof(T)); securec_check(rc, "\0", "\0"); } ~Vector() { freeVectorHead(is_POD()); } /* Add a element into the vector. */ void push_back(T val) { /* Current capacity is enough. */ if (currentSize < currentCapacity) { vectorHead[currentSize++] = val; } /* Enlarge the capacity of vector. */ else { currentCapacity = currentCapacity + CAPICITY_INCREASE_STEP; T* newAllocated = allocateMemory(is_POD()); errno_t rc = EOK; rc = memcpy_s(newAllocated, currentCapacity * sizeof(T), vectorHead, currentSize * sizeof(T)); securec_check(rc, "\0", "\0"); newAllocated[currentSize++] = val; freeVectorHead(is_POD()); vectorHead = newAllocated; } } /* Pop off a element from the tail. */ void pop_back() { if (currentSize) currentSize--; } /* Return the first one. */ const T& front() const { return vectorHead[0]; } /* Return the last one. */ const T& back() const { return vectorHead[currentSize - 1]; } /* Implement the array visit operator. */ const T& operator[](int i) const { return vectorHead[i]; } /* Implement the array visit operator. */ T& operator[](int i) { return vectorHead[i]; } /* Return the size of the current vector. */ int size() { return currentSize; } /* Return the size of the current vector. */ int size() const { return currentSize; } /* Resize the current vector and fill it with the special value. */ void resize(uint32 new_size, T x) { /* Current capacity is enough. */ if (new_size < currentCapacity) { if (currentSize < new_size) { for (uint32 i = currentSize; i < new_size; i++) { vectorHead[i] = x; } } currentSize = new_size; } /* Need to enlarge the capacity. */ else { currentCapacity = new_size; T* newAllocated = allocateMemory(is_POD()); if (NULL == newAllocated) { elog(ERROR, "memory alloc failed!\n"); } errno_t rc = EOK; rc = memcpy_s(newAllocated, currentCapacity * sizeof(T), vectorHead, currentSize * sizeof(T)); securec_check(rc, "\0", "\0"); for (uint32 i = currentSize; i < currentCapacity; i++) { newAllocated[i] = x; } freeVectorHead(is_POD()); vectorHead = newAllocated; currentSize = new_size; } } /* Resize the current vector and fill it with NULL. */ void resize(int new_size) { resize(new_size, (T)0); } /* Return the capacity of the current vector. */ int capacity() { return currentCapacity; } /* Implement the equal check operator. */ bool operator==(const Vector& b) const { for (int i = 0; i < std::min(currentSize, b.currentSize); i++) { if (!(vectorHead[i] == b.vectorHead[i])) return false; } return currentSize == b.currentSize; } /* Implement the non-equal check operator. */ bool operator!=(const Vector& b) const { return !(*this == b); } /* Clear the dynamic arrays. */ void clear() { errno_t errNo = EOK; errNo = ::memset_s(vectorHead, sizeof(T) * currentCapacity, 0, sizeof(T) * currentCapacity); if (EOK != errNo) { elog(ERROR, "Initialize memory failed."); } currentSize = 0; } /* Erase the element on the special position. */ iterator erase(iterator postion) { if (postion < iterator(vectorHead)) { return vectorHead; } if (postion >= iterator(vectorHead + currentSize)) { return vectorHead + currentSize; } T* succeedor = postion + 1; errno_t errNo = EOK; errNo = ::memmove_s(postion, end() - succeedor, succeedor, end() - succeedor); if (EOK != errNo) { elog(ERROR, "Initialize memory failed."); } currentSize--; return succeedor; } private: T* allocateMemory(__type_false) { if (currentCapacity == 0) { return 0; } T* newAllocated = new T[currentCapacity]; return newAllocated; } T* allocateMemory(__type_true) { if (currentCapacity == 0) { return 0; } T* newAllocated = (T*)palloc(currentCapacity * sizeof(T)); return newAllocated; } void freeVectorHead(__type_false) { delete[] vectorHead; vectorHead = NULL; } void freeVectorHead(__type_true) { pfree(vectorHead); } private: enum { VECTOR_INIT_SIZE = 25 }; enum { CAPICITY_INCREASE_STEP = 15 }; uint32 currentSize; // size uint32 currentCapacity; // capacity T* vectorHead; // value array }; #endif /* VECTOR_H_ */