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,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
- };