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_os_global_by_type.cc
18 Table OBJECTS_SUMMARY_GLOBAL_BY_TYPE (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_os_global_by_type.h"
27#include "pfs_global.h"
28
29THR_LOCK table_os_global_by_type::m_table_lock;
30
31PFS_engine_table_share
32table_os_global_by_type::m_share=
33{
34 { C_STRING_WITH_LEN("objects_summary_global_by_type") },
35 &pfs_truncatable_acl,
36 table_os_global_by_type::create,
37 NULL, /* write_row */
38 table_os_global_by_type::delete_all_rows,
39 NULL, /* get_row_count */
40 1000, /* records */
41 sizeof(pos_os_global_by_type),
42 &m_table_lock,
43 { C_STRING_WITH_LEN("CREATE TABLE objects_summary_global_by_type("
44 "OBJECT_TYPE VARCHAR(64),"
45 "OBJECT_SCHEMA VARCHAR(64),"
46 "OBJECT_NAME VARCHAR(64),"
47 "COUNT_STAR BIGINT unsigned not null,"
48 "SUM_TIMER_WAIT BIGINT unsigned not null,"
49 "MIN_TIMER_WAIT BIGINT unsigned not null,"
50 "AVG_TIMER_WAIT BIGINT unsigned not null,"
51 "MAX_TIMER_WAIT BIGINT unsigned not null)") }
52};
53
54PFS_engine_table*
55table_os_global_by_type::create(void)
56{
57 return new table_os_global_by_type();
58}
59
60int
61table_os_global_by_type::delete_all_rows(void)
62{
63 reset_table_waits_by_table_handle();
64 reset_table_waits_by_table();
65 return 0;
66}
67
68table_os_global_by_type::table_os_global_by_type()
69 : PFS_engine_table(&m_share, &m_pos),
70 m_row_exists(false), m_pos(), m_next_pos()
71{}
72
73void table_os_global_by_type::reset_position(void)
74{
75 m_pos.reset();
76 m_next_pos.reset();
77}
78
79int table_os_global_by_type::rnd_next(void)
80{
81 PFS_table_share *table_share;
82
83 for (m_pos.set_at(&m_next_pos);
84 m_pos.has_more_view();
85 m_pos.next_view())
86 {
87 switch (m_pos.m_index_1) {
88 case pos_os_global_by_type::VIEW_TABLE:
89 for ( ; m_pos.m_index_2 < table_share_max; m_pos.m_index_2++)
90 {
91 table_share= &table_share_array[m_pos.m_index_2];
92 if (table_share->m_lock.is_populated())
93 {
94 make_row(table_share);
95 m_next_pos.set_after(&m_pos);
96 return 0;
97 }
98 }
99 break;
100 default:
101 break;
102 }
103 }
104
105 return HA_ERR_END_OF_FILE;
106}
107
108int
109table_os_global_by_type::rnd_pos(const void *pos)
110{
111 PFS_table_share *table_share;
112
113 set_position(pos);
114
115 switch (m_pos.m_index_1) {
116 case pos_os_global_by_type::VIEW_TABLE:
117 DBUG_ASSERT(m_pos.m_index_2 < table_share_max);
118 table_share= &table_share_array[m_pos.m_index_2];
119 if (table_share->m_lock.is_populated())
120 {
121 make_row(table_share);
122 return 0;
123 }
124 break;
125 default:
126 break;
127 }
128
129 return HA_ERR_RECORD_DELETED;
130}
131
132void table_os_global_by_type::make_row(PFS_table_share *share)
133{
134 pfs_lock lock;
135 PFS_single_stat cumulated_stat;
136 uint safe_key_count;
137
138 m_row_exists= false;
139
140 share->m_lock.begin_optimistic_lock(&lock);
141
142 m_row.m_object_type= share->get_object_type();
143 memcpy(m_row.m_schema_name, share->m_schema_name, share->m_schema_name_length);
144 m_row.m_schema_name_length= share->m_schema_name_length;
145 memcpy(m_row.m_object_name, share->m_table_name, share->m_table_name_length);
146 m_row.m_object_name_length= share->m_table_name_length;
147
148 /* This is a dirty read, some thread can write data while we are reading it */
149 safe_key_count= sanitize_index_count(share->m_key_count);
150
151 share->m_table_stat.sum(& cumulated_stat, safe_key_count);
152
153 if (! share->m_lock.end_optimistic_lock(&lock))
154 return;
155
156 m_row_exists= true;
157
158 if (share->get_refcount() > 0)
159 {
160 /* For all the table handles still opened ... */
161 PFS_table *table= table_array;
162 PFS_table *table_last= table_array + table_max;
163 for ( ; table < table_last ; table++)
164 {
165 if ((table->m_share == share) && (table->m_lock.is_populated()))
166 {
167 /*
168 If the opened table handle is for this table share,
169 aggregate the table handle statistics.
170 */
171 table->m_table_stat.sum(& cumulated_stat, safe_key_count);
172 }
173 }
174 }
175
176 time_normalizer *normalizer= time_normalizer::get(wait_timer);
177 m_row.m_stat.set(normalizer, &cumulated_stat);
178}
179
180int table_os_global_by_type::read_row_values(TABLE *table,
181 unsigned char *buf,
182 Field **fields,
183 bool read_all)
184{
185 Field *f;
186
187 if (unlikely(! m_row_exists))
188 return HA_ERR_RECORD_DELETED;
189
190 /* Set the null bits */
191 DBUG_ASSERT(table->s->null_bytes == 1);
192 buf[0]= 0;
193
194 for (; (f= *fields) ; fields++)
195 {
196 if (read_all || bitmap_is_set(table->read_set, f->field_index))
197 {
198 switch(f->field_index)
199 {
200 case 0: /* OBJECT_TYPE */
201 set_field_object_type(f, m_row.m_object_type);
202 break;
203 case 1: /* SCHEMA_NAME */
204 set_field_varchar_utf8(f, m_row.m_schema_name,
205 m_row.m_schema_name_length);
206 break;
207 case 2: /* OBJECT_NAME */
208 set_field_varchar_utf8(f, m_row.m_object_name,
209 m_row.m_object_name_length);
210 break;
211 case 3: /* COUNT */
212 set_field_ulonglong(f, m_row.m_stat.m_count);
213 break;
214 case 4: /* SUM */
215 set_field_ulonglong(f, m_row.m_stat.m_sum);
216 break;
217 case 5: /* MIN */
218 set_field_ulonglong(f, m_row.m_stat.m_min);
219 break;
220 case 6: /* AVG */
221 set_field_ulonglong(f, m_row.m_stat.m_avg);
222 break;
223 case 7: /* MAX */
224 set_field_ulonglong(f, m_row.m_stat.m_max);
225 break;
226 default:
227 DBUG_ASSERT(false);
228 }
229 }
230 }
231
232 return 0;
233}
234
235