MySQL 9.4.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 /// Make a bitset that has no bits set, with the given capacity.
132 static inline OverflowBitset EmptySet(MEM_ROOT *mem_root, size_t capacity);
133
134 protected:
135 struct Ext {
137 uint64_t m_bits[1];
138 };
139 static_assert(alignof(Ext) % 2 == 0, "The lowest bit must be zero.");
140
141 union {
142 uint64_t m_bits; // Lowest bit must be 1.
144 };
145 static constexpr int kInlineBits = sizeof(m_bits) * CHAR_BIT - 1;
146
147 void InitOverflow(MEM_ROOT *mem_root, size_t capacity);
154
155 friend bool Overlaps(OverflowBitset a, OverflowBitset b);
157 friend bool IsSubset(OverflowBitset a, OverflowBitset b);
159 friend bool IsBitSet(int bit_num, OverflowBitset x);
160 friend bool IsBitSetOverflow(int bit_num, OverflowBitset x);
161 friend bool IsEmpty(OverflowBitset x);
162 friend int PopulationCount(OverflowBitset x);
164 template <size_t N, class Combine>
167};
168
169// Because OverflowBitset is designed for value semantics, it should be cheap to
170// pass by value, so we want it to be small and trivially copyable.
171static_assert(
172 sizeof(OverflowBitset) <= sizeof(uint64_t),
173 "OverflowBitset is intended to be as compact as a regular 64-bit set.");
174static_assert(std::is_trivially_copyable_v<OverflowBitset>,
175 "OverflowBitset is intended to be trivally copyable.");
176
177// Private inheritance, so that the only way of converting to OverflowBitset
178// for external callers is by a move-convert.
180 public:
181 // NOTE: Will round up the given capacity to either 31/63 (for anything
182 // smaller than 32/64), or to the next multiple of 64 (for anything else).
184 if (capacity <= kInlineBits) {
185 m_bits = 1;
186 } else {
188 }
189 }
190
191 // Move-only, so that we don't inadvertently modify aliases.
195 m_bits = other.m_bits;
196 other.m_bits = 1;
197 }
199 m_bits = other.m_bits;
200 other.m_bits = 1;
201 return *this;
202 }
203
204 void SetBit(int bit_num) {
205 assert(bit_num >= 0);
206 assert(static_cast<size_t>(bit_num) < capacity());
207 const unsigned bn = bit_num; // To avoid sign extension taking time.
208 if (is_inline()) {
209 assert(bit_num < 63);
210 m_bits |= uint64_t{1} << (bn + 1);
211 } else {
212 m_ext->m_bits[bn / 64] |= uint64_t{1} << (bn % 64);
213 }
214 }
215
216 void ClearBits(int begin_bit_num, int end_bit_num) {
217 assert(begin_bit_num >= 0);
218 assert(end_bit_num >= 0);
219 assert(begin_bit_num <= end_bit_num);
220 assert(static_cast<size_t>(begin_bit_num) <= capacity());
221 assert(static_cast<size_t>(end_bit_num) <= capacity());
222 if (is_inline()) {
223 m_bits &= ~BitsBetween(begin_bit_num + 1, end_bit_num + 1);
224 } else {
225 ClearBitsOverflow(begin_bit_num, end_bit_num);
226 }
227 }
228
229 inline void ClearBit(int bit_num) {
230 // TODO: Consider a more specialized version here if it starts
231 // showing up in the profiles.
232 ClearBits(bit_num, bit_num + 1);
233 }
234
237 }
238
239 private:
240 friend bool IsBitSet(int bit_num, const MutableOverflowBitset &x);
241 friend bool Overlaps(OverflowBitset a, const MutableOverflowBitset &b);
242 friend bool Overlaps(const MutableOverflowBitset &a,
243 const MutableOverflowBitset &b);
244 friend bool Overlaps(const MutableOverflowBitset &a, OverflowBitset b);
245 friend bool IsSubset(OverflowBitset a, const MutableOverflowBitset &b);
246 friend bool IsSubset(const MutableOverflowBitset &a,
247 const MutableOverflowBitset &b);
248 friend bool IsSubset(const MutableOverflowBitset &a, OverflowBitset b);
249 friend bool IsEmpty(const MutableOverflowBitset &x);
250 friend int PopulationCount(const MutableOverflowBitset &x);
251 void SetBitOverflow(int bit_num);
252 void ClearBitsOverflow(int begin_bit_num, int end_bit_num);
253
254 friend class OverflowBitset;
255};
256
258 m_bits = other.m_bits;
259 other.m_bits = 1;
260}
261
263 MutableOverflowBitset &&other) {
264 m_bits = other.m_bits;
265 other.m_bits = 1;
266 return *this;
267}
268
271 if (is_inline()) {
272 ret.m_bits = m_bits;
273 } else {
274 memcpy(ret.m_ext, m_ext,
275 sizeof(m_ext->m_num_blocks) +
276 m_ext->m_num_blocks * sizeof(m_ext->m_bits));
277 }
278 return ret;
279}
280
283 OverflowBitset b) {
284 assert(a.is_inline() == b.is_inline());
285 assert(a.capacity() == b.capacity());
286 if (a.is_inline()) {
288 ret.m_bits = a.m_bits | b.m_bits;
289 return ret;
290 } else {
291 return OrOverflow(mem_root, a, b);
292 }
293}
294
297 OverflowBitset b) {
298 assert(a.is_inline() == b.is_inline());
299 assert(a.capacity() == b.capacity());
300 if (a.is_inline()) {
302 ret.m_bits = a.m_bits & b.m_bits;
303 return ret;
304 } else {
305 return AndOverflow(mem_root, a, b);
306 }
307}
308
311 OverflowBitset b) {
312 assert(a.is_inline() == b.is_inline());
313 assert(a.capacity() == b.capacity());
314 if (a.is_inline()) {
316 ret.m_bits = (a.m_bits ^ b.m_bits) | 1;
317 return ret;
318 } else {
319 return XorOverflow(mem_root, a, b);
320 }
321}
322
324 size_t capacity) {
326}
327
328// Definitions overloading utility functions in bit_utils.h, making it generally
329// possible to use OverflowBitset as we use regular uint64_t bitsets
330// (e.g. NodeMap).
331//
332// Since one cannot easily combine non-inline OverflowBitsets without allocating
333// memory, the BitsSetIn() overload supports combining state as-we-go.
334// For instance, where you would normally write (for uint64_t)
335//
336// for (int bit_idx : BitsSetIn(x & y))
337//
338// you would use this variation for OverflowBitsets:
339//
340// for (int bit_idx : BitsSetInBoth(x, y))
341//
342// Under the hood, BitsSetInBoth() calls a Combine functor that ANDs the two
343// uint64_t bitwise (for inline bitsets only once, but for overflow bitsets
344// multiple times, on-demand as we iterate), which can potentially save
345// on a lot of bitscan operations and loop iterations versus trying to test
346// one-by-one. This can be extended to any number of arguments.
347//
348// Combine::operator() must be const, Combine must be movable (but can have
349// state).
350
351template <size_t N, class Combine>
353 public:
354 class iterator {
355 private:
356 const Combine *m_combine;
357 uint64_t m_state;
358
359 // m_next holds, for each bitset array, the pointer to the next
360 // uint64_t to be processed/read (once m_state is zero, ie.,
361 // there are no more bits in the current state). When m_next[0] == m_end,
362 // iteration is over. For inline bitsets, m_next[0] == m_end == nullptr,
363 // so once the first 64-bit group is processed, we are done.
364 // (We assume all arrays have the same length, so we only need one
365 // end pointer.)
366 std::array<const uint64_t *, N> m_next;
367 const uint64_t *const m_end;
368 // The number of bits in the words preceding the current word (m_state). The
369 // bit index in the overflow bitset is found by adding m_base to the index
370 // of the bit inside the current word. m_base is always a multiple of 64.
372
373 public:
374 using iterator_category = std::forward_iterator_tag;
375 using difference_type = size_t;
376 using value_type = size_t;
379
380 // For inline bitsets.
381 iterator(uint64_t state, const Combine *combine)
382 : m_combine(combine), m_state(state), m_end(nullptr), m_base(0) {
383 m_next[0] = nullptr;
384 }
385
386 // For overflow bitsets.
387 iterator(const std::array<const uint64_t *, N> begin, const uint64_t *end,
388 const Combine *combine)
389 : m_combine(combine),
390 m_state(0),
391 m_next(begin),
392 m_end(end),
393 m_base(-64) {
395 }
396
397 bool operator==(const iterator &other) const {
398 assert(m_end == other.m_end);
399 return m_state == other.m_state && m_next[0] == other.m_next[0];
400 }
401 size_t operator*() const { return FindLowestBitSet(m_state) + m_base; }
403 // Clear the lowest set bit.
404 assert(m_state != 0);
405 m_state = m_state & (m_state - 1);
406
407 // If we've seen the last bit in the current word, move forward to the
408 // next non-empty word.
410 return *this;
411 }
412
413 private:
414 // Skip past all empty words so that the iterator points into the first
415 // non-empty word.
417 while (m_state == 0 && m_next[0] != m_end) {
419 for (size_t i = 0; i < N; ++i) {
420 ++m_next[i];
421 }
422 m_base += 64;
423 }
424 }
425
426 // Read the next word from each of the bitsets and combine them into a
427 // single word using the Combine functor.
428 uint64_t ReadAndCombine() const {
429 std::array<uint64_t, N> bits;
430 for (size_t i = 0; i < N; ++i) {
431 bits[i] = *m_next[i];
432 }
433 return std::apply(*m_combine, bits);
434 }
435 };
436
437 OverflowBitsetBitsIn(std::array<OverflowBitset, N> bitsets, Combine combine)
438 : m_bitsets(bitsets), m_combine(std::move(combine)) {}
439
440 iterator begin() const {
441 if (m_bitsets[0].is_inline()) {
442 std::array<uint64_t, N> bits;
443 for (size_t i = 0; i < N; ++i) {
444 assert(m_bitsets[i].is_inline());
445 bits[i] = m_bitsets[i].m_bits;
446 }
447 uint64_t state = std::apply(m_combine, bits);
448 return iterator{state >> 1, &m_combine};
449 } else {
450 std::array<const uint64_t *, N> ptrs;
451 for (size_t i = 0; i < N; ++i) {
452 assert(!m_bitsets[i].is_inline());
453 assert(m_bitsets[i].capacity() == m_bitsets[0].capacity());
454 ptrs[i] = m_bitsets[i].m_ext->m_bits;
455 }
456 const uint64_t *end =
457 m_bitsets[0].m_ext->m_bits + m_bitsets[0].m_ext->m_num_blocks;
458 return iterator{ptrs, end, &m_combine};
459 }
460 }
461 iterator end() const {
462 if (m_bitsets[0].is_inline()) {
463 return iterator{0, &m_combine};
464 } else {
465 std::array<const uint64_t *, N> ptrs;
466 for (size_t i = 0; i < N; ++i) {
467 assert(m_bitsets[i].is_inline() == m_bitsets[0].is_inline());
468 assert(m_bitsets[i].capacity() == m_bitsets[0].capacity());
469 ptrs[i] = m_bitsets[i].m_ext->m_bits + m_bitsets[i].m_ext->m_num_blocks;
470 }
471 return iterator{ptrs, ptrs[0], &m_combine};
472 }
473 }
474
475 private:
476 const std::array<OverflowBitset, N> m_bitsets;
477 const Combine m_combine;
478};
479
480/// Get a container-like interface of an OverflowBitset, to allow passing it to
481/// algorithms that work on iterators.
482inline auto BitsSetIn(OverflowBitset bitset) {
483 return OverflowBitsetBitsIn{std::array{bitset}, std::identity{}};
484}
485
486/// Get a container-like interface for the bits set in both of the two bitsets.
487inline auto BitsSetInBoth(OverflowBitset bitset_a, OverflowBitset bitset_b) {
488 return OverflowBitsetBitsIn{std::array{bitset_a, bitset_b}, std::bit_and{}};
489}
490
492
494 if (a.m_bits == 1 || b.m_bits == 1) {
495 // Empty and inline, so nothing overlaps.
496 // This is a special case that does not require the two
497 // sets to be of the same size (see file comment).
498 return false;
499 }
500 assert(a.is_inline() == b.is_inline());
501 assert(a.capacity() == b.capacity());
502 if (a.is_inline()) {
503 return (a.m_bits & b.m_bits) != 1;
504 } else {
505 return OverlapsOverflow(a, b);
506 }
507}
508
510 return Overlaps(a, static_cast<const OverflowBitset &>(b));
511}
512
513inline bool Overlaps(const MutableOverflowBitset &a,
514 const MutableOverflowBitset &b) {
515 return Overlaps(static_cast<const OverflowBitset &>(a),
516 static_cast<const OverflowBitset &>(b));
517}
518
520 return Overlaps(static_cast<const OverflowBitset &>(a), b);
521}
522
523/// Is 'a' a subset of 'b'?
525 assert(a.is_inline() == b.is_inline());
526 assert(a.capacity() == b.capacity());
527 if (a.is_inline()) {
528 return IsSubset(a.m_bits, b.m_bits);
529 } else {
530 return IsSubsetOverflow(a, b);
531 }
532}
533
534inline bool IsBitSet(int bit_num, OverflowBitset x) {
535 assert(bit_num >= 0);
536 assert(static_cast<size_t>(bit_num) < x.capacity());
537 const unsigned bn = bit_num; // To avoid sign extension taking time.
538 if (x.is_inline()) {
539 return Overlaps(x.m_bits, uint64_t{1} << (bn + 1));
540 } else {
541 return Overlaps(x.m_ext->m_bits[bn / 64], uint64_t{1} << (bn % 64));
542 }
543}
544
545inline bool IsBitSet(int bit_num, const MutableOverflowBitset &x) {
546 return IsBitSet(bit_num, static_cast<const OverflowBitset &>(x));
547}
548
549/// Is 'a' a subset of 'b'?
551 return IsSubset(a, static_cast<const OverflowBitset &>(b));
552}
553
554/// Is 'a' a subset of 'b'?
555inline bool IsSubset(const MutableOverflowBitset &a,
556 const MutableOverflowBitset &b) {
557 return IsSubset(static_cast<const OverflowBitset &>(a),
558 static_cast<const OverflowBitset &>(b));
559}
560
561/// Is 'a' a subset of 'b'?
563 return IsSubset(static_cast<const OverflowBitset &>(a), b);
564}
565
566// This is mostly used to guard a few asserts, so it's better that it's
567// completely visible, so that the compiler can remove it totally
568// in optimized mode.
569inline bool IsEmpty(OverflowBitset x) {
570 if (x.is_inline()) {
571 return x.m_bits == 1;
572 } else {
573 for (unsigned i = 0; i < x.m_ext->m_num_blocks; ++i) {
574 if (x.m_ext->m_bits[i] != 0) {
575 return false;
576 }
577 }
578 return true;
579 }
580}
581
582inline bool IsEmpty(const MutableOverflowBitset &x) {
583 return IsEmpty(static_cast<const OverflowBitset &>(x));
584}
585
586/// Find the nuber of bits set in 'x'.
588 if (x.is_inline()) {
589 return std::popcount(x.m_bits) - 1;
590 } else {
591 return PopulationCountOverflow(x);
592 }
593}
594
595/// Find the nuber of bits set in 'x'.
597 return PopulationCount(static_cast<const OverflowBitset &>(x));
598}
599
600#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:179
void ClearBits(int begin_bit_num, int end_bit_num)
Definition: overflow_bitset.h:216
MutableOverflowBitset(MutableOverflowBitset &&other)
Definition: overflow_bitset.h:194
friend int PopulationCount(const MutableOverflowBitset &x)
Find the nuber of bits set in 'x'.
Definition: overflow_bitset.h:596
friend bool IsBitSet(int bit_num, const MutableOverflowBitset &x)
Definition: overflow_bitset.h:545
void ClearBitsOverflow(int begin_bit_num, int end_bit_num)
Definition: overflow_bitset.cc:81
void SetBit(int bit_num)
Definition: overflow_bitset.h:204
friend bool IsSubset(OverflowBitset a, const MutableOverflowBitset &b)
Is 'a' a subset of 'b'?
Definition: overflow_bitset.h:550
MutableOverflowBitset & operator=(const MutableOverflowBitset &)=delete
friend bool Overlaps(OverflowBitset a, const MutableOverflowBitset &b)
Definition: overflow_bitset.h:509
MutableOverflowBitset(MEM_ROOT *mem_root, size_t capacity)
Definition: overflow_bitset.h:183
friend class OverflowBitset
Definition: overflow_bitset.h:254
friend bool IsEmpty(const MutableOverflowBitset &x)
Definition: overflow_bitset.h:582
MutableOverflowBitset(const MutableOverflowBitset &)=delete
void SetBitOverflow(int bit_num)
MutableOverflowBitset & operator=(MutableOverflowBitset &&other)
Definition: overflow_bitset.h:198
void ClearBit(int bit_num)
Definition: overflow_bitset.h:229
MutableOverflowBitset Clone(MEM_ROOT *mem_root) const
Definition: overflow_bitset.h:235
Definition: overflow_bitset.h:354
const Combine * m_combine
Definition: overflow_bitset.h:356
bool operator==(const iterator &other) const
Definition: overflow_bitset.h:397
value_type * pointer
Definition: overflow_bitset.h:377
iterator(uint64_t state, const Combine *combine)
Definition: overflow_bitset.h:381
value_type & reference
Definition: overflow_bitset.h:378
size_t operator*() const
Definition: overflow_bitset.h:401
uint64_t ReadAndCombine() const
Definition: overflow_bitset.h:428
size_t difference_type
Definition: overflow_bitset.h:375
iterator(const std::array< const uint64_t *, N > begin, const uint64_t *end, const Combine *combine)
Definition: overflow_bitset.h:387
size_t value_type
Definition: overflow_bitset.h:376
std::array< const uint64_t *, N > m_next
Definition: overflow_bitset.h:366
const uint64_t *const m_end
Definition: overflow_bitset.h:367
void SkipEmptyWords()
Definition: overflow_bitset.h:416
std::forward_iterator_tag iterator_category
Definition: overflow_bitset.h:374
int m_base
Definition: overflow_bitset.h:371
iterator & operator++()
Definition: overflow_bitset.h:402
uint64_t m_state
Definition: overflow_bitset.h:357
Definition: overflow_bitset.h:352
iterator end() const
Definition: overflow_bitset.h:461
iterator begin() const
Definition: overflow_bitset.h:440
const std::array< OverflowBitset, N > m_bitsets
Definition: overflow_bitset.h:476
const Combine m_combine
Definition: overflow_bitset.h:477
OverflowBitsetBitsIn(std::array< OverflowBitset, N > bitsets, Combine combine)
Definition: overflow_bitset.h:437
Definition: overflow_bitset.h:81
friend bool IsSubset(OverflowBitset a, OverflowBitset b)
Is 'a' a subset of 'b'?
Definition: overflow_bitset.h:524
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:281
friend int PopulationCountOverflow(OverflowBitset x)
Definition: overflow_bitset.cc:139
friend bool Overlaps(OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:493
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:587
MutableOverflowBitset Clone(MEM_ROOT *mem_root) const
Definition: overflow_bitset.h:269
size_t capacity() const
Definition: overflow_bitset.h:108
static constexpr int kInlineBits
Definition: overflow_bitset.h:145
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 OverflowBitset EmptySet(MEM_ROOT *mem_root, size_t capacity)
Make a bitset that has no bits set, with the given capacity.
Definition: overflow_bitset.h:323
static MutableOverflowBitset AndOverflow(MEM_ROOT *mem_root, OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.cc:55
uint64_t m_bits
Definition: overflow_bitset.h:142
OverflowBitset(const OverflowBitset &)=default
friend bool IsBitSetOverflow(int bit_num, OverflowBitset x)
friend bool IsEmpty(OverflowBitset x)
Definition: overflow_bitset.h:569
static MutableOverflowBitset And(MEM_ROOT *mem_root, OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:295
OverflowBitset(uint32_t bits)
Definition: overflow_bitset.h:86
OverflowBitset(OverflowBitset &&)=default
Ext * m_ext
Definition: overflow_bitset.h:143
static MutableOverflowBitset Xor(MEM_ROOT *mem_root, OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:309
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:534
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:524
bool Overlaps(OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:493
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:487
int PopulationCount(OverflowBitset x)
Find the nuber of bits set in 'x'.
Definition: overflow_bitset.h:587
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:482
bool IsEmpty(OverflowBitset x)
Definition: overflow_bitset.h:569
bool IsBitSet(int bit_num, OverflowBitset x)
Definition: overflow_bitset.h:534
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:135
uint64_t m_bits[1]
Definition: overflow_bitset.h:137
size_t m_num_blocks
Definition: overflow_bitset.h:136