diff options
Diffstat (limited to 'sql/keycaches.cc')
-rw-r--r-- | sql/keycaches.cc | 141 |
1 files changed, 136 insertions, 5 deletions
diff --git a/sql/keycaches.cc b/sql/keycaches.cc index 10bec7c1..250a287e 100644 --- a/sql/keycaches.cc +++ b/sql/keycaches.cc @@ -15,6 +15,10 @@ #include "mariadb.h" #include "keycaches.h" +#include "optimizer_costs.h" +#include "optimizer_defaults.h" +#include "handler.h" +#include "sql_class.h" /**************************************************************************** Named list handling @@ -22,10 +26,13 @@ NAMED_ILIST key_caches; NAMED_ILIST rpl_filters; +NAMED_ILIST linked_optimizer_costs; extern "C" PSI_memory_key key_memory_KEY_CACHE; extern PSI_memory_key key_memory_NAMED_ILINK_name; +LEX_CSTRING default_base= {STRING_WITH_LEN("default")}; + /** ilink (intrusive list element) with a name */ @@ -46,7 +53,7 @@ public: } inline bool cmp(const char *name_cmp, size_t length) { - return length == name_length && !memcmp(name, name_cmp, length); + return !system_charset_info->strnncoll(name, name_length, name_cmp, length); } ~NAMED_ILINK() { @@ -72,7 +79,8 @@ uchar* find_named(I_List<NAMED_ILINK> *list, const char *name, size_t length, } -bool NAMED_ILIST::delete_element(const char *name, size_t length, void (*free_element)(const char *name, void*)) +bool NAMED_ILIST::delete_element(const char *name, size_t length, + void (*free_element)(const char *name, void*)) { I_List_iterator<NAMED_ILINK> it(*this); NAMED_ILINK *element; @@ -104,14 +112,12 @@ void NAMED_ILIST::delete_elements(void (*free_element)(const char *name, void*)) /* Key cache functions */ -LEX_CSTRING default_key_cache_base= {STRING_WITH_LEN("default")}; - KEY_CACHE zero_key_cache; ///< @@nonexistent_cache.param->value_ptr() points here KEY_CACHE *get_key_cache(const LEX_CSTRING *cache_name) { if (!cache_name || ! cache_name->length) - cache_name= &default_key_cache_base; + cache_name= &default_base; return ((KEY_CACHE*) find_named(&key_caches, cache_name->str, cache_name->length, 0)); } @@ -234,3 +240,128 @@ void free_all_rpl_filters() { rpl_filters.delete_elements(free_rpl_filter); } + + +/****************************************************************************** + Optimizer costs functions +******************************************************************************/ + +LEX_CSTRING default_costs_base= {STRING_WITH_LEN("default")}; + +OPTIMIZER_COSTS default_optimizer_costs= +{ + DEFAULT_DISK_READ_COST, // disk_read_cost + DEFAULT_INDEX_BLOCK_COPY_COST, // index_block_copy_cost + DEFAULT_WHERE_COST/4, // key_cmp_cost + DEFAULT_KEY_COPY_COST, // key_copy_cost + DEFAULT_KEY_LOOKUP_COST, // key_lookup_cost + DEFAULT_KEY_NEXT_FIND_COST, // key_next_find_cost + DEFAULT_DISK_READ_RATIO, // disk_read_ratio + DEFAULT_ROW_COPY_COST, // row_copy_cost + DEFAULT_ROW_LOOKUP_COST, // row_lookup_cost + DEFAULT_ROW_NEXT_FIND_COST, // row_next_find_cost + DEFAULT_ROWID_COMPARE_COST, // rowid_compare_cost + DEFAULT_ROWID_COPY_COST, // rowid_copy_cost + 1 // Cannot be deleted +}; + +OPTIMIZER_COSTS heap_optimizer_costs, tmp_table_optimizer_costs; + +OPTIMIZER_COSTS *get_optimizer_costs(const LEX_CSTRING *cache_name) +{ + if (!cache_name->length) + return &default_optimizer_costs; + return ((OPTIMIZER_COSTS*) find_named(&linked_optimizer_costs, + cache_name->str, cache_name->length, + 0)); +} + +OPTIMIZER_COSTS *create_optimizer_costs(const char *name, size_t length) +{ + OPTIMIZER_COSTS *optimizer_costs; + DBUG_ENTER("create_optimizer_costs"); + DBUG_PRINT("enter",("name: %.*s", (int) length, name)); + + if ((optimizer_costs= (OPTIMIZER_COSTS*) + my_malloc(key_memory_KEY_CACHE, + sizeof(OPTIMIZER_COSTS), MYF(MY_ZEROFILL | MY_WME)))) + { + if (!new NAMED_ILINK(&linked_optimizer_costs, name, length, + (uchar*) optimizer_costs)) + { + my_free(optimizer_costs); + optimizer_costs= 0; + } + else + { + /* Mark that values are not yet set */ + for (uint i=0 ; i < sizeof(OPTIMIZER_COSTS)/sizeof(double) ; i++) + ((double*) optimizer_costs)[i]= OPTIMIZER_COST_UNDEF; + } + } + DBUG_RETURN(optimizer_costs); +} + + +OPTIMIZER_COSTS *get_or_create_optimizer_costs(const char *name, size_t length) +{ + LEX_CSTRING optimizer_costs_name; + OPTIMIZER_COSTS *optimizer_costs; + + optimizer_costs_name.str= name; + optimizer_costs_name.length= length; + if (!(optimizer_costs= get_optimizer_costs(&optimizer_costs_name))) + optimizer_costs= create_optimizer_costs(name, length); + return optimizer_costs; +} + +extern "C" +{ +bool process_optimizer_costs(process_optimizer_costs_t func, TABLE *param) +{ + I_List_iterator<NAMED_ILINK> it(linked_optimizer_costs); + NAMED_ILINK *element; + int res= 0; + + while ((element= it++)) + { + LEX_CSTRING name= { element->name, element->name_length }; + OPTIMIZER_COSTS *costs= (OPTIMIZER_COSTS *) element->data; + res |= func(&name, costs, param); + } + return res != 0; +} +} + +bool create_default_optimizer_costs() +{ + return (new NAMED_ILINK(&linked_optimizer_costs, + default_base.str, default_base.length, + (uchar*) &default_optimizer_costs)) == 0; +} + + +/* + Make a copy of heap and tmp_table engine costs to be able to create + internal temporary tables without taking a mutex. +*/ + +void copy_tmptable_optimizer_costs() +{ + memcpy(&heap_optimizer_costs, heap_hton->optimizer_costs, + sizeof(heap_optimizer_costs)); + memcpy(&tmp_table_optimizer_costs, TMP_ENGINE_HTON->optimizer_costs, + sizeof(tmp_table_optimizer_costs)); +} + + +static void free_optimizer_costs(const char *name, void *cost) +{ + if ((OPTIMIZER_COSTS*) cost != &default_optimizer_costs) + my_free(cost); +} + +void free_all_optimizer_costs() +{ + linked_optimizer_costs.delete_elements(free_optimizer_costs); +} |