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