MySQL 9.1.0
Source Code Documentation
overflow_bitset.h
Go to the documentation of this file.
1/* Copyright (c) 2021, 2024, 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 <assert.h>
64#include <limits.h>
65#include <stddef.h>
66#include <stdint.h>
67#include <string.h>
68
69#include <array>
70#include <bit>
71#include <tuple>
72
73#include "my_alloc.h"
75
77
79 public:
80 // Default is to zero-initialize.
82
83 explicit OverflowBitset(uint32_t bits) : m_bits((uintptr_t{bits} << 1) | 1) {
84 // Check that we didn't overflow on 32-bit platforms.
85 assert((m_bits >> 1) == bits);
86 }
87
88 // Reset the entire bitset to an inline all-zero bitset.
89 // This is distinct from ClearBits(), which only clears a given number
90 // of bits, and does not change the capacity.
91 void Clear() { m_bits = 1; }
92
93 // Value semantics, so:
94 OverflowBitset(const OverflowBitset &) = default;
98
99 // Can move-convert MutableOverflowBitset into OverflowBitset.
102
103 bool is_inline() const { return m_bits & 1; }
104 bool empty() { return m_bits == 1; }
105
106 size_t capacity() const {
107 if (is_inline()) {
108 return kInlineBits;
109 } else {
110 return m_ext->m_num_blocks * sizeof(uint64_t) * CHAR_BIT;
111 }
112 }
113
115
116 bool IsContainedIn(const MEM_ROOT *mem_root) const {
117 return !is_inline() && mem_root->Contains(m_ext);
118 }
119
120 // NOTE: These could also be made to take in MutableOverflowBitset(),
121 // simply by templating them (due to the private inheritance).
128
129 protected:
130 struct Ext {
132 uint64_t m_bits[1];
133 };
134 static_assert(alignof(Ext) % 2 == 0, "The lowest bit must be zero.");
135
136 union {
137 uint64_t m_bits; // Lowest bit must be 1.
139 };
140 static constexpr int kInlineBits = sizeof(m_bits) * CHAR_BIT - 1;
141
142 void InitOverflow(MEM_ROOT *mem_root, size_t capacity);
149
150 friend bool Overlaps(OverflowBitset a, OverflowBitset b);
152 friend bool IsSubset(OverflowBitset a, OverflowBitset b);
154 friend bool IsBitSet(int bit_num, OverflowBitset x);
155 friend bool IsBitSetOverflow(int bit_num, OverflowBitset x);
156 friend bool IsEmpty(OverflowBitset x);
157 friend int PopulationCount(OverflowBitset x);
159 template <size_t N, class Combine>
162};
163static_assert(
164 sizeof(OverflowBitset) <= sizeof(uint64_t),
165 "OverflowBitset is intended to be as compact as a regular 64-bit set.");
166
167// Private inheritance, so that the only way of converting to OverflowBitset
168// for external callers is by a move-convert.
170 public:
171 // NOTE: Will round up the given capacity to either 31/63 (for anything
172 // smaller than 32/64), or to the next multiple of 64 (for anything else).
174 if (capacity <= kInlineBits) {
175 m_bits = 1;
176 } else {
178 }
179 }
180
181 // Move-only, so that we don't inadvertently modify aliases.
185 m_bits = other.m_bits;
186 other.m_bits = 1;
187 }
189 m_bits = other.m_bits;
190 other.m_bits = 1;
191 return *this;
192 }
193
194 void SetBit(int bit_num) {
195 assert(bit_num >= 0);
196 assert(static_cast<size_t>(bit_num) < capacity());
197 const unsigned bn = bit_num; // To avoid sign extension taking time.
198 if (is_inline()) {
199 assert(bit_num < 63);
200 m_bits |= uint64_t{1} << (bn + 1);
201 } else {
202 m_ext->m_bits[bn / 64] |= uint64_t{1} << (bn % 64);
203 }
204 }
205
206 void ClearBits(int begin_bit_num, int end_bit_num) {
207 assert(begin_bit_num >= 0);
208 assert(end_bit_num >= 0);
209 assert(begin_bit_num <= end_bit_num);
210 assert(static_cast<size_t>(begin_bit_num) <= capacity());
211 assert(static_cast<size_t>(end_bit_num) <= capacity());
212 if (is_inline()) {
213 m_bits &= ~BitsBetween(begin_bit_num + 1, end_bit_num + 1);
214 } else {
215 ClearBitsOverflow(begin_bit_num, end_bit_num);
216 }
217 }
218
219 inline void ClearBit(int bit_num) {
220 // TODO: Consider a more specialized version here if it starts
221 // showing up in the profiles.
222 ClearBits(bit_num, bit_num + 1);
223 }
224
227 }
228
229 private:
230 friend bool IsBitSet(int bit_num, const MutableOverflowBitset &x);
231 friend bool Overlaps(OverflowBitset a, const MutableOverflowBitset &b);
232 friend bool Overlaps(const MutableOverflowBitset &a,
233 const MutableOverflowBitset &b);
234 friend bool Overlaps(const MutableOverflowBitset &a, OverflowBitset b);
235 friend bool IsSubset(OverflowBitset a, const MutableOverflowBitset &b);
236 friend bool IsSubset(const MutableOverflowBitset &a,
237 const MutableOverflowBitset &b);
238 friend bool IsSubset(const MutableOverflowBitset &a, OverflowBitset b);
239 friend bool IsEmpty(const MutableOverflowBitset &x);
240 friend int PopulationCount(const MutableOverflowBitset &x);
241 void SetBitOverflow(int bit_num);
242 void ClearBitsOverflow(int begin_bit_num, int end_bit_num);
243
244 friend class OverflowBitset;
245};
246
248 m_bits = other.m_bits;
249 other.m_bits = 1;
250}
251
253 MutableOverflowBitset &&other) {
254 m_bits = other.m_bits;
255 other.m_bits = 1;
256 return *this;
257}
258
261 if (is_inline()) {
262 ret.m_bits = m_bits;
263 } else {
264 memcpy(ret.m_ext, m_ext,
265 sizeof(m_ext->m_num_blocks) +
266 m_ext->m_num_blocks * sizeof(m_ext->m_bits));
267 }
268 return ret;
269}
270
273 OverflowBitset b) {
274 assert(a.is_inline() == b.is_inline());
275 assert(a.capacity() == b.capacity());
276 if (a.is_inline()) {
278 ret.m_bits = a.m_bits | b.m_bits;
279 return ret;
280 } else {
281 return OrOverflow(mem_root, a, b);
282 }
283}
284
287 OverflowBitset b) {
288 assert(a.is_inline() == b.is_inline());
289 assert(a.capacity() == b.capacity());
290 if (a.is_inline()) {
292 ret.m_bits = a.m_bits & b.m_bits;
293 return ret;
294 } else {
295 return AndOverflow(mem_root, a, b);
296 }
297}
298
301 OverflowBitset b) {
302 assert(a.is_inline() == b.is_inline());
303 assert(a.capacity() == b.capacity());
304 if (a.is_inline()) {
306 ret.m_bits = (a.m_bits ^ b.m_bits) | 1;
307 return ret;
308 } else {
309 return XorOverflow(mem_root, a, b);
310 }
311}
312
313// Definitions overloading utility functions in bit_utils.h, making it generally
314// possible to use OverflowBitset as we use regular uint64_t bitsets
315// (e.g. NodeMap).
316//
317// Since one cannot easily combine non-inline OverflowBitsets without allocating
318// memory, the BitsSetIn() overload supports combining state as-we-go.
319// For instance, where you would normally write (for uint64_t)
320//
321// for (int bit_idx : BitsSetIn(x & y))
322//
323// you would use this variation for OverflowBitsets:
324//
325// for (int bit_idx : BitsSetInBoth(x, y))
326//
327// Under the hood, BitsSetInBoth() calls a Combine functor that ANDs the two
328// uint64_t bitwise (for inline bitsets only once, but for overflow bitsets
329// multiple times, on-demand as we iterate), which can potentially save
330// on a lot of bitscan operations and loop iterations versus trying to test
331// one-by-one. This can be extended to any number of arguments.
332//
333// Combine::operator() must be const, Combine must be movable (but can have
334// state).
335
336template <size_t N, class Combine>
338 public:
339 class iterator {
340 private:
341 const Combine *m_combine;
342 uint64_t m_state;
343
344 // m_next holds, for each bitset array, the pointer to the next
345 // uint64_t to be processed/read (once m_state is zero, ie.,
346 // there are no more bits in the current state). When m_next[0] == m_end,
347 // iteration is over. For inline bitsets, m_next[0] == m_end == nullptr,
348 // so once the first 64-bit group is processed, we are done.
349 // (We assume all arrays have the same length, so we only need one
350 // end pointer.)
351 std::array<const uint64_t *, N> m_next;
352 const uint64_t *const m_end;
354
355 public:
356 using iterator_category = std::forward_iterator_tag;
357 using difference_type = size_t;
358 using value_type = size_t;
361
362 // For inline bitsets.
363 iterator(uint64_t state, const Combine *combine)
364 : m_combine(combine), m_state(state), m_end(nullptr), m_base(0) {
365 m_next[0] = nullptr;
366 }
367
368 // For overflow bitsets.
369 iterator(const std::array<const uint64_t *, N> begin, const uint64_t *end,
370 const Combine *combine)
371 : m_combine(combine),
372 m_state(0),
373 m_next(begin),
374 m_end(end),
375 m_base(-64) {
376 while (m_state == 0 && m_next[0] != m_end) {
378 for (size_t i = 0; i < N; ++i) {
379 ++m_next[i];
380 }
381 m_base += 64;
382 }
383 }
384
385 bool operator==(const iterator &other) const {
386 assert(m_end == other.m_end);
387 return m_state == other.m_state && m_next[0] == other.m_next[0];
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 while (m_state == 0 && m_next[0] != m_end) {
401 for (size_t i = 0; i < N; ++i) {
402 ++m_next[i];
403 }
404 m_base += 64;
405 }
406 return *this;
407 }
408 };
409
410 OverflowBitsetBitsIn(std::array<OverflowBitset, N> bitsets, Combine combine)
411 : m_bitsets(bitsets), m_combine(std::move(combine)) {}
412
413 iterator begin() const {
414 if (m_bitsets[0].is_inline()) {
415 std::array<uint64_t, N> bits;
416 for (size_t i = 0; i < N; ++i) {
417 assert(m_bitsets[i].is_inline());
418 bits[i] = m_bitsets[i].m_bits;
419 }
420 uint64_t state = std::apply(m_combine, bits);
421 return iterator{state >> 1, &m_combine};
422 } else {
423 std::array<const uint64_t *, N> ptrs;
424 for (size_t i = 0; i < N; ++i) {
425 assert(!m_bitsets[i].is_inline());
426 assert(m_bitsets[i].capacity() == m_bitsets[0].capacity());
427 ptrs[i] = m_bitsets[i].m_ext->m_bits;
428 }
429 const uint64_t *end =
430 m_bitsets[0].m_ext->m_bits + m_bitsets[0].m_ext->m_num_blocks;
431 return iterator{ptrs, end, &m_combine};
432 }
433 }
434 iterator end() const {
435 if (m_bitsets[0].is_inline()) {
436 return iterator{0, &m_combine};
437 } else {
438 std::array<const uint64_t *, N> ptrs;
439 for (size_t i = 0; i < N; ++i) {
440 assert(m_bitsets[i].is_inline() == m_bitsets[0].is_inline());
441 assert(m_bitsets[i].capacity() == m_bitsets[0].capacity());
442 ptrs[i] = m_bitsets[i].m_ext->m_bits + m_bitsets[i].m_ext->m_num_blocks;
443 }
444 return iterator{ptrs, ptrs[0], &m_combine};
445 }
446 }
447
448 private:
449 static inline uint64_t ReadAndCombine(
450 const std::array<const uint64_t *, N> &ptrs, const Combine *combine) {
451 std::array<uint64_t, N> bits;
452 for (size_t i = 0; i < N; ++i) {
453 bits[i] = *ptrs[i];
454 }
455 return std::apply(*combine, bits);
456 }
457
458 const std::array<OverflowBitset, N> m_bitsets;
459 const Combine m_combine;
460};
461
463 uint64_t operator()(uint64_t x) const { return x; }
464};
465inline auto BitsSetIn(OverflowBitset bitset) {
467}
468
470 uint64_t operator()(uint64_t x, uint64_t y) const { return x & y; }
471};
472inline auto BitsSetInBoth(OverflowBitset bitset_a, OverflowBitset bitset_b) {
473 return OverflowBitsetBitsIn<2, AndCombine>{{bitset_a, bitset_b},
474 AndCombine()};
475}
476
478
480 if (a.m_bits == 1 || b.m_bits == 1) {
481 // Empty and inline, so nothing overlaps.
482 // This is a special case that does not require the two
483 // sets to be of the same size (see file comment).
484 return false;
485 }
486 assert(a.is_inline() == b.is_inline());
487 assert(a.capacity() == b.capacity());
488 if (a.is_inline()) {
489 return (a.m_bits & b.m_bits) != 1;
490 } else {
491 return OverlapsOverflow(a, b);
492 }
493}
494
496 return Overlaps(a, static_cast<const OverflowBitset &>(b));
497}
498
499inline bool Overlaps(const MutableOverflowBitset &a,
500 const MutableOverflowBitset &b) {
501 return Overlaps(static_cast<const OverflowBitset &>(a),
502 static_cast<const OverflowBitset &>(b));
503}
504
506 return Overlaps(static_cast<const OverflowBitset &>(a), b);
507}
508
510 assert(a.is_inline() == b.is_inline());
511 assert(a.capacity() == b.capacity());
512 if (a.is_inline()) {
513 return IsSubset(a.m_bits, b.m_bits);
514 } else {
515 return IsSubsetOverflow(a, b);
516 }
517}
518
519inline bool IsBitSet(int bit_num, OverflowBitset x) {
520 assert(bit_num >= 0);
521 assert(static_cast<size_t>(bit_num) < x.capacity());
522 const unsigned bn = bit_num; // To avoid sign extension taking time.
523 if (x.is_inline()) {
524 return Overlaps(x.m_bits, uint64_t{1} << (bn + 1));
525 } else {
526 return Overlaps(x.m_ext->m_bits[bn / 64], uint64_t{1} << (bn % 64));
527 }
528}
529
530inline bool IsBitSet(int bit_num, const MutableOverflowBitset &x) {
531 return IsBitSet(bit_num, static_cast<const OverflowBitset &>(x));
532}
533
535 return IsSubset(a, static_cast<const OverflowBitset &>(b));
536}
537
538inline bool IsSubset(const MutableOverflowBitset &a,
539 const MutableOverflowBitset &b) {
540 return IsSubset(static_cast<const OverflowBitset &>(a),
541 static_cast<const OverflowBitset &>(b));
542}
543
545 return IsSubset(static_cast<const OverflowBitset &>(a), b);
546}
547
548// This is mostly used to guard a few asserts, so it's better that it's
549// completely visible, so that the compiler can remove it totally
550// in optimized mode.
551inline bool IsEmpty(OverflowBitset x) {
552 if (x.is_inline()) {
553 return x.m_bits == 1;
554 } else {
555 for (unsigned i = 0; i < x.m_ext->m_num_blocks; ++i) {
556 if (x.m_ext->m_bits[i] != 0) {
557 return false;
558 }
559 }
560 return true;
561 }
562}
563
564inline bool IsEmpty(const MutableOverflowBitset &x) {
565 return IsEmpty(static_cast<const OverflowBitset &>(x));
566}
567
569 if (x.is_inline()) {
570 return std::popcount(x.m_bits) - 1;
571 } else {
572 return PopulationCountOverflow(x);
573 }
574}
575
576/// Find the nuber of bits set in 'x'.
578 return PopulationCount(static_cast<const OverflowBitset &>(x));
579}
580
581#endif // SQL_JOIN_OPTIMIZER_OVERFLOW_BITSET_H
Kerberos Client Authentication nullptr
Definition: auth_kerberos_client_plugin.cc:251
size_t FindLowestBitSet(uint64_t x)
Definition: bit_utils.h:66
Definition: overflow_bitset.h:169
void ClearBits(int begin_bit_num, int end_bit_num)
Definition: overflow_bitset.h:206
MutableOverflowBitset(MutableOverflowBitset &&other)
Definition: overflow_bitset.h:184
friend int PopulationCount(const MutableOverflowBitset &x)
Find the nuber of bits set in 'x'.
Definition: overflow_bitset.h:577
friend bool IsBitSet(int bit_num, const MutableOverflowBitset &x)
Definition: overflow_bitset.h:530
void ClearBitsOverflow(int begin_bit_num, int end_bit_num)
Definition: overflow_bitset.cc:81
void SetBit(int bit_num)
Definition: overflow_bitset.h:194
friend bool IsSubset(OverflowBitset a, const MutableOverflowBitset &b)
Definition: overflow_bitset.h:534
MutableOverflowBitset & operator=(const MutableOverflowBitset &)=delete
friend bool Overlaps(OverflowBitset a, const MutableOverflowBitset &b)
Definition: overflow_bitset.h:495
MutableOverflowBitset(MEM_ROOT *mem_root, size_t capacity)
Definition: overflow_bitset.h:173
friend class OverflowBitset
Definition: overflow_bitset.h:244
friend bool IsEmpty(const MutableOverflowBitset &x)
Definition: overflow_bitset.h:564
MutableOverflowBitset(const MutableOverflowBitset &)=delete
void SetBitOverflow(int bit_num)
MutableOverflowBitset & operator=(MutableOverflowBitset &&other)
Definition: overflow_bitset.h:188
void ClearBit(int bit_num)
Definition: overflow_bitset.h:219
MutableOverflowBitset Clone(MEM_ROOT *mem_root) const
Definition: overflow_bitset.h:225
Definition: overflow_bitset.h:339
const Combine * m_combine
Definition: overflow_bitset.h:341
bool operator==(const iterator &other) const
Definition: overflow_bitset.h:385
value_type * pointer
Definition: overflow_bitset.h:359
iterator(uint64_t state, const Combine *combine)
Definition: overflow_bitset.h:363
value_type & reference
Definition: overflow_bitset.h:360
size_t operator*() const
Definition: overflow_bitset.h:393
size_t difference_type
Definition: overflow_bitset.h:357
iterator(const std::array< const uint64_t *, N > begin, const uint64_t *end, const Combine *combine)
Definition: overflow_bitset.h:369
size_t value_type
Definition: overflow_bitset.h:358
bool operator!=(const iterator &other) const
Definition: overflow_bitset.h:389
std::array< const uint64_t *, N > m_next
Definition: overflow_bitset.h:351
const uint64_t *const m_end
Definition: overflow_bitset.h:352
std::forward_iterator_tag iterator_category
Definition: overflow_bitset.h:356
int m_base
Definition: overflow_bitset.h:353
iterator & operator++()
Definition: overflow_bitset.h:394
uint64_t m_state
Definition: overflow_bitset.h:342
Definition: overflow_bitset.h:337
iterator end() const
Definition: overflow_bitset.h:434
static uint64_t ReadAndCombine(const std::array< const uint64_t *, N > &ptrs, const Combine *combine)
Definition: overflow_bitset.h:449
iterator begin() const
Definition: overflow_bitset.h:413
const std::array< OverflowBitset, N > m_bitsets
Definition: overflow_bitset.h:458
const Combine m_combine
Definition: overflow_bitset.h:459
OverflowBitsetBitsIn(std::array< OverflowBitset, N > bitsets, Combine combine)
Definition: overflow_bitset.h:410
Definition: overflow_bitset.h:78
friend bool IsSubset(OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:509
bool IsContainedIn(const MEM_ROOT *mem_root) const
Definition: overflow_bitset.h:116
static MutableOverflowBitset Or(MEM_ROOT *mem_root, OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:271
friend int PopulationCountOverflow(OverflowBitset x)
Definition: overflow_bitset.cc:139
friend bool Overlaps(OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:479
OverflowBitset()
Definition: overflow_bitset.h:81
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)
Definition: overflow_bitset.h:568
MutableOverflowBitset Clone(MEM_ROOT *mem_root) const
Definition: overflow_bitset.h:259
size_t capacity() const
Definition: overflow_bitset.h:106
static constexpr int kInlineBits
Definition: overflow_bitset.h:140
bool empty()
Definition: overflow_bitset.h:104
OverflowBitset & operator=(const OverflowBitset &)=default
bool is_inline() const
Definition: overflow_bitset.h:103
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:137
OverflowBitset(const OverflowBitset &)=default
friend bool IsBitSetOverflow(int bit_num, OverflowBitset x)
friend bool IsEmpty(OverflowBitset x)
Definition: overflow_bitset.h:551
static MutableOverflowBitset And(MEM_ROOT *mem_root, OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:285
OverflowBitset(uint32_t bits)
Definition: overflow_bitset.h:83
OverflowBitset(OverflowBitset &&)=default
Ext * m_ext
Definition: overflow_bitset.h:138
static MutableOverflowBitset Xor(MEM_ROOT *mem_root, OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:299
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:519
void Clear()
Definition: overflow_bitset.h:91
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)
Definition: overflow_bitset.h:509
bool Overlaps(OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.h:479
auto BitsSetInBoth(OverflowBitset bitset_a, OverflowBitset bitset_b)
Definition: overflow_bitset.h:472
int PopulationCount(OverflowBitset x)
Definition: overflow_bitset.h:568
bool OverlapsOverflow(OverflowBitset a, OverflowBitset b)
Definition: overflow_bitset.cc:115
auto BitsSetIn(OverflowBitset bitset)
Definition: overflow_bitset.h:465
bool IsEmpty(OverflowBitset x)
Definition: overflow_bitset.h:551
bool IsBitSet(int bit_num, OverflowBitset x)
Definition: overflow_bitset.h:519
Definition: overflow_bitset.h:469
uint64_t operator()(uint64_t x, uint64_t y) const
Definition: overflow_bitset.h:470
Definition: overflow_bitset.h:462
uint64_t operator()(uint64_t x) const
Definition: overflow_bitset.h:463
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:130
uint64_t m_bits[1]
Definition: overflow_bitset.h:132
size_t m_num_blocks
Definition: overflow_bitset.h:131