catboost 1.25.1 → 1.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/DEPLOYMENT.md +22 -15
  2. package/README.md +37 -27
  3. package/binding.gyp +5 -7
  4. package/build_scripts/bootstrap.js +2 -1
  5. package/build_scripts/out/build.js +46 -68
  6. package/build_scripts/out/build_model.js +1 -1
  7. package/build_scripts/out/{build_ya.js → build_native.js} +1 -1
  8. package/build_scripts/out/ci.js +5 -5
  9. package/build_scripts/out/config.js +32 -18
  10. package/build_scripts/out/install.js +5 -3
  11. package/build_scripts/out/package_prepublish.js +1 -1
  12. package/build_scripts/out/packaging.js +1 -19
  13. package/build_scripts/out/run_tests.js +1 -1
  14. package/build_scripts/out/test.js +8 -3
  15. package/config.json +18 -11
  16. package/inc/catboost/libs/model_interface/c_api.h +349 -3
  17. package/lib/catboost.d.ts +65 -21
  18. package/package.json +4 -4
  19. package/src/api_helpers.cpp +100 -24
  20. package/src/api_helpers.h +8 -7
  21. package/src/api_module.cpp +1 -2
  22. package/src/model.cpp +483 -83
  23. package/src/model.h +24 -9
  24. package/inc/contrib/libs/cxxsupp/system_stl/include/stlfwd +0 -14
  25. package/inc/util/charset/recode_result.h +0 -9
  26. package/inc/util/charset/unicode_table.h +0 -123
  27. package/inc/util/charset/unidata.h +0 -421
  28. package/inc/util/charset/utf8.h +0 -384
  29. package/inc/util/charset/wide.h +0 -843
  30. package/inc/util/charset/wide_specific.h +0 -22
  31. package/inc/util/datetime/base.h +0 -669
  32. package/inc/util/datetime/constants.h +0 -7
  33. package/inc/util/datetime/cputimer.h +0 -124
  34. package/inc/util/datetime/parser.h +0 -292
  35. package/inc/util/datetime/systime.h +0 -47
  36. package/inc/util/datetime/uptime.h +0 -8
  37. package/inc/util/digest/city.h +0 -88
  38. package/inc/util/digest/fnv.h +0 -73
  39. package/inc/util/digest/multi.h +0 -14
  40. package/inc/util/digest/murmur.h +0 -57
  41. package/inc/util/digest/numeric.h +0 -86
  42. package/inc/util/digest/sequence.h +0 -48
  43. package/inc/util/draft/date.h +0 -129
  44. package/inc/util/draft/datetime.h +0 -184
  45. package/inc/util/draft/enum.h +0 -136
  46. package/inc/util/draft/holder_vector.h +0 -102
  47. package/inc/util/draft/ip.h +0 -131
  48. package/inc/util/draft/matrix.h +0 -108
  49. package/inc/util/draft/memory.h +0 -40
  50. package/inc/util/folder/dirent_win.h +0 -46
  51. package/inc/util/folder/dirut.h +0 -121
  52. package/inc/util/folder/filelist.h +0 -81
  53. package/inc/util/folder/fts.h +0 -108
  54. package/inc/util/folder/iterator.h +0 -109
  55. package/inc/util/folder/lstat_win.h +0 -20
  56. package/inc/util/folder/path.h +0 -225
  57. package/inc/util/folder/pathsplit.h +0 -113
  58. package/inc/util/folder/tempdir.h +0 -42
  59. package/inc/util/generic/adaptor.h +0 -134
  60. package/inc/util/generic/algorithm.h +0 -765
  61. package/inc/util/generic/array_ref.h +0 -282
  62. package/inc/util/generic/array_size.h +0 -24
  63. package/inc/util/generic/benchmark/vector_count_ctor/f.h +0 -9
  64. package/inc/util/generic/bitmap.h +0 -1115
  65. package/inc/util/generic/bitops.h +0 -459
  66. package/inc/util/generic/bt_exception.h +0 -24
  67. package/inc/util/generic/buffer.h +0 -232
  68. package/inc/util/generic/cast.h +0 -176
  69. package/inc/util/generic/deque.h +0 -24
  70. package/inc/util/generic/explicit_type.h +0 -42
  71. package/inc/util/generic/fastqueue.h +0 -55
  72. package/inc/util/generic/flags.h +0 -244
  73. package/inc/util/generic/function.h +0 -103
  74. package/inc/util/generic/fwd.h +0 -171
  75. package/inc/util/generic/guid.h +0 -61
  76. package/inc/util/generic/hash.h +0 -2032
  77. package/inc/util/generic/hash_primes.h +0 -140
  78. package/inc/util/generic/hash_set.h +0 -490
  79. package/inc/util/generic/hide_ptr.h +0 -3
  80. package/inc/util/generic/intrlist.h +0 -876
  81. package/inc/util/generic/is_in.h +0 -53
  82. package/inc/util/generic/iterator.h +0 -137
  83. package/inc/util/generic/iterator_range.h +0 -105
  84. package/inc/util/generic/lazy_value.h +0 -66
  85. package/inc/util/generic/list.h +0 -22
  86. package/inc/util/generic/map.h +0 -44
  87. package/inc/util/generic/mapfindptr.h +0 -60
  88. package/inc/util/generic/maybe.h +0 -713
  89. package/inc/util/generic/maybe_traits.h +0 -164
  90. package/inc/util/generic/mem_copy.h +0 -55
  91. package/inc/util/generic/noncopyable.h +0 -38
  92. package/inc/util/generic/object_counter.h +0 -53
  93. package/inc/util/generic/ptr.h +0 -1113
  94. package/inc/util/generic/queue.h +0 -57
  95. package/inc/util/generic/refcount.h +0 -162
  96. package/inc/util/generic/reserve.h +0 -11
  97. package/inc/util/generic/scope.h +0 -65
  98. package/inc/util/generic/serialized_enum.h +0 -406
  99. package/inc/util/generic/set.h +0 -42
  100. package/inc/util/generic/singleton.h +0 -136
  101. package/inc/util/generic/size_literals.h +0 -65
  102. package/inc/util/generic/stack.h +0 -18
  103. package/inc/util/generic/store_policy.h +0 -120
  104. package/inc/util/generic/strbase.h +0 -612
  105. package/inc/util/generic/strbuf.h +0 -552
  106. package/inc/util/generic/strfcpy.h +0 -17
  107. package/inc/util/generic/string.h +0 -1572
  108. package/inc/util/generic/string_hash.h +0 -21
  109. package/inc/util/generic/string_ut.h +0 -1175
  110. package/inc/util/generic/type_name.h +0 -34
  111. package/inc/util/generic/typelist.h +0 -114
  112. package/inc/util/generic/typetraits.h +0 -325
  113. package/inc/util/generic/utility.h +0 -132
  114. package/inc/util/generic/va_args.h +0 -400
  115. package/inc/util/generic/variant.h +0 -631
  116. package/inc/util/generic/variant_traits.h +0 -171
  117. package/inc/util/generic/vector.h +0 -119
  118. package/inc/util/generic/xrange.h +0 -258
  119. package/inc/util/generic/yexception.h +0 -212
  120. package/inc/util/generic/yexception_ut.h +0 -14
  121. package/inc/util/generic/ylimits.h +0 -92
  122. package/inc/util/generic/ymath.h +0 -206
  123. package/inc/util/memory/addstorage.h +0 -93
  124. package/inc/util/memory/alloc.h +0 -27
  125. package/inc/util/memory/blob.h +0 -296
  126. package/inc/util/memory/mmapalloc.h +0 -8
  127. package/inc/util/memory/pool.h +0 -432
  128. package/inc/util/memory/segmented_string_pool.h +0 -194
  129. package/inc/util/memory/segpool_alloc.h +0 -118
  130. package/inc/util/memory/smallobj.h +0 -141
  131. package/inc/util/memory/tempbuf.h +0 -111
  132. package/inc/util/network/address.h +0 -136
  133. package/inc/util/network/endpoint.h +0 -61
  134. package/inc/util/network/hostip.h +0 -16
  135. package/inc/util/network/init.h +0 -60
  136. package/inc/util/network/interface.h +0 -17
  137. package/inc/util/network/iovec.h +0 -65
  138. package/inc/util/network/ip.h +0 -116
  139. package/inc/util/network/nonblock.h +0 -8
  140. package/inc/util/network/pair.h +0 -9
  141. package/inc/util/network/poller.h +0 -58
  142. package/inc/util/network/pollerimpl.h +0 -707
  143. package/inc/util/network/sock.h +0 -608
  144. package/inc/util/network/socket.h +0 -421
  145. package/inc/util/random/common_ops.h +0 -130
  146. package/inc/util/random/easy.h +0 -47
  147. package/inc/util/random/entropy.h +0 -21
  148. package/inc/util/random/fast.h +0 -101
  149. package/inc/util/random/init_atfork.h +0 -3
  150. package/inc/util/random/lcg_engine.h +0 -66
  151. package/inc/util/random/mersenne.h +0 -46
  152. package/inc/util/random/mersenne32.h +0 -50
  153. package/inc/util/random/mersenne64.h +0 -50
  154. package/inc/util/random/normal.h +0 -38
  155. package/inc/util/random/random.h +0 -30
  156. package/inc/util/random/shuffle.h +0 -39
  157. package/inc/util/str_stl.h +0 -266
  158. package/inc/util/stream/aligned.h +0 -99
  159. package/inc/util/stream/buffer.h +0 -119
  160. package/inc/util/stream/buffered.h +0 -225
  161. package/inc/util/stream/debug.h +0 -53
  162. package/inc/util/stream/direct_io.h +0 -43
  163. package/inc/util/stream/file.h +0 -108
  164. package/inc/util/stream/format.h +0 -444
  165. package/inc/util/stream/fwd.h +0 -100
  166. package/inc/util/stream/hex.h +0 -8
  167. package/inc/util/stream/holder.h +0 -44
  168. package/inc/util/stream/input.h +0 -273
  169. package/inc/util/stream/labeled.h +0 -19
  170. package/inc/util/stream/length.h +0 -100
  171. package/inc/util/stream/mem.h +0 -255
  172. package/inc/util/stream/multi.h +0 -32
  173. package/inc/util/stream/null.h +0 -61
  174. package/inc/util/stream/output.h +0 -304
  175. package/inc/util/stream/pipe.h +0 -112
  176. package/inc/util/stream/printf.h +0 -25
  177. package/inc/util/stream/str.h +0 -207
  178. package/inc/util/stream/tee.h +0 -28
  179. package/inc/util/stream/tempbuf.h +0 -21
  180. package/inc/util/stream/tokenizer.h +0 -214
  181. package/inc/util/stream/trace.h +0 -60
  182. package/inc/util/stream/walk.h +0 -35
  183. package/inc/util/stream/zerocopy.h +0 -91
  184. package/inc/util/stream/zerocopy_output.h +0 -57
  185. package/inc/util/stream/zlib.h +0 -173
  186. package/inc/util/string/ascii.h +0 -236
  187. package/inc/util/string/builder.h +0 -39
  188. package/inc/util/string/cast.h +0 -347
  189. package/inc/util/string/cstriter.h +0 -14
  190. package/inc/util/string/escape.h +0 -70
  191. package/inc/util/string/hex.h +0 -59
  192. package/inc/util/string/join.h +0 -194
  193. package/inc/util/string/printf.h +0 -13
  194. package/inc/util/string/reverse.h +0 -16
  195. package/inc/util/string/split.h +0 -1080
  196. package/inc/util/string/strip.h +0 -257
  197. package/inc/util/string/strspn.h +0 -65
  198. package/inc/util/string/subst.h +0 -56
  199. package/inc/util/string/type.h +0 -50
  200. package/inc/util/string/util.h +0 -195
  201. package/inc/util/string/vector.h +0 -132
  202. package/inc/util/system/align.h +0 -50
  203. package/inc/util/system/atexit.h +0 -22
  204. package/inc/util/system/atomic.h +0 -51
  205. package/inc/util/system/atomic_gcc.h +0 -90
  206. package/inc/util/system/atomic_ops.h +0 -189
  207. package/inc/util/system/atomic_win.h +0 -114
  208. package/inc/util/system/backtrace.h +0 -39
  209. package/inc/util/system/byteorder.h +0 -186
  210. package/inc/util/system/compat.h +0 -84
  211. package/inc/util/system/compiler.h +0 -620
  212. package/inc/util/system/condvar.h +0 -71
  213. package/inc/util/system/context.h +0 -181
  214. package/inc/util/system/context_aarch64.h +0 -8
  215. package/inc/util/system/context_i686.h +0 -9
  216. package/inc/util/system/context_x86.h +0 -12
  217. package/inc/util/system/context_x86_64.h +0 -7
  218. package/inc/util/system/cpu_id.h +0 -159
  219. package/inc/util/system/daemon.h +0 -28
  220. package/inc/util/system/datetime.h +0 -98
  221. package/inc/util/system/defaults.h +0 -149
  222. package/inc/util/system/demangle.h +0 -5
  223. package/inc/util/system/demangle_impl.h +0 -23
  224. package/inc/util/system/direct_io.h +0 -71
  225. package/inc/util/system/dynlib.h +0 -119
  226. package/inc/util/system/env.h +0 -32
  227. package/inc/util/system/error.h +0 -95
  228. package/inc/util/system/event.h +0 -122
  229. package/inc/util/system/execpath.h +0 -17
  230. package/inc/util/system/fasttime.h +0 -6
  231. package/inc/util/system/fhandle.h +0 -27
  232. package/inc/util/system/file.h +0 -210
  233. package/inc/util/system/file_lock.h +0 -34
  234. package/inc/util/system/filemap.h +0 -383
  235. package/inc/util/system/flock.h +0 -35
  236. package/inc/util/system/fs.h +0 -156
  237. package/inc/util/system/fs_win.h +0 -29
  238. package/inc/util/system/fstat.h +0 -46
  239. package/inc/util/system/getpid.h +0 -12
  240. package/inc/util/system/guard.h +0 -179
  241. package/inc/util/system/hi_lo.h +0 -139
  242. package/inc/util/system/hostname.h +0 -10
  243. package/inc/util/system/hp_timer.h +0 -36
  244. package/inc/util/system/info.h +0 -12
  245. package/inc/util/system/interrupt_signals.h +0 -22
  246. package/inc/util/system/madvise.h +0 -30
  247. package/inc/util/system/maxlen.h +0 -32
  248. package/inc/util/system/mem_info.h +0 -18
  249. package/inc/util/system/mincore.h +0 -38
  250. package/inc/util/system/mktemp.h +0 -11
  251. package/inc/util/system/mlock.h +0 -43
  252. package/inc/util/system/mutex.h +0 -67
  253. package/inc/util/system/nice.h +0 -3
  254. package/inc/util/system/pipe.h +0 -90
  255. package/inc/util/system/platform.h +0 -246
  256. package/inc/util/system/progname.h +0 -13
  257. package/inc/util/system/protect.h +0 -25
  258. package/inc/util/system/rusage.h +0 -26
  259. package/inc/util/system/rwlock.h +0 -78
  260. package/inc/util/system/sanitizers.h +0 -122
  261. package/inc/util/system/sem.h +0 -41
  262. package/inc/util/system/shellcommand.h +0 -472
  263. package/inc/util/system/shmat.h +0 -32
  264. package/inc/util/system/sigset.h +0 -78
  265. package/inc/util/system/spin_wait.h +0 -10
  266. package/inc/util/system/spinlock.h +0 -121
  267. package/inc/util/system/src_location.h +0 -25
  268. package/inc/util/system/src_root.h +0 -68
  269. package/inc/util/system/sys_alloc.h +0 -43
  270. package/inc/util/system/sysstat.h +0 -52
  271. package/inc/util/system/tempfile.h +0 -34
  272. package/inc/util/system/thread.h +0 -167
  273. package/inc/util/system/tls.h +0 -307
  274. package/inc/util/system/types.h +0 -119
  275. package/inc/util/system/unaligned_mem.h +0 -67
  276. package/inc/util/system/user.h +0 -5
  277. package/inc/util/system/utime.h +0 -6
  278. package/inc/util/system/valgrind.h +0 -48
  279. package/inc/util/system/winint.h +0 -43
  280. package/inc/util/system/yassert.h +0 -121
  281. package/inc/util/system/yield.h +0 -4
  282. package/inc/util/thread/factory.h +0 -65
  283. package/inc/util/thread/fwd.h +0 -30
  284. package/inc/util/thread/lfqueue.h +0 -406
  285. package/inc/util/thread/lfstack.h +0 -188
  286. package/inc/util/thread/pool.h +0 -388
  287. package/inc/util/thread/singleton.h +0 -42
  288. package/inc/util/ysafeptr.h +0 -427
  289. package/inc/util/ysaveload.h +0 -700
@@ -1,406 +0,0 @@
1
- #pragma once
2
-
3
- #include "fwd.h"
4
-
5
- #include <util/generic/ptr.h>
6
- #include <util/system/atomic.h>
7
- #include <util/system/yassert.h>
8
- #include "lfstack.h"
9
-
10
- struct TDefaultLFCounter {
11
- template <class T>
12
- void IncCount(const T& data) {
13
- (void)data;
14
- }
15
- template <class T>
16
- void DecCount(const T& data) {
17
- (void)data;
18
- }
19
- };
20
-
21
- // @brief lockfree queue
22
- // @tparam T - the queue element, should be movable
23
- // @tparam TCounter, a observer class to count number of items in queue
24
- // be carifull, IncCount and DecCount can be called on a moved object and
25
- // it is TCounter class responsibility to check validity of passed object
26
- template <class T, class TCounter>
27
- class TLockFreeQueue: public TNonCopyable {
28
- struct TListNode {
29
- template <typename U>
30
- TListNode(U&& u, TListNode* next)
31
- : Next(next)
32
- , Data(std::forward<U>(u))
33
- {
34
- }
35
-
36
- template <typename U>
37
- explicit TListNode(U&& u)
38
- : Data(std::forward<U>(u))
39
- {
40
- }
41
-
42
- TListNode* volatile Next;
43
- T Data;
44
- };
45
-
46
- // using inheritance to be able to use 0 bytes for TCounter when we don't need one
47
- struct TRootNode: public TCounter {
48
- TListNode* volatile PushQueue;
49
- TListNode* volatile PopQueue;
50
- TListNode* volatile ToDelete;
51
- TRootNode* volatile NextFree;
52
-
53
- TRootNode()
54
- : PushQueue(nullptr)
55
- , PopQueue(nullptr)
56
- , ToDelete(nullptr)
57
- , NextFree(nullptr)
58
- {
59
- }
60
- void CopyCounter(TRootNode* x) {
61
- *(TCounter*)this = *(TCounter*)x;
62
- }
63
- };
64
-
65
- static void EraseList(TListNode* n) {
66
- while (n) {
67
- TListNode* keepNext = AtomicGet(n->Next);
68
- delete n;
69
- n = keepNext;
70
- }
71
- }
72
-
73
- alignas(64) TRootNode* volatile JobQueue;
74
- alignas(64) volatile TAtomic FreememCounter;
75
- alignas(64) volatile TAtomic FreeingTaskCounter;
76
- alignas(64) TRootNode* volatile FreePtr;
77
-
78
- void TryToFreeAsyncMemory() {
79
- TAtomic keepCounter = AtomicAdd(FreeingTaskCounter, 0);
80
- TRootNode* current = AtomicGet(FreePtr);
81
- if (current == nullptr)
82
- return;
83
- if (AtomicAdd(FreememCounter, 0) == 1) {
84
- // we are the last thread, try to cleanup
85
- // check if another thread have cleaned up
86
- if (keepCounter != AtomicAdd(FreeingTaskCounter, 0)) {
87
- return;
88
- }
89
- if (AtomicCas(&FreePtr, (TRootNode*)nullptr, current)) {
90
- // free list
91
- while (current) {
92
- TRootNode* p = AtomicGet(current->NextFree);
93
- EraseList(AtomicGet(current->ToDelete));
94
- delete current;
95
- current = p;
96
- }
97
- AtomicAdd(FreeingTaskCounter, 1);
98
- }
99
- }
100
- }
101
- void AsyncRef() {
102
- AtomicAdd(FreememCounter, 1);
103
- }
104
- void AsyncUnref() {
105
- TryToFreeAsyncMemory();
106
- AtomicAdd(FreememCounter, -1);
107
- }
108
- void AsyncDel(TRootNode* toDelete, TListNode* lst) {
109
- AtomicSet(toDelete->ToDelete, lst);
110
- for (;;) {
111
- AtomicSet(toDelete->NextFree, AtomicGet(FreePtr));
112
- if (AtomicCas(&FreePtr, toDelete, AtomicGet(toDelete->NextFree)))
113
- break;
114
- }
115
- }
116
- void AsyncUnref(TRootNode* toDelete, TListNode* lst) {
117
- TryToFreeAsyncMemory();
118
- if (AtomicAdd(FreememCounter, -1) == 0) {
119
- // no other operations in progress, can safely reclaim memory
120
- EraseList(lst);
121
- delete toDelete;
122
- } else {
123
- // Dequeue()s in progress, put node to free list
124
- AsyncDel(toDelete, lst);
125
- }
126
- }
127
-
128
- struct TListInvertor {
129
- TListNode* Copy;
130
- TListNode* Tail;
131
- TListNode* PrevFirst;
132
-
133
- TListInvertor()
134
- : Copy(nullptr)
135
- , Tail(nullptr)
136
- , PrevFirst(nullptr)
137
- {
138
- }
139
- ~TListInvertor() {
140
- EraseList(Copy);
141
- }
142
- void CopyWasUsed() {
143
- Copy = nullptr;
144
- Tail = nullptr;
145
- PrevFirst = nullptr;
146
- }
147
- void DoCopy(TListNode* ptr) {
148
- TListNode* newFirst = ptr;
149
- TListNode* newCopy = nullptr;
150
- TListNode* newTail = nullptr;
151
- while (ptr) {
152
- if (ptr == PrevFirst) {
153
- // short cut, we have copied this part already
154
- AtomicSet(Tail->Next, newCopy);
155
- newCopy = Copy;
156
- Copy = nullptr; // do not destroy prev try
157
- if (!newTail)
158
- newTail = Tail; // tried to invert same list
159
- break;
160
- }
161
- TListNode* newElem = new TListNode(ptr->Data, newCopy);
162
- newCopy = newElem;
163
- ptr = AtomicGet(ptr->Next);
164
- if (!newTail)
165
- newTail = newElem;
166
- }
167
- EraseList(Copy); // copy was useless
168
- Copy = newCopy;
169
- PrevFirst = newFirst;
170
- Tail = newTail;
171
- }
172
- };
173
-
174
- void EnqueueImpl(TListNode* head, TListNode* tail) {
175
- TRootNode* newRoot = new TRootNode;
176
- AsyncRef();
177
- AtomicSet(newRoot->PushQueue, head);
178
- for (;;) {
179
- TRootNode* curRoot = AtomicGet(JobQueue);
180
- AtomicSet(tail->Next, AtomicGet(curRoot->PushQueue));
181
- AtomicSet(newRoot->PopQueue, AtomicGet(curRoot->PopQueue));
182
- newRoot->CopyCounter(curRoot);
183
-
184
- for (TListNode* node = head;; node = AtomicGet(node->Next)) {
185
- newRoot->IncCount(node->Data);
186
- if (node == tail)
187
- break;
188
- }
189
-
190
- if (AtomicCas(&JobQueue, newRoot, curRoot)) {
191
- AsyncUnref(curRoot, nullptr);
192
- break;
193
- }
194
- }
195
- }
196
-
197
- template <typename TCollection>
198
- static void FillCollection(TListNode* lst, TCollection* res) {
199
- while (lst) {
200
- res->emplace_back(std::move(lst->Data));
201
- lst = AtomicGet(lst->Next);
202
- }
203
- }
204
-
205
- /** Traverses a given list simultaneously creating its inversed version.
206
- * After that, fills a collection with a reversed version and returns the last visited lst's node.
207
- */
208
- template <typename TCollection>
209
- static TListNode* FillCollectionReverse(TListNode* lst, TCollection* res) {
210
- if (!lst) {
211
- return nullptr;
212
- }
213
-
214
- TListNode* newCopy = nullptr;
215
- do {
216
- TListNode* newElem = new TListNode(std::move(lst->Data), newCopy);
217
- newCopy = newElem;
218
- lst = AtomicGet(lst->Next);
219
- } while (lst);
220
-
221
- FillCollection(newCopy, res);
222
- EraseList(newCopy);
223
-
224
- return lst;
225
- }
226
-
227
- public:
228
- TLockFreeQueue()
229
- : JobQueue(new TRootNode)
230
- , FreememCounter(0)
231
- , FreeingTaskCounter(0)
232
- , FreePtr(nullptr)
233
- {
234
- }
235
- ~TLockFreeQueue() {
236
- AsyncRef();
237
- AsyncUnref(); // should free FreeList
238
- EraseList(JobQueue->PushQueue);
239
- EraseList(JobQueue->PopQueue);
240
- delete JobQueue;
241
- }
242
- template <typename U>
243
- void Enqueue(U&& data) {
244
- TListNode* newNode = new TListNode(std::forward<U>(data));
245
- EnqueueImpl(newNode, newNode);
246
- }
247
- void Enqueue(T&& data) {
248
- TListNode* newNode = new TListNode(std::move(data));
249
- EnqueueImpl(newNode, newNode);
250
- }
251
- void Enqueue(const T& data) {
252
- TListNode* newNode = new TListNode(data);
253
- EnqueueImpl(newNode, newNode);
254
- }
255
- template <typename TCollection>
256
- void EnqueueAll(const TCollection& data) {
257
- EnqueueAll(data.begin(), data.end());
258
- }
259
- template <typename TIter>
260
- void EnqueueAll(TIter dataBegin, TIter dataEnd) {
261
- if (dataBegin == dataEnd)
262
- return;
263
-
264
- TIter i = dataBegin;
265
- TListNode* volatile node = new TListNode(*i);
266
- TListNode* volatile tail = node;
267
-
268
- for (++i; i != dataEnd; ++i) {
269
- TListNode* nextNode = node;
270
- node = new TListNode(*i, nextNode);
271
- }
272
- EnqueueImpl(node, tail);
273
- }
274
- bool Dequeue(T* data) {
275
- TRootNode* newRoot = nullptr;
276
- TListInvertor listInvertor;
277
- AsyncRef();
278
- for (;;) {
279
- TRootNode* curRoot = AtomicGet(JobQueue);
280
- TListNode* tail = AtomicGet(curRoot->PopQueue);
281
- if (tail) {
282
- // has elems to pop
283
- if (!newRoot)
284
- newRoot = new TRootNode;
285
-
286
- AtomicSet(newRoot->PushQueue, AtomicGet(curRoot->PushQueue));
287
- AtomicSet(newRoot->PopQueue, AtomicGet(tail->Next));
288
- newRoot->CopyCounter(curRoot);
289
- newRoot->DecCount(tail->Data);
290
- Y_ASSERT(AtomicGet(curRoot->PopQueue) == tail);
291
- if (AtomicCas(&JobQueue, newRoot, curRoot)) {
292
- *data = std::move(tail->Data);
293
- AtomicSet(tail->Next, nullptr);
294
- AsyncUnref(curRoot, tail);
295
- return true;
296
- }
297
- continue;
298
- }
299
- if (AtomicGet(curRoot->PushQueue) == nullptr) {
300
- delete newRoot;
301
- AsyncUnref();
302
- return false; // no elems to pop
303
- }
304
-
305
- if (!newRoot)
306
- newRoot = new TRootNode;
307
- AtomicSet(newRoot->PushQueue, nullptr);
308
- listInvertor.DoCopy(AtomicGet(curRoot->PushQueue));
309
- AtomicSet(newRoot->PopQueue, listInvertor.Copy);
310
- newRoot->CopyCounter(curRoot);
311
- Y_ASSERT(AtomicGet(curRoot->PopQueue) == nullptr);
312
- if (AtomicCas(&JobQueue, newRoot, curRoot)) {
313
- newRoot = nullptr;
314
- listInvertor.CopyWasUsed();
315
- AsyncDel(curRoot, AtomicGet(curRoot->PushQueue));
316
- } else {
317
- AtomicSet(newRoot->PopQueue, nullptr);
318
- }
319
- }
320
- }
321
- template <typename TCollection>
322
- void DequeueAll(TCollection* res) {
323
- AsyncRef();
324
-
325
- TRootNode* newRoot = new TRootNode;
326
- TRootNode* curRoot;
327
- do {
328
- curRoot = AtomicGet(JobQueue);
329
- } while (!AtomicCas(&JobQueue, newRoot, curRoot));
330
-
331
- FillCollection(curRoot->PopQueue, res);
332
-
333
- TListNode* toDeleteHead = curRoot->PushQueue;
334
- TListNode* toDeleteTail = FillCollectionReverse(curRoot->PushQueue, res);
335
- AtomicSet(curRoot->PushQueue, nullptr);
336
-
337
- if (toDeleteTail) {
338
- toDeleteTail->Next = curRoot->PopQueue;
339
- } else {
340
- toDeleteTail = curRoot->PopQueue;
341
- }
342
- AtomicSet(curRoot->PopQueue, nullptr);
343
-
344
- AsyncUnref(curRoot, toDeleteHead);
345
- }
346
- bool IsEmpty() {
347
- AsyncRef();
348
- TRootNode* curRoot = AtomicGet(JobQueue);
349
- bool res = AtomicGet(curRoot->PushQueue) == nullptr && AtomicGet(curRoot->PopQueue) == nullptr;
350
- AsyncUnref();
351
- return res;
352
- }
353
- TCounter GetCounter() {
354
- AsyncRef();
355
- TRootNode* curRoot = AtomicGet(JobQueue);
356
- TCounter res = *(TCounter*)curRoot;
357
- AsyncUnref();
358
- return res;
359
- }
360
- };
361
-
362
- template <class T, class TCounter>
363
- class TAutoLockFreeQueue {
364
- public:
365
- using TRef = THolder<T>;
366
-
367
- inline ~TAutoLockFreeQueue() {
368
- TRef tmp;
369
-
370
- while (Dequeue(&tmp)) {
371
- }
372
- }
373
-
374
- inline bool Dequeue(TRef* t) {
375
- T* res = nullptr;
376
-
377
- if (Queue.Dequeue(&res)) {
378
- t->Reset(res);
379
-
380
- return true;
381
- }
382
-
383
- return false;
384
- }
385
-
386
- inline void Enqueue(TRef& t) {
387
- Queue.Enqueue(t.Get());
388
- Y_UNUSED(t.Release());
389
- }
390
-
391
- inline void Enqueue(TRef&& t) {
392
- Queue.Enqueue(t.Get());
393
- Y_UNUSED(t.Release());
394
- }
395
-
396
- inline bool IsEmpty() {
397
- return Queue.IsEmpty();
398
- }
399
-
400
- inline TCounter GetCounter() {
401
- return Queue.GetCounter();
402
- }
403
-
404
- private:
405
- TLockFreeQueue<T*, TCounter> Queue;
406
- };
@@ -1,188 +0,0 @@
1
- #pragma once
2
-
3
- #include <util/generic/noncopyable.h>
4
- #include <util/system/atomic.h>
5
-
6
- //////////////////////////////
7
- // lock free lifo stack
8
- template <class T>
9
- class TLockFreeStack : TNonCopyable {
10
- struct TNode {
11
- T Value;
12
- TNode* Next;
13
-
14
- TNode() = default;
15
-
16
- template<class U>
17
- explicit TNode(U&& val)
18
- : Value(std::forward<U>(val))
19
- , Next(nullptr)
20
- {
21
- }
22
- };
23
-
24
- TNode* Head;
25
- TNode* FreePtr;
26
- TAtomic DequeueCount;
27
-
28
- void TryToFreeMemory() {
29
- TNode* current = AtomicGet(FreePtr);
30
- if (!current)
31
- return;
32
- if (AtomicAdd(DequeueCount, 0) == 1) {
33
- // node current is in free list, we are the last thread so try to cleanup
34
- if (AtomicCas(&FreePtr, (TNode*)nullptr, current))
35
- EraseList(current);
36
- }
37
- }
38
- void EraseList(TNode* volatile p) {
39
- while (p) {
40
- TNode* next = p->Next;
41
- delete p;
42
- p = next;
43
- }
44
- }
45
- void EnqueueImpl(TNode* volatile head, TNode* volatile tail) {
46
- for (;;) {
47
- tail->Next = AtomicGet(Head);
48
- if (AtomicCas(&Head, head, tail->Next))
49
- break;
50
- }
51
- }
52
- template <class U>
53
- void EnqueueImpl(U&& u) {
54
- TNode* volatile node = new TNode(std::forward<U>(u));
55
- EnqueueImpl(node, node);
56
- }
57
-
58
- public:
59
- TLockFreeStack()
60
- : Head(nullptr)
61
- , FreePtr(nullptr)
62
- , DequeueCount(0)
63
- {
64
- }
65
- ~TLockFreeStack() {
66
- EraseList(Head);
67
- EraseList(FreePtr);
68
- }
69
-
70
- void Enqueue(const T& t) {
71
- EnqueueImpl(t);
72
- }
73
-
74
- void Enqueue(T&& t) {
75
- EnqueueImpl(std::move(t));
76
- }
77
-
78
- template <typename TCollection>
79
- void EnqueueAll(const TCollection& data) {
80
- EnqueueAll(data.begin(), data.end());
81
- }
82
- template <typename TIter>
83
- void EnqueueAll(TIter dataBegin, TIter dataEnd) {
84
- if (dataBegin == dataEnd) {
85
- return;
86
- }
87
- TIter i = dataBegin;
88
- TNode* volatile node = new TNode(*i);
89
- TNode* volatile tail = node;
90
-
91
- for (++i; i != dataEnd; ++i) {
92
- TNode* nextNode = node;
93
- node = new TNode(*i);
94
- node->Next = nextNode;
95
- }
96
- EnqueueImpl(node, tail);
97
- }
98
- bool Dequeue(T* res) {
99
- AtomicAdd(DequeueCount, 1);
100
- for (TNode* current = AtomicGet(Head); current; current = AtomicGet(Head)) {
101
- if (AtomicCas(&Head, AtomicGet(current->Next), current)) {
102
- *res = std::move(current->Value);
103
- // delete current; // ABA problem
104
- // even more complex node deletion
105
- TryToFreeMemory();
106
- if (AtomicAdd(DequeueCount, -1) == 0) {
107
- // no other Dequeue()s, can safely reclaim memory
108
- delete current;
109
- } else {
110
- // Dequeue()s in progress, put node to free list
111
- for (;;) {
112
- AtomicSet(current->Next, AtomicGet(FreePtr));
113
- if (AtomicCas(&FreePtr, current, current->Next))
114
- break;
115
- }
116
- }
117
- return true;
118
- }
119
- }
120
- TryToFreeMemory();
121
- AtomicAdd(DequeueCount, -1);
122
- return false;
123
- }
124
- // add all elements to *res
125
- // elements are returned in order of dequeue (top to bottom; see example in unittest)
126
- template <typename TCollection>
127
- void DequeueAll(TCollection* res) {
128
- AtomicAdd(DequeueCount, 1);
129
- for (TNode* current = AtomicGet(Head); current; current = AtomicGet(Head)) {
130
- if (AtomicCas(&Head, (TNode*)nullptr, current)) {
131
- for (TNode* x = current; x;) {
132
- res->push_back(std::move(x->Value));
133
- x = x->Next;
134
- }
135
- // EraseList(current); // ABA problem
136
- // even more complex node deletion
137
- TryToFreeMemory();
138
- if (AtomicAdd(DequeueCount, -1) == 0) {
139
- // no other Dequeue()s, can safely reclaim memory
140
- EraseList(current);
141
- } else {
142
- // Dequeue()s in progress, add nodes list to free list
143
- TNode* currentLast = current;
144
- while (currentLast->Next) {
145
- currentLast = currentLast->Next;
146
- }
147
- for (;;) {
148
- AtomicSet(currentLast->Next, AtomicGet(FreePtr));
149
- if (AtomicCas(&FreePtr, current, currentLast->Next))
150
- break;
151
- }
152
- }
153
- return;
154
- }
155
- }
156
- TryToFreeMemory();
157
- AtomicAdd(DequeueCount, -1);
158
- }
159
- bool DequeueSingleConsumer(T* res) {
160
- for (TNode* current = AtomicGet(Head); current; current = AtomicGet(Head)) {
161
- if (AtomicCas(&Head, current->Next, current)) {
162
- *res = std::move(current->Value);
163
- delete current; // with single consumer thread ABA does not happen
164
- return true;
165
- }
166
- }
167
- return false;
168
- }
169
- // add all elements to *res
170
- // elements are returned in order of dequeue (top to bottom; see example in unittest)
171
- template <typename TCollection>
172
- void DequeueAllSingleConsumer(TCollection* res) {
173
- for (TNode* current = AtomicGet(Head); current; current = AtomicGet(Head)) {
174
- if (AtomicCas(&Head, (TNode*)nullptr, current)) {
175
- for (TNode* x = current; x;) {
176
- res->push_back(std::move(x->Value));
177
- x = x->Next;
178
- }
179
- EraseList(current); // with single consumer thread ABA does not happen
180
- return;
181
- }
182
- }
183
- }
184
- bool IsEmpty() {
185
- AtomicAdd(DequeueCount, 0); // mem barrier
186
- return AtomicGet(Head) == nullptr; // without lock, so result is approximate
187
- }
188
- };