diff options
Diffstat (limited to 'storage/perfschema/pfs_digest.h')
-rw-r--r-- | storage/perfschema/pfs_digest.h | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/storage/perfschema/pfs_digest.h b/storage/perfschema/pfs_digest.h new file mode 100644 index 00000000000..2646596171c --- /dev/null +++ b/storage/perfschema/pfs_digest.h @@ -0,0 +1,221 @@ +/* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ + +#ifndef PFS_DIGEST_H +#define PFS_DIGEST_H + +/** + @file storage/perfschema/pfs_digest.h + Statement Digest data structures (declarations). +*/ + +#include "pfs_column_types.h" +#include "lf.h" +#include "pfs_stat.h" + +#define PFS_SIZE_OF_A_TOKEN 2 + +extern bool flag_statements_digest; +extern ulong digest_max; +extern ulong digest_lost; +struct PFS_thread; + +/* Fixed, per MD5 hash. */ +#define PFS_MD5_SIZE 16 + +/** + Structure to store a MD5 hash value (digest) for a statement. +*/ +struct PFS_digest_hash +{ + unsigned char m_md5[PFS_MD5_SIZE]; +}; + +/** A statement digest stat record. */ +struct PFS_statements_digest_stat +{ + /** + Digest MD5 Hash. + */ + PFS_digest_hash m_digest_hash; + + /** + Digest Storage. + */ + PSI_digest_storage m_digest_storage; + + /** + Statement stat. + */ + PFS_statement_stat m_stat; + + /** + First Seen/last seen. + */ + ulonglong m_first_seen; + ulonglong m_last_seen; + + /** Reset data for this record. */ + void reset_data(); + /** Reset data and remove index for this record. */ + void reset_index(PFS_thread *thread); +}; + +int init_digest(const PFS_global_param *param); +void cleanup_digest(); + +int init_digest_hash(void); +void cleanup_digest_hash(void); +PFS_statement_stat* find_or_create_digest(PFS_thread*, + PSI_digest_storage*); + +void get_digest_text(char* digest_text, PSI_digest_storage*); + +void reset_esms_by_digest(); + +/* Exposing the data directly, for iterators. */ +extern PFS_statements_digest_stat *statements_digest_stat_array; + +/* Instrumentation callbacks for pfs.cc */ + +struct PSI_digest_locker* pfs_digest_start_v1(PSI_statement_locker *locker); +PSI_digest_locker* pfs_digest_add_token_v1(PSI_digest_locker *locker, + uint token, + OPAQUE_LEX_YYSTYPE *yylval); + +static inline void digest_reset(PSI_digest_storage *digest) +{ + digest->m_full= false; + digest->m_byte_count= 0; +} + +static inline void digest_copy(PSI_digest_storage *to, const PSI_digest_storage *from) +{ + if (from->m_byte_count > 0) + { + to->m_full= from->m_full; + to->m_byte_count= from->m_byte_count; + DBUG_ASSERT(to->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE); + memcpy(to->m_token_array, from->m_token_array, to->m_byte_count); + } + else + { + DBUG_ASSERT(! from->m_full); + DBUG_ASSERT(from->m_byte_count == 0); + to->m_full= false; + to->m_byte_count= 0; + } +} + +/** + Function to read a single token from token array. +*/ +inline int read_token(PSI_digest_storage *digest_storage, + int index, uint *tok) +{ + DBUG_ASSERT(index <= digest_storage->m_byte_count); + DBUG_ASSERT(digest_storage->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE); + + if (index + PFS_SIZE_OF_A_TOKEN <= digest_storage->m_byte_count) + { + unsigned char *src= & digest_storage->m_token_array[index]; + *tok= src[0] | (src[1] << 8); + return index + PFS_SIZE_OF_A_TOKEN; + } + + /* The input byte stream is exhausted. */ + *tok= 0; + return PSI_MAX_DIGEST_STORAGE_SIZE + 1; +} + +/** + Function to store a single token in token array. +*/ +inline void store_token(PSI_digest_storage* digest_storage, uint token) +{ + DBUG_ASSERT(digest_storage->m_byte_count >= 0); + DBUG_ASSERT(digest_storage->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE); + + if (digest_storage->m_byte_count + PFS_SIZE_OF_A_TOKEN <= PSI_MAX_DIGEST_STORAGE_SIZE) + { + unsigned char* dest= & digest_storage->m_token_array[digest_storage->m_byte_count]; + dest[0]= token & 0xff; + dest[1]= (token >> 8) & 0xff; + digest_storage->m_byte_count+= PFS_SIZE_OF_A_TOKEN; + } + else + { + digest_storage->m_full= true; + } +} + +/** + Function to read an identifier from token array. +*/ +inline int read_identifier(PSI_digest_storage* digest_storage, + int index, char ** id_string, int *id_length) +{ + int new_index; + DBUG_ASSERT(index <= digest_storage->m_byte_count); + DBUG_ASSERT(digest_storage->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE); + + /* + token + length + string are written in an atomic way, + so we do always expect a length + string here + */ + unsigned char *src= & digest_storage->m_token_array[index]; + uint length= src[0] | (src[1] << 8); + *id_string= (char *) (src + 2); + *id_length= length; + + new_index= index + PFS_SIZE_OF_A_TOKEN + length; + DBUG_ASSERT(new_index <= digest_storage->m_byte_count); + return new_index; +} + +/** + Function to store an identifier in token array. +*/ +inline void store_token_identifier(PSI_digest_storage* digest_storage, + uint token, + uint id_length, const char *id_name) +{ + DBUG_ASSERT(digest_storage->m_byte_count >= 0); + DBUG_ASSERT(digest_storage->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE); + + uint bytes_needed= 2 * PFS_SIZE_OF_A_TOKEN + id_length; + if (digest_storage->m_byte_count + bytes_needed <= PSI_MAX_DIGEST_STORAGE_SIZE) + { + unsigned char* dest= & digest_storage->m_token_array[digest_storage->m_byte_count]; + /* Write the token */ + dest[0]= token & 0xff; + dest[1]= (token >> 8) & 0xff; + /* Write the string length */ + dest[2]= id_length & 0xff; + dest[3]= (id_length >> 8) & 0xff; + /* Write the string data */ + if (id_length > 0) + { + strncpy((char *)(dest + 4), id_name, id_length); + } + digest_storage->m_byte_count+= bytes_needed; + } + else + { + digest_storage->m_full= true; + } +} + +#endif |