1/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
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 as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
15
16/**
17 @file storage/perfschema/table_ews_by_account_by_event_name.cc
18 Table EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME (implementation).
19*/
20
21#include "my_global.h"
22#include "my_pthread.h"
23#include "pfs_instr_class.h"
24#include "pfs_column_types.h"
25#include "pfs_column_values.h"
26#include "table_ews_by_account_by_event_name.h"
27#include "pfs_global.h"
28#include "pfs_visitor.h"
29
30THR_LOCK table_ews_by_account_by_event_name::m_table_lock;
31
32PFS_engine_table_share
33table_ews_by_account_by_event_name::m_share=
34{
35 { C_STRING_WITH_LEN("events_waits_summary_by_account_by_event_name") },
36 &pfs_truncatable_acl,
37 table_ews_by_account_by_event_name::create,
38 NULL, /* write_row */
39 table_ews_by_account_by_event_name::delete_all_rows,
40 NULL, /* get_row_count */
41 1000, /* records */
42 sizeof(pos_ews_by_account_by_event_name),
43 &m_table_lock,
44 { C_STRING_WITH_LEN("CREATE TABLE events_waits_summary_by_account_by_event_name("
45 "USER CHAR(16) collate utf8_bin default null,"
46 "HOST CHAR(60) collate utf8_bin default null,"
47 "EVENT_NAME VARCHAR(128) not null,"
48 "COUNT_STAR BIGINT unsigned not null,"
49 "SUM_TIMER_WAIT BIGINT unsigned not null,"
50 "MIN_TIMER_WAIT BIGINT unsigned not null,"
51 "AVG_TIMER_WAIT BIGINT unsigned not null,"
52 "MAX_TIMER_WAIT BIGINT unsigned not null)") }
53};
54
55PFS_engine_table*
56table_ews_by_account_by_event_name::create(void)
57{
58 return new table_ews_by_account_by_event_name();
59}
60
61int
62table_ews_by_account_by_event_name::delete_all_rows(void)
63{
64 reset_events_waits_by_thread();
65 reset_events_waits_by_account();
66 return 0;
67}
68
69table_ews_by_account_by_event_name::table_ews_by_account_by_event_name()
70 : PFS_engine_table(&m_share, &m_pos),
71 m_row_exists(false), m_pos(), m_next_pos()
72{}
73
74void table_ews_by_account_by_event_name::reset_position(void)
75{
76 m_pos.reset();
77 m_next_pos.reset();
78}
79
80int table_ews_by_account_by_event_name::rnd_next(void)
81{
82 PFS_account *account;
83 PFS_instr_class *instr_class;
84
85 for (m_pos.set_at(&m_next_pos);
86 m_pos.has_more_account();
87 m_pos.next_account())
88 {
89 account= &account_array[m_pos.m_index_1];
90 if (account->m_lock.is_populated())
91 {
92 for ( ;
93 m_pos.has_more_view();
94 m_pos.next_view())
95 {
96 switch (m_pos.m_index_2)
97 {
98 case pos_ews_by_account_by_event_name::VIEW_MUTEX:
99 instr_class= find_mutex_class(m_pos.m_index_3);
100 break;
101 case pos_ews_by_account_by_event_name::VIEW_RWLOCK:
102 instr_class= find_rwlock_class(m_pos.m_index_3);
103 break;
104 case pos_ews_by_account_by_event_name::VIEW_COND:
105 instr_class= find_cond_class(m_pos.m_index_3);
106 break;
107 case pos_ews_by_account_by_event_name::VIEW_FILE:
108 instr_class= find_file_class(m_pos.m_index_3);
109 break;
110 case pos_ews_by_account_by_event_name::VIEW_TABLE:
111 instr_class= find_table_class(m_pos.m_index_3);
112 break;
113 case pos_ews_by_account_by_event_name::VIEW_SOCKET:
114 instr_class= find_socket_class(m_pos.m_index_3);
115 break;
116 case pos_ews_by_account_by_event_name::VIEW_IDLE:
117 instr_class= find_idle_class(m_pos.m_index_3);
118 break;
119 default:
120 instr_class= NULL;
121 DBUG_ASSERT(false);
122 break;
123 }
124
125 if (instr_class)
126 {
127 make_row(account, instr_class);
128 m_next_pos.set_after(&m_pos);
129 return 0;
130 }
131 }
132 }
133 }
134
135 return HA_ERR_END_OF_FILE;
136}
137
138int
139table_ews_by_account_by_event_name::rnd_pos(const void *pos)
140{
141 PFS_account *account;
142 PFS_instr_class *instr_class;
143
144 set_position(pos);
145 DBUG_ASSERT(m_pos.m_index_1 < account_max);
146
147 account= &account_array[m_pos.m_index_1];
148 if (! account->m_lock.is_populated())
149 return HA_ERR_RECORD_DELETED;
150
151 switch (m_pos.m_index_2)
152 {
153 case pos_ews_by_account_by_event_name::VIEW_MUTEX:
154 instr_class= find_mutex_class(m_pos.m_index_3);
155 break;
156 case pos_ews_by_account_by_event_name::VIEW_RWLOCK:
157 instr_class= find_rwlock_class(m_pos.m_index_3);
158 break;
159 case pos_ews_by_account_by_event_name::VIEW_COND:
160 instr_class= find_cond_class(m_pos.m_index_3);
161 break;
162 case pos_ews_by_account_by_event_name::VIEW_FILE:
163 instr_class= find_file_class(m_pos.m_index_3);
164 break;
165 case pos_ews_by_account_by_event_name::VIEW_TABLE:
166 instr_class= find_table_class(m_pos.m_index_3);
167 break;
168 case pos_ews_by_account_by_event_name::VIEW_SOCKET:
169 instr_class= find_socket_class(m_pos.m_index_3);
170 break;
171 case pos_ews_by_account_by_event_name::VIEW_IDLE:
172 instr_class= find_idle_class(m_pos.m_index_3);
173 break;
174 default:
175 instr_class= NULL;
176 DBUG_ASSERT(false);
177 }
178 if (instr_class)
179 {
180 make_row(account, instr_class);
181 return 0;
182 }
183
184 return HA_ERR_RECORD_DELETED;
185}
186
187void table_ews_by_account_by_event_name
188::make_row(PFS_account *account, PFS_instr_class *klass)
189{
190 pfs_lock lock;
191 m_row_exists= false;
192
193 account->m_lock.begin_optimistic_lock(&lock);
194
195 if (m_row.m_account.make_row(account))
196 return;
197
198 m_row.m_event_name.make_row(klass);
199
200 PFS_connection_wait_visitor visitor(klass);
201 PFS_connection_iterator::visit_account(account, true, & visitor);
202
203 if (! account->m_lock.end_optimistic_lock(&lock))
204 return;
205
206 m_row_exists= true;
207
208 get_normalizer(klass);
209 m_row.m_stat.set(m_normalizer, & visitor.m_stat);
210}
211
212int table_ews_by_account_by_event_name
213::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
214 bool read_all)
215{
216 Field *f;
217
218 if (unlikely(! m_row_exists))
219 return HA_ERR_RECORD_DELETED;
220
221 /* Set the null bits */
222 DBUG_ASSERT(table->s->null_bytes == 1);
223 buf[0]= 0;
224
225 for (; (f= *fields) ; fields++)
226 {
227 if (read_all || bitmap_is_set(table->read_set, f->field_index))
228 {
229 switch(f->field_index)
230 {
231 case 0: /* USER */
232 case 1: /* HOST */
233 m_row.m_account.set_field(f->field_index, f);
234 break;
235 case 2: /* EVENT_NAME */
236 m_row.m_event_name.set_field(f);
237 break;
238 default: /* 3, ... COUNT/SUM/MIN/AVG/MAX */
239 m_row.m_stat.set_field(f->field_index - 3, f);
240 break;
241 }
242 }
243 }
244
245 return 0;
246}
247
248