MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
slow_select.cpp
1 /*
2  Copyright (C) 2004, 2005 MySQL AB, 2009 Sun Microsystems, Inc.
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include <ndb_global.h>
20 #include <NdbApi.hpp>
21 #include <NdbOut.hpp>
22 #include <NdbTick.h>
23 
24 struct
25 S_Scan {
26  const char * m_table;
27  const char * m_index;
28  NdbIndexScanOperation * m_scan;
29  Uint32 metaid;
30  Uint32 match_count;
31  Uint32 row_count;
32 };
33 
34 static S_Scan g_scans[] = {
35  { "affiliatestometa", "ind_affiliatestometa", 0, 0, 0, 0 },
36  { "media", "metaid", 0, 0, 0, 0 },
37  { "meta", "PRIMARY", 0, 0, 0, 0 },
38  { "artiststometamap", "PRIMARY", 0, 0, 0, 0 },
39  { "subgenrestometamap", "metaid", 0, 0, 0, 0 }
40 };
41 
42 #undef require
43 #define require(x) require_exit_or_core_with_printer((x), 0, ndbout_printer)
44 #define require2(o, x) \
45  if(!(x))\
46  {\
47  ndbout << o->getNdbError() << endl;\
48  require_exit_or_core_with_printer(0, 0, ndbout_printer);\
49  }
50 
51 Uint32 g_affiliateid = 2;
52 Uint32 g_formatids[] = { 8, 31, 76 };
53 
54 Uint64 start;
55 Uint32 g_artistid = 0;
56 Uint32 g_subgenreid = 0;
57 
58 NdbConnection* g_trans = 0;
59 static void lookup();
60 
61 int
62 main(void){
63  ndb_init();
64 
66  if(con.connect(12, 5, 1) != 0)
67  {
68  return 1;
69  }
70 
71  Ndb g_ndb(&con, "test");
72  g_ndb.init(1024);
73 
74  require(g_ndb.waitUntilReady() == 0);
75 
76  while(true){
77  g_trans = g_ndb.startTransaction();
78  require(g_trans);
79 
80  size_t i, j;
81  const size_t cnt = sizeof(g_scans)/sizeof(g_scans[0]);
82 
83  start = NdbTick_CurrentMillisecond();
84 
85  for(i = 0; i<cnt; i++){
86  ndbout_c("starting scan on: %s %s",
87  g_scans[i].m_table, g_scans[i].m_index);
88  g_scans[i].m_scan = g_trans->getNdbIndexScanOperation(g_scans[i].m_index,
89  g_scans[i].m_table);
90  NdbIndexScanOperation* scan = g_scans[i].m_scan;
91  require(scan);
93  0, 0, true) == 0);
94  }
95 
96  require(!g_scans[0].m_scan->setBound((Uint32)0,
98  &g_affiliateid,
99  sizeof(g_affiliateid)));
100 #if 0
101  require(!g_scans[1].m_scan->setBound((Uint32)0,
103  &g_formatids[0],
104  sizeof(g_formatids[0])));
105 #endif
106 
107  NdbScanFilter sf(g_scans[1].m_scan);
108  sf.begin(NdbScanFilter::OR);
109  sf.eq(2, g_formatids[0]);
110  sf.eq(2, g_formatids[1]);
111  sf.eq(2, g_formatids[2]);
112  sf.end();
113 
114  // affiliatestometa
115  require(g_scans[0].m_scan->getValue("uniquekey"));
116  require(g_scans[0].m_scan->getValue("xml"));
117 
118  // media
119  require(g_scans[1].m_scan->getValue("path"));
120  require(g_scans[1].m_scan->getValue("mediaid"));
121  require(g_scans[1].m_scan->getValue("formatid"));
122 
123  // meta
124  require(g_scans[2].m_scan->getValue("name"));
125  require(g_scans[2].m_scan->getValue("xml"));
126 
127  // artiststometamap
128  require(g_scans[3].m_scan->getValue("artistid", (char*)&g_artistid));
129 
130  // subgenrestometamap
131  require(g_scans[4].m_scan->getValue("subgenreid", (char*)&g_subgenreid));
132 
133  for(i = 0; i<cnt; i++){
134  g_scans[i].m_scan->getValue("metaid", (char*)&g_scans[i].metaid);
135  }
136 
137  g_trans->execute(NoCommit, AbortOnError, 1);
138 
139  Uint32 max_val = 0;
140  Uint32 match_val = 0;
141 
142  S_Scan * F [5], * Q [5], * nextF [5];
143  Uint32 F_sz = 0, Q_sz = 0;
144  for(i = 0; i<cnt; i++){
145  F_sz++;
146  F[i] = &g_scans[i];
147  }
148 
149  Uint32 match_count = 0;
150  while(F_sz > 0){
151  Uint32 prev_F_sz = F_sz;
152  F_sz = 0;
153  bool found = false;
154  //for(i = 0; i<cnt; i++)
155  //ndbout_c("%s - %d", g_scans[i].m_table, g_scans[i].metaid);
156 
157  for(i = 0; i<prev_F_sz; i++){
158  int res = F[i]->m_scan->nextResult();
159  if(res == -1)
160  abort();
161 
162  if(res == 1){
163  continue;
164  }
165 
166  Uint32 metaid = F[i]->metaid;
167  F[i]->row_count++;
168 
169  if(metaid == match_val){
170  //ndbout_c("flera");
171  nextF[F_sz++] = F[i];
172  require(F_sz <= cnt);
173  F[i]->match_count++;
174  Uint32 comb = 1;
175  for(j = 0; j<cnt; j++){
176  comb *= (&g_scans[j] == F[i] ? 1 : g_scans[j].match_count);
177  }
178  match_count += comb;
179  found = true;
180  continue;
181  }
182  if(metaid < max_val){
183  nextF[F_sz++] = F[i];
184  require(F_sz <= cnt);
185  continue;
186  }
187  if(metaid > max_val){
188  for(j = 0; j<Q_sz; j++)
189  nextF[F_sz++] = Q[j];
190  require(F_sz <= cnt);
191  Q_sz = 0;
192  max_val = metaid;
193  }
194  Q[Q_sz++] = F[i];
195  require(Q_sz <= cnt);
196  }
197  if(F_sz == 0 && Q_sz > 0){
198  match_val = max_val;
199  for(j = 0; j<Q_sz; j++){
200  nextF[F_sz++] = Q[j];
201  Q[j]->match_count = 1;
202  }
203  require(F_sz <= cnt);
204  require(Q_sz <= cnt);
205  Q_sz = 0;
206  match_count++;
207  lookup();
208  } else if(!found && F_sz + Q_sz < cnt){
209  F_sz = 0;
210  }
211  require(F_sz <= cnt);
212  for(i = 0; i<F_sz; i++)
213  F[i] = nextF[i];
214  }
215 
216  start = NdbTick_CurrentMillisecond() - start;
217  ndbout_c("Elapsed: %lldms", start);
218 
219  ndbout_c("rows: %d", match_count);
220  for(i = 0; i<cnt; i++){
221  ndbout_c("%s : %d", g_scans[i].m_table, g_scans[i].row_count);
222  }
223  g_trans->close();
224  }
225 }
226 
227 static
228 void
229 lookup(){
230  {
231  NdbOperation* op = g_trans->getNdbOperation("artists");
232  require2(g_trans, op);
233  require2(op, op->readTuple() == 0);
234  require2(op, op->equal("artistid", g_artistid) == 0);
235  require2(op, op->getValue("name"));
236  }
237 
238  {
239  NdbOperation* op = g_trans->getNdbOperation("subgenres");
240  require2(g_trans, op);
241  require2(op, op->readTuple() == 0);
242  require2(op, op->equal("subgenreid", g_subgenreid) == 0);
243  require2(op, op->getValue("name"));
244  }
245 
246  static int loop = 0;
247  if(loop++ >= 16){
248  loop = 0;
249  require(g_trans->execute(NoCommit) == 0);
250  }
251  //require(g_trans->restart() == 0);
252 }