LibUDB
1.0.1
Toggle main menu visibility
Loading...
Searching...
No Matches
Algorithm.h
1
/*
2
* Copyright (C) 2026 Yury Bobylev <bobilev_yury@mail.ru>
3
*
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License as published by the Free
6
* Software Foundation, version 3.
7
*
8
* This program is distributed in the hope that it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11
* more details.
12
*
13
* You should have received a copy of the GNU General Public License along with
14
* this program. If not, see <https://www.gnu.org/licenses/>.
15
*/
16
#ifndef ALGORITHM_H
17
#define ALGORITHM_H
18
19
#include <algorithm>
20
#include <omp.h>
21
#include <vector>
22
28
class
Algorithm
29
{
30
public
:
31
Algorithm();
32
45
template
<
class
InputIt,
46
class
T =
typename
std::iterator_traits<InputIt>::value_type>
47
static
InputIt
48
parallelFind
(InputIt start, InputIt end,
const
T &val)
49
{
50
InputIt result = end;
51
#pragma omp parallel
52
#pragma omp for
53
for
(InputIt i = start; i < end; i++)
54
{
55
if
(*i == val)
56
{
57
#pragma omp critical
58
{
59
if
(i < result)
60
{
61
result = i;
62
}
63
}
64
#pragma omp cancel for
65
}
66
}
67
68
return
result;
69
}
70
83
template
<
class
InputIt,
class
UnaryPred>
84
static
InputIt
85
parallelFindIf
(InputIt start, InputIt end, UnaryPred predicate)
86
{
87
InputIt res = end;
88
#pragma omp parallel
89
#pragma omp for
90
for
(InputIt i = start; i < end; i++)
91
{
92
if
(predicate(*i))
93
{
94
#pragma omp critical
95
{
96
if
(i < res)
97
{
98
res = i;
99
}
100
}
101
#pragma omp cancel for
102
}
103
}
104
105
return
res;
106
}
107
118
template
<
class
InputIt,
class
UnaryPred>
119
static
void
120
parallelSort
(InputIt start, InputIt end, UnaryPred predicate)
121
{
122
if
(end - start < 1)
123
{
124
return
void();
125
}
126
std::vector<std::tuple<InputIt, InputIt>> parts;
127
parts.push_back(std::make_tuple(start, end));
128
129
omp_lock_t mtx;
130
omp_init_lock(&mtx);
131
132
while
(parts.size() > 0)
133
{
134
std::vector<std::tuple<InputIt, InputIt>> l_parts;
135
#pragma omp parallel
136
#pragma omp masked
137
{
138
for
(
auto
it = parts.begin(); it != parts.end(); it++)
139
{
140
#pragma omp task
141
{
142
InputIt i = std::get<0>(*it);
143
InputIt end = std::get<1>(*it);
144
std::ptrdiff_t diff = end - i;
145
while
(diff > 1)
146
{
147
if
(predicate(*i, *(end - 1)))
148
{
149
i++;
150
}
151
else
152
{
153
if
(diff > 2)
154
{
155
std::swap(*(end - 1), *(end - 2));
156
}
157
std::swap(*i, *(end - 1));
158
end--;
159
}
160
diff = end - i;
161
}
162
if
(end - 1 - std::get<0>(*it) > 1)
163
{
164
omp_set_lock(&mtx);
165
l_parts.push_back(
166
std::make_tuple(std::get<0>(*it), end - 1));
167
omp_unset_lock(&mtx);
168
}
169
if
(std::get<1>(*it) - end > 1)
170
{
171
omp_set_lock(&mtx);
172
l_parts.push_back(std::make_tuple(end, std::get<1>(*it)));
173
omp_unset_lock(&mtx);
174
}
175
}
176
}
177
}
178
parts = std::move(l_parts);
179
}
180
181
omp_destroy_lock(&mtx);
182
}
183
196
template
<
class
InputIt,
197
class
T =
typename
std::iterator_traits<InputIt>::value_type>
198
static
InputIt
199
parallelRemove
(InputIt start, InputIt end,
const
T &val)
200
{
201
#ifndef OMP_REMOVING
202
return
std::remove(start, end, val);
203
#else
204
start =
parallelFind
(start, end, val);
205
if
(start < end)
206
{
207
T *s = start.base();
208
T *e = end.base();
209
#pragma omp parallel
210
#pragma omp for ordered
211
for
(T *i = s + 1; i != e; i++)
212
{
213
if
((*i) != val)
214
{
215
#pragma omp ordered
216
{
217
*s = std::move((*i));
218
s++;
219
}
220
}
221
}
222
start += s - start.base();
223
}
224
return
start;
225
#endif
226
}
227
240
template
<
class
InputIt,
class
UnaryPred,
241
class
T =
typename
std::iterator_traits<InputIt>::value_type>
242
static
InputIt
243
parallelRemoveIf
(InputIt start, InputIt end, UnaryPred predicate)
244
{
245
#ifndef OMP_REMOVING
246
return
std::remove_if(start, end, predicate);
247
#else
248
start =
parallelFindIf
(start, end, predicate);
249
if
(start < end)
250
{
251
T *s = start.base();
252
T *e = end.base();
253
#pragma omp parallel
254
#pragma omp for ordered
255
for
(T *i = s + 1; i != e; i++)
256
{
257
if
(!predicate(*i))
258
{
259
#pragma omp ordered
260
{
261
*s = std::move(*i);
262
s++;
263
}
264
}
265
}
266
start += s - start.base();
267
}
268
return
start;
269
#endif
270
}
271
};
272
273
#endif
// ALGORITHM_H
Algorithm::parallelFind
static InputIt parallelFind(InputIt start, InputIt end, const T &val)
Definition
Algorithm.h:48
Algorithm::parallelRemoveIf
static InputIt parallelRemoveIf(InputIt start, InputIt end, UnaryPred predicate)
Definition
Algorithm.h:243
Algorithm::parallelFindIf
static InputIt parallelFindIf(InputIt start, InputIt end, UnaryPred predicate)
Definition
Algorithm.h:85
Algorithm::parallelRemove
static InputIt parallelRemove(InputIt start, InputIt end, const T &val)
Definition
Algorithm.h:199
Algorithm::parallelSort
static void parallelSort(InputIt start, InputIt end, UnaryPred predicate)
Definition
Algorithm.h:120
Algorithm.h
Generated by
1.17.0