catboost 1.25.1 → 1.27.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 (290) hide show
  1. package/DEPLOYMENT.md +22 -15
  2. package/README.md +43 -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/common.js +1 -1
  10. package/build_scripts/out/config.js +32 -18
  11. package/build_scripts/out/install.js +5 -3
  12. package/build_scripts/out/package_prepublish.js +1 -1
  13. package/build_scripts/out/packaging.js +1 -19
  14. package/build_scripts/out/run_tests.js +1 -1
  15. package/build_scripts/out/test.js +8 -3
  16. package/config.json +18 -11
  17. package/inc/catboost/libs/model_interface/c_api.h +367 -5
  18. package/lib/catboost.d.ts +65 -21
  19. package/package.json +4 -4
  20. package/src/api_helpers.cpp +100 -24
  21. package/src/api_helpers.h +8 -7
  22. package/src/api_module.cpp +1 -2
  23. package/src/model.cpp +483 -83
  24. package/src/model.h +24 -9
  25. package/inc/contrib/libs/cxxsupp/system_stl/include/stlfwd +0 -14
  26. package/inc/util/charset/recode_result.h +0 -9
  27. package/inc/util/charset/unicode_table.h +0 -123
  28. package/inc/util/charset/unidata.h +0 -421
  29. package/inc/util/charset/utf8.h +0 -384
  30. package/inc/util/charset/wide.h +0 -843
  31. package/inc/util/charset/wide_specific.h +0 -22
  32. package/inc/util/datetime/base.h +0 -669
  33. package/inc/util/datetime/constants.h +0 -7
  34. package/inc/util/datetime/cputimer.h +0 -124
  35. package/inc/util/datetime/parser.h +0 -292
  36. package/inc/util/datetime/systime.h +0 -47
  37. package/inc/util/datetime/uptime.h +0 -8
  38. package/inc/util/digest/city.h +0 -88
  39. package/inc/util/digest/fnv.h +0 -73
  40. package/inc/util/digest/multi.h +0 -14
  41. package/inc/util/digest/murmur.h +0 -57
  42. package/inc/util/digest/numeric.h +0 -86
  43. package/inc/util/digest/sequence.h +0 -48
  44. package/inc/util/draft/date.h +0 -129
  45. package/inc/util/draft/datetime.h +0 -184
  46. package/inc/util/draft/enum.h +0 -136
  47. package/inc/util/draft/holder_vector.h +0 -102
  48. package/inc/util/draft/ip.h +0 -131
  49. package/inc/util/draft/matrix.h +0 -108
  50. package/inc/util/draft/memory.h +0 -40
  51. package/inc/util/folder/dirent_win.h +0 -46
  52. package/inc/util/folder/dirut.h +0 -121
  53. package/inc/util/folder/filelist.h +0 -81
  54. package/inc/util/folder/fts.h +0 -108
  55. package/inc/util/folder/iterator.h +0 -109
  56. package/inc/util/folder/lstat_win.h +0 -20
  57. package/inc/util/folder/path.h +0 -225
  58. package/inc/util/folder/pathsplit.h +0 -113
  59. package/inc/util/folder/tempdir.h +0 -42
  60. package/inc/util/generic/adaptor.h +0 -134
  61. package/inc/util/generic/algorithm.h +0 -765
  62. package/inc/util/generic/array_ref.h +0 -282
  63. package/inc/util/generic/array_size.h +0 -24
  64. package/inc/util/generic/benchmark/vector_count_ctor/f.h +0 -9
  65. package/inc/util/generic/bitmap.h +0 -1115
  66. package/inc/util/generic/bitops.h +0 -459
  67. package/inc/util/generic/bt_exception.h +0 -24
  68. package/inc/util/generic/buffer.h +0 -232
  69. package/inc/util/generic/cast.h +0 -176
  70. package/inc/util/generic/deque.h +0 -24
  71. package/inc/util/generic/explicit_type.h +0 -42
  72. package/inc/util/generic/fastqueue.h +0 -55
  73. package/inc/util/generic/flags.h +0 -244
  74. package/inc/util/generic/function.h +0 -103
  75. package/inc/util/generic/fwd.h +0 -171
  76. package/inc/util/generic/guid.h +0 -61
  77. package/inc/util/generic/hash.h +0 -2032
  78. package/inc/util/generic/hash_primes.h +0 -140
  79. package/inc/util/generic/hash_set.h +0 -490
  80. package/inc/util/generic/hide_ptr.h +0 -3
  81. package/inc/util/generic/intrlist.h +0 -876
  82. package/inc/util/generic/is_in.h +0 -53
  83. package/inc/util/generic/iterator.h +0 -137
  84. package/inc/util/generic/iterator_range.h +0 -105
  85. package/inc/util/generic/lazy_value.h +0 -66
  86. package/inc/util/generic/list.h +0 -22
  87. package/inc/util/generic/map.h +0 -44
  88. package/inc/util/generic/mapfindptr.h +0 -60
  89. package/inc/util/generic/maybe.h +0 -713
  90. package/inc/util/generic/maybe_traits.h +0 -164
  91. package/inc/util/generic/mem_copy.h +0 -55
  92. package/inc/util/generic/noncopyable.h +0 -38
  93. package/inc/util/generic/object_counter.h +0 -53
  94. package/inc/util/generic/ptr.h +0 -1113
  95. package/inc/util/generic/queue.h +0 -57
  96. package/inc/util/generic/refcount.h +0 -162
  97. package/inc/util/generic/reserve.h +0 -11
  98. package/inc/util/generic/scope.h +0 -65
  99. package/inc/util/generic/serialized_enum.h +0 -406
  100. package/inc/util/generic/set.h +0 -42
  101. package/inc/util/generic/singleton.h +0 -136
  102. package/inc/util/generic/size_literals.h +0 -65
  103. package/inc/util/generic/stack.h +0 -18
  104. package/inc/util/generic/store_policy.h +0 -120
  105. package/inc/util/generic/strbase.h +0 -612
  106. package/inc/util/generic/strbuf.h +0 -552
  107. package/inc/util/generic/strfcpy.h +0 -17
  108. package/inc/util/generic/string.h +0 -1572
  109. package/inc/util/generic/string_hash.h +0 -21
  110. package/inc/util/generic/string_ut.h +0 -1175
  111. package/inc/util/generic/type_name.h +0 -34
  112. package/inc/util/generic/typelist.h +0 -114
  113. package/inc/util/generic/typetraits.h +0 -325
  114. package/inc/util/generic/utility.h +0 -132
  115. package/inc/util/generic/va_args.h +0 -400
  116. package/inc/util/generic/variant.h +0 -631
  117. package/inc/util/generic/variant_traits.h +0 -171
  118. package/inc/util/generic/vector.h +0 -119
  119. package/inc/util/generic/xrange.h +0 -258
  120. package/inc/util/generic/yexception.h +0 -212
  121. package/inc/util/generic/yexception_ut.h +0 -14
  122. package/inc/util/generic/ylimits.h +0 -92
  123. package/inc/util/generic/ymath.h +0 -206
  124. package/inc/util/memory/addstorage.h +0 -93
  125. package/inc/util/memory/alloc.h +0 -27
  126. package/inc/util/memory/blob.h +0 -296
  127. package/inc/util/memory/mmapalloc.h +0 -8
  128. package/inc/util/memory/pool.h +0 -432
  129. package/inc/util/memory/segmented_string_pool.h +0 -194
  130. package/inc/util/memory/segpool_alloc.h +0 -118
  131. package/inc/util/memory/smallobj.h +0 -141
  132. package/inc/util/memory/tempbuf.h +0 -111
  133. package/inc/util/network/address.h +0 -136
  134. package/inc/util/network/endpoint.h +0 -61
  135. package/inc/util/network/hostip.h +0 -16
  136. package/inc/util/network/init.h +0 -60
  137. package/inc/util/network/interface.h +0 -17
  138. package/inc/util/network/iovec.h +0 -65
  139. package/inc/util/network/ip.h +0 -116
  140. package/inc/util/network/nonblock.h +0 -8
  141. package/inc/util/network/pair.h +0 -9
  142. package/inc/util/network/poller.h +0 -58
  143. package/inc/util/network/pollerimpl.h +0 -707
  144. package/inc/util/network/sock.h +0 -608
  145. package/inc/util/network/socket.h +0 -421
  146. package/inc/util/random/common_ops.h +0 -130
  147. package/inc/util/random/easy.h +0 -47
  148. package/inc/util/random/entropy.h +0 -21
  149. package/inc/util/random/fast.h +0 -101
  150. package/inc/util/random/init_atfork.h +0 -3
  151. package/inc/util/random/lcg_engine.h +0 -66
  152. package/inc/util/random/mersenne.h +0 -46
  153. package/inc/util/random/mersenne32.h +0 -50
  154. package/inc/util/random/mersenne64.h +0 -50
  155. package/inc/util/random/normal.h +0 -38
  156. package/inc/util/random/random.h +0 -30
  157. package/inc/util/random/shuffle.h +0 -39
  158. package/inc/util/str_stl.h +0 -266
  159. package/inc/util/stream/aligned.h +0 -99
  160. package/inc/util/stream/buffer.h +0 -119
  161. package/inc/util/stream/buffered.h +0 -225
  162. package/inc/util/stream/debug.h +0 -53
  163. package/inc/util/stream/direct_io.h +0 -43
  164. package/inc/util/stream/file.h +0 -108
  165. package/inc/util/stream/format.h +0 -444
  166. package/inc/util/stream/fwd.h +0 -100
  167. package/inc/util/stream/hex.h +0 -8
  168. package/inc/util/stream/holder.h +0 -44
  169. package/inc/util/stream/input.h +0 -273
  170. package/inc/util/stream/labeled.h +0 -19
  171. package/inc/util/stream/length.h +0 -100
  172. package/inc/util/stream/mem.h +0 -255
  173. package/inc/util/stream/multi.h +0 -32
  174. package/inc/util/stream/null.h +0 -61
  175. package/inc/util/stream/output.h +0 -304
  176. package/inc/util/stream/pipe.h +0 -112
  177. package/inc/util/stream/printf.h +0 -25
  178. package/inc/util/stream/str.h +0 -207
  179. package/inc/util/stream/tee.h +0 -28
  180. package/inc/util/stream/tempbuf.h +0 -21
  181. package/inc/util/stream/tokenizer.h +0 -214
  182. package/inc/util/stream/trace.h +0 -60
  183. package/inc/util/stream/walk.h +0 -35
  184. package/inc/util/stream/zerocopy.h +0 -91
  185. package/inc/util/stream/zerocopy_output.h +0 -57
  186. package/inc/util/stream/zlib.h +0 -173
  187. package/inc/util/string/ascii.h +0 -236
  188. package/inc/util/string/builder.h +0 -39
  189. package/inc/util/string/cast.h +0 -347
  190. package/inc/util/string/cstriter.h +0 -14
  191. package/inc/util/string/escape.h +0 -70
  192. package/inc/util/string/hex.h +0 -59
  193. package/inc/util/string/join.h +0 -194
  194. package/inc/util/string/printf.h +0 -13
  195. package/inc/util/string/reverse.h +0 -16
  196. package/inc/util/string/split.h +0 -1080
  197. package/inc/util/string/strip.h +0 -257
  198. package/inc/util/string/strspn.h +0 -65
  199. package/inc/util/string/subst.h +0 -56
  200. package/inc/util/string/type.h +0 -50
  201. package/inc/util/string/util.h +0 -195
  202. package/inc/util/string/vector.h +0 -132
  203. package/inc/util/system/align.h +0 -50
  204. package/inc/util/system/atexit.h +0 -22
  205. package/inc/util/system/atomic.h +0 -51
  206. package/inc/util/system/atomic_gcc.h +0 -90
  207. package/inc/util/system/atomic_ops.h +0 -189
  208. package/inc/util/system/atomic_win.h +0 -114
  209. package/inc/util/system/backtrace.h +0 -39
  210. package/inc/util/system/byteorder.h +0 -186
  211. package/inc/util/system/compat.h +0 -84
  212. package/inc/util/system/compiler.h +0 -620
  213. package/inc/util/system/condvar.h +0 -71
  214. package/inc/util/system/context.h +0 -181
  215. package/inc/util/system/context_aarch64.h +0 -8
  216. package/inc/util/system/context_i686.h +0 -9
  217. package/inc/util/system/context_x86.h +0 -12
  218. package/inc/util/system/context_x86_64.h +0 -7
  219. package/inc/util/system/cpu_id.h +0 -159
  220. package/inc/util/system/daemon.h +0 -28
  221. package/inc/util/system/datetime.h +0 -98
  222. package/inc/util/system/defaults.h +0 -149
  223. package/inc/util/system/demangle.h +0 -5
  224. package/inc/util/system/demangle_impl.h +0 -23
  225. package/inc/util/system/direct_io.h +0 -71
  226. package/inc/util/system/dynlib.h +0 -119
  227. package/inc/util/system/env.h +0 -32
  228. package/inc/util/system/error.h +0 -95
  229. package/inc/util/system/event.h +0 -122
  230. package/inc/util/system/execpath.h +0 -17
  231. package/inc/util/system/fasttime.h +0 -6
  232. package/inc/util/system/fhandle.h +0 -27
  233. package/inc/util/system/file.h +0 -210
  234. package/inc/util/system/file_lock.h +0 -34
  235. package/inc/util/system/filemap.h +0 -383
  236. package/inc/util/system/flock.h +0 -35
  237. package/inc/util/system/fs.h +0 -156
  238. package/inc/util/system/fs_win.h +0 -29
  239. package/inc/util/system/fstat.h +0 -46
  240. package/inc/util/system/getpid.h +0 -12
  241. package/inc/util/system/guard.h +0 -179
  242. package/inc/util/system/hi_lo.h +0 -139
  243. package/inc/util/system/hostname.h +0 -10
  244. package/inc/util/system/hp_timer.h +0 -36
  245. package/inc/util/system/info.h +0 -12
  246. package/inc/util/system/interrupt_signals.h +0 -22
  247. package/inc/util/system/madvise.h +0 -30
  248. package/inc/util/system/maxlen.h +0 -32
  249. package/inc/util/system/mem_info.h +0 -18
  250. package/inc/util/system/mincore.h +0 -38
  251. package/inc/util/system/mktemp.h +0 -11
  252. package/inc/util/system/mlock.h +0 -43
  253. package/inc/util/system/mutex.h +0 -67
  254. package/inc/util/system/nice.h +0 -3
  255. package/inc/util/system/pipe.h +0 -90
  256. package/inc/util/system/platform.h +0 -246
  257. package/inc/util/system/progname.h +0 -13
  258. package/inc/util/system/protect.h +0 -25
  259. package/inc/util/system/rusage.h +0 -26
  260. package/inc/util/system/rwlock.h +0 -78
  261. package/inc/util/system/sanitizers.h +0 -122
  262. package/inc/util/system/sem.h +0 -41
  263. package/inc/util/system/shellcommand.h +0 -472
  264. package/inc/util/system/shmat.h +0 -32
  265. package/inc/util/system/sigset.h +0 -78
  266. package/inc/util/system/spin_wait.h +0 -10
  267. package/inc/util/system/spinlock.h +0 -121
  268. package/inc/util/system/src_location.h +0 -25
  269. package/inc/util/system/src_root.h +0 -68
  270. package/inc/util/system/sys_alloc.h +0 -43
  271. package/inc/util/system/sysstat.h +0 -52
  272. package/inc/util/system/tempfile.h +0 -34
  273. package/inc/util/system/thread.h +0 -167
  274. package/inc/util/system/tls.h +0 -307
  275. package/inc/util/system/types.h +0 -119
  276. package/inc/util/system/unaligned_mem.h +0 -67
  277. package/inc/util/system/user.h +0 -5
  278. package/inc/util/system/utime.h +0 -6
  279. package/inc/util/system/valgrind.h +0 -48
  280. package/inc/util/system/winint.h +0 -43
  281. package/inc/util/system/yassert.h +0 -121
  282. package/inc/util/system/yield.h +0 -4
  283. package/inc/util/thread/factory.h +0 -65
  284. package/inc/util/thread/fwd.h +0 -30
  285. package/inc/util/thread/lfqueue.h +0 -406
  286. package/inc/util/thread/lfstack.h +0 -188
  287. package/inc/util/thread/pool.h +0 -388
  288. package/inc/util/thread/singleton.h +0 -42
  289. package/inc/util/ysafeptr.h +0 -427
  290. 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
- };