Commit a24d0926 authored by Monty's avatar Monty

Second stage of optimizer_trace optimizations

- Move testing of my_writer to inline functions to avoid calls
- Made more functions inline. Especially thd->thread_started()
  is now very optimized!
- Moved Opt_trace_stmt classe to opt_trace_context.h to get critical
  functions inline
parent 940fcbe7
...@@ -260,50 +260,6 @@ void Json_writer::add_str(const String &str) ...@@ -260,50 +260,6 @@ void Json_writer::add_str(const String &str)
add_str(str.ptr(), str.length()); add_str(str.ptr(), str.length());
} }
Json_writer_object::Json_writer_object(THD *thd) :
Json_writer_struct(thd)
{
if (unlikely(my_writer))
my_writer->start_object();
}
Json_writer_object::Json_writer_object(THD* thd, const char *str) :
Json_writer_struct(thd)
{
if (unlikely(my_writer))
my_writer->add_member(str).start_object();
}
Json_writer_object::~Json_writer_object()
{
if (my_writer && !closed)
my_writer->end_object();
closed= TRUE;
}
Json_writer_array::Json_writer_array(THD *thd) :
Json_writer_struct(thd)
{
if (unlikely(my_writer))
my_writer->start_array();
}
Json_writer_array::Json_writer_array(THD *thd, const char *str) :
Json_writer_struct(thd)
{
if (unlikely(my_writer))
my_writer->add_member(str).start_array();
}
Json_writer_array::~Json_writer_array()
{
if (unlikely(my_writer && !closed))
{
my_writer->end_array();
closed= TRUE;
}
}
Json_writer_temp_disable::Json_writer_temp_disable(THD *thd_arg) Json_writer_temp_disable::Json_writer_temp_disable(THD *thd_arg)
{ {
thd= thd_arg; thd= thd_arg;
......
...@@ -256,63 +256,51 @@ class Json_value_helper ...@@ -256,63 +256,51 @@ class Json_value_helper
void init(Json_writer *my_writer) { writer= my_writer; } void init(Json_writer *my_writer) { writer= my_writer; }
void add_str(const char* val) void add_str(const char* val)
{ {
if (unlikely(writer))
writer->add_str(val); writer->add_str(val);
} }
void add_str(const char* val, size_t length) void add_str(const char* val, size_t length)
{ {
if (unlikely(writer))
writer->add_str(val, length); writer->add_str(val, length);
} }
void add_str(const String &str) void add_str(const String &str)
{ {
if (unlikely(writer))
writer->add_str(str.ptr(), str.length()); writer->add_str(str.ptr(), str.length());
} }
void add_str(const LEX_CSTRING &str) void add_str(const LEX_CSTRING &str)
{ {
if (unlikely(writer))
writer->add_str(str.str, str.length); writer->add_str(str.str, str.length);
} }
void add_str(Item *item) void add_str(Item *item)
{ {
if (unlikely(writer))
writer->add_str(item); writer->add_str(item);
} }
void add_ll(longlong val) void add_ll(longlong val)
{ {
if (unlikely(writer))
writer->add_ll(val); writer->add_ll(val);
} }
void add_size(longlong val) void add_size(longlong val)
{ {
if (unlikely(writer))
writer->add_size(val); writer->add_size(val);
} }
void add_double(double val) void add_double(double val)
{ {
if (unlikely(writer))
writer->add_double(val); writer->add_double(val);
} }
void add_bool(bool val) void add_bool(bool val)
{ {
if (unlikely(writer))
writer->add_bool(val); writer->add_bool(val);
} }
void add_null() void add_null()
{ {
if (unlikely(writer))
writer->add_null(); writer->add_null();
} }
void add_table_name(const JOIN_TAB *tab) void add_table_name(const JOIN_TAB *tab)
{ {
if (unlikely(writer))
writer->add_table_name(tab); writer->add_table_name(tab);
} }
void add_table_name(const TABLE* table) void add_table_name(const TABLE* table)
{ {
if (unlikely(writer))
writer->add_table_name(table); writer->add_table_name(table);
} }
}; };
...@@ -355,55 +343,90 @@ class Json_writer_object : public Json_writer_struct ...@@ -355,55 +343,90 @@ class Json_writer_object : public Json_writer_struct
private: private:
void add_member(const char *name) void add_member(const char *name)
{ {
if (unlikely(my_writer)) my_writer->add_member(name);
my_writer->add_member(name);
} }
public: public:
explicit Json_writer_object(THD *thd); explicit Json_writer_object(THD *thd)
explicit Json_writer_object(THD *thd, const char *str); : Json_writer_struct(thd)
{
if (unlikely(my_writer))
my_writer->start_object();
}
explicit Json_writer_object(THD* thd, const char *str)
: Json_writer_struct(thd)
{
if (unlikely(my_writer))
my_writer->add_member(str).start_object();
}
~Json_writer_object()
{
if (my_writer && !closed)
my_writer->end_object();
closed= TRUE;
}
Json_writer_object& add(const char *name, bool value) Json_writer_object& add(const char *name, bool value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
add_member(name); if (my_writer)
context.add_bool(value); {
add_member(name);
context.add_bool(value);
}
return *this; return *this;
} }
Json_writer_object& add(const char *name, ulonglong value) Json_writer_object& add(const char *name, ulonglong value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
add_member(name); if (my_writer)
context.add_ll(static_cast<longlong>(value)); {
add_member(name);
context.add_ll(static_cast<longlong>(value));
}
return *this; return *this;
} }
Json_writer_object& add(const char *name, longlong value) Json_writer_object& add(const char *name, longlong value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
add_member(name); if (my_writer)
context.add_ll(value); {
add_member(name);
context.add_ll(value);
}
return *this; return *this;
} }
Json_writer_object& add(const char *name, double value) Json_writer_object& add(const char *name, double value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
add_member(name); if (my_writer)
context.add_double(value); {
add_member(name);
context.add_double(value);
}
return *this; return *this;
} }
#ifndef _WIN64 #ifndef _WIN64
Json_writer_object& add(const char *name, size_t value) Json_writer_object& add(const char *name, size_t value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
add_member(name); if (my_writer)
context.add_ll(static_cast<longlong>(value)); {
add_member(name);
context.add_ll(static_cast<longlong>(value));
}
return *this; return *this;
} }
#endif #endif
Json_writer_object& add(const char *name, const char *value) Json_writer_object& add(const char *name, const char *value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
add_member(name); if (my_writer)
context.add_str(value); {
add_member(name);
context.add_str(value);
}
return *this; return *this;
} }
Json_writer_object& add(const char *name, const char *value, size_t num_bytes) Json_writer_object& add(const char *name, const char *value, size_t num_bytes)
...@@ -415,46 +438,64 @@ class Json_writer_object : public Json_writer_struct ...@@ -415,46 +438,64 @@ class Json_writer_object : public Json_writer_struct
Json_writer_object& add(const char *name, const LEX_CSTRING &value) Json_writer_object& add(const char *name, const LEX_CSTRING &value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
add_member(name); if (my_writer)
context.add_str(value.str, value.length); {
add_member(name);
context.add_str(value.str, value.length);
}
return *this; return *this;
} }
Json_writer_object& add(const char *name, Item *value) Json_writer_object& add(const char *name, Item *value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
add_member(name); if (my_writer)
context.add_str(value); {
add_member(name);
context.add_str(value);
}
return *this; return *this;
} }
Json_writer_object& add_null(const char*name) Json_writer_object& add_null(const char*name)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
add_member(name); if (my_writer)
context.add_null(); {
add_member(name);
context.add_null();
}
return *this; return *this;
} }
Json_writer_object& add_table_name(const JOIN_TAB *tab) Json_writer_object& add_table_name(const JOIN_TAB *tab)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
add_member("table"); if (my_writer)
context.add_table_name(tab); {
add_member("table");
context.add_table_name(tab);
}
return *this; return *this;
} }
Json_writer_object& add_table_name(const TABLE *table) Json_writer_object& add_table_name(const TABLE *table)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
add_member("table"); if (my_writer)
context.add_table_name(table); {
add_member("table");
context.add_table_name(table);
}
return *this; return *this;
} }
Json_writer_object& add_select_number(uint select_number) Json_writer_object& add_select_number(uint select_number)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
add_member("select_id"); if (my_writer)
if (unlikely(select_number >= INT_MAX)) {
context.add_str("fake"); add_member("select_id");
else if (unlikely(select_number >= INT_MAX))
context.add_ll(static_cast<longlong>(select_number)); context.add_str("fake");
else
context.add_ll(static_cast<longlong>(select_number));
}
return *this; return *this;
} }
void end() void end()
...@@ -464,7 +505,6 @@ class Json_writer_object : public Json_writer_struct ...@@ -464,7 +505,6 @@ class Json_writer_object : public Json_writer_struct
my_writer->end_object(); my_writer->end_object();
closed= TRUE; closed= TRUE;
} }
~Json_writer_object();
}; };
...@@ -479,8 +519,25 @@ class Json_writer_object : public Json_writer_struct ...@@ -479,8 +519,25 @@ class Json_writer_object : public Json_writer_struct
class Json_writer_array : public Json_writer_struct class Json_writer_array : public Json_writer_struct
{ {
public: public:
Json_writer_array(THD *thd); Json_writer_array(THD *thd): Json_writer_struct(thd)
Json_writer_array(THD *thd, const char *str); {
if (unlikely(my_writer))
my_writer->start_array();
}
Json_writer_array(THD *thd, const char *str) : Json_writer_struct(thd)
{
if (unlikely(my_writer))
my_writer->add_member(str).start_array();
}
~Json_writer_array()
{
if (unlikely(my_writer && !closed))
{
my_writer->end_array();
closed= TRUE;
}
}
void end() void end()
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
...@@ -492,78 +549,89 @@ class Json_writer_array : public Json_writer_struct ...@@ -492,78 +549,89 @@ class Json_writer_array : public Json_writer_struct
Json_writer_array& add(bool value) Json_writer_array& add(bool value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
context.add_bool(value); if (my_writer)
context.add_bool(value);
return *this; return *this;
} }
Json_writer_array& add(ulonglong value) Json_writer_array& add(ulonglong value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
context.add_ll(static_cast<longlong>(value)); if (my_writer)
context.add_ll(static_cast<longlong>(value));
return *this; return *this;
} }
Json_writer_array& add(longlong value) Json_writer_array& add(longlong value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
context.add_ll(value); if (my_writer)
context.add_ll(value);
return *this; return *this;
} }
Json_writer_array& add(double value) Json_writer_array& add(double value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
context.add_double(value); if (my_writer)
context.add_double(value);
return *this; return *this;
} }
#ifndef _WIN64 #ifndef _WIN64
Json_writer_array& add(size_t value) Json_writer_array& add(size_t value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
context.add_ll(static_cast<longlong>(value)); if (my_writer)
context.add_ll(static_cast<longlong>(value));
return *this; return *this;
} }
#endif #endif
Json_writer_array& add(const char *value) Json_writer_array& add(const char *value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
context.add_str(value); if (my_writer)
context.add_str(value);
return *this; return *this;
} }
Json_writer_array& add(const char *value, size_t num_bytes) Json_writer_array& add(const char *value, size_t num_bytes)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
context.add_str(value, num_bytes); if (my_writer)
context.add_str(value, num_bytes);
return *this; return *this;
} }
Json_writer_array& add(const LEX_CSTRING &value) Json_writer_array& add(const LEX_CSTRING &value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
context.add_str(value.str, value.length); if (my_writer)
context.add_str(value.str, value.length);
return *this; return *this;
} }
Json_writer_array& add(Item *value) Json_writer_array& add(Item *value)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
context.add_str(value); if (my_writer)
context.add_str(value);
return *this; return *this;
} }
Json_writer_array& add_null() Json_writer_array& add_null()
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
context.add_null(); if (my_writer)
context.add_null();
return *this; return *this;
} }
Json_writer_array& add_table_name(const JOIN_TAB *tab) Json_writer_array& add_table_name(const JOIN_TAB *tab)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
context.add_table_name(tab); if (my_writer)
context.add_table_name(tab);
return *this; return *this;
} }
Json_writer_array& add_table_name(const TABLE *table) Json_writer_array& add_table_name(const TABLE *table)
{ {
DBUG_ASSERT(!closed); DBUG_ASSERT(!closed);
context.add_table_name(table); if (my_writer)
context.add_table_name(table);
return *this; return *this;
} }
~Json_writer_array();
}; };
/* /*
......
...@@ -328,64 +328,33 @@ void opt_trace_disable_if_no_view_access(THD *thd, TABLE_LIST *view, ...@@ -328,64 +328,33 @@ void opt_trace_disable_if_no_view_access(THD *thd, TABLE_LIST *view,
The trace of one statement. The trace of one statement.
*/ */
class Opt_trace_stmt { Opt_trace_stmt::Opt_trace_stmt(Opt_trace_context *ctx_arg)
public: {
/** ctx= ctx_arg;
Constructor, starts a trace for information_schema and dbug. current_json= new Json_writer();
@param ctx_arg context missing_priv= false;
*/ I_S_disabled= 0;
Opt_trace_stmt(Opt_trace_context *ctx_arg) }
{
ctx= ctx_arg;
current_json= new Json_writer();
missing_priv= false;
I_S_disabled= 0;
}
~Opt_trace_stmt()
{
delete current_json;
}
void set_query(const char *query_ptr, size_t length, const CHARSET_INFO *charset);
void open_struct(const char *key, char opening_bracket);
void close_struct(const char *saved_key, char closing_bracket);
void fill_info(Opt_trace_info* info);
void add(const char *key, char *opening_bracket, size_t val_length);
Json_writer* get_current_json() {return current_json;}
void missing_privilege();
void disable_tracing_for_children();
void enable_tracing_for_children();
bool is_enabled();
void set_allowed_mem_size(size_t mem_size);
size_t get_length() { return current_json->output.length(); }
size_t get_truncated_bytes() { return current_json->get_truncated_bytes(); }
bool get_missing_priv() { return missing_priv; }
private:
Opt_trace_context *ctx;
String query; // store the query sent by the user
Json_writer *current_json; // stores the trace
bool missing_priv; ///< whether user lacks privilege to see this trace
/*
0 <=> this trace should be in information_schema.
!=0 tracing is disabled, this currently happens when we want to trace a
sub-statement. For now traces are only collect for the top statement
not for the sub-statments.
*/
uint I_S_disabled;
};
void Opt_trace_stmt::set_query(const char *query_ptr, size_t length, Opt_trace_stmt::~Opt_trace_stmt()
const CHARSET_INFO *charset)
{ {
query.append(query_ptr, length, charset); delete current_json;
} }
Json_writer* Opt_trace_context::get_current_json() size_t Opt_trace_stmt::get_length()
{ {
if (!is_started()) return current_json->output.length();
return NULL; }
return current_trace->get_current_json();
size_t Opt_trace_stmt::get_truncated_bytes()
{
return current_json->get_truncated_bytes();
}
void Opt_trace_stmt::set_query(const char *query_ptr, size_t length,
const CHARSET_INFO *charset)
{
query.append(query_ptr, length, charset);
} }
void Opt_trace_context::missing_privilege() void Opt_trace_context::missing_privilege()
...@@ -573,11 +542,6 @@ void Opt_trace_stmt::enable_tracing_for_children() ...@@ -573,11 +542,6 @@ void Opt_trace_stmt::enable_tracing_for_children()
--I_S_disabled; --I_S_disabled;
} }
bool Opt_trace_stmt::is_enabled()
{
return I_S_disabled == 0;
}
void Opt_trace_stmt::set_allowed_mem_size(size_t mem_size) void Opt_trace_stmt::set_allowed_mem_size(size_t mem_size)
{ {
current_json->set_size_limit(mem_size); current_json->set_size_limit(mem_size);
......
...@@ -21,8 +21,6 @@ class Item; ...@@ -21,8 +21,6 @@ class Item;
class THD; class THD;
struct TABLE_LIST; struct TABLE_LIST;
class Opt_trace_stmt;
/* /*
User-visible information about a trace. User-visible information about a trace.
*/ */
......
...@@ -3,7 +3,50 @@ ...@@ -3,7 +3,50 @@
#include "sql_array.h" #include "sql_array.h"
class Opt_trace_stmt; class Opt_trace_context;
class Opt_trace_info;
class Json_writer;
class Opt_trace_stmt {
public:
/**
Constructor, starts a trace for information_schema and dbug.
@param ctx_arg context
*/
Opt_trace_stmt(Opt_trace_context *ctx_arg);
~Opt_trace_stmt();
void set_query(const char *query_ptr, size_t length, const CHARSET_INFO *charset);
void open_struct(const char *key, char opening_bracket);
void close_struct(const char *saved_key, char closing_bracket);
void fill_info(Opt_trace_info* info);
void add(const char *key, char *opening_bracket, size_t val_length);
Json_writer* get_current_json() {return current_json;}
void missing_privilege();
void disable_tracing_for_children();
void enable_tracing_for_children();
bool is_enabled()
{
return I_S_disabled == 0;
}
void set_allowed_mem_size(size_t mem_size);
size_t get_length();
size_t get_truncated_bytes();
bool get_missing_priv() { return missing_priv; }
private:
Opt_trace_context *ctx;
String query; // store the query sent by the user
Json_writer *current_json; // stores the trace
bool missing_priv; ///< whether user lacks privilege to see this trace
/*
0 <=> this trace should be in information_schema.
!=0 tracing is disabled, this currently happens when we want to trace a
sub-statement. For now traces are only collect for the top statement
not for the sub-statments.
*/
uint I_S_disabled;
};
class Opt_trace_context class Opt_trace_context
{ {
...@@ -48,7 +91,12 @@ class Opt_trace_context ...@@ -48,7 +91,12 @@ class Opt_trace_context
This returns the current trace, to which we are still writing and has not been finished This returns the current trace, to which we are still writing and has not been finished
*/ */
Json_writer* get_current_json(); Json_writer* get_current_json()
{
if (!is_started())
return NULL;
return current_trace->get_current_json();
}
bool empty() bool empty()
{ {
...@@ -57,7 +105,7 @@ class Opt_trace_context ...@@ -57,7 +105,7 @@ class Opt_trace_context
bool is_started() bool is_started()
{ {
return current_trace && is_enabled(); return current_trace && current_trace->is_enabled();
} }
bool disable_tracing_if_required(); bool disable_tracing_if_required();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment