MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbIndexStatImpl.hpp
1 /* Copyright (C) 2003 MySQL AB
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
15 
16 #ifndef NDB_INDEX_STAT_IMPL_HPP
17 #define NDB_INDEX_STAT_IMPL_HPP
18 
19 #include <ndb_global.h>
20 #include <ndb_limits.h>
21 #include <NdbDictionary.hpp>
22 #include <NdbIndexStat.hpp>
23 #include <util/NdbPack.hpp>
24 #include <NdbError.hpp>
25 #include <NdbMutex.h>
26 #include <NdbTick.h>
27 class Ndb;
28 class NdbTransaction;
30 class NdbRecAttr;
31 class NdbOperation;
32 class NdbEventOperation;
33 
34 extern const uint g_ndb_index_stat_head_frm_len;
35 extern const uint8 g_ndb_index_stat_head_frm_data[];
36 extern const uint g_ndb_index_stat_sample_frm_len;
37 extern const uint8 g_ndb_index_stat_sample_frm_data[];
38 
40 public:
41  friend class NdbIndexStat;
42  struct Con;
43  struct Cache;
44 
45  enum { MaxKeyCount = MAX_INDEX_STAT_KEY_COUNT };
46  enum { MaxKeyBytes = MAX_INDEX_STAT_KEY_SIZE * 4 };
47  enum { MaxValueBytes = MAX_INDEX_STAT_VALUE_SIZE * 4 };
48  enum { MaxValueCBytes = MAX_INDEX_STAT_VALUE_CSIZE * 4 };
49 
52  void init();
53 
54  NdbIndexStat* const m_facade;
55  Head m_facadeHead; // owned by facade
56  bool m_indexSet;
57  Uint32 m_indexId;
58  Uint32 m_indexVersion;
59  Uint32 m_tableId;
60  uint m_keyAttrs;
61  uint m_valueAttrs;
62  NdbPack::Spec m_keySpec;
63  NdbPack::Spec m_valueSpec;
64  NdbPack::Type* m_keySpecBuf;
65  NdbPack::Type* m_valueSpecBuf;
66  NdbPack::Data m_keyData;
67  NdbPack::Data m_valueData;
68  Uint8* m_keyDataBuf;
69  Uint8* m_valueDataBuf;
70  Cache* m_cacheBuild;
71  Cache* m_cacheQuery;
72  Cache* m_cacheClean;
73  // mutex for query cache switch, memory barrier would do
74  NdbMutex* m_query_mutex;
75  NdbEventOperation* m_eventOp;
76  Mem* m_mem_handler;
77  NdbIndexStat::Error m_error;
78 
79  // sys tables meta
80  struct Sys {
81  NdbIndexStatImpl* const m_impl;
82  Ndb* const m_ndb;
84  const NdbDictionary::Table* m_headtable;
85  const NdbDictionary::Table* m_sampletable;
86  const NdbDictionary::Index* m_sampleindex1;
87  int m_obj_cnt;
88  enum { ObjCnt = 3 };
89  Sys(NdbIndexStatImpl* impl, Ndb* ndb);
90  ~Sys();
91  };
92  void sys_release(Sys& sys);
93  int make_headtable(NdbDictionary::Table& tab);
94  int make_sampletable(NdbDictionary::Table& tab);
95  int make_sampleindex1(NdbDictionary::Index& ind);
96  int check_table(const NdbDictionary::Table& tab1,
97  const NdbDictionary::Table& tab2);
98  int check_index(const NdbDictionary::Index& ind1,
99  const NdbDictionary::Index& ind2);
100  int get_systables(Sys& sys);
101  int create_systables(Ndb* ndb);
102  int drop_systables(Ndb* ndb);
103  int check_systables(Sys& sys);
104  int check_systables(Ndb* ndb);
105 
106  // operation context
107  struct Con {
108  NdbIndexStatImpl* const m_impl;
109  Head& m_head;
110  Ndb* const m_ndb;
112  const NdbDictionary::Table* m_headtable;
113  const NdbDictionary::Table* m_sampletable;
114  const NdbDictionary::Index* m_sampleindex1;
115  NdbTransaction* m_tx;
116  NdbOperation* m_op;
117  NdbIndexScanOperation* m_scanop;
118  Cache* m_cacheBuild;
119  uint m_cachePos;
120  uint m_cacheKeyOffset; // in bytes
121  uint m_cacheValueOffset; // in bytes
122  MicroSecondTimer m_start;
123  Con(NdbIndexStatImpl* impl, Head& head, Ndb* ndb);
124  ~Con();
125  int startTransaction();
126  int execute(bool commit);
127  int getNdbOperation();
128  int getNdbIndexScanOperation();
129  void set_time();
130  NDB_TICKS get_time();
131  };
132 
133  // index
134  int set_index(const NdbDictionary::Index& index,
135  const NdbDictionary::Table& table);
136  void reset_index();
137 
138  // init m_facadeHead here (keep API struct a POD)
139  void init_head(Head& head);
140 
141  // sys tables data
142  int sys_init(Con& con);
143  void sys_release(Con& con);
144  int sys_read_head(Con& con, bool commit);
145  int sys_head_setkey(Con& con);
146  int sys_head_getvalue(Con& con);
147  int sys_sample_setkey(Con& con);
148  int sys_sample_getvalue(Con& con);
149  int sys_sample_setbound(Con& con, int sv_bound);
150 
151  // update, delete (head may record elapsed time)
152  int update_stat(Ndb* ndb, Head& head);
153  int delete_stat(Ndb* ndb, Head& head);
154 
155  // read
156  int read_head(Ndb* ndb, Head& head);
157  int read_stat(Ndb* ndb, Head& head);
158  int read_start(Con& con);
159  int read_next(Con& con);
160  int read_commit(Con& con);
161  int save_start(Con& con);
162  int save_next(Con& con);
163  int save_commit(Con& con);
164  int cache_init(Con& con);
165  int cache_insert(Con& con);
166  int cache_commit(Con& con);
167 
168  // cache
169  struct Cache {
170  bool m_valid;
171  uint m_keyAttrs; // number of attrs in index key
172  uint m_valueAttrs; // number of values
173  uint m_fragCount; // index fragments
174  uint m_sampleVersion;
175  uint m_sampleCount; // sample count from head record
176  uint m_keyBytes; // total key bytes from head record
177  uint m_valueLen; // value bytes per entry i.e. valueAttrs * ValueSize
178  uint m_valueBytes; // total value bytes i.e. sampleCount * valuelen
179  uint m_addrLen; // 1-4 based on keyBytes
180  uint m_addrBytes; // total address bytes
181  Uint8* m_addrArray;
182  Uint8* m_keyArray;
183  Uint8* m_valueArray;
184  Cache* m_nextClean;
185  // performance
186  mutable Uint64 m_save_time;
187  mutable Uint64 m_sort_time;
188  Cache();
189  // pos is index < sampleCount, addr is offset in keyArray
190  uint get_keyaddr(uint pos) const;
191  void set_keyaddr(uint pos, uint addr);
192  // get pointers to key and value arrays at pos
193  const Uint8* get_keyptr(uint addr) const;
194  Uint8* get_keyptr(uint addr);
195  const Uint8* get_valueptr(uint pos) const;
196  Uint8* get_valueptr(uint pos);
197  // for sort
198  void swap_entry(uint pos1, uint pos2);
199  // get stats values primitives
200  double get_rir(uint pos) const;
201  double get_rir(uint pos1, uint pos2) const;
202  double get_unq(uint pos, uint k) const;
203  double get_unq(uint pos1, uint pos2, uint k) const;
204  double get_rpk(uint pos, uint k) const;
205  double get_rpk(uint pos1, uint pos2, uint k) const;
206  };
207  int cache_cmpaddr(const Cache& c, uint addr1, uint addr2) const;
208  int cache_cmppos(const Cache& c, uint pos1, uint pos2) const;
209  int cache_sort(Cache& c);
210  void cache_isort(Cache& c);
211  void cache_hsort(Cache& c);
212  void cache_hsort_sift(Cache& c, int i, int count);
213  void cache_hsort_verify(Cache& c, int count);
214  int cache_verify(const Cache& c);
215  void move_cache();
216  void clean_cache();
217  void free_cache(Cache* c);
218  void free_cache();
219 
220  // query cache dump (not available via facade)
221  struct CacheIter {
222  Uint32 m_keyCount;
223  Uint32 m_sampleCount;
224  Uint32 m_sampleIndex;
225  NdbPack::DataC m_keyData;
226  NdbPack::DataC m_valueData;
227  CacheIter(const NdbIndexStatImpl& impl);
228  };
229  int dump_cache_start(CacheIter& iter);
230  bool dump_cache_next(CacheIter& iter);
231 
232  // bound
233  struct Bound {
234  NdbPack::Data m_data;
235  NdbPack::Bound m_bound;
236  int m_type; // 0-lower 1-upper
237  int m_strict;
238  Bound(const NdbPack::Spec& spec);
239  };
240  int finalize_bound(Bound&);
241 
242  // range
243  struct Range {
244  Range(Bound& bound1, Bound& bound2);
245  Bound& m_bound1;
246  Bound& m_bound2;
247  };
248  int finalize_range(Range& range);
249  int convert_range(Range& range,
250  const NdbRecord* key_record,
252 
253  // computed stats values
254  struct StatValue {
255  bool m_empty;
256  double m_rir;
257  double m_unq[MaxKeyCount];
258  StatValue();
259  };
260 
261  // query
262  struct StatBound {
263  uint m_pos; // non-empty bound is between pos-1,pos
264  uint m_numEqL; // components matching key at pos-1
265  uint m_numEqH; // components matching key at pos
266  StatValue m_value;
267  const char* m_rule;
268  StatBound();
269  };
270  struct Stat {
271  StatBound m_stat1;
272  StatBound m_stat2;
273  StatValue m_value;
274  const char* m_rule[3];
275  Stat();
276  };
277  void query_normalize(const Cache&, StatValue&);
278  void query_unq2rpk(const Cache&, StatValue&);
279  int query_stat(const Range&, Stat&);
280  void query_interpolate(const Cache&, const Range&, Stat&);
281  void query_interpolate(const Cache&, const Bound&, StatBound&);
282  void query_search(const Cache&, const Bound&, StatBound&);
283  int query_keycmp(const Cache&, const Bound&, uint pos, Uint32& numEq);
284 
285  // events and polling
286  int create_sysevents(Ndb* ndb);
287  int drop_sysevents(Ndb* ndb);
288  int check_sysevents(Ndb* ndb);
289  //
290  int create_listener(Ndb* ndb);
291  int execute_listener(Ndb* ndb);
292  int poll_listener(Ndb* ndb, int max_wait_ms);
293  int next_listener(Ndb* ndb);
294  int drop_listener(Ndb* ndb);
295 
296  // default memory allocator
297  struct MemDefault : public Mem {
298  virtual void* mem_alloc(UintPtr bytes);
299  virtual void mem_free(void* ptr);
300  MemDefault();
301  virtual ~MemDefault();
302  };
303  MemDefault c_mem_default_handler;
304 
305  // error
306  const NdbIndexStat::Error& getNdbError() const;
307  void setError(int code, int line, int extra = 0);
308  void setError(const Con& con, int line);
309  void mapError(const int* map, int code);
310 
311 // moved from NdbIndexStat.hpp by jonas
312 
313  /* Need 2 words per column in a bound plus space for the
314  * bound data.
315  * Worst case is 32 cols in key and max key size used.
316  */
317  STATIC_CONST( BoundBufWords = (2 * NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY)
318  + NDB_MAX_KEYSIZE_IN_WORDS );
319 };
320 
321 inline
322 NdbIndexStatImpl::Bound::Bound(const NdbPack::Spec& spec) :
323  m_data(spec, true, 0),
324  m_bound(m_data)
325 {
326  m_type = -1;
327  m_strict = -1;
328 }
329 
330 inline
331 NdbIndexStatImpl::Range::Range(Bound& bound1, Bound& bound2) :
332  m_bound1(bound1),
333  m_bound2(bound2)
334 {
335  bound1.m_type = 0;
336  bound2.m_type = 1;
337 }
338 
339 inline int
340 NdbIndexStatImpl::finalize_range(Range& range)
341 {
342  if (finalize_bound(range.m_bound1) == -1)
343  return -1;
344  if (finalize_bound(range.m_bound2) == -1)
345  return -1;
346  return 0;
347 }
348 
349 inline
350 NdbIndexStatImpl::StatValue::StatValue()
351 {
352  m_empty = false;
353 }
354 
355 inline
356 NdbIndexStatImpl::StatBound::StatBound()
357 {
358  m_pos = 0;
359  m_numEqL = 0;
360  m_numEqH = 0;
361 }
362 
363 inline
364 NdbIndexStatImpl::Stat::Stat()
365 {
366  m_rule[0] = 0;
367  m_rule[1] = 0;
368  m_rule[2] = 0;
369 }
370 
371 #endif