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 02110-1335 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 
Expression_cache()39   Expression_cache(){};
~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};
Expression_cache_tracker(Expression_cache * c)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];
set(ulong h,ulong m,enum expr_cache_state s)91   void set(ulong h, ulong m, enum expr_cache_state s)
92   {hit= h; miss= m; state= s;}
93 
fetch_current_stats()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);
is_inited()115   bool is_inited() { return inited; };
116   void init();
117 
set_tracker(Expression_cache_tracker * st)118   void set_tracker(Expression_cache_tracker *st)
119   {
120     tracker= st;
121     update_tracker();
122   }
update_tracker()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