1 /* Copyright (c) 2010, 2021, 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 /**
24   @file storage/perfschema/table_esgs_by_thread_by_event_name.cc
25   Table EVENTS_STAGES_SUMMARY_BY_HOST_BY_EVENT_NAME (implementation).
26 */
27 
28 #include "my_global.h"
29 #include "my_thread.h"
30 #include "pfs_instr_class.h"
31 #include "pfs_column_types.h"
32 #include "pfs_column_values.h"
33 #include "table_esgs_by_thread_by_event_name.h"
34 #include "pfs_global.h"
35 #include "pfs_visitor.h"
36 #include "pfs_buffer_container.h"
37 #include "field.h"
38 
39 THR_LOCK table_esgs_by_thread_by_event_name::m_table_lock;
40 
41 static const TABLE_FIELD_TYPE field_types[]=
42 {
43   {
44     { C_STRING_WITH_LEN("THREAD_ID") },
45     { C_STRING_WITH_LEN("bigint(20)") },
46     { NULL, 0}
47   },
48   {
49     { C_STRING_WITH_LEN("EVENT_NAME") },
50     { C_STRING_WITH_LEN("varchar(128)") },
51     { NULL, 0}
52   },
53   {
54     { C_STRING_WITH_LEN("COUNT_STAR") },
55     { C_STRING_WITH_LEN("bigint(20)") },
56     { NULL, 0}
57   },
58   {
59     { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
60     { C_STRING_WITH_LEN("bigint(20)") },
61     { NULL, 0}
62   },
63   {
64     { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
65     { C_STRING_WITH_LEN("bigint(20)") },
66     { NULL, 0}
67   },
68   {
69     { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
70     { C_STRING_WITH_LEN("bigint(20)") },
71     { NULL, 0}
72   },
73   {
74     { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
75     { C_STRING_WITH_LEN("bigint(20)") },
76     { NULL, 0}
77   }
78 };
79 
80 TABLE_FIELD_DEF
81 table_esgs_by_thread_by_event_name::m_field_def=
82 { 7, field_types };
83 
84 PFS_engine_table_share
85 table_esgs_by_thread_by_event_name::m_share=
86 {
87   { C_STRING_WITH_LEN("events_stages_summary_by_thread_by_event_name") },
88   &pfs_truncatable_acl,
89   table_esgs_by_thread_by_event_name::create,
90   NULL, /* write_row */
91   table_esgs_by_thread_by_event_name::delete_all_rows,
92   table_esgs_by_thread_by_event_name::get_row_count,
93   sizeof(pos_esgs_by_thread_by_event_name),
94   &m_table_lock,
95   &m_field_def,
96   false, /* checked */
97   false  /* perpetual */
98 };
99 
100 PFS_engine_table*
create(void)101 table_esgs_by_thread_by_event_name::create(void)
102 {
103   return new table_esgs_by_thread_by_event_name();
104 }
105 
106 int
delete_all_rows(void)107 table_esgs_by_thread_by_event_name::delete_all_rows(void)
108 {
109   reset_events_stages_by_thread();
110   return 0;
111 }
112 
113 ha_rows
get_row_count(void)114 table_esgs_by_thread_by_event_name::get_row_count(void)
115 {
116   return global_thread_container.get_row_count() * stage_class_max;
117 }
118 
table_esgs_by_thread_by_event_name()119 table_esgs_by_thread_by_event_name::table_esgs_by_thread_by_event_name()
120   : PFS_engine_table(&m_share, &m_pos),
121     m_row_exists(false), m_pos(), m_next_pos()
122 {}
123 
reset_position(void)124 void table_esgs_by_thread_by_event_name::reset_position(void)
125 {
126   m_pos.reset();
127   m_next_pos.reset();
128 }
129 
rnd_init(bool scan)130 int table_esgs_by_thread_by_event_name::rnd_init(bool scan)
131 {
132   m_normalizer= time_normalizer::get(stage_timer);
133   return 0;
134 }
135 
rnd_next(void)136 int table_esgs_by_thread_by_event_name::rnd_next(void)
137 {
138   PFS_thread *thread;
139   PFS_stage_class *stage_class;
140   bool has_more_thread= true;
141 
142   for (m_pos.set_at(&m_next_pos);
143        has_more_thread;
144        m_pos.next_thread())
145   {
146     thread= global_thread_container.get(m_pos.m_index_1, & has_more_thread);
147     if (thread != NULL)
148     {
149       stage_class= find_stage_class(m_pos.m_index_2);
150       if (stage_class)
151       {
152         make_row(thread, stage_class);
153         m_next_pos.set_after(&m_pos);
154         return 0;
155       }
156     }
157   }
158 
159   return HA_ERR_END_OF_FILE;
160 }
161 
162 int
rnd_pos(const void * pos)163 table_esgs_by_thread_by_event_name::rnd_pos(const void *pos)
164 {
165   PFS_thread *thread;
166   PFS_stage_class *stage_class;
167 
168   set_position(pos);
169 
170   thread= global_thread_container.get(m_pos.m_index_1);
171   if (thread != NULL)
172   {
173     stage_class= find_stage_class(m_pos.m_index_2);
174     if (stage_class)
175     {
176       make_row(thread, stage_class);
177       return 0;
178     }
179   }
180 
181   return HA_ERR_RECORD_DELETED;
182 }
183 
184 void table_esgs_by_thread_by_event_name
make_row(PFS_thread * thread,PFS_stage_class * klass)185 ::make_row(PFS_thread *thread, PFS_stage_class *klass)
186 {
187   pfs_optimistic_state lock;
188   m_row_exists= false;
189 
190   /* Protect this reader against a thread termination */
191   thread->m_lock.begin_optimistic_lock(&lock);
192 
193   m_row.m_thread_internal_id= thread->m_thread_internal_id;
194 
195   m_row.m_event_name.make_row(klass);
196 
197   PFS_connection_stage_visitor visitor(klass);
198   PFS_connection_iterator::visit_thread(thread, & visitor);
199 
200   if (thread->m_lock.end_optimistic_lock(&lock))
201     m_row_exists= true;
202 
203   m_row.m_stat.set(m_normalizer, & visitor.m_stat);
204 }
205 
206 int table_esgs_by_thread_by_event_name
read_row_values(TABLE * table,unsigned char *,Field ** fields,bool read_all)207 ::read_row_values(TABLE *table, unsigned char *, Field **fields,
208                   bool read_all)
209 {
210   Field *f;
211 
212   if (unlikely(! m_row_exists))
213     return HA_ERR_RECORD_DELETED;
214 
215   /* Set the null bits */
216   assert(table->s->null_bytes == 0);
217 
218   for (; (f= *fields) ; fields++)
219   {
220     if (read_all || bitmap_is_set(table->read_set, f->field_index))
221     {
222       switch(f->field_index)
223       {
224       case 0: /* THREAD_ID */
225         set_field_ulonglong(f, m_row.m_thread_internal_id);
226         break;
227       case 1: /* NAME */
228         m_row.m_event_name.set_field(f);
229         break;
230       default: /* 2, ... COUNT/SUM/MIN/AVG/MAX */
231         m_row.m_stat.set_field(f->field_index - 2, f);
232         break;
233       }
234     }
235   }
236 
237   return 0;
238 }
239 
240