summaryrefslogtreecommitdiffstats
path: root/sql/keycaches.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/keycaches.cc')
-rw-r--r--sql/keycaches.cc141
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);
+}