1 /* Copyright (c) 2011, 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 Foundation,
21   51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22 
23 /**
24   @file storage/perfschema/table_mems_by_host_by_event_name.cc
25   Table MEMORY_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_mems_by_host_by_event_name.h"
34 #include "pfs_global.h"
35 #include "pfs_visitor.h"
36 #include "pfs_memory.h"
37 #include "pfs_buffer_container.h"
38 #include "field.h"
39 
40 THR_LOCK table_mems_by_host_by_event_name::m_table_lock;
41 
42 static const TABLE_FIELD_TYPE field_types[]=
43 {
44   {
45     { C_STRING_WITH_LEN("HOST") },
46     { C_STRING_WITH_LEN("char(60)") },
47     { NULL, 0}
48   },
49   {
50     { C_STRING_WITH_LEN("EVENT_NAME") },
51     { C_STRING_WITH_LEN("varchar(128)") },
52     { NULL, 0}
53   },
54   {
55     { C_STRING_WITH_LEN("COUNT_ALLOC") },
56     { C_STRING_WITH_LEN("bigint(20)") },
57     { NULL, 0}
58   },
59   {
60     { C_STRING_WITH_LEN("COUNT_FREE") },
61     { C_STRING_WITH_LEN("bigint(20)") },
62     { NULL, 0}
63   },
64   {
65     { C_STRING_WITH_LEN("SUM_NUMBER_OF_BYTES_ALLOC") },
66     { C_STRING_WITH_LEN("bigint(20)") },
67     { NULL, 0}
68   },
69   {
70     { C_STRING_WITH_LEN("SUM_NUMBER_OF_BYTES_FREE") },
71     { C_STRING_WITH_LEN("bigint(20)") },
72     { NULL, 0}
73   },
74   {
75     { C_STRING_WITH_LEN("LOW_COUNT_USED") },
76     { C_STRING_WITH_LEN("bigint(20)") },
77     { NULL, 0}
78   },
79   {
80     { C_STRING_WITH_LEN("CURRENT_COUNT_USED") },
81     { C_STRING_WITH_LEN("bigint(20)") },
82     { NULL, 0}
83   },
84   {
85     { C_STRING_WITH_LEN("HIGH_COUNT_USED") },
86     { C_STRING_WITH_LEN("bigint(20)") },
87     { NULL, 0}
88   },
89   {
90     { C_STRING_WITH_LEN("LOW_NUMBER_OF_BYTES_USED") },
91     { C_STRING_WITH_LEN("bigint(20)") },
92     { NULL, 0}
93   },
94   {
95     { C_STRING_WITH_LEN("CURRENT_NUMBER_OF_BYTES_USED") },
96     { C_STRING_WITH_LEN("bigint(20)") },
97     { NULL, 0}
98   },
99   {
100     { C_STRING_WITH_LEN("HIGH_NUMBER_OF_BYTES_USED") },
101     { C_STRING_WITH_LEN("bigint(20)") },
102     { NULL, 0}
103   }
104 };
105 
106 TABLE_FIELD_DEF
107 table_mems_by_host_by_event_name::m_field_def=
108 { 12, field_types };
109 
110 PFS_engine_table_share
111 table_mems_by_host_by_event_name::m_share=
112 {
113   { C_STRING_WITH_LEN("memory_summary_by_host_by_event_name") },
114   &pfs_readonly_acl,
115   table_mems_by_host_by_event_name::create,
116   NULL, /* write_row */
117   table_mems_by_host_by_event_name::delete_all_rows,
118   table_mems_by_host_by_event_name::get_row_count,
119   sizeof(PFS_simple_index),
120   &m_table_lock,
121   &m_field_def,
122   false, /* checked */
123   false  /* perpetual */
124 };
125 
create(void)126 PFS_engine_table* table_mems_by_host_by_event_name::create(void)
127 {
128   return new table_mems_by_host_by_event_name();
129 }
130 
131 int
delete_all_rows(void)132 table_mems_by_host_by_event_name::delete_all_rows(void)
133 {
134   reset_memory_by_thread();
135   reset_memory_by_account();
136   reset_memory_by_host();
137   return 0;
138 }
139 
140 ha_rows
get_row_count(void)141 table_mems_by_host_by_event_name::get_row_count(void)
142 {
143   return global_host_container.get_row_count() * memory_class_max;
144 }
145 
table_mems_by_host_by_event_name()146 table_mems_by_host_by_event_name::table_mems_by_host_by_event_name()
147   : PFS_engine_table(&m_share, &m_pos),
148   m_row_exists(false), m_pos(), m_next_pos()
149 {}
150 
reset_position(void)151 void table_mems_by_host_by_event_name::reset_position(void)
152 {
153   m_pos.reset();
154   m_next_pos.reset();
155 }
156 
rnd_next(void)157 int table_mems_by_host_by_event_name::rnd_next(void)
158 {
159   PFS_host *host;
160   PFS_memory_class *memory_class;
161   bool has_more_host= true;
162 
163   for (m_pos.set_at(&m_next_pos);
164        has_more_host;
165        m_pos.next_host())
166   {
167     host= global_host_container.get(m_pos.m_index_1, & has_more_host);
168     if (host != NULL)
169     {
170       do
171       {
172         memory_class= find_memory_class(m_pos.m_index_2);
173         if (memory_class != NULL)
174         {
175           if (! memory_class->is_global())
176           {
177             make_row(host, memory_class);
178             m_next_pos.set_after(&m_pos);
179             return 0;
180           }
181 
182           m_pos.next_class();
183         }
184       }
185       while (memory_class != NULL);
186     }
187   }
188 
189   return HA_ERR_END_OF_FILE;
190 }
191 
rnd_pos(const void * pos)192 int table_mems_by_host_by_event_name::rnd_pos(const void *pos)
193 {
194   PFS_host *host;
195   PFS_memory_class *memory_class;
196 
197   set_position(pos);
198 
199   host= global_host_container.get(m_pos.m_index_1);
200   if (host != NULL)
201   {
202     memory_class= find_memory_class(m_pos.m_index_2);
203     if (memory_class != NULL)
204     {
205       if (! memory_class->is_global())
206       {
207         make_row(host, memory_class);
208         return 0;
209       }
210     }
211   }
212 
213   return HA_ERR_RECORD_DELETED;
214 }
215 
216 void table_mems_by_host_by_event_name
make_row(PFS_host * host,PFS_memory_class * klass)217 ::make_row(PFS_host *host, PFS_memory_class *klass)
218 {
219   pfs_optimistic_state lock;
220   m_row_exists= false;
221 
222   host->m_lock.begin_optimistic_lock(&lock);
223 
224   if (m_row.m_host.make_row(host))
225     return;
226 
227   m_row.m_event_name.make_row(klass);
228 
229   PFS_connection_memory_visitor visitor(klass);
230   PFS_connection_iterator::visit_host(host,
231                                       true,  /* accounts */
232                                       true,  /* threads */
233                                       false, /* THDs */
234                                       & visitor);
235 
236   if (! host->m_lock.end_optimistic_lock(&lock))
237     return;
238 
239   m_row_exists= true;
240   m_row.m_stat.set(& visitor.m_stat);
241 }
242 
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)243 int table_mems_by_host_by_event_name::read_row_values(TABLE *table,
244                                                     unsigned char *buf,
245                                                     Field **fields,
246                                                     bool read_all)
247 {
248   Field *f;
249 
250   if (unlikely(! m_row_exists))
251     return HA_ERR_RECORD_DELETED;
252 
253   /* Set the null bits */
254   assert(table->s->null_bytes == 1);
255   buf[0]= 0;
256 
257   for (; (f= *fields) ; fields++)
258   {
259     if (read_all || bitmap_is_set(table->read_set, f->field_index))
260     {
261       switch(f->field_index)
262       {
263       case 0: /* HOST */
264         m_row.m_host.set_field(f);
265         break;
266       case 1: /* EVENT_NAME */
267         m_row.m_event_name.set_field(f);
268         break;
269       default: /* 2, ... HIGH_NUMBER_OF_BYTES_USED */
270         m_row.m_stat.set_field(f->field_index - 2, f);
271         break;
272       }
273     }
274   }
275 
276   return 0;
277 }
278 
279