| 1 | /* |
| 2 | Copyright (c) 2010, 2011, Monty Program Ab |
| 3 | |
| 4 | This program is free software; you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by |
| 6 | the Free Software Foundation; version 2 of the License. |
| 7 | |
| 8 | This program is distributed in the hope that it will be useful, |
| 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | GNU General Public License for more details. |
| 12 | |
| 13 | You should have received a copy of the GNU General Public License |
| 14 | along with this program; if not, write to the Free Software |
| 15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ |
| 16 | |
| 17 | #ifndef SQL_EXPRESSION_CACHE_INCLUDED |
| 18 | #define SQL_EXPRESSION_CACHE_INCLUDED |
| 19 | |
| 20 | #include "sql_select.h" |
| 21 | |
| 22 | |
| 23 | /** |
| 24 | Interface for expression cache |
| 25 | |
| 26 | @note |
| 27 | Parameters of an expression cache interface are set on the creation of the |
| 28 | cache. They are passed when a cache object of the implementation class is |
| 29 | constructed. That's why they are not visible in this interface. |
| 30 | */ |
| 31 | |
| 32 | extern ulong subquery_cache_miss, subquery_cache_hit; |
| 33 | |
| 34 | class Expression_cache :public Sql_alloc |
| 35 | { |
| 36 | public: |
| 37 | enum result {ERROR, HIT, MISS}; |
| 38 | |
| 39 | Expression_cache(){}; |
| 40 | virtual ~Expression_cache() {}; |
| 41 | /** |
| 42 | Shall check the presence of expression value in the cache for a given |
| 43 | set of values of the expression parameters. Return the result of the |
| 44 | expression if it's found in the cache. |
| 45 | */ |
| 46 | virtual result check_value(Item **value)= 0; |
| 47 | /** |
| 48 | Shall put the value of an expression for given set of its parameters |
| 49 | into the expression cache |
| 50 | */ |
| 51 | virtual my_bool put_value(Item *value)= 0; |
| 52 | |
| 53 | /** |
| 54 | Print cache parameters |
| 55 | */ |
| 56 | virtual void print(String *str, enum_query_type query_type)= 0; |
| 57 | |
| 58 | /** |
| 59 | Is this cache initialized |
| 60 | */ |
| 61 | virtual bool is_inited()= 0; |
| 62 | /** |
| 63 | Initialize this cache |
| 64 | */ |
| 65 | virtual void init()= 0; |
| 66 | |
| 67 | /** |
| 68 | Save this object's statistics into Expression_cache_tracker object |
| 69 | */ |
| 70 | virtual void update_tracker()= 0; |
| 71 | }; |
| 72 | |
| 73 | struct st_table_ref; |
| 74 | struct st_join_table; |
| 75 | class Item_field; |
| 76 | |
| 77 | |
| 78 | class Expression_cache_tracker :public Sql_alloc |
| 79 | { |
| 80 | public: |
| 81 | enum expr_cache_state {UNINITED, STOPPED, OK}; |
| 82 | Expression_cache_tracker(Expression_cache *c) : |
| 83 | cache(c), hit(0), miss(0), state(UNINITED) |
| 84 | {} |
| 85 | |
| 86 | Expression_cache *cache; |
| 87 | ulong hit, miss; |
| 88 | enum expr_cache_state state; |
| 89 | |
| 90 | static const char* state_str[3]; |
| 91 | void set(ulong h, ulong m, enum expr_cache_state s) |
| 92 | {hit= h; miss= m; state= s;} |
| 93 | |
| 94 | void fetch_current_stats() |
| 95 | { |
| 96 | if (cache) |
| 97 | cache->update_tracker(); |
| 98 | } |
| 99 | }; |
| 100 | |
| 101 | |
| 102 | /** |
| 103 | Implementation of expression cache over a temporary table |
| 104 | */ |
| 105 | |
| 106 | class Expression_cache_tmptable :public Expression_cache |
| 107 | { |
| 108 | public: |
| 109 | Expression_cache_tmptable(THD *thd, List<Item> &dependants, Item *value); |
| 110 | virtual ~Expression_cache_tmptable(); |
| 111 | virtual result check_value(Item **value); |
| 112 | virtual my_bool put_value(Item *value); |
| 113 | |
| 114 | void print(String *str, enum_query_type query_type); |
| 115 | bool is_inited() { return inited; }; |
| 116 | void init(); |
| 117 | |
| 118 | void set_tracker(Expression_cache_tracker *st) |
| 119 | { |
| 120 | tracker= st; |
| 121 | update_tracker(); |
| 122 | } |
| 123 | virtual void update_tracker() |
| 124 | { |
| 125 | if (tracker) |
| 126 | { |
| 127 | tracker->set(hit, miss, (inited ? (cache_table ? |
| 128 | Expression_cache_tracker::OK : |
| 129 | Expression_cache_tracker::STOPPED) : |
| 130 | Expression_cache_tracker::UNINITED)); |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | private: |
| 135 | void disable_cache(); |
| 136 | |
| 137 | /* tmp table parameters */ |
| 138 | TMP_TABLE_PARAM cache_table_param; |
| 139 | /* temporary table to store this cache */ |
| 140 | TABLE *cache_table; |
| 141 | /* Thread handle for the temporary table */ |
| 142 | THD *table_thd; |
| 143 | /* EXPALIN/ANALYZE statistics */ |
| 144 | Expression_cache_tracker *tracker; |
| 145 | /* TABLE_REF for index lookup */ |
| 146 | struct st_table_ref ref; |
| 147 | /* Cached result */ |
| 148 | Item_field *cached_result; |
| 149 | /* List of parameter items */ |
| 150 | List<Item> &items; |
| 151 | /* Value Item example */ |
| 152 | Item *val; |
| 153 | /* hit/miss counters */ |
| 154 | ulong hit, miss; |
| 155 | /* Set on if the object has been succesfully initialized with init() */ |
| 156 | bool inited; |
| 157 | }; |
| 158 | |
| 159 | #endif /* SQL_EXPRESSION_CACHE_INCLUDED */ |
| 160 | |