MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pfs_digest.h
Go to the documentation of this file.
1 /* Copyright (c) 2011, 2013, 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 Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 #ifndef PFS_DIGEST_H
17 #define PFS_DIGEST_H
18 
24 #include "pfs_column_types.h"
25 #include "lf.h"
26 #include "pfs_stat.h"
27 
28 #define PFS_SIZE_OF_A_TOKEN 2
29 
30 extern bool flag_statements_digest;
31 extern ulong digest_max;
32 extern ulong digest_lost;
33 struct PFS_thread;
34 
35 /* Fixed, per MD5 hash. */
36 #define PFS_MD5_SIZE 16
37 
42 {
43  unsigned char m_md5[PFS_MD5_SIZE];
44  char m_schema_name[NAME_LEN];
45  uint m_schema_name_length;
46 };
47 
49 struct PFS_ALIGNED PFS_statements_digest_stat
50 {
53 
55  PSI_digest_storage m_digest_storage;
56 
59 
61  ulonglong m_first_seen;
62  ulonglong m_last_seen;
63 
65  void reset_data();
67  void reset_index(PFS_thread *thread);
68 };
69 
70 int init_digest(const PFS_global_param *param);
71 void cleanup_digest();
72 
73 int init_digest_hash(void);
74 void cleanup_digest_hash(void);
75 PFS_statement_stat* find_or_create_digest(PFS_thread *thread,
76  PSI_digest_storage *digest_storage,
77  const char *schema_name,
78  uint schema_name_length);
79 
80 void get_digest_text(char *digest_text, PSI_digest_storage *digest_storage);
81 
82 void reset_esms_by_digest();
83 
84 /* Exposing the data directly, for iterators. */
85 extern PFS_statements_digest_stat *statements_digest_stat_array;
86 
87 /* Instrumentation callbacks for pfs.cc */
88 
89 struct PSI_digest_locker *pfs_digest_start_v1(PSI_statement_locker *locker);
90 PSI_digest_locker *pfs_digest_add_token_v1(PSI_digest_locker *locker,
91  uint token,
92  OPAQUE_LEX_YYSTYPE *yylval);
93 
94 static inline void digest_reset(PSI_digest_storage *digest)
95 {
96  digest->m_full= false;
97  digest->m_byte_count= 0;
98  digest->m_charset_number= 0;
99 }
100 
101 static inline void digest_copy(PSI_digest_storage *to, const PSI_digest_storage *from)
102 {
103  if (from->m_byte_count > 0)
104  {
105  to->m_full= from->m_full;
106  to->m_byte_count= from->m_byte_count;
107  to->m_charset_number= from->m_charset_number;
108  DBUG_ASSERT(to->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE);
109  memcpy(to->m_token_array, from->m_token_array, to->m_byte_count);
110  }
111  else
112  {
113  DBUG_ASSERT(from->m_byte_count == 0);
114  to->m_full= false;
115  to->m_byte_count= 0;
116  to->m_charset_number= 0;
117  }
118 }
119 
123 inline int read_token(PSI_digest_storage *digest_storage,
124  int index, uint *tok)
125 {
126  int safe_byte_count= digest_storage->m_byte_count;
127 
128  if (index + PFS_SIZE_OF_A_TOKEN <= safe_byte_count &&
129  safe_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE)
130  {
131  unsigned char *src= & digest_storage->m_token_array[index];
132  *tok= src[0] | (src[1] << 8);
133  return index + PFS_SIZE_OF_A_TOKEN;
134  }
135 
136  /* The input byte stream is exhausted. */
137  *tok= 0;
138  return PSI_MAX_DIGEST_STORAGE_SIZE + 1;
139 }
140 
144 inline void store_token(PSI_digest_storage* digest_storage, uint token)
145 {
146  DBUG_ASSERT(digest_storage->m_byte_count >= 0);
147  DBUG_ASSERT(digest_storage->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE);
148 
149  if (digest_storage->m_byte_count + PFS_SIZE_OF_A_TOKEN <= PSI_MAX_DIGEST_STORAGE_SIZE)
150  {
151  unsigned char* dest= & digest_storage->m_token_array[digest_storage->m_byte_count];
152  dest[0]= token & 0xff;
153  dest[1]= (token >> 8) & 0xff;
154  digest_storage->m_byte_count+= PFS_SIZE_OF_A_TOKEN;
155  }
156  else
157  {
158  digest_storage->m_full= true;
159  }
160 }
161 
165 inline int read_identifier(PSI_digest_storage* digest_storage,
166  int index, char ** id_string, int *id_length)
167 {
168  int new_index;
169  DBUG_ASSERT(index <= digest_storage->m_byte_count);
170  DBUG_ASSERT(digest_storage->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE);
171 
172  /*
173  token + length + string are written in an atomic way,
174  so we do always expect a length + string here
175  */
176  unsigned char *src= & digest_storage->m_token_array[index];
177  uint length= src[0] | (src[1] << 8);
178  *id_string= (char *) (src + 2);
179  *id_length= length;
180 
181  new_index= index + PFS_SIZE_OF_A_TOKEN + length;
182  DBUG_ASSERT(new_index <= digest_storage->m_byte_count);
183  return new_index;
184 }
185 
189 inline void store_token_identifier(PSI_digest_storage* digest_storage,
190  uint token,
191  uint id_length, const char *id_name)
192 {
193  DBUG_ASSERT(digest_storage->m_byte_count >= 0);
194  DBUG_ASSERT(digest_storage->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE);
195 
196  uint bytes_needed= 2 * PFS_SIZE_OF_A_TOKEN + id_length;
197  if (digest_storage->m_byte_count + bytes_needed <= PSI_MAX_DIGEST_STORAGE_SIZE)
198  {
199  unsigned char* dest= & digest_storage->m_token_array[digest_storage->m_byte_count];
200  /* Write the token */
201  dest[0]= token & 0xff;
202  dest[1]= (token >> 8) & 0xff;
203  /* Write the string length */
204  dest[2]= id_length & 0xff;
205  dest[3]= (id_length >> 8) & 0xff;
206  /* Write the string data */
207  if (id_length > 0)
208  memcpy((char *)(dest + 4), id_name, id_length);
209  digest_storage->m_byte_count+= bytes_needed;
210  }
211  else
212  {
213  digest_storage->m_full= true;
214  }
215 }
216 
217 extern LF_HASH digest_hash;
218 
219 #endif