MySQL 9.3.0
Source Code Documentation
overflow_bitset.h
Go to the documentation of this file.
1/* Copyright (c) 2021, 2025, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef SQL_JOIN_OPTIMIZER_OVERFLOW_BITSET_H
25#define SQL_JOIN_OPTIMIZER_OVERFLOW_BITSET_H
26
27/**
28 @file
29
30 OverflowBitset is a fixed-size (once allocated) bitmap that is optimized for
31 the common case of few elements, yet can support an arbitrary number.
32 For 63 bits or fewer, it fits into a simple 64-bit machine word; for more,
33 it instead “overflows” to a pointer to externally-allocated storage
34 (typically on a MEM_ROOT). In other words, one loses only 1 bit for the common
35 (small) case. For small (“inline”) bit sets, most operations are simple
36 bit-twiddling operations, adding only a small and easily-predicatable test to
37 each of them.
38
39 This is possible because a pointer to external storage of 64-bit values
40 will (must) be aligned to 8 bytes, so the lowest bit of the address
41 cannot be 1. We can use this to distinguish between inline and non-inline
42 sets.
43
44 There are two classes: OverflowBitset is an immutable (const) bitset with
45 value semantics; it can be freely assigned, copied, stored in AccessPath
46 (which also has value semantics), etc. with no worries, but not modified.
47 (The storage is never freed; it is presumed to live on a MEM_ROOT.)
48 MutableOverflowBitset can be modified, but it is move-only; this avoids
49 the problem where one takes a copy of a (non-inline) bit set and then
50 modify one of them, not expecting that modification to also affect
51 the other one. (Ie., it avoids the design mistake in String, where the
52 copy constructor unexpectedly can become a shallow copy, but not always.)
53 MutableOverflowBitset can be converted to OverflowBitset by means of a
54 move, at which point it is effectively frozen and cannot be changed further.
55
56 For simplicity, most operations over OverflowBitset require the two
57 bit sets to be of the same size. The exception is that an all-zero inline
58 bit set can be tested against others in Overlaps(); this is useful so that we
59 don't need to initialize bit sets in AccessPath that never have any filters
60 set (the default constructor makes them inline and all-zero).
61 */
62
63#include <array>
64#include <bit>
65#include <cassert>
66#include <climits>
67#include <cstddef>
68#include <cstdint>
69#include <cstring>
70#include <functional>
71#include <iterator>
72#include <tuple>
73#include <type_traits>
74#include <utility>
75
76#include "my_alloc.h"
78
80
82 public:
83 // Default is to zero-initialize.
85
86 explicit OverflowBitset(uint32_t bits) : m_bits((uintptr_t{bits} << 1) | 1) {
87 // Check that we didn't overflow on 32-bit platforms.
88 assert((m_bits >> 1) == bits);
89 }
90
91 // Reset the entire bitset to an inline all-zero bitset.
92 // This is distinct from ClearBits(), which only clears a given number
93 // of bits, and does not change the capacity.
94 void Clear() { m_bits = 1; }
95
96 // Value semantics, so:
97 OverflowBitset(const OverflowBitset &) = default;
101
102 // Can move-convert MutableOverflowBitset into OverflowBitset.
105
106 bool is_inline() const { return m_bits & 1; }
107
108 size_t capacity() const {
109 if (is_inline()) {
110 return kInlineBits;
111 } else {
112 return m_ext->m_num_blocks * sizeof(uint64_t) * CHAR_BIT;
113 }
114 }
115
117
118 bool IsContainedIn(const MEM_ROOT *mem_root) const {
119 return !is_inline() && mem_root->Contains(m_ext);
120 }
121
122 // NOTE: These could also be made to take in MutableOverflowBitset(),
123 // simply by templating them (due to the private inheritance).
130
131 protected:
132 struct Ext {
134 uint64_t m_bits[1];
135 };
136 static_assert(alignof(Ext) % 2 == 0, "The lowest bit must be zero.");
137
138 union {
139 uint64_t m_bits; // Lowest bit must be 1.
141 };
142 static constexpr int kInlineBits = sizeof(m_bits) * CHAR_BIT - 1;
143
144 void InitOverflow(MEM_ROOT *mem_root, size_t capacity);
151
152 friend bool Overlaps(OverflowBitset a, OverflowBitset b);
154 friend bool IsSubset(OverflowBitset a, OverflowBitset b);
156 friend bool IsBitSet(int bit_num, OverflowBitset x);
157 friend bool IsBitSetOverflow(int bit_num, OverflowBitset x);
158 friend bool IsEmpty(OverflowBitset x);
159 friend int PopulationCount(OverflowBitset x);
161 template <size_t N, class Combine>
164};
165
166// Because OverflowBitset is designed for value semantics, it should be cheap to
167// pass by value, so we want it to be small and trivially copyable.
168static_assert(
169 sizeof(OverflowBitset) <= sizeof(uint64_t),
170 "OverflowBitset is intended to be as compact as a regular 64-bit set.");
171static_assert(std::is_trivially_copyable_v<OverflowBitset>,
172 "OverflowBitset is intended to be trivally copyable.");
173
174// Private inheritance, so that the only way of converting to OverflowBitset
175// for external callers is by a move-convert.
177 public:
178 // NOTE: Will round up the given capacity to either 31/63 (for anything
179 // smaller than 32/64), or to the next multiple of 64 (for anything else).
181 if (capacity <= kInlineBits) {
182 m_bits = 1;
183 } else {
185 }
186 }
187
188 // Move-only, so that we don't inadvertently modify aliases.
192 m_bits = other.m_bits;
193 other.m_bits = 1;
194 }
196 m_bits = other.m_bits;
197 other.m_bits = 1;
198 return *this;
199 }
200
201 void SetBit(int bit_num) {
202 assert(bit_num >= 0);
203 assert(static_cast<size_t>(bit_num) < capacity());
204 const unsigned bn = bit_num; // To avoid sign extension taking time.
205 if (is_inline()) {
206 assert(bit_num < 63);
207 m_bits |= uint64_t{1} << (bn + 1);
208 } else {
209 m_ext->m_bits[bn / 64] |= uint64_t{1} << (bn % 64);
210 }
211 }
212
213 void ClearBits(int begin_bit_num, int end_bit_num) {
214 assert(begin_bit_num >= 0);
215 assert(end_bit_num >= 0);
216 assert(begin_bit_num <= end_bit_num);
217 assert(static_cast<size_t>(begin_bit_num) <= capacity());
218 assert(static_cast<size_t>(end_bit_num) <= capacity());
219 if (is_inline()) {
220 m_bits &= ~BitsBetween(begin_bit_num + 1, end_bit_num + 1);
221 } else {
222 ClearBitsOverflow(begin_bit_num, end_bit_num);
223 }
224 }
225
226 inline void ClearBit(int bit_num) {
227 // TODO: Consider a more specialized version here if it starts
228 // showing up in the profiles.
229 ClearBits(bit_num, bit_num + 1);
230 }
231
234 }
235
236 private:
237 friend bool IsBitSet(int bit_num, const MutableOverflowBitset &x);
238 friend bool Overlaps(OverflowBitset a, const MutableOverflowBitset &b);
239 friend bool Overlaps(const MutableOverflowBitset &a,
240 const MutableOverflowBitset &b);
241 friend bool Overlaps(const MutableOverflowBitset &a, OverflowBitset b);
242 friend bool IsSubset(OverflowBitset a, const MutableOverflowBitset &b);
243 friend bool IsSubset(const MutableOverflowBitset &a,
244 const MutableOverflowBitset &b);
245 friend bool IsSubset(const MutableOverflowBitset &a, OverflowBitset b);
246 friend bool IsEmpty(const MutableOverflowBitset &x);
247 friend int PopulationCount(const MutableOverflowBitset &x);
248 void SetBitOverflow(int bit_num);
249 void ClearBitsOverflow(int begin_bit_num, int end_bit_num);
250
251 friend class OverflowBitset;
252};
253
255 m_bits = other.m_bits;
256 other.m_bits = 1;
257}
258
260 MutableOverflowBitset &&other) {
261 m_bits = other.m_bits;
262 other.m_bits = 1;
263 return *this;
264}
265
268 if (is_inline()) {
269 ret.m_bits = m_bits;
270 } else {
271 memcpy(ret.m_ext, m_ext,
272 sizeof(m_ext->m_num_blocks) +
273 m_ext->m_num_blocks * sizeof(m_ext->m_bits));
274 }
275 return ret;
276}
277
280 OverflowBitset b) {
281 assert(a.is_inline() == b.is_inline());
282 assert(a.capacity() == b.capacity());
283 if (a.is_inline()) {
285 ret.m_bits = a.m_bits | b.m_bits;
286 return ret;
287 } else {
288 return OrOverflow(mem_root, a, b);
289 }
290}
291
294 OverflowBitset b) {
295 assert(a.is_inline() == b.is_inline());
296 assert(a.capacity() == b.capacity());
297 if (a.is_inline()) {
299 ret.m_bits = a.m_bits & b.m_bits;
300 return ret;
301 } else {
302 return AndOverflow(mem_root, a, b);
303 }
304}
305
308 OverflowBitset b) {
309 assert(a.is_inline() == b.is_inline());
310 assert(a.capacity() == b.capacity());
311 if (a.is_inline()) {
313 ret.m_bits = (a.m_bits ^ b.m_bits) | 1;
314 return ret;
315 } else {
316 return XorOverflow(mem_root, a, b);
317 }
318}
319
320// Definitions overloading utility functions in bit_utils.h, making it generally
321// possible to use OverflowBitset as we use regular uint64_t bitsets
322// (e.g. NodeMap).
323//
324// Since one cannot easily combine non-inline OverflowBitsets without allocating
325// memory, the BitsSetIn() overload supports combining state as-we-go.
326// For instance, where you would normally write (for uint64_t)
327//
328// for (int bit_idx : BitsSetIn(x & y))
329//
330// you would use this variation for OverflowBitsets:
331//
332// for (int bit_idx : BitsSetInBoth(x, y))
333//
334// Under the hood, BitsSetInBoth() calls a Combine functor that ANDs the two
335// uint64_t bitwise (for inline bitsets only once, but for overflow bitsets
336// multiple times, on-demand as we iterate), which can potentially save
337// on a lot of bitscan operations and loop iterations versus trying to test
338// one-by-one. This can be extended to any number of arguments.
339//
340// Combine::operator() must be const, Combine must be movable (but can have
341// state).
342
343template <size_t N, class Combine>
345 public:
346 class iterator {
347 private:
348 const Combine *m_combine;
349 uint64_t m_state;
350
351 // m_next holds, for each bitset array, the pointer to the next
352 // uint64_t to be processed/read (once m_state is zero, ie.,
353 // there are no more bits in the current state). When m_next[0] == m_end,
354 // iteration is over. For inline bitsets, m_next[0] == m_end == nullptr,
355 // so once the first 64-bit group is processed, we are done.
356 // (We assume all arrays have the same length, so we only need one
357 // end pointer.)
358 std::array<const uint64_t *, N> m_next;
359 const uint64_t *const m_end;
360 // The number of bits in the words preceding the current word (m_state). The
361 // bit index in the overflow bitset is found by adding m_base to the index
362 // of the bit inside the current word. m_base is always a multiple of 64.
364
365 public:
366 using iterator_category = std::forward_iterator_tag;
367 using difference_type = size_t;
368 using value_type = size_t;
371
372 // For inline bitsets.
373 iterator(uint64_t state, const Combine *combine)
374 : m_combine(combine), m_state(state), m_end(nullptr), m_base(0) {
375 m_next[0] = nullptr;
376 }
377
378 // For overflow bitsets.
379 iterator(const std::array<const uint64_t *, N> begin, const uint64_t *end,
380 const Combine *combine)
381 : m_combine(combine),
382 m_state(0),
383 m_next(begin),
384 m_end(end),
385 m_base(-64) {
387 }
388
389 bool operator==(const iterator &other) const {
390 assert(m_end == other.m_end);
391 return m_state == other.m_state && m_next[0] == other.m_next[0];
392 }
393 size_t operator*() const { return FindLowestBitSet(m_state) + m_base; }
395 // Clear the lowest set bit.
396 assert(m_state != 0);
397 m_state = m_state & (m_state - 1);
398
399 // If we've seen the last bit in the current word, move forward to the
400 // next non-empty word.
402 return *this;
403 }
404
405 private:
406 // Skip past all empty words so that the iterator points into the first
407 // non-empty word.
409 while (m_state == 0 && m_next[0] != m_end) {
411 for (size_t i = 0; i < N; ++i) {
412 ++m_next[i];
413 }
414 m_base += 64;
415 }
416 }
417
418 // Read the next word from each of the bitsets and combine them into a
419 // single word using the Combine functor.
420 uint64_t ReadAndCombine() const {
421 std::array<uint64_t, N> bits;
422 for (size_t i = 0; i < N; ++i) {
423 bits[i] = *m_next[i];
424 }
425 return std::apply(*m_combine, bits);
426 }
427 };
428
429 OverflowBitsetBitsIn(std::array<OverflowBitset, N> bitsets, Combine combine)
430 : m_bitsets(bitsets), m_combine(std::move(combine)) {}
431
432 iterator begin() const {
433 if (m_bitsets[0].is_inline()) {
434 std::array<uint64_t, N> bits;
435 for (size_t i = 0; i < N; ++i) {
436 assert(m_bitsets[i].is_inline());
437 bits[i] = m_bitsets[i].m_bits;
438 }
439 uint64_t state = std::apply(m_combine, bits);
440 return iterator{state >> 1, &m_combine};
441 } else {
442 std::array<const uint64_t *, N> ptrs;
443 for (size_t i = 0; i < N; ++i) {
444 assert(!m_bitsets[i].is_inline());
445 assert(m_bitsets[i].capacity() == m_bitsets[0].capacity());
446 ptrs[i] = m_bitsets[i].m_ext->m_bits;
447 }
448 const uint64_t *end =
449 m_bitsets[0].m_ext->m_bits + m_bitsets[0].m_ext->m_num_blocks;
450 return iterator{ptrs, end, &m_combine};
451 }
452 }
453 iterator end() const {
454 if (m_bitsets[0].is_inline()) {
455 return iterator{0, &m_combine};
456 } else {
457 std::array<const uint64_t *, N> ptrs;
458 for (size_t i = 0; i < N; ++i) {
459 assert(m_bitsets[i].is_inline() == m_bitsets[0].is_inline());
460 assert(m_bitsets[i].capacity() == m_bitsets[0].capacity());
461 ptrs[i] = m_bitsets[i].m_ext->m_bits + m_bitsets[i].m_ext->m_num_blocks;
462 }
463 return iterator{ptrs, ptrs[0], &m_combine};
464 }
465 }
466
467 private:
468 const std::array<OverflowBitset, N> m_bitsets;
469 const Combine m_combine;
470};
471
472/// Get a container-like interface of an OverflowBitset, to allow passing it to
473/// algorithms that work on iterators.
474inline auto BitsSetIn(OverflowBitset bitset) {
475 return OverflowBitsetBitsIn{std::array{bitset}, std::identity{}};
476}
477
478/// Get a container-like interface for the bits set in both of the two bitsets.
479inline auto BitsSetInBoth(OverflowBitset bitset_a, OverflowBitset bitset_b) {
480 return OverflowBitsetBitsIn{std::array{bitset_a, bitset_b}, std::bit_and{}};
481}
482
484
486 if (a.m_bits == 1 || b.m_bits == 1) {
487 // Empty and inline, so nothing overlaps.
488 // This is a special case that does not require the two
489 // sets to be of the same size (see file comment).
490 return false;
491 }
492 assert(a.is_inline() == b.is_inline());
493 assert(a.capacity() == b.capacity());
494 if (a.is_inline()) {
495 return (a.m_bits & b.m_bits) != 1;
496 } else {
497 return OverlapsOverflow(a, b);
498 }
499}
500
502 return Overlaps(a, static_cast<const OverflowBitset &>(b));
503}
504
505inline bool Overlaps(const MutableOverflowBitset &a,
506 const MutableOverflowBitset &b) {
507 return Overlaps(static_cast<const OverflowBitset &>(a),
508 static_cast<const OverflowBitset &>(b));
509}
510
512 return Overlaps(static_cast<const OverflowBitset &>(a), b);
513}
514
515/// Is 'a' a subset of 'b'?
517 assert(a.is_inline() == b.is_inline());
518 assert(a.capacity() == b.capacity());
519 if (a.is_inline()) {
520 return IsSubset(a.m_bits, b.m_bits);
521 } else {
522 return IsSubsetOverflow(a, b);
523 }
524}
525
526inline bool IsBitSet(int bit_num, OverflowBitset x) {
527 assert(bit_num >= 0);
528 assert(static_cast<size_t>(bit_num) < x.capacity());
529 const unsigned bn = bit_num; // To avoid sign extension taking time.
530 if (x.is_inline()) {
531 return Overlaps(x.m_bits, uint64_t{1} << (bn + 1));
532 } else {
533 return Overlaps(x.m_ext->m_bits[bn / 64], uint64_t{1} << (bn % 64));
534 }
535}
536
537inline bool IsBitSet(int bit_num, const MutableOverflowBitset &x) {
538 return IsBitSet(bit_num, static_cast<const OverflowBitset &>(x));
539}
540
541/// Is 'a' a subset of 'b'?
543 return IsSubset(a, static_cast<const OverflowBitset &>(b));
544}
545
546/// Is 'a' a subset of 'b'?
547inline bool IsSubset(const MutableOverflowBitset &a,
548 const MutableOverflowBitset &b) {
549 return IsSubset(static_cast<const OverflowBitset &>(a),
550 static_cast<const OverflowBitset &>(b));
551}
552
553/// Is 'a' a subset of 'b'?
555 return IsSubset(static_cast<const OverflowBitset &>(a), b);
556}
557
558// This is mostly used to guard a few asserts, so it's better that it's
559// completely visible, so that the compiler can remove it totally
560// in optimized mode.
561inline bool IsEmpty(OverflowBitset x) {
562 if (x.is_inline()) {
563 return x.m_bits == 1;
564 } else {
565 for (unsigned i = 0; i < x.m_ext->m_num_blocks; ++i) {
566 if (x.m_ext->m_bits[i] != 0) {
567 return false;
568 }
569 }
570 return true;
571 }
572}
573
574inline bool IsEmpty(const MutableOverflowBitset &x) {
575 return IsEmpty(static_cast<const OverflowBitset &>(x));
576}
577
578/// Find the nuber of bits set in 'x'.
580 if (x.is_inline()) {
581 return std::popcount(x.m_bits) - 1;
582 } else {
583 return PopulationCountOverflow(x);
584 }
585}
586
587/// Find the nuber of bits set in 'x'.
589 return PopulationCount(static_cast<const OverflowBitset &>(x));
590}
591
592#endif // SQL_JOIN_OPTIMIZER_OVERFLOW_BITSET_H
Kerberos Client Authentication nullptr
Definition: auth_kerberos_client_plugin.cc:247
size_t FindLowestBitSet(uint64_t x)
Definition: bit_utils.h:66
Definition: overflow_bitset.h:176
void ClearBits(int begin_bit_num, int end_bit_num)
Definition: overflow_bitset.h:213
MutableOverflowBitset(MutableOverflowBitset &&other)
Definition: overflow_bitset.h:191
friend int PopulationCount(const MutableOverflowBitset &x)
Find the nuber of bits set in 'x'.
Definition: overflow_bitset.h:588
friend bool IsBitSet(int bit_num, const MutableOverflowBitset &x)
Definition: overflow_bitset.h:537
void ClearBitsOverflow(int begin_bit_num, int end_bit_num)
Definition: overflow_bitset.cc:81
void SetBit(int bit_num)
Definition: overflow_bitset.h:201
friend bool IsSubset(OverflowBitset a, const MutableOverflowBitset &b)
Is 'a' a subset of 'b'?
Definition: overflow_bitset.h:542
MutableOverflowBitset & operator=(const MutableOverflowBitset &)=delete
friend bool Overlaps(OverflowBitset a, const MutableOverflowBitset &b)
Definition: overflow_bitset.h:501
MutableOverflowBitset(MEM_ROOT *mem_root, size_t capacity)
Definition: overflow_bitset.h:180
friend class OverflowBitset
Definition: overflow_bitset.h:251
friend bool IsEmpty(const MutableOverflowBitset &x)
Definition: overflow_bitset.h:574
MutableOverflowBitset(const MutableOverflowBitset &)=delete
void SetBitOverflow(int bit_num)
MutableOverflowBitset & operator=(MutableOverflowBitset &&other)
Definition: overflow_bitset.h:195
void ClearBit(int bit_num)
Definition: overflow_bitset.h:226
MutableOverflowBitset Clone(MEM_ROOT *mem_root) const
Definition: overflow_bitset.h:232
Definition: overflow_bitset.h:346
const Combine * m_combine
Definition: overflow_bitset.h:348
bool operator==(const iterator &other) const
Definition: overflow_bitset.h:389
value_type * pointer
Definition: overflow_bitset.h:369
iterator(uint64_t state, const Combine *combine)
Definition: overflow_bitset.h:373
value_type & reference
Definition: overflow_bitset.h:370
size_t operator*() const
Definition: overflow_bitset.h:393
uint64_t ReadAndCombine() const
Definition: overflow_bitset.h:420
size_t difference_type
Definition: overflow_bitset.h:367
iterator(const std::array< const uint64_t *, N > begin, const uint64_t *end, const Combine *combine)
Definition: overflow_bitset.h:379
size_t value_type
Definition: overflow_bitset.h:368
std::array< const uint64_t *, N > m_next
Definition: overflow_bitset.h:358
const uint64_t *const m_end
Definition: overflow_bitset.h:359
void SkipEmptyWords()
Definition: overflow_bitset.h:408
std::forward_iterator_tag iterator_category
Definition: overflow_bitset.h:366
int m_base
Definition: overflow_bitset.h:363
iterator & operator++()
Definition: overflow_bitset.h:394
uint64_t m_state
Definition: overflow_bitset.h:349
Definition: overflow_bitset.h:344
iterator end() const
Definition: overflow_bitset.h:453
iterator begin() const
Definition: overflow_bitset.h:432
const std::array< OverflowBitset, N > m_bitsets
Definition: overflow_bitset.h:468
const Combine m_combine
Definition: overflow_bitset.h:469
OverflowBitsetBitsIn(std::array< OverflowBitset, N > bitsets, Combine combine)
Definition: overflow_bitset.h:429
Definition: overflow_bitset.h:81
friend bool IsSubset(OverflowBitset a, OverflowBitset b)
Is 'a' a subset of 'b'?
Definition: overflow_bitset.h:516
bool IsContainedIn(const MEM_ROOT *mem_root) const
Definition: overflow_bitset.h:118
static MutableOverflowBitset Or(MEM_ROOT *mem_root, OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:278
friend int PopulationCountOverflow(OverflowBitset x)
Definition: overflow_bitset.cc:139
friend bool Overlaps(OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:485
OverflowBitset()
Definition: overflow_bitset.h:84
static MutableOverflowBitset OrOverflow(MEM_ROOT *mem_root, OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.cc:42
friend bool IsSubsetOverflow(OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.cc:127
friend int PopulationCount(OverflowBitset x)
Find the nuber of bits set in 'x'.
Definition: overflow_bitset.h:579
MutableOverflowBitset Clone(MEM_ROOT *mem_root) const
Definition: overflow_bitset.h:266
size_t capacity() const
Definition: overflow_bitset.h:108
static constexpr int kInlineBits
Definition: overflow_bitset.h:142
OverflowBitset & operator=(const OverflowBitset &)=default
bool is_inline() const
Definition: overflow_bitset.h:106
static MutableOverflowBitset XorOverflow(MEM_ROOT *mem_root, OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.cc:68
friend bool OverlapsOverflow(OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.cc:115
static MutableOverflowBitset AndOverflow(MEM_ROOT *mem_root, OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.cc:55
uint64_t m_bits
Definition: overflow_bitset.h:139
OverflowBitset(const OverflowBitset &)=default
friend bool IsBitSetOverflow(int bit_num, OverflowBitset x)
friend bool IsEmpty(OverflowBitset x)
Definition: overflow_bitset.h:561
static MutableOverflowBitset And(MEM_ROOT *mem_root, OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:292
OverflowBitset(uint32_t bits)
Definition: overflow_bitset.h:86
OverflowBitset(OverflowBitset &&)=default
Ext * m_ext
Definition: overflow_bitset.h:140
static MutableOverflowBitset Xor(MEM_ROOT *mem_root, OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:306
void InitOverflow(MEM_ROOT *mem_root, size_t capacity)
Definition: overflow_bitset.cc:33
friend bool IsBitSet(int bit_num, OverflowBitset x)
Definition: overflow_bitset.h:526
void Clear()
Definition: overflow_bitset.h:94
OverflowBitset & operator=(OverflowBitset &&)=default
static MEM_ROOT mem_root
Definition: client_plugin.cc:114
This file follows Google coding style, except for the name MEM_ROOT (which is kept for historical rea...
std::atomic< Type > N
Definition: ut0counter.h:225
Definition: gcs_xcom_synode.h:64
int PopulationCountOverflow(OverflowBitset x)
Definition: overflow_bitset.cc:139
bool IsSubsetOverflow(OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.cc:127
bool IsSubset(OverflowBitset a, OverflowBitset b)
Is 'a' a subset of 'b'?
Definition: overflow_bitset.h:516
bool Overlaps(OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:485
auto BitsSetInBoth(OverflowBitset bitset_a, OverflowBitset bitset_b)
Get a container-like interface for the bits set in both of the two bitsets.
Definition: overflow_bitset.h:479
int PopulationCount(OverflowBitset x)
Find the nuber of bits set in 'x'.
Definition: overflow_bitset.h:579
bool OverlapsOverflow(OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.cc:115
auto BitsSetIn(OverflowBitset bitset)
Get a container-like interface of an OverflowBitset, to allow passing it to algorithms that work on i...
Definition: overflow_bitset.h:474
bool IsEmpty(OverflowBitset x)
Definition: overflow_bitset.h:561
bool IsBitSet(int bit_num, OverflowBitset x)
Definition: overflow_bitset.h:526
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:83
bool Contains(void *ptr) const
Returns whether this MEM_ROOT contains the given pointer, ie., whether it was given back from Alloc(n...
Definition: my_alloc.h:353
Definition: overflow_bitset.h:132
uint64_t m_bits[1]
Definition: overflow_bitset.h:134
size_t m_num_blocks
Definition: overflow_bitset.h:133