1 /* Copyright (c) 2003-2005, 2007 MySQL AB
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.
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.
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 */
16 #include <ndb_global.h>
23 #include <NDBT_Thread.hpp>
24 #include <NDBT_Stats.hpp>
28 #include <HugoTransactions.hpp>
30 static NDBT_ThreadFunc hugoPkRead
;
33 const NdbDictionary::Table
* pTab
;
43 int main(int argc
, const char** argv
){
52 const char* _tabname
= NULL
;
55 struct getargs args
[] = {
56 { "aborts", 'a', arg_integer
, &_abort
, "percent of transactions that are aborted", "abort%" },
57 { "loops", 'l', arg_integer
, &_loops
, "number of times to run this program(0=infinite loop)", "loops" },
58 { "threads", 't', arg_integer
, &_threads
, "number of threads (default 1)", "threads" },
59 { "stats", 's', arg_flag
, &_stats
, "report latency per batch", "stats" },
60 { "batch", 'b', arg_integer
, &_batch
, "batch value(not 0)", "batch" },
61 { "records", 'r', arg_integer
, &_records
, "Number of records", "records" },
62 { "usage", '?', arg_flag
, &_help
, "Print help", "" }
64 int num_args
= sizeof(args
) / sizeof(args
[0]);
68 "This program will read 'r' records from one table in Ndb. \n"\
69 "It will verify every column read by calculating the expected value.\n";
71 if(getarg(args
, num_args
, argc
, argv
, &optind
) ||
72 argv
[optind
] == NULL
|| _records
== 0 || _batch
== 0 || _help
) {
73 arg_printusage(args
, num_args
, argv
[0], desc
);
74 return NDBT_ProgramExit(NDBT_WRONGARGS
);
76 _tabname
= argv
[optind
];
80 Ndb_cluster_connection con
;
81 if(con
.connect(12, 5, 1) != 0)
83 return NDBT_ProgramExit(NDBT_FAILED
);
86 Ndb
MyNdb(&con
, "TEST_DB" );
88 if(MyNdb
.init() != 0){
89 ERR(MyNdb
.getNdbError());
90 return NDBT_ProgramExit(NDBT_FAILED
);
93 while(MyNdb
.waitUntilReady() != 0)
94 ndbout
<< "Waiting for ndb to become ready..." << endl
;
96 // Check if table exists in db
97 const NdbDictionary::Table
* pTab
= NDBT_Table::discoverTableFromDb(&MyNdb
, _tabname
);
99 ndbout
<< " Table " << _tabname
<< " does not exist!" << endl
;
100 return NDBT_ProgramExit(NDBT_WRONGARGS
);
104 NDBT_ThreadSet
ths(_threads
);
106 // create Ndb object for each thread
107 if (ths
.connect(&con
, "TEST_DB") == -1) {
108 ndbout
<< "connect failed: err=" << ths
.get_err() << endl
;
109 return NDBT_ProgramExit(NDBT_FAILED
);
114 ths
.set_input(&input
);
116 input
.records
= _records
;
117 input
.batch
= _batch
;
118 input
.stats
= _stats
;
122 ths
.set_output
<ThrOutput
>();
125 while (i
< _loops
|| _loops
== 0) {
128 ths
.set_func(hugoPkRead
);
133 NDBT_ProgramExit(NDBT_FAILED
);
138 // add stats from each thread
140 for (n
= 0; n
< ths
.get_count(); n
++) {
141 NDBT_Thread
& thr
= ths
.get_thread(n
);
142 ThrOutput
* output
= (ThrOutput
*)thr
.get_output();
143 latency
+= output
->latency
;
147 << "latency per batch (us): "
148 << " samples=" << latency
.getCount()
149 << " min=" << (int)latency
.getMin()
150 << " max=" << (int)latency
.getMax()
151 << " mean=" << (int)latency
.getMean()
152 << " stddev=" << (int)latency
.getStddev()
158 return NDBT_ProgramExit(NDBT_OK
);
161 static void hugoPkRead(NDBT_Thread
& thr
)
163 const ThrInput
* input
= (const ThrInput
*)thr
.get_input();
164 ThrOutput
* output
= (ThrOutput
*)thr
.get_output();
166 HugoTransactions
hugoTrans(*input
->pTab
);
167 output
->latency
.reset();
169 hugoTrans
.setStatsLatency(&output
->latency
);
172 ret
= hugoTrans
.pkReadRecords(thr
.get_ndb(),