MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
hugoJoin.cpp
1 /*
2  Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
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 St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 
19 #include <ndb_global.h>
20 #include <ndb_opts.h>
21 
22 #include <my_sys.h>
23 #include <my_getopt.h>
24 #include <mysql_version.h>
25 
26 #include <NdbOut.hpp>
27 #include <NdbApi.hpp>
28 #include <NdbSleep.h>
29 #include <NDBT.hpp>
30 #include <HugoTransactions.hpp>
31 #include <HugoQueryBuilder.hpp>
32 #include <HugoQueries.hpp>
33 #include <NdbTick.h>
34 
35 int _verbose = 1;
36 int _help = 0;
37 int _batch = 128;
38 int _records = 1000;
39 int _loops = 100;
40 int _loops_per_query = 100;
41 int _depth = 4;
42 unsigned int _seed = 0;
43 static const char * _options = "";
44 static const char * _db = "TEST_DB";
45 
46 extern const char *load_default_groups[];
47 static struct my_option my_long_options[] =
48 {
49  NDB_STD_OPTS("hugoJoin"),
50  { "database", 'd', "Database",
51  (uchar**) &_db, (uchar**) &_db,
52  0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
53  { "options", 'o', "comma separated list of options",
54  (uchar**) &_options, (uchar**) &_options,
55  0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
56  { "loops", 'l', "Loops",
57  (uchar**) &_loops, 0,
58  0, GET_INT, REQUIRED_ARG, _loops, 0, 0, 0, 0, 0},
59  { "verbose", 'v', "verbosity",
60  (uchar**) &_verbose, 0,
61  0, GET_INT, REQUIRED_ARG, _verbose, 0, 0, 0, 0, 0},
62  { "loops_per_query", 'q', "Recreate query each #loops",
63  (uchar**) &_loops_per_query, 0,
64  0, GET_INT, REQUIRED_ARG, _loops_per_query, 0, 0, 0, 0, 0},
65  { "batch", 'b', "Batch size (for lookups)",
66  (uchar**) &_batch, 0,
67  0, GET_INT, REQUIRED_ARG, _batch, 0, 0, 0, 0, 0},
68  { "records", 'r', "Records (for lookups)",
69  (uchar**) &_records, 0,
70  0, GET_INT, REQUIRED_ARG, _records, 0, 0, 0, 0, 0},
71  { "join-depth", 'j', "Join depth",
72  (uchar**) &_depth, 0,
73  0, GET_INT, REQUIRED_ARG, _depth, 0, 0, 0, 0, 0},
74  { "seed", NDB_OPT_NOSHORT, "Random seed",
75  (uchar **) &_seed, (uchar **) &_seed, 0,
76  GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
77  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
78 };
79 
80 static void short_usage_sub(void)
81 {
82  ndb_short_usage_sub(NULL);
83 }
84 
85 static void usage()
86 {
87  char desc[] =
88  "This run random joins on table-list\n";
89  puts(desc);
90  ndb_usage(short_usage_sub, load_default_groups, my_long_options);
91 }
92 
93 int main(int argc, char** argv){
94  NDB_INIT(argv[0]);
95  ndb_opt_set_usage_funcs(short_usage_sub, usage);
96  load_defaults("my", load_default_groups, &argc, &argv);
97  int ho_error;
98  if ((ho_error=handle_options(&argc, &argv, my_long_options,
99  ndb_std_get_one_option)))
100  return -1;
101 
102 
103  // Connect to Ndb
105  if(con.connect(12, 5, 1) != 0)
106  {
107  return NDBT_ProgramExit(NDBT_FAILED);
108  }
109 
110  if (con.wait_until_ready(30,0) < 0)
111  {
112  ndbout << "Cluster nodes not ready in 30 seconds." << endl;
113  return NDBT_ProgramExit(NDBT_FAILED);
114  }
115 
116  Ndb MyNdb( &con, _db);
117 
118  if(MyNdb.init() != 0)
119  {
120  ERR(MyNdb.getNdbError());
121  return NDBT_ProgramExit(NDBT_FAILED);
122  }
123 
125  for(int i = 0; i<argc; i++)
126  {
127  const char* _tabname = argv[i];
128  // Check if table exists in db
129  const NdbDictionary::Table* pTab =
130  NDBT_Table::discoverTableFromDb(&MyNdb, _tabname);
131  if(pTab == NULL)
132  {
133  ndbout << " Table " << _tabname << " does not exist!" << endl;
134  return NDBT_ProgramExit(NDBT_WRONGARGS);
135  }
136  else
137  {
138  ndbout << " Discovered " << _tabname << endl;
139  }
140  tables.push_back(pTab);
141  }
142  tables.push_back(0);
143 
144  HugoQueryBuilder::OptionMask mask = 0;
145  struct { const char * name; HugoQueryBuilder::QueryOption option; }
146  _ops[] = {
147  { "lookup", HugoQueryBuilder::O_LOOKUP },
148  { "scan", HugoQueryBuilder::O_SCAN },
153 
154  // end-marker
156  };
157 
158  Vector<BaseString> list;
159  BaseString tmp(_options);
160  tmp.split(list, ",");
161  for (size_t i = 0; i<list.size(); i++)
162  {
163  bool found = false;
164  for (int o = 0; _ops[o].name != 0; o++)
165  {
166  if (strcasecmp(list[i].c_str(), _ops[o].name) == 0)
167  {
168  found = true;
169  mask |= _ops[o].option;
170  break;
171  }
172  }
173  if (!found)
174  {
175  ndbout << "Unknown option " << list[i].c_str() << ", ignoring" << endl;
176  }
177  }
178 
179  if (_seed == 0)
180  {
181  _seed = (unsigned)NdbTick_CurrentMillisecond();
182  }
183  ndbout << "--seed=" << _seed << endl;
184  srand(_seed);
185 
186  for (int i = 0; (_loops == 0) || (i < _loops);)
187  {
188  if (_verbose >= 1)
189  {
190  ndbout << "******\tbuilding new query (mask: 0x" << hex
191  << (Uint64)mask << ")" << endl;
192  }
193  HugoQueryBuilder builder(&MyNdb, tables.getBase(), mask);
194  builder.setJoinLevel(_depth);
195  const NdbQueryDef * q = builder.createQuery(&MyNdb);
196  if (_verbose >= 2)
197  {
198  q->print(); ndbout << endl;
199  }
200 
201  for (int j = 0; j < _loops_per_query && ((_loops == 0) || (i < _loops));
202  i++, j++)
203  {
204  int res = 0;
205  HugoQueries hq(* q);
206  if (q->isScanQuery())
207  {
208  res = hq.runScanQuery(&MyNdb);
209  }
210  else
211  {
212  res = hq.runLookupQuery(&MyNdb, _records, _batch);
213  }
214  if (res != 0)
215  {
216  return NDBT_ProgramExit(NDBT_FAILED);
217  }
218  if (hq.m_rows_found.size() != 0)
219  {
220  printf("\tfound: [ ");
221  for (size_t i = 0; i<hq.m_rows_found.size(); i++)
222  {
223  printf("%u ", (Uint32)hq.m_rows_found[i]);
224  }
225  ndbout_c("]");
226  }
227  }
228  }
229 
230  return NDBT_ProgramExit(NDBT_OK);
231 }