MySQL 8.4.0
Source Code Documentation
pfs_buffer_container.h
Go to the documentation of this file.
1/* Copyright (c) 2014, 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 PFS_BUFFER_CONTAINER_H
25#define PFS_BUFFER_CONTAINER_H
26
27/**
28 @file storage/perfschema/pfs_buffer_container.h
29 Generic buffer container.
30*/
31
32#include <assert.h>
33#include <stddef.h>
34#include <sys/types.h>
35#include <atomic>
36
37#include "my_inttypes.h"
48
49#define USE_SCALABLE
50
51class PFS_opaque_container_page;
52class PFS_opaque_container;
53
55
56template <class T>
58
59template <class T>
61
62template <class T, class U, class V>
64
65template <class T, int PFS_PAGE_SIZE, int PFS_PAGE_COUNT, class U, class V>
67
68template <class T>
70
71template <class T>
73
74template <class T, class U, class V>
76
77template <class T, int PFS_PAGE_SIZE, int PFS_PAGE_COUNT, class U, class V>
79
80template <class B, int COUNT>
82
83template <class B, int COUNT>
85
86template <class T>
88 public:
89 typedef T value_type;
90
92 size_t index;
93 size_t monotonic;
94 size_t monotonic_max;
96
97 if (m_full) {
98 return nullptr;
99 }
100
101 monotonic = m_monotonic.m_size_t++;
102 monotonic_max = monotonic + m_max;
103
104 if (unlikely(monotonic >= monotonic_max)) {
105 /*
106 This will happen once every 2^64 - m_max calls.
107 Computation of monotonic_max just overflowed,
108 so reset monotonic counters and start again from the beginning.
109 */
110 m_monotonic.m_size_t.store(0);
111 monotonic = 0;
112 monotonic_max = m_max;
113 }
114
115 while (monotonic < monotonic_max) {
116 index = monotonic % m_max;
117 pfs = m_ptr + index;
118
119 if (pfs->m_lock.free_to_dirty(dirty_state)) {
120 return pfs;
121 }
122 monotonic = m_monotonic.m_size_t++;
123 }
124
125 m_full = true;
126 return nullptr;
127 }
128
130 pfs->m_lock.allocated_to_free();
131 m_full = false;
132 }
133
134 T *get_first() { return m_ptr; }
135
136 T *get_last() { return m_ptr + m_max; }
137
138 bool m_full;
141 size_t m_max;
142 /** Container. */
143 PFS_opaque_container *m_container;
144};
145
146template <class T>
148 public:
150
152 : m_builtin_class(klass) {}
153
155 array->m_ptr = nullptr;
156 array->m_full = true;
157 array->m_monotonic.m_size_t.store(0);
158
159 if (array->m_max > 0) {
160 array->m_ptr = PFS_MALLOC_ARRAY(m_builtin_class, array->m_max, sizeof(T),
161 T, MYF(MY_ZEROFILL));
162 if (array->m_ptr == nullptr) {
163 return 1;
164 }
165 array->m_full = false;
166 }
167 return 0;
168 }
169
170 void free_array(array_type *array) {
171 assert(array->m_max > 0);
172
173 PFS_FREE_ARRAY(m_builtin_class, array->m_max, sizeof(T), array->m_ptr);
174 array->m_ptr = nullptr;
175 }
176
177 private:
179};
180
181template <class T, class U = PFS_buffer_default_array<T>,
182 class V = PFS_buffer_default_allocator<T>>
184 public:
185 friend class PFS_buffer_iterator<T, U, V>;
186
187 typedef T value_type;
188 typedef U array_type;
189 typedef V allocator_type;
193 typedef void (*function_type)(value_type *);
194
196 m_array.m_full = true;
197 m_array.m_ptr = NULL;
198 m_array.m_max = 0;
199 m_array.m_monotonic.m_size_t = 0;
200 m_lost = 0;
201 m_max = 0;
202 m_allocator = allocator;
203 }
204
205 int init(size_t max_size) {
206 if (max_size > 0) {
207 m_array.m_max = max_size;
208 int rc = m_allocator->alloc_array(&m_array);
209 if (rc != 0) {
210 m_allocator->free_array(&m_array);
211 return 1;
212 }
213 m_max = max_size;
214 m_array.m_full = false;
215 }
216 return 0;
217 }
218
219 void cleanup() { m_allocator->free_array(&m_array); }
220
221 size_t get_row_count() const { return m_max; }
222
223 size_t get_row_size() const { return sizeof(value_type); }
224
225 size_t get_memory() const { return get_row_count() * get_row_size(); }
226
229
230 pfs = m_array.allocate(dirty_state, m_max);
231 if (pfs == NULL) {
232 m_lost++;
233 }
234
235 return pfs;
236 }
237
238 void deallocate(value_type *pfs) { m_array.deallocate(pfs); }
239
241
242 iterator_type iterate(uint index) {
243 assert(index <= m_max);
244 return PFS_buffer_iterator<T, U, V>(this, index);
245 }
246
248 value_type *pfs = m_array.get_first();
249 value_type *pfs_last = m_array.get_last();
250
251 while (pfs < pfs_last) {
252 if (pfs->m_lock.is_populated()) {
253 fct(pfs);
254 }
255 pfs++;
256 }
257 }
258
260 value_type *pfs = m_array.get_first();
261 value_type *pfs_last = m_array.get_last();
262
263 while (pfs < pfs_last) {
264 fct(pfs);
265 pfs++;
266 }
267 }
268
269 void apply(processor_type &proc) {
270 value_type *pfs = m_array.get_first();
271 value_type *pfs_last = m_array.get_last();
272
273 while (pfs < pfs_last) {
274 if (pfs->m_lock.is_populated()) {
275 proc(pfs);
276 }
277 pfs++;
278 }
279 }
280
282 value_type *pfs = m_array.get_first();
283 value_type *pfs_last = m_array.get_last();
284
285 while (pfs < pfs_last) {
286 proc(pfs);
287 pfs++;
288 }
289 }
290
291 inline value_type *get(uint index) {
292 assert(index < m_max);
293
294 value_type *pfs = m_array.m_ptr + index;
295 if (pfs->m_lock.is_populated()) {
296 return pfs;
297 }
298
299 return NULL;
300 }
301
302 value_type *get(uint index, bool *has_more) {
303 if (index >= m_max) {
304 *has_more = false;
305 return NULL;
306 }
307
308 *has_more = true;
309 return get(index);
310 }
311
313 intptr offset;
314 value_type *pfs = m_array.get_first();
315 value_type *pfs_last = m_array.get_last();
316
317 if ((pfs <= unsafe) && (unsafe < pfs_last)) {
318 offset = ((intptr)unsafe - (intptr)pfs) % sizeof(value_type);
319 if (offset == 0) {
320 return unsafe;
321 }
322 }
323
324 return NULL;
325 }
326
327 ulong m_lost;
328
329 private:
330 value_type *scan_next(uint &index, uint *found_index) {
331 assert(index <= m_max);
332
333 value_type *pfs_first = m_array.get_first();
334 value_type *pfs = pfs_first + index;
335 value_type *pfs_last = m_array.get_last();
336
337 while (pfs < pfs_last) {
338 if (pfs->m_lock.is_populated()) {
339 uint found = pfs - pfs_first;
340 *found_index = found;
341 index = found + 1;
342 return pfs;
343 }
344 pfs++;
345 }
346
347 index = m_max;
348 return NULL;
349 }
350
351 size_t m_max;
354};
355
356template <class T, int PFS_PAGE_SIZE, int PFS_PAGE_COUNT,
360 public:
361 friend class PFS_buffer_scalable_iterator<T, PFS_PAGE_SIZE, PFS_PAGE_COUNT, U,
362 V>;
363
364 /**
365 Type of elements in the buffer.
366 The following attributes are required:
367 - @code pfs_lock m_lock @endcode
368 - @code PFS_opaque_container_page *m_page @endcode
369 */
370 typedef T value_type;
371 /**
372 Type of pages in the buffer.
373 The following attributes are required:
374 - @code PFS_opaque_container *m_container @endcode
375 */
376 typedef U array_type;
377 typedef V allocator_type;
378 /** This container type */
385 typedef void (*function_type)(value_type *);
386
387 static const size_t MAX_SIZE = PFS_PAGE_SIZE * PFS_PAGE_COUNT;
388
390 m_allocator = allocator;
391 m_initialized = false;
392 }
393
394 int init(long max_size) {
395 int i;
396
397 m_initialized = true;
398 m_full = true;
399 m_max = PFS_PAGE_COUNT * PFS_PAGE_SIZE;
400 m_max_page_count = PFS_PAGE_COUNT;
401 m_last_page_size = PFS_PAGE_SIZE;
402 m_lost = 0;
403 m_monotonic.m_size_t.store(0);
404 m_max_page_index.m_size_t.store(0);
405
406 for (i = 0; i < PFS_PAGE_COUNT; i++) {
407 m_pages[i] = nullptr;
408 }
409
410 if (max_size == 0) {
411 /* No allocation. */
413 } else if (max_size > 0) {
414 if (max_size % PFS_PAGE_SIZE == 0) {
415 m_max_page_count = max_size / PFS_PAGE_SIZE;
416 } else {
417 m_max_page_count = max_size / PFS_PAGE_SIZE + 1;
418 m_last_page_size = max_size % PFS_PAGE_SIZE;
419 }
420 /* Bounded allocation. */
421 m_full = false;
422
423 if (m_max_page_count > PFS_PAGE_COUNT) {
424 m_max_page_count = PFS_PAGE_COUNT;
425 m_last_page_size = PFS_PAGE_SIZE;
426 }
427 } else {
428 /* max_size = -1 means unbounded allocation */
429 m_full = false;
430 }
431
432 assert(m_max_page_count <= PFS_PAGE_COUNT);
433 assert(0 < m_last_page_size);
434 assert(m_last_page_size <= PFS_PAGE_SIZE);
435
437 return 0;
438 }
439
440 void cleanup() {
441 int i;
443
444 if (!m_initialized) {
445 return;
446 }
447
449
450 for (i = 0; i < PFS_PAGE_COUNT; i++) {
451 page = m_pages[i];
452 if (page != nullptr) {
453 m_allocator->free_array(page);
454 delete page;
455 m_pages[i] = nullptr;
456 }
457 }
459
461
462 m_initialized = false;
463 }
464
465 size_t get_row_count() {
466 size_t page_count = m_max_page_index.m_size_t.load();
467 size_t result = page_count * PFS_PAGE_SIZE;
468
469 if ((page_count > 0) && (m_last_page_size != PFS_PAGE_SIZE)) {
470 /* Bounded allocation, the last page may be incomplete. */
471 result = result - PFS_PAGE_SIZE + m_last_page_size;
472 }
473 return result;
474 }
475
476 size_t get_row_size() const { return sizeof(value_type); }
477
478 size_t get_memory() { return get_row_count() * get_row_size(); }
479
481 if (m_full) {
482 m_lost++;
483 return nullptr;
484 }
485
486 size_t index;
487 size_t monotonic;
488 size_t monotonic_max;
489 size_t current_page_count;
491 array_type *array;
492
493 /*
494 1: Try to find an available record within the existing pages
495 */
496 current_page_count = m_max_page_index.m_size_t.load();
497
498 if (current_page_count != 0) {
499 monotonic = m_monotonic.m_size_t.load();
500 monotonic_max = monotonic + current_page_count;
501
502 if (unlikely(monotonic >= monotonic_max)) {
503 /*
504 This will happen once every 2^64 - current_page_count calls.
505 Computation of monotonic_max just overflowed,
506 so reset monotonic counters and start again from the beginning.
507 */
508 m_monotonic.m_size_t.store(0);
509 monotonic = 0;
510 monotonic_max = current_page_count;
511 }
512
513 while (monotonic < monotonic_max) {
514 /*
515 Scan in the [0 .. current_page_count - 1] range,
516 in parallel with m_monotonic (see below)
517 */
518 index = monotonic % current_page_count;
519
520 /* Atomic Load, array= m_pages[index] */
521 array = m_pages[index].load();
522
523 if (array != nullptr) {
524 pfs = array->allocate(dirty_state);
525 if (pfs != nullptr) {
526 /* Keep a pointer to the parent page, for deallocate(). */
527 pfs->m_page = reinterpret_cast<PFS_opaque_container_page *>(array);
528 return pfs;
529 }
530 }
531
532 /*
533 Parallel scans collaborate to increase
534 the common monotonic scan counter.
535
536 Note that when all the existing page are full,
537 one thread will eventually add a new page,
538 and cause m_max_page_index to increase,
539 which fools all the modulo logic for scans already in progress,
540 because the monotonic counter is not folded to the same place
541 (sometime modulo N, sometime modulo N+1).
542
543 This is actually ok: since all the pages are full anyway,
544 there is nothing to miss, so better increase the monotonic
545 counter faster and then move on to the detection of new pages,
546 in part 2: below.
547 */
548 monotonic = m_monotonic.m_size_t++;
549 };
550 }
551
552 /*
553 2: Try to add a new page, beyond the m_max_page_index limit
554 */
555 while (current_page_count < m_max_page_count) {
556 /* Peek for pages added by collaborating threads */
557
558 /* (2-a) Atomic Load, array= m_pages[current_page_count] */
559 array = m_pages[current_page_count].load();
560
561 if (array == nullptr) {
562 // ==================================================================
563 // BEGIN CRITICAL SECTION -- buffer expand
564 // ==================================================================
565
566 /*
567 On a fresh started server, buffers are typically empty.
568 When a sudden load spike is seen by the server,
569 multiple threads may want to expand the buffer at the same time.
570
571 Using a compare and swap to allow multiple pages to be added,
572 possibly freeing duplicate pages on collisions,
573 does not work well because the amount of code involved
574 when creating a new page can be significant (PFS_thread),
575 causing MANY collisions between (2-b) and (2-d).
576
577 A huge number of collisions (which can happen when thousands
578 of new connections hits the server after a restart)
579 leads to a huge memory consumption, and to OOM.
580
581 To mitigate this, we use here a mutex,
582 to enforce that only ONE page is added at a time,
583 so that scaling the buffer happens in a predictable
584 and controlled manner.
585 */
587
588 /*
589 Peek again for pages added by collaborating threads,
590 this time as the only thread allowed to expand the buffer
591 */
592
593 /* (2-b) Atomic Load, array= m_pages[current_page_count] */
594
595 array = m_pages[current_page_count].load();
596
597 if (array == nullptr) {
598 /* (2-c) Found no page, allocate a new one */
599 array = new array_type();
601
602 array->m_max = get_page_logical_size(current_page_count);
603 int rc = m_allocator->alloc_array(array);
604 if (rc != 0) {
605 m_allocator->free_array(array);
606 delete array;
608 m_lost++;
610 return nullptr;
611 }
612
613 /* Keep a pointer to this container, for static_deallocate(). */
614 array->m_container = reinterpret_cast<PFS_opaque_container *>(this);
615
616 /* (2-d) Atomic STORE, m_pages[current_page_count] = array */
617 m_pages[current_page_count].store(array);
618
619 /* Advertise the new page */
621 }
622
624
625 // ==================================================================
626 // END CRITICAL SECTION -- buffer expand
627 // ==================================================================
628 }
629
630 assert(array != nullptr);
631 pfs = array->allocate(dirty_state);
632 if (pfs != nullptr) {
633 /* Keep a pointer to the parent page, for deallocate(). */
634 pfs->m_page = reinterpret_cast<PFS_opaque_container_page *>(array);
635 return pfs;
636 }
637
638 current_page_count++;
639 }
640
641 m_lost++;
642 m_full = true;
643 return nullptr;
644 }
645
646 void dirty_to_free(pfs_dirty_state *dirty_state, value_type *safe_pfs) {
647 /* Find the containing page */
648 PFS_opaque_container_page *opaque_page = safe_pfs->m_page;
649 auto *page = reinterpret_cast<array_type *>(opaque_page);
650
651 /* Mark the object free */
652 safe_pfs->m_lock.dirty_to_free(dirty_state);
653
654 /* Flag the containing page as not full. */
655 page->m_full = false;
656
657 /* Flag the overall container as not full. */
658 m_full = false;
659 }
660
661 void deallocate(value_type *safe_pfs) {
662 /* Find the containing page */
663 PFS_opaque_container_page *opaque_page = safe_pfs->m_page;
664 auto *page = reinterpret_cast<array_type *>(opaque_page);
665
666 /* Mark the object free */
667 safe_pfs->m_lock.allocated_to_free();
668
669 /* Flag the containing page as not full. */
670 page->m_full = false;
671
672 /* Flag the overall container as not full. */
673 m_full = false;
674 }
675
676 static void static_deallocate(value_type *safe_pfs) {
677 /* Find the containing page */
678 PFS_opaque_container_page *opaque_page = safe_pfs->m_page;
679 auto *page = reinterpret_cast<array_type *>(opaque_page);
680
681 /* Mark the object free */
682 safe_pfs->m_lock.allocated_to_free();
683
684 /* Flag the containing page as not full. */
685 page->m_full = false;
686
687 /* Find the containing buffer */
688 PFS_opaque_container *opaque_container = page->m_container;
690 container = reinterpret_cast<container_type *>(opaque_container);
691
692 /* Flag the overall container as not full. */
693 container->m_full = false;
694 }
695
698 this, 0);
699 }
700
701 iterator_type iterate(uint index) {
702 assert(index <= m_max);
704 this, index);
705 }
706
708 uint i;
711 value_type *pfs_last;
712
713 for (i = 0; i < PFS_PAGE_COUNT; i++) {
714 page = m_pages[i];
715 if (page != nullptr) {
716 pfs = page->get_first();
717 pfs_last = page->get_last();
718
719 while (pfs < pfs_last) {
720 if (pfs->m_lock.is_populated()) {
721 fct(pfs);
722 }
723 pfs++;
724 }
725 }
726 }
727 }
728
730 uint i;
733 value_type *pfs_last;
734
735 for (i = 0; i < PFS_PAGE_COUNT; i++) {
736 page = m_pages[i];
737 if (page != nullptr) {
738 pfs = page->get_first();
739 pfs_last = page->get_last();
740
741 while (pfs < pfs_last) {
742 fct(pfs);
743 pfs++;
744 }
745 }
746 }
747 }
748
749 void apply(processor_type &proc) {
750 uint i;
753 value_type *pfs_last;
754
755 for (i = 0; i < PFS_PAGE_COUNT; i++) {
756 page = m_pages[i];
757 if (page != nullptr) {
758 pfs = page->get_first();
759 pfs_last = page->get_last();
760
761 while (pfs < pfs_last) {
762 if (pfs->m_lock.is_populated()) {
763 proc(pfs);
764 }
765 pfs++;
766 }
767 }
768 }
769 }
770
772 uint i;
775 value_type *pfs_last;
776
777 for (i = 0; i < PFS_PAGE_COUNT; i++) {
778 page = m_pages[i];
779 if (page != NULL) {
780 pfs = page->get_first();
781 pfs_last = page->get_last();
782
783 while (pfs < pfs_last) {
784 proc(pfs);
785 pfs++;
786 }
787 }
788 }
789 }
790
791 value_type *get(uint index) {
792 assert(index < m_max);
793
794 uint index_1 = index / PFS_PAGE_SIZE;
795 array_type *page = m_pages[index_1];
796 if (page != nullptr) {
797 uint index_2 = index % PFS_PAGE_SIZE;
798
799 if (index_2 >= page->m_max) {
800 return nullptr;
801 }
802
803 value_type *pfs = page->m_ptr + index_2;
804
805 if (pfs->m_lock.is_populated()) {
806 return pfs;
807 }
808 }
809
810 return nullptr;
811 }
812
813 value_type *get(uint index, bool *has_more) {
814 if (index >= m_max) {
815 *has_more = false;
816 return nullptr;
817 }
818
819 uint index_1 = index / PFS_PAGE_SIZE;
820 array_type *page = m_pages[index_1];
821
822 if (page == nullptr) {
823 *has_more = false;
824 return nullptr;
825 }
826
827 uint index_2 = index % PFS_PAGE_SIZE;
828
829 if (index_2 >= page->m_max) {
830 *has_more = false;
831 return nullptr;
832 }
833
834 *has_more = true;
835 value_type *pfs = page->m_ptr + index_2;
836
837 if (pfs->m_lock.is_populated()) {
838 return pfs;
839 }
840
841 return nullptr;
842 }
843
845 intptr offset;
846 uint i;
849 value_type *pfs_last;
850
851 for (i = 0; i < PFS_PAGE_COUNT; i++) {
852 page = m_pages[i];
853 if (page != nullptr) {
854 pfs = page->get_first();
855 pfs_last = page->get_last();
856
857 if ((pfs <= unsafe) && (unsafe < pfs_last)) {
858 offset = ((intptr)unsafe - (intptr)pfs) % sizeof(value_type);
859 if (offset == 0) {
860 return unsafe;
861 }
862 }
863 }
864 }
865
866 return nullptr;
867 }
868
869 ulong m_lost;
870
871 private:
872 uint get_page_logical_size(uint page_index) {
873 if (page_index + 1 < m_max_page_count) {
874 return PFS_PAGE_SIZE;
875 }
876 assert(page_index + 1 == m_max_page_count);
877 return m_last_page_size;
878 }
879
880 value_type *scan_next(uint &index, uint *found_index) {
881 assert(index <= m_max);
882
883 uint index_1 = index / PFS_PAGE_SIZE;
884 uint index_2 = index % PFS_PAGE_SIZE;
886 value_type *pfs_first;
888 value_type *pfs_last;
889
890 while (index_1 < PFS_PAGE_COUNT) {
891 page = m_pages[index_1];
892
893 if (page == nullptr) {
894 index = static_cast<uint>(m_max);
895 return nullptr;
896 }
897
898 pfs_first = page->get_first();
899 pfs = pfs_first + index_2;
900 pfs_last = page->get_last();
901
902 while (pfs < pfs_last) {
903 if (pfs->m_lock.is_populated()) {
904 uint found =
905 index_1 * PFS_PAGE_SIZE + static_cast<uint>(pfs - pfs_first);
906 *found_index = found;
907 index = found + 1;
908 return pfs;
909 }
910 pfs++;
911 }
912
913 index_1++;
914 index_2 = 0;
915 }
916
917 index = static_cast<uint>(m_max);
918 return nullptr;
919 }
920
922 bool m_full;
923 size_t m_max;
928 std::atomic<array_type *> m_pages[PFS_PAGE_COUNT];
931};
932
933template <class T, class U, class V>
935 friend class PFS_buffer_container<T, U, V>;
936
937 typedef T value_type;
939
940 public:
942 uint unused;
943 return m_container->scan_next(m_index, &unused);
944 }
945
946 value_type *scan_next(uint *found_index) {
947 return m_container->scan_next(m_index, found_index);
948 }
949
950 private:
952 : m_container(container), m_index(index) {}
953
956};
957
958template <class T, int page_size, int page_count, class U, class V>
960 friend class PFS_buffer_scalable_container<T, page_size, page_count, U, V>;
961
962 typedef T value_type;
965
966 public:
968 uint unused;
969 return m_container->scan_next(m_index, &unused);
970 }
971
972 value_type *scan_next(uint *found_index) {
973 return m_container->scan_next(m_index, found_index);
974 }
975
976 private:
978 : m_container(container), m_index(index) {}
979
982};
983
984template <class T>
986 public:
987 virtual ~PFS_buffer_processor() = default;
988 virtual void operator()(T *element) = 0;
989};
990
991template <class B, int PFS_PARTITION_COUNT>
993 public:
994 friend class PFS_partitioned_buffer_scalable_iterator<B, PFS_PARTITION_COUNT>;
995
996 typedef typename B::value_type value_type;
997 typedef typename B::allocator_type allocator_type;
1000 typedef typename B::iterator_type sub_iterator_type;
1001 typedef typename B::processor_type processor_type;
1002 typedef typename B::function_type function_type;
1003
1005 allocator_type *allocator) {
1006 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1007 m_partitions[i] = new B(allocator);
1008 }
1009 }
1010
1012 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1013 delete m_partitions[i];
1014 }
1015 }
1016
1017 int init(long max_size) {
1018 int rc = 0;
1019 // FIXME: we have max_size * PFS_PARTITION_COUNT here
1020 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1021 rc |= m_partitions[i]->init(max_size);
1022 }
1023 return rc;
1024 }
1025
1026 void cleanup() {
1027 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1028 m_partitions[i]->cleanup();
1029 }
1030 }
1031
1032 size_t get_row_count() const {
1033 size_t sum = 0;
1034
1035 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1036 sum += m_partitions[i]->get_row_count();
1037 }
1038
1039 return sum;
1040 }
1041
1042 size_t get_row_size() const { return sizeof(value_type); }
1043
1044 size_t get_memory() const {
1045 size_t sum = 0;
1046
1047 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1048 sum += m_partitions[i]->get_memory();
1049 }
1050
1051 return sum;
1052 }
1053
1055 long sum = 0;
1056
1057 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1058 sum += m_partitions[i]->m_lost;
1059 }
1060
1061 return sum;
1062 }
1063
1064 value_type *allocate(pfs_dirty_state *dirty_state, uint partition) {
1065 assert(partition < PFS_PARTITION_COUNT);
1066
1067 return m_partitions[partition]->allocate(dirty_state);
1068 }
1069
1070 void deallocate(value_type *safe_pfs) {
1071 /*
1072 One issue here is that we do not know which partition
1073 the record belongs to.
1074 Each record points to the parent page,
1075 and each page points to the parent buffer,
1076 so using static_deallocate here,
1077 which will find the correct partition by itself.
1078 */
1079 B::static_deallocate(safe_pfs);
1080 }
1081
1082 iterator_type iterate() { return iterator_type(this, 0, 0); }
1083
1084 iterator_type iterate(uint user_index) {
1085 uint partition_index;
1086 uint sub_index;
1087 unpack_index(user_index, &partition_index, &sub_index);
1088 return iterator_type(this, partition_index, sub_index);
1089 }
1090
1092 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1093 m_partitions[i]->apply(fct);
1094 }
1095 }
1096
1098 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1099 m_partitions[i]->apply_all(fct);
1100 }
1101 }
1102
1103 void apply(processor_type &proc) {
1104 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1105 m_partitions[i]->apply(proc);
1106 }
1107 }
1108
1110 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1111 m_partitions[i]->apply_all(proc);
1112 }
1113 }
1114
1115 value_type *get(uint user_index) {
1116 uint partition_index;
1117 uint sub_index;
1118 unpack_index(user_index, &partition_index, &sub_index);
1119
1120 if (partition_index >= PFS_PARTITION_COUNT) {
1121 return nullptr;
1122 }
1123
1124 return m_partitions[partition_index]->get(sub_index);
1125 }
1126
1127 value_type *get(uint user_index, bool *has_more) {
1128 uint partition_index;
1129 uint sub_index;
1130 unpack_index(user_index, &partition_index, &sub_index);
1131
1132 if (partition_index >= PFS_PARTITION_COUNT) {
1133 *has_more = false;
1134 return NULL;
1135 }
1136
1137 *has_more = true;
1138 return m_partitions[partition_index]->get(sub_index);
1139 }
1140
1142 value_type *safe = nullptr;
1143
1144 for (int i = 0; i < PFS_PARTITION_COUNT; i++) {
1145 safe = m_partitions[i]->sanitize(unsafe);
1146 if (safe != nullptr) {
1147 return safe;
1148 }
1149 }
1150
1151 return safe;
1152 }
1153
1154 private:
1155 static void pack_index(uint partition_index, uint sub_index,
1156 uint *user_index) {
1157 static_assert(PFS_PARTITION_COUNT <= (1 << 8), "2^8 = 256 partitions max.");
1158 static_assert((B::MAX_SIZE) <= (1 << 24),
1159 "2^24 = 16777216 max per partitioned buffer.");
1160
1161 *user_index = (partition_index << 24) + sub_index;
1162 }
1163
1164 static void unpack_index(uint user_index, uint *partition_index,
1165 uint *sub_index) {
1166 *partition_index = user_index >> 24;
1167 *sub_index = user_index & 0x00FFFFFF;
1168 }
1169
1170 value_type *scan_next(uint &partition_index, uint &sub_index,
1171 uint *found_partition, uint *found_sub_index) {
1172 value_type *record = nullptr;
1173 assert(partition_index < PFS_PARTITION_COUNT);
1174
1175 while (partition_index < PFS_PARTITION_COUNT) {
1176 sub_iterator_type sub_iterator =
1177 m_partitions[partition_index]->iterate(sub_index);
1178 record = sub_iterator.scan_next(found_sub_index);
1179 if (record != nullptr) {
1180 *found_partition = partition_index;
1181 sub_index = *found_sub_index + 1;
1182 return record;
1183 }
1184
1185 partition_index++;
1186 sub_index = 0;
1187 }
1188
1189 *found_partition = PFS_PARTITION_COUNT;
1190 *found_sub_index = 0;
1191 sub_index = 0;
1192 return nullptr;
1193 }
1194
1195 B *m_partitions[PFS_PARTITION_COUNT];
1196};
1197
1198template <class B, int PFS_PARTITION_COUNT>
1200 public:
1202 PFS_PARTITION_COUNT>;
1203
1204 typedef typename B::value_type value_type;
1207
1209 uint unused_partition;
1210 uint unused_sub_index;
1211 return m_container->scan_next(m_partition, m_sub_index, &unused_partition,
1212 &unused_sub_index);
1213 }
1214
1215 value_type *scan_next(uint *found_user_index) {
1216 uint found_partition;
1217 uint found_sub_index;
1219 record = m_container->scan_next(m_partition, m_sub_index, &found_partition,
1220 &found_sub_index);
1221 container_type::pack_index(found_partition, found_sub_index,
1222 found_user_index);
1223 return record;
1224 }
1225
1226 private:
1228 uint partition, uint sub_index)
1230 m_partition(partition),
1231 m_sub_index(sub_index) {}
1232
1236};
1237
1238#ifdef USE_SCALABLE
1244#else
1246#endif
1249
1250#ifdef USE_SCALABLE
1253#else
1255#endif
1258
1259#ifdef USE_SCALABLE
1261#else
1263#endif
1266
1267#ifdef USE_SCALABLE
1270#else
1272#endif
1275
1276#ifdef USE_SCALABLE
1279#else
1281#endif
1284
1285#ifdef USE_SCALABLE
1288#else
1290#endif
1293
1294#ifdef USE_SCALABLE
1297#else
1299#endif
1302
1303#ifdef USE_SCALABLE
1306#else
1308#endif
1311
1312#ifdef USE_SCALABLE
1315#else
1317#endif
1320
1321#ifdef USE_SCALABLE
1324#else
1326#endif
1329
1330#ifdef USE_SCALABLE
1333#else
1336#endif
1340
1341#ifdef USE_SCALABLE
1344#else
1347#endif
1351
1352#ifdef USE_SCALABLE
1355#else
1357#endif
1360
1361#ifdef USE_SCALABLE
1364#else
1366#endif
1369
1370class PFS_account_array : public PFS_buffer_default_array<PFS_account> {
1371 public:
1378};
1379
1381 public:
1382 int alloc_array(PFS_account_array *array);
1383 void free_array(PFS_account_array *array);
1384};
1385
1386#ifdef USE_SCALABLE
1390#else
1394#endif
1397
1399 public:
1406};
1407
1409 public:
1410 int alloc_array(PFS_host_array *array);
1411 void free_array(PFS_host_array *array);
1412};
1413
1414#ifdef USE_SCALABLE
1418#else
1421#endif
1424
1425class PFS_thread_array : public PFS_buffer_default_array<PFS_thread> {
1426 public:
1433
1440
1445};
1446
1448 public:
1449 int alloc_array(PFS_thread_array *array);
1450 void free_array(PFS_thread_array *array);
1451};
1452
1453#ifdef USE_SCALABLE
1457#else
1460#endif
1463
1465 public:
1472};
1473
1475 public:
1476 int alloc_array(PFS_user_array *array);
1477 void free_array(PFS_user_array *array);
1478};
1479
1480#ifdef USE_SCALABLE
1484#else
1487#endif
1490
1491#endif
Definition: pfs_buffer_container.h:1380
void free_array(PFS_account_array *array)
Definition: pfs_buffer_container.cc:235
int alloc_array(PFS_account_array *array)
Definition: pfs_buffer_container.cc:102
Definition: pfs_buffer_container.h:1370
PFS_stage_stat * m_instr_class_stages_array
Definition: pfs_buffer_container.h:1373
PFS_memory_shared_stat * m_instr_class_memory_array
Definition: pfs_buffer_container.h:1377
PFS_error_stat * m_instr_class_errors_array
Definition: pfs_buffer_container.h:1376
PFS_single_stat * m_instr_class_waits_array
Definition: pfs_buffer_container.h:1372
PFS_transaction_stat * m_instr_class_transactions_array
Definition: pfs_buffer_container.h:1375
PFS_statement_stat * m_instr_class_statements_array
Definition: pfs_buffer_container.h:1374
Definition: pfs_buffer_container.h:57
Definition: pfs_buffer_container.h:183
PFS_buffer_processor< T > processor_type
Definition: pfs_buffer_container.h:192
void apply(function_type fct)
Definition: pfs_buffer_container.h:247
void cleanup()
Definition: pfs_buffer_container.h:219
size_t get_memory() const
Definition: pfs_buffer_container.h:225
size_t get_row_count() const
Definition: pfs_buffer_container.h:221
size_t m_max
Definition: pfs_buffer_container.h:351
value_type * get(uint index)
Definition: pfs_buffer_container.h:291
size_t get_row_size() const
Definition: pfs_buffer_container.h:223
U array_type
Definition: pfs_buffer_container.h:188
int init(size_t max_size)
Definition: pfs_buffer_container.h:205
void apply(processor_type &proc)
Definition: pfs_buffer_container.h:269
value_type * get(uint index, bool *has_more)
Definition: pfs_buffer_container.h:302
PFS_buffer_const_iterator< T > const_iterator_type
Definition: pfs_buffer_container.h:190
void apply_all(function_type fct)
Definition: pfs_buffer_container.h:259
void(* function_type)(value_type *)
Definition: pfs_buffer_container.h:193
iterator_type iterate()
Definition: pfs_buffer_container.h:240
ulong m_lost
Definition: pfs_buffer_container.h:327
value_type * allocate(pfs_dirty_state *dirty_state)
Definition: pfs_buffer_container.h:227
void apply_all(processor_type &proc)
Definition: pfs_buffer_container.h:281
value_type * sanitize(value_type *unsafe)
Definition: pfs_buffer_container.h:312
V allocator_type
Definition: pfs_buffer_container.h:189
PFS_buffer_container(allocator_type *allocator)
Definition: pfs_buffer_container.h:195
PFS_buffer_iterator< T, U, V > iterator_type
Definition: pfs_buffer_container.h:191
void deallocate(value_type *pfs)
Definition: pfs_buffer_container.h:238
iterator_type iterate(uint index)
Definition: pfs_buffer_container.h:242
friend class PFS_buffer_iterator< T, U, V >
Definition: pfs_buffer_container.h:185
value_type * scan_next(uint &index, uint *found_index)
Definition: pfs_buffer_container.h:330
allocator_type * m_allocator
Definition: pfs_buffer_container.h:353
array_type m_array
Definition: pfs_buffer_container.h:352
T value_type
Definition: pfs_buffer_container.h:187
Definition: pfs_buffer_container.h:147
PFS_buffer_default_array< T > array_type
Definition: pfs_buffer_container.h:149
PFS_buffer_default_allocator(PFS_builtin_memory_class *klass)
Definition: pfs_buffer_container.h:151
int alloc_array(array_type *array)
Definition: pfs_buffer_container.h:154
void free_array(array_type *array)
Definition: pfs_buffer_container.h:170
PFS_builtin_memory_class * m_builtin_class
Definition: pfs_buffer_container.h:178
Definition: pfs_buffer_container.h:87
bool m_full
Definition: pfs_buffer_container.h:138
T * get_last()
Definition: pfs_buffer_container.h:136
size_t m_max
Definition: pfs_buffer_container.h:141
PFS_cacheline_atomic_size_t m_monotonic
Definition: pfs_buffer_container.h:139
T * m_ptr
Definition: pfs_buffer_container.h:140
value_type * allocate(pfs_dirty_state *dirty_state)
Definition: pfs_buffer_container.h:91
T value_type
Definition: pfs_buffer_container.h:89
T * get_first()
Definition: pfs_buffer_container.h:134
PFS_opaque_container * m_container
Container.
Definition: pfs_buffer_container.h:143
void deallocate(value_type *pfs)
Definition: pfs_buffer_container.h:129
Definition: pfs_buffer_container.h:934
T value_type
Definition: pfs_buffer_container.h:937
PFS_buffer_container< T, U, V > container_type
Definition: pfs_buffer_container.h:938
container_type * m_container
Definition: pfs_buffer_container.h:954
value_type * scan_next()
Definition: pfs_buffer_container.h:941
value_type * scan_next(uint *found_index)
Definition: pfs_buffer_container.h:946
PFS_buffer_iterator(container_type *container, uint index)
Definition: pfs_buffer_container.h:951
uint m_index
Definition: pfs_buffer_container.h:955
Definition: pfs_buffer_container.h:985
virtual void operator()(T *element)=0
virtual ~PFS_buffer_processor()=default
Definition: pfs_buffer_container.h:359
void(* function_type)(value_type *)
Definition: pfs_buffer_container.h:385
static const size_t MAX_SIZE
Definition: pfs_buffer_container.h:387
int init(long max_size)
Definition: pfs_buffer_container.h:394
size_t get_row_size() const
Definition: pfs_buffer_container.h:476
friend class PFS_buffer_scalable_iterator< T, PFS_PAGE_SIZE, PFS_PAGE_COUNT, U, V >
Definition: pfs_buffer_container.h:362
void apply(processor_type &proc)
Definition: pfs_buffer_container.h:749
bool m_initialized
Definition: pfs_buffer_container.h:921
void apply_all(function_type fct)
Definition: pfs_buffer_container.h:729
void apply_all(processor_type &proc)
Definition: pfs_buffer_container.h:771
void dirty_to_free(pfs_dirty_state *dirty_state, value_type *safe_pfs)
Definition: pfs_buffer_container.h:646
PFS_buffer_scalable_container< T, PFS_PAGE_SIZE, PFS_PAGE_COUNT, U, V > container_type
This container type.
Definition: pfs_buffer_container.h:380
size_t m_max_page_count
Definition: pfs_buffer_container.h:926
value_type * sanitize(value_type *unsafe)
Definition: pfs_buffer_container.h:844
PFS_buffer_scalable_iterator< T, PFS_PAGE_SIZE, PFS_PAGE_COUNT, U, V > iterator_type
Definition: pfs_buffer_container.h:383
value_type * allocate(pfs_dirty_state *dirty_state)
Definition: pfs_buffer_container.h:480
native_mutex_t m_critical_section
Definition: pfs_buffer_container.h:930
PFS_cacheline_atomic_size_t m_max_page_index
Definition: pfs_buffer_container.h:925
size_t get_memory()
Definition: pfs_buffer_container.h:478
iterator_type iterate()
Definition: pfs_buffer_container.h:696
uint get_page_logical_size(uint page_index)
Definition: pfs_buffer_container.h:872
void apply(function_type fct)
Definition: pfs_buffer_container.h:707
iterator_type iterate(uint index)
Definition: pfs_buffer_container.h:701
V allocator_type
Definition: pfs_buffer_container.h:377
size_t m_last_page_size
Definition: pfs_buffer_container.h:927
U array_type
Type of pages in the buffer.
Definition: pfs_buffer_container.h:376
PFS_buffer_processor< T > processor_type
Definition: pfs_buffer_container.h:384
value_type * get(uint index, bool *has_more)
Definition: pfs_buffer_container.h:813
PFS_cacheline_atomic_size_t m_monotonic
Definition: pfs_buffer_container.h:924
void cleanup()
Definition: pfs_buffer_container.h:440
size_t get_row_count()
Definition: pfs_buffer_container.h:465
PFS_buffer_const_iterator< T > const_iterator_type
Definition: pfs_buffer_container.h:381
allocator_type * m_allocator
Definition: pfs_buffer_container.h:929
size_t m_max
Definition: pfs_buffer_container.h:923
value_type * get(uint index)
Definition: pfs_buffer_container.h:791
static void static_deallocate(value_type *safe_pfs)
Definition: pfs_buffer_container.h:676
T value_type
Type of elements in the buffer.
Definition: pfs_buffer_container.h:370
PFS_buffer_scalable_container(allocator_type *allocator)
Definition: pfs_buffer_container.h:389
value_type * scan_next(uint &index, uint *found_index)
Definition: pfs_buffer_container.h:880
void deallocate(value_type *safe_pfs)
Definition: pfs_buffer_container.h:661
bool m_full
Definition: pfs_buffer_container.h:922
ulong m_lost
Definition: pfs_buffer_container.h:869
std::atomic< array_type * > m_pages[PFS_PAGE_COUNT]
Definition: pfs_buffer_container.h:928
Definition: pfs_buffer_container.h:959
T value_type
Definition: pfs_buffer_container.h:962
uint m_index
Definition: pfs_buffer_container.h:981
value_type * scan_next(uint *found_index)
Definition: pfs_buffer_container.h:972
value_type * scan_next()
Definition: pfs_buffer_container.h:967
PFS_buffer_scalable_container< T, page_size, page_count, U, V > container_type
Definition: pfs_buffer_container.h:964
PFS_buffer_scalable_iterator(container_type *container, uint index)
Definition: pfs_buffer_container.h:977
container_type * m_container
Definition: pfs_buffer_container.h:980
Definition: pfs_buffer_container.h:1408
int alloc_array(PFS_host_array *array)
Definition: pfs_buffer_container.cc:285
void free_array(PFS_host_array *array)
Definition: pfs_buffer_container.cc:418
Definition: pfs_buffer_container.h:1398
PFS_transaction_stat * m_instr_class_transactions_array
Definition: pfs_buffer_container.h:1403
PFS_memory_shared_stat * m_instr_class_memory_array
Definition: pfs_buffer_container.h:1405
PFS_error_stat * m_instr_class_errors_array
Definition: pfs_buffer_container.h:1404
PFS_single_stat * m_instr_class_waits_array
Definition: pfs_buffer_container.h:1400
PFS_stage_stat * m_instr_class_stages_array
Definition: pfs_buffer_container.h:1401
PFS_statement_stat * m_instr_class_statements_array
Definition: pfs_buffer_container.h:1402
Definition: pfs_buffer_container.h:992
B::function_type function_type
Definition: pfs_buffer_container.h:1002
value_type * get(uint user_index, bool *has_more)
Definition: pfs_buffer_container.h:1127
B::allocator_type allocator_type
Definition: pfs_buffer_container.h:997
void apply(processor_type &proc)
Definition: pfs_buffer_container.h:1103
void apply(function_type fct)
Definition: pfs_buffer_container.h:1091
B * m_partitions[PFS_PARTITION_COUNT]
Definition: pfs_buffer_container.h:1195
value_type * scan_next(uint &partition_index, uint &sub_index, uint *found_partition, uint *found_sub_index)
Definition: pfs_buffer_container.h:1170
iterator_type iterate()
Definition: pfs_buffer_container.h:1082
PFS_partitioned_buffer_scalable_iterator< B, PFS_PARTITION_COUNT > iterator_type
Definition: pfs_buffer_container.h:999
size_t get_row_count() const
Definition: pfs_buffer_container.h:1032
void apply_all(function_type fct)
Definition: pfs_buffer_container.h:1097
value_type * sanitize(value_type *unsafe)
Definition: pfs_buffer_container.h:1141
B::value_type value_type
Definition: pfs_buffer_container.h:996
static void unpack_index(uint user_index, uint *partition_index, uint *sub_index)
Definition: pfs_buffer_container.h:1164
PFS_partitioned_buffer_scalable_container(allocator_type *allocator)
Definition: pfs_buffer_container.h:1004
void deallocate(value_type *safe_pfs)
Definition: pfs_buffer_container.h:1070
int init(long max_size)
Definition: pfs_buffer_container.h:1017
~PFS_partitioned_buffer_scalable_container()
Definition: pfs_buffer_container.h:1011
B::iterator_type sub_iterator_type
Definition: pfs_buffer_container.h:1000
size_t get_memory() const
Definition: pfs_buffer_container.h:1044
iterator_type iterate(uint user_index)
Definition: pfs_buffer_container.h:1084
size_t get_row_size() const
Definition: pfs_buffer_container.h:1042
B::processor_type processor_type
Definition: pfs_buffer_container.h:1001
void apply_all(processor_type &proc)
Definition: pfs_buffer_container.h:1109
value_type * get(uint user_index)
Definition: pfs_buffer_container.h:1115
value_type * allocate(pfs_dirty_state *dirty_state, uint partition)
Definition: pfs_buffer_container.h:1064
void cleanup()
Definition: pfs_buffer_container.h:1026
long get_lost_counter()
Definition: pfs_buffer_container.h:1054
static void pack_index(uint partition_index, uint sub_index, uint *user_index)
Definition: pfs_buffer_container.h:1155
Definition: pfs_buffer_container.h:1199
uint m_sub_index
Definition: pfs_buffer_container.h:1235
PFS_partitioned_buffer_scalable_container< B, PFS_PARTITION_COUNT > container_type
Definition: pfs_buffer_container.h:1206
container_type * m_container
Definition: pfs_buffer_container.h:1233
B::value_type value_type
Definition: pfs_buffer_container.h:1204
value_type * scan_next(uint *found_user_index)
Definition: pfs_buffer_container.h:1215
value_type * scan_next()
Definition: pfs_buffer_container.h:1208
PFS_partitioned_buffer_scalable_iterator(container_type *container, uint partition, uint sub_index)
Definition: pfs_buffer_container.h:1227
uint m_partition
Definition: pfs_buffer_container.h:1234
Definition: pfs_buffer_container.h:1447
void free_array(PFS_thread_array *array)
Definition: pfs_buffer_container.cc:766
int alloc_array(PFS_thread_array *array)
Definition: pfs_buffer_container.cc:467
Definition: pfs_buffer_container.h:1425
PFS_statement_stat * m_instr_class_statements_array
Definition: pfs_buffer_container.h:1429
PFS_single_stat * m_instr_class_waits_array
Definition: pfs_buffer_container.h:1427
PFS_error_stat * m_instr_class_errors_array
Definition: pfs_buffer_container.h:1431
PFS_events_statements * m_statements_stack_array
Definition: pfs_buffer_container.h:1437
PFS_events_statements * m_statements_history_array
Definition: pfs_buffer_container.h:1436
PFS_stage_stat * m_instr_class_stages_array
Definition: pfs_buffer_container.h:1428
unsigned char * m_current_stmts_digest_token_array
Definition: pfs_buffer_container.h:1443
PFS_events_stages * m_stages_history_array
Definition: pfs_buffer_container.h:1435
char * m_current_stmts_text_array
Definition: pfs_buffer_container.h:1441
PFS_memory_safe_stat * m_instr_class_memory_array
Definition: pfs_buffer_container.h:1432
unsigned char * m_history_stmts_digest_token_array
Definition: pfs_buffer_container.h:1444
PFS_transaction_stat * m_instr_class_transactions_array
Definition: pfs_buffer_container.h:1430
char * m_session_connect_attrs_array
Definition: pfs_buffer_container.h:1439
PFS_events_waits * m_waits_history_array
Definition: pfs_buffer_container.h:1434
PFS_events_transactions * m_transactions_history_array
Definition: pfs_buffer_container.h:1438
char * m_history_stmts_text_array
Definition: pfs_buffer_container.h:1442
Definition: pfs_buffer_container.h:1474
void free_array(PFS_user_array *array)
Definition: pfs_buffer_container.cc:1013
int alloc_array(PFS_user_array *array)
Definition: pfs_buffer_container.cc:880
Definition: pfs_buffer_container.h:1464
PFS_statement_stat * m_instr_class_statements_array
Definition: pfs_buffer_container.h:1468
PFS_transaction_stat * m_instr_class_transactions_array
Definition: pfs_buffer_container.h:1469
PFS_stage_stat * m_instr_class_stages_array
Definition: pfs_buffer_container.h:1467
PFS_single_stat * m_instr_class_waits_array
Definition: pfs_buffer_container.h:1466
PFS_error_stat * m_instr_class_errors_array
Definition: pfs_buffer_container.h:1470
PFS_memory_shared_stat * m_instr_class_memory_array
Definition: pfs_buffer_container.h:1471
int page
Definition: ctype-mb.cc:1234
#define MY_ZEROFILL
Definition: my_sys.h:141
#define PFS_MUTEX_PARTITIONS
Definition: pfs_instr_class.h:326
constexpr bool unlikely(bool expr)
Definition: my_compiler.h:58
Some integer typedefs for easier portability.
intptr_t intptr
Definition: my_inttypes.h:70
#define MYF(v)
Definition: my_inttypes.h:97
static int record
Definition: mysqltest.cc:195
uint16_t value_type
Definition: vt100.h:184
Definition: atomics_array.h:39
const ulint MAX_SIZE
The maximum size possible for an LOB.
Definition: lob0lob.h:84
Performance schema account (declarations).
PFS_file_container global_file_container
PFS_buffer_scalable_container< PFS_mutex, 1024, 1024 > PFS_mutex_basic_container
Definition: pfs_buffer_container.h:1240
PFS_host_container global_host_container
PFS_buffer_scalable_container< PFS_socket, 256, 256 > PFS_socket_container
Definition: pfs_buffer_container.h:1278
PFS_thread_container global_thread_container
PFS_table_share_index_container global_table_share_index_container
PFS_cond_container::iterator_type PFS_cond_iterator
Definition: pfs_buffer_container.h:1264
PFS_buffer_scalable_container< PFS_table, 1024, 1024 > PFS_table_container
Definition: pfs_buffer_container.h:1314
PFS_file_container::iterator_type PFS_file_iterator
Definition: pfs_buffer_container.h:1273
PFS_user_container::iterator_type PFS_user_iterator
Definition: pfs_buffer_container.h:1488
PFS_mutex_container::iterator_type PFS_mutex_iterator
Definition: pfs_buffer_container.h:1247
PFS_prepared_stmt_container::iterator_type PFS_prepared_stmt_iterator
Definition: pfs_buffer_container.h:1367
PFS_buffer_scalable_container< PFS_table_share, 4 *1024, 4 *1024 > PFS_table_share_container
Definition: pfs_buffer_container.h:1323
PFS_setup_object_container::iterator_type PFS_setup_object_iterator
Definition: pfs_buffer_container.h:1309
PFS_cond_container global_cond_container
PFS_buffer_scalable_container< PFS_prepared_stmt, 1024, 1024 > PFS_prepared_stmt_container
Definition: pfs_buffer_container.h:1363
PFS_buffer_scalable_container< PFS_table_share_lock, 4 *1024, 4 *1024 > PFS_table_share_lock_container
Definition: pfs_buffer_container.h:1343
PFS_socket_container::iterator_type PFS_socket_iterator
Definition: pfs_buffer_container.h:1282
PFS_table_share_container global_table_share_container
PFS_rwlock_container::iterator_type PFS_rwlock_iterator
Definition: pfs_buffer_container.h:1256
PFS_program_container global_program_container
PFS_buffer_scalable_container< PFS_thread, 256, 256, PFS_thread_array, PFS_thread_allocator > PFS_thread_container
Definition: pfs_buffer_container.h:1456
PFS_host_container::iterator_type PFS_host_iterator
Definition: pfs_buffer_container.h:1422
PFS_socket_container global_socket_container
PFS_partitioned_buffer_scalable_container< PFS_mutex_basic_container, PFS_MUTEX_PARTITIONS > PFS_mutex_container
Definition: pfs_buffer_container.h:1243
PFS_table_share_lock_container::iterator_type PFS_table_share_lock_iterator
Definition: pfs_buffer_container.h:1349
PFS_buffer_scalable_container< PFS_program, 1024, 1024 > PFS_program_container
Definition: pfs_buffer_container.h:1354
PFS_account_container::iterator_type PFS_account_iterator
Definition: pfs_buffer_container.h:1395
PFS_buffer_scalable_container< PFS_file, 4 *1024, 4 *1024 > PFS_file_container
Definition: pfs_buffer_container.h:1269
PFS_setup_object_container global_setup_object_container
PFS_table_share_index_container::iterator_type PFS_table_share_index_iterator
Definition: pfs_buffer_container.h:1338
PFS_mdl_container global_mdl_container
PFS_buffer_scalable_container< PFS_setup_actor, 128, 1024 > PFS_setup_actor_container
Definition: pfs_buffer_container.h:1296
PFS_rwlock_container global_rwlock_container
PFS_thread_container::iterator_type PFS_thread_iterator
Definition: pfs_buffer_container.h:1461
PFS_mdl_container::iterator_type PFS_mdl_iterator
Definition: pfs_buffer_container.h:1291
PFS_table_share_lock_container global_table_share_lock_container
PFS_table_container global_table_container
PFS_table_container::iterator_type PFS_table_iterator
Definition: pfs_buffer_container.h:1318
PFS_buffer_scalable_container< PFS_host, 128, 128, PFS_host_array, PFS_host_allocator > PFS_host_container
Definition: pfs_buffer_container.h:1417
PFS_account_container global_account_container
PFS_buffer_scalable_container< PFS_cond, 256, 256 > PFS_cond_container
Definition: pfs_buffer_container.h:1260
PFS_setup_actor_container::iterator_type PFS_setup_actor_iterator
Definition: pfs_buffer_container.h:1300
PFS_program_container::iterator_type PFS_program_iterator
Definition: pfs_buffer_container.h:1358
PFS_prepared_stmt_container global_prepared_stmt_container
PFS_buffer_scalable_container< PFS_user, 128, 128, PFS_user_array, PFS_user_allocator > PFS_user_container
Definition: pfs_buffer_container.h:1483
PFS_buffer_scalable_container< PFS_table_share_index, 8 *1024, 8 *1024 > PFS_table_share_index_container
Definition: pfs_buffer_container.h:1332
PFS_buffer_scalable_container< PFS_setup_object, 128, 1024 > PFS_setup_object_container
Definition: pfs_buffer_container.h:1305
PFS_table_share_container::iterator_type PFS_table_share_iterator
Definition: pfs_buffer_container.h:1327
PFS_setup_actor_container global_setup_actor_container
PFS_mutex_container global_mutex_container
PFS_buffer_scalable_container< PFS_metadata_lock, 1024, 1024 > PFS_mdl_container
Definition: pfs_buffer_container.h:1287
PFS_buffer_scalable_container< PFS_rwlock, 1024, 1024 > PFS_rwlock_container
Definition: pfs_buffer_container.h:1252
PFS_user_container global_user_container
PFS_buffer_scalable_container< PFS_account, 128, 128, PFS_account_array, PFS_account_allocator > PFS_account_container
Definition: pfs_buffer_container.h:1389
PFS_builtin_memory_class builtin_memory_scalable_buffer
Definition: pfs_builtin_memory.cc:128
Performance schema instruments metadata (declarations).
#define PFS_MALLOC_ARRAY(k, n, s, T, f)
Helper, to allocate an array of structures.
Definition: pfs_global.h:135
#define PFS_FREE_ARRAY(k, n, s, p)
Helper, to free an array of structures.
Definition: pfs_global.h:152
Performance schema host (declarations).
Performance schema instruments (declarations).
Performance schema internal locks (declarations).
Stored Program data structures (declarations).
Stored Program data structures (declarations).
Performance schema setup actors (declarations).
Performance schema setup object (declarations).
Performance schema user (declarations).
struct result result
Definition: result.h:34
static const LEX_CSTRING pfs
Definition: sql_show_processlist.cc:66
Per account statistics.
Definition: pfs_account.h:67
Definition: pfs_builtin_memory.h:39
void count_alloc(size_t size)
Definition: pfs_builtin_memory.h:43
void count_free(size_t size)
Definition: pfs_builtin_memory.h:45
An atomic size_t variable, guaranteed to be alone in a CPU cache line.
Definition: pfs_global.h:99
std::atomic< size_t > m_size_t
Definition: pfs_global.h:100
Statistics for all server errors.
Definition: pfs_stat.h:557
A stage record.
Definition: pfs_events_stages.h:45
A statement record.
Definition: pfs_events_statements.h:47
A transaction record.
Definition: pfs_events_transactions.h:86
A wait event record.
Definition: pfs_events_waits.h:69
Per host statistics.
Definition: pfs_host.h:64
Memory statistics.
Definition: pfs_stat.h:913
Definition: pfs_stat.h:937
Single statistic.
Definition: pfs_stat.h:52
Statistics for stage usage.
Definition: pfs_stat.h:323
Statistics for statement usage.
Definition: pfs_stat.h:376
Instrumented thread implementation.
Definition: pfs_instr.h:375
Statistics for transaction usage.
Definition: pfs_stat.h:459
Per user statistics.
Definition: pfs_user.h:63
Definition: pfs_lock.h:77
Definition: result.h:30
static int native_mutex_unlock(native_mutex_t *mutex)
Definition: thr_mutex.h:115
static int native_mutex_destroy(native_mutex_t *mutex)
Definition: thr_mutex.h:124
static int native_mutex_lock(native_mutex_t *mutex)
Definition: thr_mutex.h:90
static int native_mutex_init(native_mutex_t *mutex, const native_mutexattr_t *attr)
Definition: thr_mutex.h:79
pthread_mutex_t native_mutex_t
Definition: thr_mutex_bits.h:55
#define NULL
Definition: types.h:55
Definition: dtoa.cc:589