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,1115 +0,0 @@
1
- #pragma once
2
-
3
- #include "fwd.h"
4
- #include "ptr.h"
5
- #include "bitops.h"
6
- #include "typetraits.h"
7
- #include "algorithm.h"
8
- #include "utility.h"
9
-
10
- #include <util/system/yassert.h>
11
- #include <util/system/defaults.h>
12
- #include <util/str_stl.h>
13
- #include <util/ysaveload.h>
14
-
15
- namespace NBitMapPrivate {
16
- // Returns number of bits set; result is in most significatnt byte
17
- inline ui64 ByteSums(ui64 x) {
18
- ui64 byteSums = x - ((x & 0xAAAAAAAAAAAAAAAAULL) >> 1);
19
-
20
- byteSums = (byteSums & 0x3333333333333333ULL) + ((byteSums >> 2) & 0x3333333333333333ULL);
21
- byteSums = (byteSums + (byteSums >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
22
-
23
- return byteSums * 0x0101010101010101ULL;
24
- }
25
-
26
- // better than intrinsics without -mpopcnt
27
- template <typename T>
28
- static unsigned CountBitsPrivate(T v) noexcept {
29
- return static_cast<unsigned>(ByteSums(v) >> 56);
30
- }
31
-
32
- template <typename TChunkType, size_t ExtraBits>
33
- struct TSanitizeMask {
34
- static constexpr TChunkType Value = ~((~TChunkType(0)) << ExtraBits);
35
- };
36
-
37
- template <typename TChunkType>
38
- struct TSanitizeMask<TChunkType, 0> {
39
- static constexpr TChunkType Value = (TChunkType)~TChunkType(0u);
40
- };
41
-
42
- template <typename TTargetChunk, typename TSourceChunk>
43
- struct TBigToSmallDataCopier {
44
- static_assert(sizeof(TTargetChunk) < sizeof(TSourceChunk), "expect sizeof(TTargetChunk) < sizeof(TSourceChunk)");
45
- static_assert(0 == sizeof(TSourceChunk) % sizeof(TTargetChunk), "expect 0 == sizeof(TSourceChunk) % sizeof(TTargetChunk)");
46
-
47
- static constexpr size_t BLOCK_SIZE = sizeof(TSourceChunk) / sizeof(TTargetChunk);
48
-
49
- union TCnv {
50
- TSourceChunk BigData;
51
- TTargetChunk SmallData[BLOCK_SIZE];
52
- };
53
-
54
- static inline void CopyChunk(TTargetChunk* target, TSourceChunk source) {
55
- TCnv c;
56
- c.BigData = source;
57
- #if defined(_big_endian_)
58
- ::ReverseCopy(c.SmallData, c.SmallData + Y_ARRAY_SIZE(c.SmallData), target);
59
- #else
60
- ::Copy(c.SmallData, c.SmallData + Y_ARRAY_SIZE(c.SmallData), target);
61
- #endif
62
- }
63
-
64
- static inline void Copy(TTargetChunk* target, size_t targetSize, const TSourceChunk* source, size_t sourceSize) {
65
- Y_ASSERT(targetSize >= sourceSize * BLOCK_SIZE);
66
- if (targetSize > sourceSize * BLOCK_SIZE) {
67
- ::Fill(target + sourceSize * BLOCK_SIZE, target + targetSize, 0);
68
- }
69
- for (size_t i = 0; i < sourceSize; ++i) {
70
- CopyChunk(target + i * BLOCK_SIZE, source[i]);
71
- }
72
- }
73
- };
74
-
75
- template <typename TTargetChunk, typename TSourceChunk>
76
- struct TSmallToBigDataCopier {
77
- static_assert(sizeof(TTargetChunk) > sizeof(TSourceChunk), "expect sizeof(TTargetChunk) > sizeof(TSourceChunk)");
78
- static_assert(0 == sizeof(TTargetChunk) % sizeof(TSourceChunk), "expect 0 == sizeof(TTargetChunk) % sizeof(TSourceChunk)");
79
-
80
- static constexpr size_t BLOCK_SIZE = sizeof(TTargetChunk) / sizeof(TSourceChunk);
81
-
82
- union TCnv {
83
- TSourceChunk SmallData[BLOCK_SIZE];
84
- TTargetChunk BigData;
85
- };
86
-
87
- static inline TTargetChunk CopyFullChunk(const TSourceChunk* source) {
88
- TCnv c;
89
- #if defined(_big_endian_)
90
- ::ReverseCopy(source, source + BLOCK_SIZE, c.SmallData);
91
- #else
92
- ::Copy(source, source + BLOCK_SIZE, c.SmallData);
93
- #endif
94
- return c.BigData;
95
- }
96
-
97
- static inline TTargetChunk CopyPartChunk(const TSourceChunk* source, size_t count) {
98
- Y_ASSERT(count <= BLOCK_SIZE);
99
- TCnv c;
100
- c.BigData = 0;
101
- #if defined(_big_endian_)
102
- ::ReverseCopy(source, source + count, c.SmallData);
103
- #else
104
- ::Copy(source, source + count, c.SmallData);
105
- #endif
106
- return c.BigData;
107
- }
108
-
109
- static inline void Copy(TTargetChunk* target, size_t targetSize, const TSourceChunk* source, size_t sourceSize) {
110
- Y_ASSERT(targetSize * BLOCK_SIZE >= sourceSize);
111
- if (targetSize * BLOCK_SIZE > sourceSize) {
112
- ::Fill(target + sourceSize / BLOCK_SIZE, target + targetSize, 0);
113
- }
114
- size_t i = 0;
115
- for (; i < sourceSize / BLOCK_SIZE; ++i) {
116
- target[i] = CopyFullChunk(source + i * BLOCK_SIZE);
117
- }
118
- if (0 != sourceSize % BLOCK_SIZE) {
119
- target[i] = CopyPartChunk(source + i * BLOCK_SIZE, sourceSize % BLOCK_SIZE);
120
- }
121
- }
122
- };
123
-
124
- template <typename TChunk>
125
- struct TUniformDataCopier {
126
- static inline void Copy(TChunk* target, size_t targetSize, const TChunk* source, size_t sourceSize) {
127
- Y_ASSERT(targetSize >= sourceSize);
128
- for (size_t i = 0; i < sourceSize; ++i) {
129
- target[i] = source[i];
130
- }
131
- for (size_t i = sourceSize; i < targetSize; ++i) {
132
- target[i] = 0;
133
- }
134
- }
135
- };
136
-
137
- template <typename TFirst, typename TSecond>
138
- struct TIsSmaller {
139
- enum {
140
- Result = sizeof(TFirst) < sizeof(TSecond)
141
- };
142
- };
143
-
144
- template <typename TTargetChunk, typename TSourceChunk>
145
- struct TDataCopier: public std::conditional_t<std::is_same<TTargetChunk, TSourceChunk>::value, TUniformDataCopier<TTargetChunk>, std::conditional_t<TIsSmaller<TTargetChunk, TSourceChunk>::Result, TBigToSmallDataCopier<TTargetChunk, TSourceChunk>, TSmallToBigDataCopier<TTargetChunk, TSourceChunk>>> {
146
- };
147
-
148
- template <typename TTargetChunk, typename TSourceChunk>
149
- inline void CopyData(TTargetChunk* target, size_t targetSize, const TSourceChunk* source, size_t sourceSize) {
150
- TDataCopier<TTargetChunk, TSourceChunk>::Copy(target, targetSize, source, sourceSize);
151
- }
152
-
153
- template <size_t BitCount, typename TChunkType>
154
- struct TFixedStorage {
155
- using TChunk = TChunkType;
156
-
157
- static constexpr size_t Size = (BitCount + 8 * sizeof(TChunk) - 1) / (8 * sizeof(TChunk));
158
-
159
- TChunk Data[Size];
160
-
161
- TFixedStorage() {
162
- Zero(Data);
163
- }
164
-
165
- TFixedStorage(const TFixedStorage<BitCount, TChunkType>& st) {
166
- for (size_t i = 0; i < Size; ++i) {
167
- Data[i] = st.Data[i];
168
- }
169
- }
170
-
171
- template <typename TOtherChunk>
172
- TFixedStorage(const TOtherChunk* data, size_t size) {
173
- Y_VERIFY(Size * sizeof(TChunk) >= size * sizeof(TOtherChunk), "Exceeding bitmap storage capacity");
174
- CopyData(Data, Size, data, size);
175
- }
176
-
177
- Y_FORCE_INLINE void Swap(TFixedStorage<BitCount, TChunkType>& st) {
178
- for (size_t i = 0; i < Size; ++i) {
179
- DoSwap(Data[i], st.Data[i]);
180
- }
181
- }
182
-
183
- Y_FORCE_INLINE static constexpr size_t GetBitCapacity() noexcept {
184
- return BitCount;
185
- }
186
-
187
- Y_FORCE_INLINE static constexpr size_t GetChunkCapacity() noexcept {
188
- return Size;
189
- }
190
-
191
- // Returns true if the resulting storage capacity is enough to fit the requested size
192
- Y_FORCE_INLINE static constexpr bool ExpandBitSize(const size_t bitSize) noexcept {
193
- return bitSize <= BitCount;
194
- }
195
-
196
- Y_FORCE_INLINE void Sanitize() {
197
- Data[Size - 1] &= TSanitizeMask<TChunk, BitCount % (8 * sizeof(TChunk))>::Value;
198
- }
199
- };
200
-
201
- // Dynamically expanded storage.
202
- // It uses "on stack" realization with no allocation for one chunk spaces
203
- template <typename TChunkType>
204
- struct TDynamicStorage {
205
- using TChunk = TChunkType;
206
-
207
- size_t Size;
208
- TChunk StackData;
209
- TArrayHolder<TChunk> ArrayData;
210
- TChunk* Data;
211
-
212
- TDynamicStorage()
213
- : Size(1)
214
- , StackData(0)
215
- , Data(&StackData)
216
- {
217
- }
218
-
219
- TDynamicStorage(const TDynamicStorage<TChunk>& st)
220
- : Size(1)
221
- , StackData(0)
222
- , Data(&StackData)
223
- {
224
- ExpandSize(st.Size, false);
225
- for (size_t i = 0; i < st.Size; ++i) {
226
- Data[i] = st.Data[i];
227
- }
228
- for (size_t i = st.Size; i < Size; ++i) {
229
- Data[i] = 0;
230
- }
231
- }
232
-
233
- template <typename TOtherChunk>
234
- TDynamicStorage(const TOtherChunk* data, size_t size)
235
- : Size(1)
236
- , StackData(0)
237
- , Data(&StackData)
238
- {
239
- ExpandBitSize(size * sizeof(TOtherChunk) * 8, false);
240
- CopyData(Data, Size, data, size);
241
- }
242
-
243
- Y_FORCE_INLINE void Swap(TDynamicStorage<TChunkType>& st) {
244
- DoSwap(Size, st.Size);
245
- DoSwap(StackData, st.StackData);
246
- DoSwap(ArrayData, st.ArrayData);
247
- Data = 1 == Size ? &StackData : ArrayData.Get();
248
- st.Data = 1 == st.Size ? &st.StackData : st.ArrayData.Get();
249
- }
250
-
251
- Y_FORCE_INLINE size_t GetBitCapacity() const {
252
- return Size * 8 * sizeof(TChunk);
253
- }
254
-
255
- Y_FORCE_INLINE size_t GetChunkCapacity() const {
256
- return Size;
257
- }
258
-
259
- // Returns true if the resulting storage capacity is enough to fit the requested size
260
- Y_FORCE_INLINE bool ExpandSize(size_t size, bool keepData = true) {
261
- if (size > Size) {
262
- size = Max(size, Size * 2);
263
- TArrayHolder<TChunk> newData(new TChunk[size]);
264
- if (keepData) {
265
- for (size_t i = 0; i < Size; ++i) {
266
- newData[i] = Data[i];
267
- }
268
- for (size_t i = Size; i < size; ++i) {
269
- newData[i] = 0;
270
- }
271
- }
272
- DoSwap(ArrayData, newData);
273
- Data = ArrayData.Get();
274
- Size = size;
275
- }
276
- return true;
277
- }
278
-
279
- Y_FORCE_INLINE bool ExpandBitSize(size_t bitSize, bool keepData = true) {
280
- return ExpandSize((bitSize + 8 * sizeof(TChunk) - 1) / (8 * sizeof(TChunk)), keepData);
281
- }
282
-
283
- Y_FORCE_INLINE void Sanitize() {
284
- }
285
- };
286
-
287
- template <size_t num>
288
- struct TDivCount {
289
- static constexpr size_t Value = 1 + TDivCount<(num >> 1)>::Value;
290
- };
291
-
292
- template <>
293
- struct TDivCount<0> {
294
- static constexpr size_t Value = 0;
295
- };
296
-
297
- }
298
-
299
- template <size_t BitCount, typename TChunkType>
300
- struct TFixedBitMapTraits {
301
- using TChunk = TChunkType;
302
- using TStorage = NBitMapPrivate::TFixedStorage<BitCount, TChunkType>;
303
- };
304
-
305
- template <typename TChunkType>
306
- struct TDynamicBitMapTraits {
307
- using TChunk = TChunkType;
308
- using TStorage = NBitMapPrivate::TDynamicStorage<TChunkType>;
309
- };
310
-
311
- template <class TTraits>
312
- class TBitMapOps {
313
- public:
314
- using TChunk = typename TTraits::TChunk;
315
- using TThis = TBitMapOps<TTraits>;
316
-
317
- private:
318
- static_assert(std::is_unsigned<TChunk>::value, "expect std::is_unsigned<TChunk>::value");
319
-
320
- static constexpr size_t BitsPerChunk = 8 * sizeof(TChunk);
321
- static constexpr TChunk ModMask = static_cast<TChunk>(BitsPerChunk - 1);
322
- static constexpr size_t DivCount = NBitMapPrivate::TDivCount<BitsPerChunk>::Value - 1;
323
- static constexpr TChunk FullChunk = (TChunk)~TChunk(0);
324
-
325
- template <class>
326
- friend class TBitMapOps;
327
-
328
- using TStorage = typename TTraits::TStorage;
329
-
330
- // The smallest unsigned type, which can be used in bit ops
331
- using TIntType = std::conditional_t<sizeof(TChunk) < sizeof(unsigned int), unsigned int, TChunk>;
332
-
333
- TStorage Mask;
334
-
335
- public:
336
- class TReference {
337
- private:
338
- friend class TBitMapOps<TTraits>;
339
-
340
- TChunk* Chunk;
341
- size_t Offset;
342
-
343
- TReference(TChunk* c, size_t offset)
344
- : Chunk(c)
345
- , Offset(offset)
346
- {
347
- }
348
-
349
- public:
350
- ~TReference() = default;
351
-
352
- Y_FORCE_INLINE TReference& operator=(bool val) {
353
- if (val)
354
- *Chunk |= static_cast<TChunk>(1) << Offset;
355
- else
356
- *Chunk &= ~(static_cast<TChunk>(1) << Offset);
357
-
358
- return *this;
359
- }
360
-
361
- Y_FORCE_INLINE TReference& operator=(const TReference& ref) {
362
- if (ref)
363
- *Chunk |= static_cast<TChunk>(1) << Offset;
364
- else
365
- *Chunk &= ~(static_cast<TChunk>(1) << Offset);
366
-
367
- return *this;
368
- }
369
-
370
- Y_FORCE_INLINE bool operator~() const {
371
- return 0 == (*Chunk & (static_cast<TChunk>(1) << Offset));
372
- }
373
-
374
- Y_FORCE_INLINE operator bool() const {
375
- return 0 != (*Chunk & (static_cast<TChunk>(1) << Offset));
376
- }
377
-
378
- Y_FORCE_INLINE TReference& Flip() {
379
- *Chunk ^= static_cast<TChunk>(1) << Offset;
380
- return *this;
381
- }
382
- };
383
-
384
- private:
385
- struct TSetOp {
386
- static constexpr TChunk Op(const TChunk src, const TChunk mask) noexcept {
387
- return src | mask;
388
- }
389
- };
390
-
391
- struct TResetOp {
392
- static constexpr TChunk Op(const TChunk src, const TChunk mask) noexcept {
393
- return src & ~mask;
394
- }
395
- };
396
-
397
- template <class TUpdateOp>
398
- void UpdateRange(size_t start, size_t end) {
399
- const size_t startChunk = start >> DivCount;
400
- const size_t startBitOffset = start & ModMask;
401
-
402
- const size_t endChunk = end >> DivCount;
403
- const size_t endBitOffset = end & ModMask;
404
-
405
- size_t bitOffset = startBitOffset;
406
- for (size_t chunk = startChunk; chunk <= endChunk; ++chunk) {
407
- TChunk updateMask = FullChunk << bitOffset;
408
- if (chunk == endChunk) {
409
- updateMask ^= FullChunk << endBitOffset;
410
- if (!updateMask)
411
- break;
412
- }
413
- Mask.Data[chunk] = TUpdateOp::Op(Mask.Data[chunk], updateMask);
414
- bitOffset = 0;
415
- }
416
- }
417
-
418
- public:
419
- TBitMapOps() = default;
420
-
421
- TBitMapOps(TChunk val) {
422
- Mask.Data[0] = val;
423
- Mask.Sanitize();
424
- }
425
-
426
- TBitMapOps(const TThis&) = default;
427
-
428
- template <class T>
429
- TBitMapOps(const TBitMapOps<T>& bitmap)
430
- : Mask(bitmap.Mask.Data, bitmap.Mask.GetChunkCapacity())
431
- {
432
- Mask.Sanitize();
433
- }
434
-
435
- template <class T>
436
- Y_FORCE_INLINE bool operator==(const TBitMapOps<T>& bitmap) const {
437
- return Equal(bitmap);
438
- }
439
-
440
- Y_FORCE_INLINE TThis& operator=(const TThis& bitmap) {
441
- if (this != &bitmap) {
442
- TThis bm(bitmap);
443
- Swap(bm);
444
- }
445
- return *this;
446
- }
447
-
448
- template <class T>
449
- Y_FORCE_INLINE TThis& operator=(const TBitMapOps<T>& bitmap) {
450
- TThis bm(bitmap);
451
- Swap(bm);
452
- return *this;
453
- }
454
-
455
- template <class T>
456
- Y_FORCE_INLINE TThis& operator&=(const TBitMapOps<T>& bitmap) {
457
- return And(bitmap);
458
- }
459
-
460
- Y_FORCE_INLINE TThis& operator&=(const TChunk& val) {
461
- return And(val);
462
- }
463
-
464
- template <class T>
465
- Y_FORCE_INLINE TThis& operator|=(const TBitMapOps<T>& bitmap) {
466
- return Or(bitmap);
467
- }
468
-
469
- Y_FORCE_INLINE TThis& operator|=(const TChunk& val) {
470
- return Or(val);
471
- }
472
-
473
- template <class T>
474
- Y_FORCE_INLINE TThis& operator^=(const TBitMapOps<T>& bitmap) {
475
- return Xor(bitmap);
476
- }
477
-
478
- Y_FORCE_INLINE TThis& operator^=(const TChunk& val) {
479
- return Xor(val);
480
- }
481
-
482
- template <class T>
483
- Y_FORCE_INLINE TThis& operator-=(const TBitMapOps<T>& bitmap) {
484
- return SetDifference(bitmap);
485
- }
486
-
487
- Y_FORCE_INLINE TThis& operator-=(const TChunk& val) {
488
- return SetDifference(val);
489
- }
490
-
491
- Y_FORCE_INLINE TThis& operator<<=(size_t pos) {
492
- return LShift(pos);
493
- }
494
-
495
- Y_FORCE_INLINE TThis& operator>>=(size_t pos) {
496
- return RShift(pos);
497
- }
498
-
499
- Y_FORCE_INLINE TThis operator<<(size_t pos) const {
500
- return TThis(*this).LShift(pos);
501
- }
502
-
503
- Y_FORCE_INLINE TThis operator>>(size_t pos) const {
504
- return TThis(*this).RShift(pos);
505
- }
506
-
507
- Y_FORCE_INLINE bool operator[](size_t pos) const {
508
- return Get(pos);
509
- }
510
-
511
- Y_FORCE_INLINE TReference operator[](size_t pos) {
512
- const bool fitStorage = Mask.ExpandBitSize(pos + 1);
513
- Y_ASSERT(fitStorage);
514
- return TReference(&Mask.Data[pos >> DivCount], ModMask & pos);
515
- }
516
-
517
- Y_FORCE_INLINE void Swap(TThis& bitmap) {
518
- DoSwap(Mask, bitmap.Mask);
519
- }
520
-
521
- Y_FORCE_INLINE TThis& Set(size_t pos) {
522
- const bool fitStorage = Mask.ExpandBitSize(pos + 1);
523
- Y_ASSERT(fitStorage);
524
- Mask.Data[pos >> DivCount] |= static_cast<TChunk>(1) << (pos & ModMask);
525
- return *this;
526
- }
527
-
528
- // Fills the specified [start, end) bit range by the 1. Other bits are kept unchanged
529
- TThis& Set(size_t start, size_t end) {
530
- Y_ASSERT(start <= end);
531
- if (start < end) {
532
- Reserve(end);
533
- UpdateRange<TSetOp>(start, end);
534
- }
535
- return *this;
536
- }
537
-
538
- Y_FORCE_INLINE TThis& Reset(size_t pos) {
539
- if ((pos >> DivCount) < Mask.GetChunkCapacity()) {
540
- Mask.Data[pos >> DivCount] &= ~(static_cast<TChunk>(1) << (pos & ModMask));
541
- }
542
- return *this;
543
- }
544
-
545
- // Clears the specified [start, end) bit range. Other bits are kept unchanged
546
- TThis& Reset(size_t start, size_t end) {
547
- Y_ASSERT(start <= end);
548
- if (start < end && (start >> DivCount) < Mask.GetChunkCapacity()) {
549
- UpdateRange<TResetOp>(start, Min(end, Mask.GetBitCapacity()));
550
- }
551
- return *this;
552
- }
553
-
554
- Y_FORCE_INLINE TThis& Flip(size_t pos) {
555
- const bool fitStorage = Mask.ExpandBitSize(pos + 1);
556
- Y_ASSERT(fitStorage);
557
- Mask.Data[pos >> DivCount] ^= static_cast<TChunk>(1) << (pos & ModMask);
558
- return *this;
559
- }
560
-
561
- Y_FORCE_INLINE bool Get(size_t pos) const {
562
- if ((pos >> DivCount) < Mask.GetChunkCapacity()) {
563
- return Mask.Data[pos >> DivCount] & (static_cast<TChunk>(1) << (pos & ModMask));
564
- }
565
- return false;
566
- }
567
-
568
- template <class TTo>
569
- void Export(size_t pos, TTo& to) const {
570
- static_assert(std::is_unsigned<TTo>::value, "expect std::is_unsigned<TTo>::value");
571
- to = 0;
572
- size_t chunkpos = pos >> DivCount;
573
- if (chunkpos >= Mask.GetChunkCapacity())
574
- return;
575
- if ((pos & ModMask) == 0) {
576
- if (sizeof(TChunk) >= sizeof(TTo))
577
- to = (TTo)Mask.Data[chunkpos];
578
- else //if (sizeof(TChunk) < sizeof(TTo))
579
- NBitMapPrivate::CopyData(&to, 1, Mask.Data + chunkpos, Min(((sizeof(TTo) * 8) >> DivCount), Mask.GetChunkCapacity() - chunkpos));
580
- } else if ((pos & (sizeof(TTo) * 8 - 1)) == 0 && sizeof(TChunk) >= 2 * sizeof(TTo))
581
- to = (TTo)(Mask.Data[chunkpos] >> (pos & ModMask));
582
- else {
583
- static constexpr size_t copyToSize = (sizeof(TChunk) >= sizeof(TTo)) ? (sizeof(TChunk) / sizeof(TTo)) + 2 : 3;
584
- TTo temp[copyToSize] = {0, 0};
585
- //or use non defined by now TBitmap<copyToSize, TTo>::CopyData,RShift(pos & ModMask),Export(0,to)
586
- NBitMapPrivate::CopyData(temp, copyToSize, Mask.Data + chunkpos, Min((sizeof(TTo) / sizeof(TChunk)) + 1, Mask.GetChunkCapacity() - chunkpos));
587
- to = (temp[0] >> (pos & ModMask)) | (temp[1] << (8 * sizeof(TTo) - (pos & ModMask)));
588
- }
589
- }
590
-
591
- Y_FORCE_INLINE bool Test(size_t n) const {
592
- return Get(n);
593
- }
594
-
595
- Y_FORCE_INLINE TThis& Push(bool val) {
596
- LShift(1);
597
- return val ? Set(0) : *this;
598
- }
599
-
600
- Y_FORCE_INLINE bool Pop() {
601
- bool val = Get(0);
602
- return RShift(1), val;
603
- }
604
-
605
- // Clear entire bitmap. Current capacity is kept unchanged
606
- Y_FORCE_INLINE TThis& Clear() {
607
- for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i) {
608
- Mask.Data[i] = 0;
609
- }
610
- return *this;
611
- }
612
-
613
- // Returns bits capacity
614
- Y_FORCE_INLINE constexpr size_t Size() const noexcept {
615
- return Mask.GetBitCapacity();
616
- }
617
-
618
- Y_FORCE_INLINE void Reserve(size_t bitCount) {
619
- Y_VERIFY(Mask.ExpandBitSize(bitCount), "Exceeding bitmap storage capacity");
620
- }
621
-
622
- Y_FORCE_INLINE size_t ValueBitCount() const {
623
- size_t nonZeroChunk = Mask.GetChunkCapacity() - 1;
624
- while (nonZeroChunk != 0 && !Mask.Data[nonZeroChunk])
625
- --nonZeroChunk;
626
- return nonZeroChunk || Mask.Data[nonZeroChunk]
627
- ? nonZeroChunk * BitsPerChunk + GetValueBitCount(TIntType(Mask.Data[nonZeroChunk]))
628
- : 0;
629
- }
630
-
631
- Y_PURE_FUNCTION Y_FORCE_INLINE
632
- bool Empty() const {
633
- for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i)
634
- if (Mask.Data[i])
635
- return false;
636
- return true;
637
- }
638
-
639
- bool HasAny(const TThis& bitmap) const {
640
- for (size_t i = 0; i < Min(Mask.GetChunkCapacity(), bitmap.Mask.GetChunkCapacity()); ++i) {
641
- if (0 != (Mask.Data[i] & bitmap.Mask.Data[i])) {
642
- return true;
643
- }
644
- }
645
- return false;
646
- }
647
-
648
- template <class T>
649
- Y_FORCE_INLINE bool HasAny(const TBitMapOps<T>& bitmap) const {
650
- return HasAny(TThis(bitmap));
651
- }
652
-
653
- Y_FORCE_INLINE bool HasAny(const TChunk& val) const {
654
- return 0 != (Mask.Data[0] & val);
655
- }
656
-
657
- bool HasAll(const TThis& bitmap) const {
658
- for (size_t i = 0; i < Min(Mask.GetChunkCapacity(), bitmap.Mask.GetChunkCapacity()); ++i) {
659
- if (bitmap.Mask.Data[i] != (Mask.Data[i] & bitmap.Mask.Data[i])) {
660
- return false;
661
- }
662
- }
663
- for (size_t i = Mask.GetChunkCapacity(); i < bitmap.Mask.GetChunkCapacity(); ++i) {
664
- if (bitmap.Mask.Data[i] != 0) {
665
- return false;
666
- }
667
- }
668
- return true;
669
- }
670
-
671
- template <class T>
672
- Y_FORCE_INLINE bool HasAll(const TBitMapOps<T>& bitmap) const {
673
- return HasAll(TThis(bitmap));
674
- }
675
-
676
- Y_FORCE_INLINE bool HasAll(const TChunk& val) const {
677
- return (Mask.Data[0] & val) == val;
678
- }
679
-
680
- TThis& And(const TThis& bitmap) {
681
- // Don't expand capacity here, because resulting bits in positions,
682
- // which are greater then size of one of these bitmaps, will be zero
683
- for (size_t i = 0; i < Min(bitmap.Mask.GetChunkCapacity(), Mask.GetChunkCapacity()); ++i)
684
- Mask.Data[i] &= bitmap.Mask.Data[i];
685
- // Clear bits if current bitmap size is greater than AND-ed one
686
- for (size_t i = bitmap.Mask.GetChunkCapacity(); i < Mask.GetChunkCapacity(); ++i)
687
- Mask.Data[i] = 0;
688
- return *this;
689
- }
690
-
691
- template <class T>
692
- Y_FORCE_INLINE TThis& And(const TBitMapOps<T>& bitmap) {
693
- return And(TThis(bitmap));
694
- }
695
-
696
- Y_FORCE_INLINE TThis& And(const TChunk& val) {
697
- Mask.Data[0] &= val;
698
- for (size_t i = 1; i < Mask.GetChunkCapacity(); ++i)
699
- Mask.Data[i] = 0;
700
- return *this;
701
- }
702
-
703
- TThis& Or(const TThis& bitmap) {
704
- const size_t valueBitCount = bitmap.ValueBitCount();
705
- if (valueBitCount) {
706
- // Memory optimization: expand size only for non-zero bits
707
- Reserve(valueBitCount);
708
- for (size_t i = 0; i < Min(bitmap.Mask.GetChunkCapacity(), Mask.GetChunkCapacity()); ++i)
709
- Mask.Data[i] |= bitmap.Mask.Data[i];
710
- }
711
- return *this;
712
- }
713
-
714
- template <class T>
715
- Y_FORCE_INLINE TThis& Or(const TBitMapOps<T>& bitmap) {
716
- return Or(TThis(bitmap));
717
- }
718
-
719
- Y_FORCE_INLINE TThis& Or(const TChunk& val) {
720
- Mask.Data[0] |= val;
721
- Mask.Sanitize();
722
- return *this;
723
- }
724
-
725
- TThis& Xor(const TThis& bitmap) {
726
- Reserve(bitmap.Size());
727
- for (size_t i = 0; i < bitmap.Mask.GetChunkCapacity(); ++i)
728
- Mask.Data[i] ^= bitmap.Mask.Data[i];
729
- return *this;
730
- }
731
-
732
- template <class T>
733
- Y_FORCE_INLINE TThis& Xor(const TBitMapOps<T>& bitmap) {
734
- return Xor(TThis(bitmap));
735
- }
736
-
737
- Y_FORCE_INLINE TThis& Xor(const TChunk& val) {
738
- Mask.Data[0] ^= val;
739
- Mask.Sanitize();
740
- return *this;
741
- }
742
-
743
- TThis& SetDifference(const TThis& bitmap) {
744
- for (size_t i = 0; i < Min(bitmap.Mask.GetChunkCapacity(), Mask.GetChunkCapacity()); ++i)
745
- Mask.Data[i] &= ~bitmap.Mask.Data[i];
746
- return *this;
747
- }
748
-
749
- template <class T>
750
- Y_FORCE_INLINE TThis& SetDifference(const TBitMapOps<T>& bitmap) {
751
- return SetDifference(TThis(bitmap));
752
- }
753
-
754
- Y_FORCE_INLINE TThis& SetDifference(const TChunk& val) {
755
- Mask.Data[0] &= ~val;
756
- return *this;
757
- }
758
-
759
- Y_FORCE_INLINE TThis& Flip() {
760
- for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i)
761
- Mask.Data[i] = ~Mask.Data[i];
762
- Mask.Sanitize();
763
- return *this;
764
- }
765
-
766
- TThis& LShift(size_t shift) {
767
- if (shift != 0) {
768
- const size_t valueBitCount = ValueBitCount();
769
- // Do nothing for empty bitmap
770
- if (valueBitCount != 0) {
771
- const size_t eshift = shift / BitsPerChunk;
772
- const size_t offset = shift % BitsPerChunk;
773
- const size_t subOffset = BitsPerChunk - offset;
774
-
775
- // Don't verify expand result, so l-shift of fixed bitmap will work in the same way as for unsigned integer.
776
- Mask.ExpandBitSize(valueBitCount + shift);
777
-
778
- if (offset == 0) {
779
- for (size_t i = Mask.GetChunkCapacity() - 1; i >= eshift; --i) {
780
- Mask.Data[i] = Mask.Data[i - eshift];
781
- }
782
- } else {
783
- for (size_t i = Mask.GetChunkCapacity() - 1; i > eshift; --i)
784
- Mask.Data[i] = (Mask.Data[i - eshift] << offset) | (Mask.Data[i - eshift - 1] >> subOffset);
785
- if (eshift < Mask.GetChunkCapacity())
786
- Mask.Data[eshift] = Mask.Data[0] << offset;
787
- }
788
- for (size_t i = 0; i < Min(eshift, Mask.GetChunkCapacity()); ++i)
789
- Mask.Data[i] = 0;
790
-
791
- // Cleanup extra high bits in the storage
792
- Mask.Sanitize();
793
- }
794
- }
795
- return *this;
796
- }
797
-
798
- TThis& RShift(size_t shift) {
799
- if (shift != 0) {
800
- const size_t eshift = shift / BitsPerChunk;
801
- const size_t offset = shift % BitsPerChunk;
802
- if (eshift >= Mask.GetChunkCapacity()) {
803
- Clear();
804
-
805
- } else {
806
- const size_t limit = Mask.GetChunkCapacity() - eshift - 1;
807
-
808
- if (offset == 0) {
809
- for (size_t i = 0; i <= limit; ++i) {
810
- Mask.Data[i] = Mask.Data[i + eshift];
811
- }
812
- } else {
813
- const size_t subOffset = BitsPerChunk - offset;
814
- for (size_t i = 0; i < limit; ++i)
815
- Mask.Data[i] = (Mask.Data[i + eshift] >> offset) | (Mask.Data[i + eshift + 1] << subOffset);
816
- Mask.Data[limit] = Mask.Data[Mask.GetChunkCapacity() - 1] >> offset;
817
- }
818
-
819
- for (size_t i = limit + 1; i < Mask.GetChunkCapacity(); ++i)
820
- Mask.Data[i] = 0;
821
- }
822
- }
823
- return *this;
824
- }
825
-
826
- // Applies bitmap at the specified offset using OR operator.
827
- // This method is optimized combination of Or() and LShift(), which allows reducing memory allocation
828
- // when combining long dynamic bitmaps.
829
- TThis& Or(const TThis& bitmap, size_t offset) {
830
- if (0 == offset)
831
- return Or(bitmap);
832
-
833
- const size_t otherValueBitCount = bitmap.ValueBitCount();
834
- // Continue only if OR-ed bitmap have non-zero bits
835
- if (otherValueBitCount) {
836
- const size_t chunkShift = offset / BitsPerChunk;
837
- const size_t subShift = offset % BitsPerChunk;
838
- const size_t subOffset = BitsPerChunk - subShift;
839
-
840
- Reserve(otherValueBitCount + offset);
841
-
842
- if (subShift == 0) {
843
- for (size_t i = chunkShift; i < Min(bitmap.Mask.GetChunkCapacity() + chunkShift, Mask.GetChunkCapacity()); ++i) {
844
- Mask.Data[i] |= bitmap.Mask.Data[i - chunkShift];
845
- }
846
- } else {
847
- Mask.Data[chunkShift] |= bitmap.Mask.Data[0] << subShift;
848
- size_t i = chunkShift + 1;
849
- for (; i < Min(bitmap.Mask.GetChunkCapacity() + chunkShift, Mask.GetChunkCapacity()); ++i) {
850
- Mask.Data[i] |= (bitmap.Mask.Data[i - chunkShift] << subShift) | (bitmap.Mask.Data[i - chunkShift - 1] >> subOffset);
851
- }
852
- if (i < Mask.GetChunkCapacity())
853
- Mask.Data[i] |= bitmap.Mask.Data[i - chunkShift - 1] >> subOffset;
854
- }
855
- }
856
-
857
- return *this;
858
- }
859
-
860
- bool Equal(const TThis& bitmap) const {
861
- if (Mask.GetChunkCapacity() > bitmap.Mask.GetChunkCapacity()) {
862
- for (size_t i = bitmap.Mask.GetChunkCapacity(); i < Mask.GetChunkCapacity(); ++i) {
863
- if (0 != Mask.Data[i])
864
- return false;
865
- }
866
- } else if (Mask.GetChunkCapacity() < bitmap.Mask.GetChunkCapacity()) {
867
- for (size_t i = Mask.GetChunkCapacity(); i < bitmap.Mask.GetChunkCapacity(); ++i) {
868
- if (0 != bitmap.Mask.Data[i])
869
- return false;
870
- }
871
- }
872
- size_t size = Min(Mask.GetChunkCapacity(), bitmap.Mask.GetChunkCapacity());
873
- for (size_t i = 0; i < size; ++i) {
874
- if (Mask.Data[i] != bitmap.Mask.Data[i])
875
- return false;
876
- }
877
- return true;
878
- }
879
-
880
- template <class T>
881
- Y_FORCE_INLINE bool Equal(const TBitMapOps<T>& bitmap) const {
882
- return Equal(TThis(bitmap));
883
- }
884
-
885
- int Compare(const TThis& bitmap) const {
886
- size_t size = Min(Mask.GetChunkCapacity(), bitmap.Mask.GetChunkCapacity());
887
- int res = ::memcmp(Mask.Data, bitmap.Mask.Data, size * sizeof(TChunk));
888
- if (0 != res || Mask.GetChunkCapacity() == bitmap.Mask.GetChunkCapacity())
889
- return res;
890
-
891
- if (Mask.GetChunkCapacity() > bitmap.Mask.GetChunkCapacity()) {
892
- for (size_t i = bitmap.Mask.GetChunkCapacity(); i < Mask.GetChunkCapacity(); ++i) {
893
- if (0 != Mask.Data[i])
894
- return 1;
895
- }
896
- } else {
897
- for (size_t i = Mask.GetChunkCapacity(); i < bitmap.Mask.GetChunkCapacity(); ++i) {
898
- if (0 != bitmap.Mask.Data[i])
899
- return -1;
900
- }
901
- }
902
- return 0;
903
- }
904
-
905
- template <class T>
906
- Y_FORCE_INLINE int Compare(const TBitMapOps<T>& bitmap) const {
907
- return Compare(TThis(bitmap));
908
- }
909
-
910
- // For backward compatibility
911
- Y_FORCE_INLINE static int Compare(const TThis& l, const TThis& r) {
912
- return l.Compare(r);
913
- }
914
-
915
- size_t FirstNonZeroBit() const {
916
- for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i) {
917
- if (Mask.Data[i]) {
918
- // CountTrailingZeroBits() expects unsigned types not smaller than unsigned int. So, convert before calling
919
- return BitsPerChunk * i + CountTrailingZeroBits(TIntType(Mask.Data[i]));
920
- }
921
- }
922
- return Size();
923
- }
924
-
925
- // Returns position of the next non-zero bit, which offset is greater than specified pos
926
- // Typical loop for iterating bits:
927
- // for (size_t pos = bits.FirstNonZeroBit(); pos != bits.Size(); pos = bits.NextNonZeroBit(pos)) {
928
- // ...
929
- // }
930
- // See Y_FOR_EACH_BIT macro definition at the bottom
931
- size_t NextNonZeroBit(size_t pos) const {
932
- size_t i = (pos + 1) >> DivCount;
933
- if (i < Mask.GetChunkCapacity()) {
934
- const size_t offset = (pos + 1) & ModMask;
935
- // Process the current chunk
936
- if (offset) {
937
- // Zero already iterated trailing bits using mask
938
- const TChunk val = Mask.Data[i] & ((~TChunk(0)) << offset);
939
- if (val) {
940
- return BitsPerChunk * i + CountTrailingZeroBits(TIntType(val));
941
- }
942
- // Continue with other chunks
943
- ++i;
944
- }
945
-
946
- for (; i < Mask.GetChunkCapacity(); ++i) {
947
- if (Mask.Data[i]) {
948
- return BitsPerChunk * i + CountTrailingZeroBits(TIntType(Mask.Data[i]));
949
- }
950
- }
951
- }
952
- return Size();
953
- }
954
-
955
- Y_FORCE_INLINE size_t Count() const {
956
- size_t count = 0;
957
- for (size_t i = 0; i < Mask.GetChunkCapacity(); ++i)
958
- count += ::NBitMapPrivate::CountBitsPrivate(Mask.Data[i]);
959
- return count;
960
- }
961
-
962
- void Save(IOutputStream* out) const {
963
- ::Save(out, ui8(sizeof(TChunk)));
964
- ::Save(out, ui64(Size()));
965
- ::SavePodArray(out, Mask.Data, Mask.GetChunkCapacity());
966
- }
967
-
968
- void Load(IInputStream* inp) {
969
- ui8 chunkSize = 0;
970
- ::Load(inp, chunkSize);
971
- Y_VERIFY(size_t(chunkSize) == sizeof(TChunk), "Chunk size is not the same");
972
-
973
- ui64 bitCount64 = 0;
974
- ::Load(inp, bitCount64);
975
- size_t bitCount = size_t(bitCount64);
976
- Reserve(bitCount);
977
-
978
- size_t chunkCount = 0;
979
- if (bitCount > 0) {
980
- chunkCount = ((bitCount - 1) >> DivCount) + 1;
981
- ::LoadPodArray(inp, Mask.Data, chunkCount);
982
- }
983
-
984
- if (chunkCount < Mask.GetChunkCapacity()) {
985
- ::memset(Mask.Data + chunkCount, 0, (Mask.GetChunkCapacity() - chunkCount) * sizeof(TChunk));
986
- }
987
- Mask.Sanitize();
988
- }
989
-
990
- inline size_t Hash() const {
991
- THash<TChunk> chunkHasher;
992
-
993
- size_t hash = chunkHasher(0);
994
- bool tailSkipped = false;
995
- for (size_t i = Mask.GetChunkCapacity(); i > 0; --i) {
996
- if (tailSkipped || Mask.Data[i - 1]) {
997
- hash = ::CombineHashes(hash, chunkHasher(Mask.Data[i - 1]));
998
- tailSkipped = true;
999
- }
1000
- }
1001
-
1002
- return hash;
1003
- }
1004
-
1005
- inline const TChunk* GetChunks() const {
1006
- return Mask.Data;
1007
- }
1008
-
1009
- constexpr size_t GetChunkCount() const noexcept {
1010
- return Mask.GetChunkCapacity();
1011
- }
1012
- };
1013
-
1014
- template <class X, class Y>
1015
- inline TBitMapOps<X> operator&(const TBitMapOps<X>& x, const TBitMapOps<Y>& y) {
1016
- return TBitMapOps<X>(x).And(y);
1017
- }
1018
-
1019
- template <class X>
1020
- inline TBitMapOps<X> operator&(const TBitMapOps<X>& x, const typename TBitMapOps<X>::TChunk& y) {
1021
- return TBitMapOps<X>(x).And(y);
1022
- }
1023
-
1024
- template <class X>
1025
- inline TBitMapOps<X> operator&(const typename TBitMapOps<X>::TChunk& x, const TBitMapOps<X>& y) {
1026
- return TBitMapOps<X>(x).And(y);
1027
- }
1028
-
1029
- template <class X, class Y>
1030
- inline TBitMapOps<X> operator|(const TBitMapOps<X>& x, const TBitMapOps<Y>& y) {
1031
- return TBitMapOps<X>(x).Or(y);
1032
- }
1033
-
1034
- template <class X>
1035
- inline TBitMapOps<X> operator|(const TBitMapOps<X>& x, const typename TBitMapOps<X>::TChunk& y) {
1036
- return TBitMapOps<X>(x).Or(y);
1037
- }
1038
-
1039
- template <class X>
1040
- inline TBitMapOps<X> operator|(const typename TBitMapOps<X>::TChunk& x, const TBitMapOps<X>& y) {
1041
- return TBitMapOps<X>(x).Or(y);
1042
- }
1043
-
1044
- template <class X, class Y>
1045
- inline TBitMapOps<X> operator^(const TBitMapOps<X>& x, const TBitMapOps<Y>& y) {
1046
- return TBitMapOps<X>(x).Xor(y);
1047
- }
1048
-
1049
- template <class X>
1050
- inline TBitMapOps<X> operator^(const TBitMapOps<X>& x, const typename TBitMapOps<X>::TChunk& y) {
1051
- return TBitMapOps<X>(x).Xor(y);
1052
- }
1053
-
1054
- template <class X>
1055
- inline TBitMapOps<X> operator^(const typename TBitMapOps<X>::TChunk& x, const TBitMapOps<X>& y) {
1056
- return TBitMapOps<X>(x).Xor(y);
1057
- }
1058
-
1059
- template <class X, class Y>
1060
- inline TBitMapOps<X> operator-(const TBitMapOps<X>& x, const TBitMapOps<Y>& y) {
1061
- return TBitMapOps<X>(x).SetDifference(y);
1062
- }
1063
-
1064
- template <class X>
1065
- inline TBitMapOps<X> operator-(const TBitMapOps<X>& x, const typename TBitMapOps<X>::TChunk& y) {
1066
- return TBitMapOps<X>(x).SetDifference(y);
1067
- }
1068
-
1069
- template <class X>
1070
- inline TBitMapOps<X> operator-(const typename TBitMapOps<X>::TChunk& x, const TBitMapOps<X>& y) {
1071
- return TBitMapOps<X>(x).SetDifference(y);
1072
- }
1073
-
1074
- template <class X>
1075
- inline TBitMapOps<X> operator~(const TBitMapOps<X>& x) {
1076
- return TBitMapOps<X>(x).Flip();
1077
- }
1078
-
1079
- /////////////////// Specialization ///////////////////////////
1080
-
1081
- template <size_t BitCount, typename TChunkType /*= ui64*/>
1082
- class TBitMap: public TBitMapOps<TFixedBitMapTraits<BitCount, TChunkType>> {
1083
- private:
1084
- using TBase = TBitMapOps<TFixedBitMapTraits<BitCount, TChunkType>>;
1085
-
1086
- public:
1087
- TBitMap()
1088
- : TBase()
1089
- {
1090
- }
1091
-
1092
- TBitMap(typename TBase::TChunk val)
1093
- : TBase(val)
1094
- {
1095
- }
1096
-
1097
- TBitMap(const TBitMap<BitCount, TChunkType>&) = default;
1098
-
1099
- template <class T>
1100
- TBitMap(const TBitMapOps<T>& bitmap)
1101
- : TBase(bitmap)
1102
- {
1103
- }
1104
- };
1105
-
1106
- using TDynBitMap = TBitMapOps<TDynamicBitMapTraits<ui64>>;
1107
-
1108
- #define Y_FOR_EACH_BIT(var, bitmap) for (size_t var = (bitmap).FirstNonZeroBit(); var != (bitmap).Size(); var = (bitmap).NextNonZeroBit(var))
1109
-
1110
- template <typename TTraits>
1111
- struct THash<TBitMapOps<TTraits>> {
1112
- size_t operator()(const TBitMapOps<TTraits>& elem) const {
1113
- return elem.Hash();
1114
- }
1115
- };