PIDeque optimization
This commit is contained in:
@@ -38,17 +38,17 @@ public:
|
|||||||
}
|
}
|
||||||
inline PIDeque(const PIDeque<T> & other): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
inline PIDeque(const PIDeque<T> & other): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
||||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||||
alloc(other.pid_size, true);
|
alloc_forward(other.pid_size);
|
||||||
newT(pid_data + pid_start, other.pid_data + other.pid_start, pid_size);
|
newT(pid_data + pid_start, other.pid_data + other.pid_start, pid_size);
|
||||||
}
|
}
|
||||||
inline PIDeque(std::initializer_list<T> init_list): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
inline PIDeque(std::initializer_list<T> init_list): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
||||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||||
alloc(init_list.size(), true);
|
alloc_forward(init_list.size());
|
||||||
newT(pid_data, init_list.begin(), init_list.size());
|
newT(pid_data, init_list.begin(), init_list.size());
|
||||||
}
|
}
|
||||||
inline PIDeque(const T * data, size_t size): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
inline PIDeque(const T * data, size_t size): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
||||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||||
alloc(size, true);
|
alloc_forward(size);
|
||||||
newT(pid_data + pid_start, data, pid_size);
|
newT(pid_data + pid_start, data, pid_size);
|
||||||
}
|
}
|
||||||
inline PIDeque(size_t pid_size, const T & f = T()): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
inline PIDeque(size_t pid_size, const T & f = T()): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
||||||
@@ -74,7 +74,7 @@ public:
|
|||||||
inline PIDeque<T> & operator =(const PIDeque<T> & other) {
|
inline PIDeque<T> & operator =(const PIDeque<T> & other) {
|
||||||
if (this == &other) return *this;
|
if (this == &other) return *this;
|
||||||
deleteT(pid_data + pid_start, pid_size);
|
deleteT(pid_data + pid_start, pid_size);
|
||||||
alloc(other.pid_size, true);
|
alloc_forward(other.pid_size);
|
||||||
newT(pid_data + pid_start, other.pid_data + other.pid_start, pid_size);
|
newT(pid_data + pid_start, other.pid_data + other.pid_start, pid_size);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -458,7 +458,7 @@ public:
|
|||||||
}
|
}
|
||||||
if (new_size > pid_size) {
|
if (new_size > pid_size) {
|
||||||
size_t os = pid_size;
|
size_t os = pid_size;
|
||||||
alloc(new_size, true);
|
alloc_forward(new_size);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
||||||
for (size_t i = os + pid_start; i < new_size + pid_start; ++i) {
|
for (size_t i = os + pid_start; i < new_size + pid_start; ++i) {
|
||||||
elementNew(pid_data + i, f);
|
elementNew(pid_data + i, f);
|
||||||
@@ -476,7 +476,7 @@ public:
|
|||||||
}
|
}
|
||||||
if (new_size > pid_size) {
|
if (new_size > pid_size) {
|
||||||
size_t os = pid_size;
|
size_t os = pid_size;
|
||||||
alloc(new_size, true);
|
alloc_forward(new_size);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
||||||
for (size_t i = os + pid_start; i < new_size + pid_start; ++i) {
|
for (size_t i = os + pid_start; i < new_size + pid_start; ++i) {
|
||||||
elementNew(pid_data + i, f(i));
|
elementNew(pid_data + i, f(i));
|
||||||
@@ -495,14 +495,14 @@ public:
|
|||||||
if (new_size < pid_size) {
|
if (new_size < pid_size) {
|
||||||
PIINTROSPECTION_CONTAINER_UNUSED(T, (pid_size-new_size));
|
PIINTROSPECTION_CONTAINER_UNUSED(T, (pid_size-new_size));
|
||||||
}
|
}
|
||||||
alloc(new_size, true);
|
alloc_forward(new_size);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PIDeque<T> & reserve(size_t new_size) {
|
inline PIDeque<T> & reserve(size_t new_size) {
|
||||||
if (new_size <= pid_rsize) return *this;
|
if (new_size <= pid_rsize) return *this;
|
||||||
size_t os = pid_size;
|
size_t os = pid_size;
|
||||||
alloc(new_size, true);
|
alloc_forward(new_size);
|
||||||
pid_size = os;
|
pid_size = os;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -512,13 +512,13 @@ public:
|
|||||||
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
||||||
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
|
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
|
||||||
if (dir) {
|
if (dir) {
|
||||||
alloc(pid_size + 1, true);
|
alloc_forward(pid_size + 1);
|
||||||
if (index < pid_size - 1) {
|
if (index < pid_size - 1) {
|
||||||
size_t os = pid_size - index - 1;
|
size_t os = pid_size - index - 1;
|
||||||
memmove((void*)(&(pid_data[index + pid_start + 1])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T));
|
memmove((void*)(&(pid_data[index + pid_start + 1])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alloc(pid_size + 1, false, -1);
|
alloc_backward(pid_size + 1, -1);
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T));
|
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T));
|
||||||
}
|
}
|
||||||
@@ -531,13 +531,13 @@ public:
|
|||||||
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
||||||
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
|
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
|
||||||
if (dir) {
|
if (dir) {
|
||||||
alloc(pid_size + 1, true);
|
alloc_forward(pid_size + 1);
|
||||||
if (index < pid_size - 1) {
|
if (index < pid_size - 1) {
|
||||||
size_t os = pid_size - index - 1;
|
size_t os = pid_size - index - 1;
|
||||||
memmove((void*)(&(pid_data[index + pid_start + 1])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T));
|
memmove((void*)(&(pid_data[index + pid_start + 1])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alloc(pid_size + 1, false, -1);
|
alloc_backward(pid_size + 1, -1);
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T));
|
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T));
|
||||||
}
|
}
|
||||||
@@ -556,12 +556,12 @@ public:
|
|||||||
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
|
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
|
||||||
if (dir) {
|
if (dir) {
|
||||||
ssize_t os = pid_size - index;
|
ssize_t os = pid_size - index;
|
||||||
alloc(pid_size + other.pid_size, true);
|
alloc_forward(pid_size + other.pid_size);
|
||||||
if (os > 0) {
|
if (os > 0) {
|
||||||
memmove((void*)(&(pid_data[index + pid_start + other.pid_size])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T));
|
memmove((void*)(&(pid_data[index + pid_start + other.pid_size])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alloc(pid_size + other.pid_size, false, -other.pid_size);
|
alloc_backward(pid_size + other.pid_size, -other.pid_size);
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + other.pid_size])), index * sizeof(T));
|
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + other.pid_size])), index * sizeof(T));
|
||||||
}
|
}
|
||||||
@@ -634,6 +634,8 @@ public:
|
|||||||
//! bool comp(const T &a, const T &b);
|
//! bool comp(const T &a, const T &b);
|
||||||
//! \endcode
|
//! \endcode
|
||||||
//! While the signature does not need to have const &, the function must not modify the objects passed to it.
|
//! While the signature does not need to have const &, the function must not modify the objects passed to it.
|
||||||
|
//! The function must return `false` for identical elements,
|
||||||
|
//! otherwise, it will lead to undefined program behavior and memory errors.
|
||||||
//! Sorting provided by [std::sort](https://en.cppreference.com/w/cpp/algorithm/sort).
|
//! Sorting provided by [std::sort](https://en.cppreference.com/w/cpp/algorithm/sort).
|
||||||
//! Complexity `O(N·log(N))`.
|
//! Complexity `O(N·log(N))`.
|
||||||
//! \~russian Сохранность порядка элементов, имеющих одинаковое значение, не гарантируется.
|
//! \~russian Сохранность порядка элементов, имеющих одинаковое значение, не гарантируется.
|
||||||
@@ -644,6 +646,8 @@ public:
|
|||||||
//! bool comp(const T &a, const T &b);
|
//! bool comp(const T &a, const T &b);
|
||||||
//! \endcode
|
//! \endcode
|
||||||
//! Сигнатура не обязана содержать const &, однако, функция не может изменять переданные объекты.
|
//! Сигнатура не обязана содержать const &, однако, функция не может изменять переданные объекты.
|
||||||
|
//! Функция обязана возвращать `false` для одинаковых элементов,
|
||||||
|
//! иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||||
//! Для сортировки используется функция [std::sort](https://ru.cppreference.com/w/cpp/algorithm/sort).
|
//! Для сортировки используется функция [std::sort](https://ru.cppreference.com/w/cpp/algorithm/sort).
|
||||||
//! Сложность сортировки `O(N·log(N))`.
|
//! Сложность сортировки `O(N·log(N))`.
|
||||||
//! \~\code
|
//! \~\code
|
||||||
@@ -693,13 +697,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline PIDeque<T> & push_back(const T & e) {
|
inline PIDeque<T> & push_back(const T & e) {
|
||||||
alloc(pid_size + 1, true);
|
alloc_forward(pid_size + 1);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, 1);
|
PIINTROSPECTION_CONTAINER_USED(T, 1);
|
||||||
elementNew(pid_data + pid_start + pid_size - 1, e);
|
elementNew(pid_data + pid_start + pid_size - 1, e);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIDeque<T> & push_back(T && e) {
|
inline PIDeque<T> & push_back(T && e) {
|
||||||
alloc(pid_size + 1, true);
|
alloc_forward(pid_size + 1);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, 1);
|
PIINTROSPECTION_CONTAINER_USED(T, 1);
|
||||||
elementNew(pid_data + pid_start + pid_size - 1, std::move(e));
|
elementNew(pid_data + pid_start + pid_size - 1, std::move(e));
|
||||||
return *this;
|
return *this;
|
||||||
@@ -714,7 +718,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
assert(&v != this);
|
assert(&v != this);
|
||||||
size_t ps = pid_size;
|
size_t ps = pid_size;
|
||||||
alloc(pid_size + v.pid_size, true);
|
alloc_forward(pid_size + v.pid_size);
|
||||||
newT(pid_data + ps + pid_start, v.pid_data + v.pid_start, v.pid_size);
|
newT(pid_data + ps + pid_start, v.pid_data + v.pid_start, v.pid_size);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -904,7 +908,7 @@ private:
|
|||||||
if ((uchar*)pid_data != 0) free((uchar*)pid_data);
|
if ((uchar*)pid_data != 0) free((uchar*)pid_data);
|
||||||
pid_data = 0;
|
pid_data = 0;
|
||||||
}
|
}
|
||||||
inline void checkMove(bool direction) {
|
inline void checkMove() {
|
||||||
if (pid_size >= 4) {
|
if (pid_size >= 4) {
|
||||||
if (pid_size < pid_rsize / 6) {
|
if (pid_size < pid_rsize / 6) {
|
||||||
if (pid_start < ssize_t(pid_size + pid_size) || pid_start > (ssize_t(pid_rsize) - ssize_t(pid_size) - ssize_t(pid_size))) {
|
if (pid_start < ssize_t(pid_size + pid_size) || pid_start > (ssize_t(pid_rsize) - ssize_t(pid_size) - ssize_t(pid_size))) {
|
||||||
@@ -923,11 +927,10 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline void alloc(size_t new_size, bool direction, ssize_t start_offset = 0) { // direction == true -> alloc forward
|
inline void alloc_forward(size_t new_size) { // direction == true -> alloc forward
|
||||||
if (direction) {
|
|
||||||
if (pid_start + new_size <= pid_rsize) {
|
if (pid_start + new_size <= pid_rsize) {
|
||||||
pid_size = new_size;
|
pid_size = new_size;
|
||||||
checkMove(direction);
|
checkMove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pid_size = new_size;
|
pid_size = new_size;
|
||||||
@@ -944,7 +947,8 @@ private:
|
|||||||
pid_data = p_d;
|
pid_data = p_d;
|
||||||
pid_rsize = as;
|
pid_rsize = as;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
inline void alloc_backward(size_t new_size, ssize_t start_offset = 0) { //alloc backward
|
||||||
size_t as;
|
size_t as;
|
||||||
if (pid_start + start_offset < 0) {
|
if (pid_start + start_offset < 0) {
|
||||||
as = asize(pid_rsize - start_offset);
|
as = asize(pid_rsize - start_offset);
|
||||||
@@ -965,8 +969,7 @@ private:
|
|||||||
}
|
}
|
||||||
pid_start += start_offset;
|
pid_start += start_offset;
|
||||||
pid_size = new_size;
|
pid_size = new_size;
|
||||||
checkMove(direction);
|
checkMove();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
T * pid_data;
|
T * pid_data;
|
||||||
|
|||||||
@@ -1287,6 +1287,8 @@ public:
|
|||||||
//! bool comp(const T &a, const T &b);
|
//! bool comp(const T &a, const T &b);
|
||||||
//! \endcode
|
//! \endcode
|
||||||
//! While the signature does not need to have const &, the function must not modify the objects passed to it.
|
//! While the signature does not need to have const &, the function must not modify the objects passed to it.
|
||||||
|
//! The function must return `false` for identical elements,
|
||||||
|
//! otherwise, it will lead to undefined program behavior and memory errors.
|
||||||
//! Sorting provided by [std::sort](https://en.cppreference.com/w/cpp/algorithm/sort).
|
//! Sorting provided by [std::sort](https://en.cppreference.com/w/cpp/algorithm/sort).
|
||||||
//! Complexity `O(N·log(N))`.
|
//! Complexity `O(N·log(N))`.
|
||||||
//! \~russian Сохранность порядка элементов, имеющих одинаковое значение, не гарантируется.
|
//! \~russian Сохранность порядка элементов, имеющих одинаковое значение, не гарантируется.
|
||||||
@@ -1297,6 +1299,8 @@ public:
|
|||||||
//! bool comp(const T &a, const T &b);
|
//! bool comp(const T &a, const T &b);
|
||||||
//! \endcode
|
//! \endcode
|
||||||
//! Сигнатура не обязана содержать const &, однако, функция не может изменять переданные объекты.
|
//! Сигнатура не обязана содержать const &, однако, функция не может изменять переданные объекты.
|
||||||
|
//! Функция обязана возвращать `false` для одинаковых элементов,
|
||||||
|
//! иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||||
//! Для сортировки используется функция [std::sort](https://ru.cppreference.com/w/cpp/algorithm/sort).
|
//! Для сортировки используется функция [std::sort](https://ru.cppreference.com/w/cpp/algorithm/sort).
|
||||||
//! Сложность сортировки `O(N·log(N))`.
|
//! Сложность сортировки `O(N·log(N))`.
|
||||||
//! \~\code
|
//! \~\code
|
||||||
@@ -1795,6 +1799,18 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \brief
|
||||||
|
//! \~english Returns a new array with all elements
|
||||||
|
//! that pass the test implemented by the provided function `test`.
|
||||||
|
//! \~russian Возвращает новый массив со всеми элементами,
|
||||||
|
//! прошедшими проверку, задаваемую в передаваемой функции `test`.
|
||||||
|
//! \~\details
|
||||||
|
//! \~\code
|
||||||
|
//! PIVector<int> v{3, 2, 5, 2, 7};
|
||||||
|
//! PIVector<int> v2 = v.filter([](const int & i){return i > 2;});
|
||||||
|
//! piCout << v2; // {3, 5, 7}
|
||||||
|
//! \endcode
|
||||||
|
//! \~\sa \a take_front(), \a pop_back(), \a pop_front()
|
||||||
inline PIVector<T> filter(std::function<bool(const T & e)> test) const {
|
inline PIVector<T> filter(std::function<bool(const T & e)> test) const {
|
||||||
PIVector<T> ret;
|
PIVector<T> ret;
|
||||||
for (size_t i = 0; i < piv_size; ++i) {
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
|
|||||||
Reference in New Issue
Block a user