mariadb/ndb/test/ndbapi/benchronja.cpp
tnurnberg@sin.intern.azundris.com 8dd4751be9 Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2
mysqld hasn't been built on AIX with ndb-everything in quite a while.
this allowed a variety of changes to be added that broke the AIX build
for both the GNU and IBM compilers (but the IBM suite in particular).
Changeset lets build to complete on AIX 5.2 for users of the GNU and
the IBM suite both. Tudo bem?
2007-08-01 04:56:58 +02:00

1207 lines
43 KiB
C++

/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* ***************************************************
NODEREC
Perform benchmark of insert, update and delete transactions
Arguments:
-t Number of threads to start, default 1
-o Number of loops per thread, default 100000
* *************************************************** */
#include <ndb_global.h>
#include <NdbApi.hpp>
#include <NdbTest.hpp>
#include <NdbOut.hpp>
#include <NdbThread.h>
#include <NdbSleep.h>
#include <NdbMain.h>
#include <NdbTimer.hpp>
#include <NdbTick.h>
#include <random.h>
#define MAX_TIMERS 4
#define MAXSTRLEN 16
#define MAXATTR 64
#define MAXTABLES 64
#define NDB_MAXTHREADS 256
/*
NDB_MAXTHREADS used to be just MAXTHREADS, which collides with a
#define from <sys/thread.h> on AIX (IBM compiler). We explicitly
#undef it here lest someone use it by habit and get really funny
results. K&R says we may #undef non-existent symbols, so let's go.
*/
#undef MAXTHREADS
#define MAXATTRSIZE 8000
#define START_TIMER NdbTimer timer; timer.doStart();
#define STOP_TIMER timer.doStop();
#define START_TIMER_TOP NdbTimer timer_top; timer_top.doStart();
#define STOP_TIMER_TOP timer_top.doStop();
void* ThreadExec(void*);
struct ThreadNdb
{
int NoOfOps;
int ThreadNo;
Ndb* NdbRef;
};
static NdbThread* threadLife[NDB_MAXTHREADS];
static unsigned int tNoOfThreads;
static unsigned int tNoOfOpsPerExecute;
static unsigned int tNoOfRecords;
static unsigned int tNoOfOperations;
static int ThreadReady[NDB_MAXTHREADS];
static int ThreadStart[NDB_MAXTHREADS];
NDB_COMMAND(benchronja, "benchronja", "benchronja", "benchronja", 65535){
ndb_init();
ThreadNdb tabThread[NDB_MAXTHREADS];
int i = 0 ;
int cont = 0 ;
Ndb* pMyNdb = NULL ; //( "TEST_DB" );
int tmp = 0 ;
int nTest = 0 ;
char inp[100] ;
tNoOfThreads = 1; // Default Value
tNoOfOpsPerExecute = 1; // Default Value
tNoOfOperations = 100000; // Default Value
tNoOfRecords = 500 ; // Default Value <epaulsa: changed from original 500,000 to match 'initronja's' default
i = 1;
while (argc > 1)
{
if (strcmp(argv[i], "-t") == 0){
tNoOfThreads = atoi(argv[i+1]);
if ((tNoOfThreads < 1) || (tNoOfThreads > NDB_MAXTHREADS)) goto error_input;
}else if (strcmp(argv[i], "-o") == 0){
tNoOfOperations = atoi(argv[i+1]);
if (tNoOfOperations < 1) goto error_input;
}else if (strcmp(argv[i], "-r") == 0){
tNoOfRecords = atoi(argv[i+1]);
if ((tNoOfRecords < 1) || (tNoOfRecords > 1000000000)) goto error_input;
}else if (strcmp(argv[i], "-p") == 0){
nTest = atoi(argv[i+1]) ;
if (0 > nTest || 18 < nTest) goto error_input ;
}else if (strcmp(argv[i], "-c") == 0){
tNoOfOpsPerExecute = atoi(argv[i+1]);
if ((tNoOfOpsPerExecute < 1) || (tNoOfOpsPerExecute > 1024)) goto error_input;
}else{
goto error_input;
}
argc -= 2;
i = i + 2;
}
ndbout << "Initialisation started. " << endl;
pMyNdb = new Ndb("TEST_DB") ;
pMyNdb->init();
ndbout << "Initialisation completed. " << endl;
ndbout << endl << "Execute Ronja Benchmark" << endl;
ndbout << " NdbAPI node with id = " << pMyNdb->getNodeId() << endl;
ndbout << " " << tNoOfThreads << " thread(s) " << endl;
ndbout << " " << tNoOfOperations << " transaction(s) per thread and round " << endl;
if (pMyNdb->waitUntilReady(120) != 0) {
ndbout << "Benchmark failed - NDB is not ready" << endl;
delete pMyNdb ;
return NDBT_ProgramExit(NDBT_FAILED);
}//if
NdbThread_SetConcurrencyLevel(2 + tNoOfThreads);
for (i = 0; i < tNoOfThreads ; i++) {
ThreadReady[i] = 0;
ThreadStart[i] = 0;
}//for
for (i = 0; i < tNoOfThreads ; i++) {
tabThread[i].ThreadNo = i;
tabThread[i].NdbRef = NULL;
tabThread[i].NoOfOps = tNoOfOperations;
threadLife[i] = NdbThread_Create(ThreadExec,
(void**)&tabThread[i],
32768,
"RonjaThread",
NDB_THREAD_PRIO_LOW);
}//for
cont = 1;
while (cont) {
NdbSleep_MilliSleep(10);
cont = 0;
for (i = 0; i < tNoOfThreads ; i++)
if (!ThreadReady[i]) cont = 1;
}//while
ndbout << "All threads started" << endl;
if(!nTest){
for (;;){
inp[0] = 0;
ndbout << endl << "What to do next:" << endl;
ndbout << "1 \t=> Perform lookups in short table" << endl;
ndbout << "2 \t=> Perform lookups in long table" << endl;
ndbout << "3 \t=> Perform updates in short table" << endl;
ndbout << "4 \t=> Perform updates in long table" << endl;
ndbout << "5 \t=> Perform 50% lookups/50% updates in short table" << endl;
ndbout << "6 \t=> Perform 50% lookups/50% updates in long table" << endl;
ndbout << "7 \t=> Perform 80% lookups/20% updates in short table" << endl;
ndbout << "8 \t=> Perform 80% lookups/20% updates in long table" << endl;
ndbout << "9 \t=> Perform 25% lookups short/25% lookups long/25% updates short/25% updates long" << endl;
ndbout << "10\t=> Test bug with replicated interpreted updates, short table" << endl;
ndbout << "11\t=> Test interpreter functions, short table" << endl;
ndbout << "12\t=> Test bug with replicated interpreted updates, long table" << endl;
ndbout << "13\t=> Test interpreter functions, long table" << endl;
ndbout << "14\t=> Perform lookups in short table, no guess of TC" << endl;
ndbout << "15\t=> Perform lookups in long table, no guess of TC" << endl;
ndbout << "16\t=> Perform updates in short table, no guess of TC" << endl;
ndbout << "17\t=> Perform updates in long table, no guess of TC" << endl;
ndbout << "18\t=> Multi record updates of transactions" << endl;
ndbout << "All other responses will exit" << endl;
ndbout << "_____________________________" << endl << endl ;
int inp_i = 0;
do {
inp[inp_i] = (char) fgetc(stdin);
if (inp[inp_i] == '\n' || inp[inp_i] == EOF) {
inp[inp_i] ='\0';
break;
}
inp_i++;
} while (inp[inp_i - 1] != '\n' && inp[inp_i - 1] != EOF);
tmp = atoi(inp);
if ((tmp > 18) || (tmp <= 0)) break;
ndbout << "Starting test " << tmp << "..." << endl;
for (i = 0; i < tNoOfThreads ; i++){ ThreadStart[i] = tmp; }
cont = 1;
while (cont) {
NdbSleep_MilliSleep(10);
cont = 0;
for (i = 0; i < tNoOfThreads ; i++){
if (!ThreadReady[i]) cont = 1;
}
}//while
}//for(;;)
}else{
if(19 == nTest){
ndbout << "Executing all 18 available tests..." << endl << endl;
for (int count = 1; count < nTest; count++){
ndbout << "Test " << count << endl ;
ndbout << "------" << endl << endl ;
for (i = 0; i < tNoOfThreads ; i++) { ThreadStart[i] = count ; }
cont = 1;
while (cont) {
NdbSleep_MilliSleep(10);
cont = 0;
for (i = 0; i < tNoOfThreads ; i++){
if (!ThreadReady[i]) cont = 1;
}
}
}//for
}else{
ndbout << endl << "Executing test " << nTest << endl << endl;
for (i = 0; i < tNoOfThreads ; i++) { ThreadStart[i] = nTest ; }
cont = 1;
while (cont) {
NdbSleep_MilliSleep(10);
cont = 0;
for (i = 0; i < tNoOfThreads ; i++){
if (!ThreadReady[i]) cont = 1;
}
}
}//if(18 == nTest)
} //if(!nTest)
ndbout << "--------------------------------------------------" << endl;
for (i = 0; i < tNoOfThreads ; i++) ThreadReady[i] = 0;
// Signaling threads to stop
for (i = 0; i < tNoOfThreads ; i++) ThreadStart[i] = 999;
// Wait for threads to stop
cont = 1;
do {
NdbSleep_MilliSleep(1);
cont = 0;
for (i = 0; i < tNoOfThreads ; i++){
if (ThreadReady[i] == 0) cont = 1;
}
} while (cont == 1);
delete pMyNdb ;
ndbout << endl << "Ronja Benchmark completed" << endl;
return NDBT_ProgramExit(NDBT_OK) ;
error_input:
ndbout << endl << " Ivalid parameter(s)" << endl;
ndbout << " Usage: benchronja [-t threads][-r rec] [-o ops] [-c ops_per_exec] [-p test], where:" << endl;
ndbout << " threads - the number of threads to start; default: 1" << endl;
ndbout << " rec - the number of records in the tables; default: 500" << endl;
ndbout << " ops - the number of operations per transaction; default: 100000" << endl;
ndbout << " ops_per_exec - the number of operations per execution; default: 1" << endl ;
ndbout << " test - the number of test to execute; 19 executes all available tests; default: 0"<< endl ;
ndbout << " which enters a loop expecting manual input of test number to execute." << endl << endl ;
delete pMyNdb ;
return NDBT_ProgramExit(NDBT_WRONGARGS) ;
}
////////////////////////////////////////
void commitTrans(Ndb* aNdb, NdbConnection* aCon)
{
int ret = aCon->execute(Commit);
assert (ret != -1);
aNdb->closeTransaction(aCon);
}
void rollbackTrans(Ndb* aNdb, NdbConnection* aCon)
{
int ret = aCon->execute(Rollback);
assert (ret != -1);
aNdb->closeTransaction(aCon);
}
void updateNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key)
{
NdbOperation* theOperation;
*flip = *flip + 1;
theOperation = aCon->getNdbOperation("SHORT_REC");
theOperation->updateTuple();
theOperation->equal((Uint32)0, key);
theOperation->setValue((Uint32)1, (char*)flip);
int ret = aCon->execute(NoCommit);
assert (ret != -1);
}
void updateNoCommitFail(NdbConnection* aCon, unsigned int key)
{
NdbOperation* theOperation;
Uint32 flip = 0;
theOperation = aCon->getNdbOperation("SHORT_REC");
theOperation->updateTuple();
theOperation->equal((Uint32)0, key);
theOperation->setValue((Uint32)1, (char*)flip);
int ret = aCon->execute(NoCommit);
assert (ret == -1);
}
void deleteNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key)
{
NdbOperation* theOperation;
*flip = 0;
theOperation = aCon->getNdbOperation("SHORT_REC");
theOperation->deleteTuple();
theOperation->equal((Uint32)0, key);
int ret = aCon->execute(NoCommit);
assert (ret != -1);
}
void insertNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key)
{
NdbOperation* theOperation;
Uint32 placeholder[100];
*flip = *flip + 1;
theOperation = aCon->getNdbOperation("SHORT_REC");
theOperation->insertTuple();
theOperation->equal((Uint32)0, key);
theOperation->setValue((Uint32)1, (char*)flip);
theOperation->setValue((Uint32)2, (char*)&placeholder[0]);
theOperation->setValue((Uint32)3, (char*)&placeholder[0]);
int ret = aCon->execute(NoCommit);
assert (ret != -1);
}
void writeNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key)
{
NdbOperation* theOperation;
Uint32 placeholder[100];
*flip = *flip + 1;
theOperation = aCon->getNdbOperation("SHORT_REC");
theOperation->writeTuple();
theOperation->equal((Uint32)0, key);
theOperation->setValue((Uint32)1, (char*)flip);
theOperation->setValue((Uint32)2, (char*)&placeholder[0]);
theOperation->setValue((Uint32)3, (char*)&placeholder[0]);
int ret = aCon->execute(NoCommit);
assert (ret != -1);
}
void readNoCommit(NdbConnection* aCon, Uint32* flip, Uint32 key, int expected_ret)
{
NdbOperation* theOperation;
Uint32 readFlip;
theOperation = aCon->getNdbOperation("SHORT_REC");
theOperation->readTuple();
theOperation->equal((Uint32)0, key);
theOperation->getValue((Uint32)1, (char*)&readFlip);
int ret = aCon->execute(NoCommit);
assert (ret == expected_ret);
if (ret == 0)
assert (*flip == readFlip);
}
void readDirtyNoCommit(NdbConnection* aCon, Uint32* flip, Uint32 key, int expected_ret)
{
NdbOperation* theOperation;
Uint32 readFlip;
theOperation = aCon->getNdbOperation("SHORT_REC");
theOperation->committedRead();
theOperation->equal((Uint32)0, key);
theOperation->getValue((Uint32)1, (char*)&readFlip);
int ret = aCon->execute(NoCommit);
assert (ret == expected_ret);
if (ret == 0)
assert (*flip == readFlip);
}
void readVerify(Ndb* aNdb, Uint32* flip, Uint32 key, int expected_ret)
{
NdbConnection* theTransaction;
theTransaction = aNdb->startTransaction();
readNoCommit(theTransaction, flip, key, expected_ret);
commitTrans(aNdb, theTransaction);
}
void readDirty(Ndb* aNdb, Uint32* flip, Uint32 key, int expected_ret)
{
NdbOperation* theOperation;
NdbConnection* theTransaction;
Uint32 readFlip;
theTransaction = aNdb->startTransaction();
theOperation = theTransaction->getNdbOperation("SHORT_REC");
theOperation->committedRead();
theOperation->equal((Uint32)0, key);
theOperation->getValue((Uint32)1, (char*)&readFlip);
int ret = theTransaction->execute(Commit);
assert (ret == expected_ret);
if (ret == 0)
assert (*flip == readFlip);
aNdb->closeTransaction(theTransaction);
}
int multiRecordTest(Ndb* aNdb, unsigned int key)
{
NdbConnection* theTransaction;
Uint32 flip = 0;
Uint32 save_flip;
ndbout << "0" << endl;
theTransaction = aNdb->startTransaction();
updateNoCommit(theTransaction, &flip, key);
readNoCommit(theTransaction, &flip, key, 0);
updateNoCommit(theTransaction, &flip, key);
readNoCommit(theTransaction, &flip, key, 0);
commitTrans(aNdb, theTransaction);
ndbout << "1 " << endl;
readVerify(aNdb, &flip, key, 0);
readDirty(aNdb, &flip, key, 0);
save_flip = flip;
ndbout << "1.1 " << endl;
theTransaction = aNdb->startTransaction();
deleteNoCommit(theTransaction, &flip, key);
readNoCommit(theTransaction, &flip, key, -1);
readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!!
readDirtyNoCommit(theTransaction, &flip, key, -1);
ndbout << "1.2 " << endl;
insertNoCommit(theTransaction, &flip, key);
readNoCommit(theTransaction, &flip, key, 0);
readDirtyNoCommit(theTransaction, &flip, key, 0);
readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!!
ndbout << "1.3 " << endl;
updateNoCommit(theTransaction, &flip, key);
readNoCommit(theTransaction, &flip, key, 0);
readDirtyNoCommit(theTransaction, &flip, key, 0);
readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!!
ndbout << "1.4 " << endl;
commitTrans(aNdb, theTransaction);
ndbout << "2 " << endl;
readDirty(aNdb, &flip, key, 0); // COMMITTED READ!!!
readVerify(aNdb, &flip, key, 0);
save_flip = flip;
theTransaction = aNdb->startTransaction();
deleteNoCommit(theTransaction, &flip, key);
readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!!
readDirtyNoCommit(theTransaction, &flip, key, -1); // COMMITTED READ!!!
readNoCommit(theTransaction, &flip, key, -1);
insertNoCommit(theTransaction, &flip, key);
readNoCommit(theTransaction, &flip, key, 0);
updateNoCommit(theTransaction, &flip, key);
readNoCommit(theTransaction, &flip, key, 0);
readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!!
readDirtyNoCommit(theTransaction, &flip, key, 0); // COMMITTED READ!!!
deleteNoCommit(theTransaction, &flip, key);
readNoCommit(theTransaction, &flip, key, -1);
readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!!
readDirtyNoCommit(theTransaction, &flip, key, -1);
rollbackTrans(aNdb, theTransaction);
ndbout << "3 " << endl;
flip = save_flip;
readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!!
readVerify(aNdb, &flip, key, 0);
theTransaction = aNdb->startTransaction();
updateNoCommit(theTransaction, &flip, key);
readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!!
readDirtyNoCommit(theTransaction, &flip, key, 0);
readNoCommit(theTransaction, &flip, key, 0);
deleteNoCommit(theTransaction, &flip, key);
readNoCommit(theTransaction, &flip, key, -1);
readDirtyNoCommit(theTransaction, &flip, key, -1);
readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!!
insertNoCommit(theTransaction, &flip, key);
readNoCommit(theTransaction, &flip, key, 0);
readDirtyNoCommit(theTransaction, &flip, key, 0);
readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!!
updateNoCommit(theTransaction, &flip, key);
readNoCommit(theTransaction, &flip, key, 0);
readDirtyNoCommit(theTransaction, &flip, key, 0);
readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!!
deleteNoCommit(theTransaction, &flip, key);
readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!!
readNoCommit(theTransaction, &flip, key, -1);
readDirtyNoCommit(theTransaction, &flip, key, -1);
commitTrans(aNdb, theTransaction);
ndbout << "4 " << endl;
readVerify(aNdb, &flip, key, -1);
theTransaction = aNdb->startTransaction();
insertNoCommit(theTransaction, &flip, key);
readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!!
readNoCommit(theTransaction, &flip, key, 0);
readDirtyNoCommit(theTransaction, &flip, key, 0);
deleteNoCommit(theTransaction, &flip, key);
readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!!
readNoCommit(theTransaction, &flip, key, -1);
readDirtyNoCommit(theTransaction, &flip, key, -1);
insertNoCommit(theTransaction, &flip, key);
readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!!
readNoCommit(theTransaction, &flip, key, 0);
readDirtyNoCommit(theTransaction, &flip, key, 0);
updateNoCommit(theTransaction, &flip, key);
readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!!
readNoCommit(theTransaction, &flip, key, 0);
readDirtyNoCommit(theTransaction, &flip, key, 0);
deleteNoCommit(theTransaction, &flip, key);
readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!!
readNoCommit(theTransaction, &flip, key, -1);
readDirtyNoCommit(theTransaction, &flip, key, -1);
commitTrans(aNdb, theTransaction);
ndbout << "5 " << endl;
readDirty(aNdb, &flip, key, -1); // COMMITTED READ!!!
readVerify(aNdb, &flip, key, -1);
theTransaction = aNdb->startTransaction();
insertNoCommit(theTransaction, &flip, key);
readDirty(aNdb, &flip, key, -1); // COMMITTED READ!!!
readDirtyNoCommit(theTransaction, &flip, key, 0); // COMMITTED READ!!!
commitTrans(aNdb, theTransaction);
readDirty(aNdb, &flip, key, 0); // COMMITTED READ!!!
ndbout << "6 " << endl;
theTransaction = aNdb->startTransaction();
deleteNoCommit(theTransaction, &flip, key);
updateNoCommitFail(theTransaction, key);
rollbackTrans(aNdb, theTransaction);
return 0;
}
int lookup(Ndb* aNdb, unsigned int key, unsigned int long_short, int guess){
int placeholder[500];
unsigned int flip, count;
int ret_value, i;
NdbConnection* theTransaction;
NdbOperation* theOperation;
if ( !aNdb ) return -1 ;
if (guess != 0)
theTransaction = aNdb->startTransaction((Uint32)0, (const char*)&key, (Uint32)4);
else
theTransaction = aNdb->startTransaction();
for (i = 0; i < tNoOfOpsPerExecute; i++) {
if (long_short == 0)
theOperation = theTransaction->getNdbOperation("SHORT_REC");
else
theOperation = theTransaction->getNdbOperation("LONG_REC");
if (theOperation == NULL) {
ndbout << "Table missing" << endl;
aNdb->closeTransaction(theTransaction) ;
return -1;
}//if
theOperation->simpleRead();
theOperation->equal((Uint32)0, key);
theOperation->getValue((Uint32)1, (char*)&flip);
theOperation->getValue((Uint32)2, (char*)&count);
if (theOperation->getValue((Uint32)3, (char*)&placeholder[0]) == NULL) {
ndbout << "Error in definition phase = " << theTransaction->getNdbError() << endl;
aNdb->closeTransaction(theTransaction);
return -1;
}//if
}//for
ret_value = theTransaction->execute(Commit);
if (ret_value == -1)
ndbout << "Error in lookup:" << theTransaction->getNdbError() << endl;
aNdb->closeTransaction(theTransaction);
return ret_value;
}//lookup()
int update(Ndb* aNdb, unsigned int key, unsigned int long_short, int guess)
{
int placeholder[500];
int ret_value, i;
unsigned int flip, count;
NdbConnection* theTransaction;
NdbOperation* theOperation;
if ( !aNdb ) return -1 ;
if (guess != 0)
theTransaction = aNdb->startTransaction((Uint32)0, (const char*)&key, (Uint32)4);
else
theTransaction = aNdb->startTransaction();
for (i = 0; i < tNoOfOpsPerExecute; i++) {
if (long_short == 0)
theOperation = theTransaction->getNdbOperation("SHORT_REC"); // Use table SHORT_REC
else
theOperation = theTransaction->getNdbOperation("LONG_REC"); // Use table LONG_REC
if (theOperation == NULL) {
ndbout << "Table missing" << endl;
aNdb->closeTransaction(theTransaction) ;
delete aNdb ;
return -1;
}//if
theOperation->interpretedUpdateTuple(); // Send interpreted program to NDB kernel
theOperation->equal((Uint32)0, key); // Search key
theOperation->getValue((Uint32)1, (char*)&flip); // Read value of flip
theOperation->getValue((Uint32)2, (char*)&count); // Read value of count
theOperation->getValue((Uint32)3, (char*)&placeholder[0]); // Read value of placeholder
theOperation->load_const_u32((Uint32)1, (Uint32)0); // Load register 1 with 0
theOperation->read_attr((Uint32)1, (Uint32)2); // Read Flip value into register 2
theOperation->branch_eq((Uint32)1, (Uint32)2, (Uint32)0); // If Flip (register 2) == 0 (register 1) goto label 0
theOperation->branch_label((Uint32)1); // Goto label 1
theOperation->def_label((Uint32)0); // Define label 0
theOperation->load_const_u32((Uint32)1, (Uint32)1); // Load register 1 with 1
theOperation->def_label((Uint32)1); // Define label 0
theOperation->write_attr((Uint32)1, (Uint32)1); // Write 1 (register 1) into Flip
ret_value = theOperation->incValue((Uint32)2, (Uint32)1); // Increment Count by 1
if (ret_value == -1) {
ndbout << "Error in definition phase " << endl;
aNdb->closeTransaction(theTransaction);
return ret_value;
}//if
}//for
ret_value = theTransaction->execute(Commit); // Perform the actual read and update
if (ret_value == -1) {
ndbout << "Error in update:" << theTransaction->getNdbError() << endl;
aNdb->closeTransaction(theTransaction); // < epaulsa
return ret_value ;
}//if
aNdb->closeTransaction(theTransaction);
return ret_value;
}//update()
int update_bug(Ndb* aNdb, unsigned int key, unsigned int long_short)
{
int placeholder[500];
int ret_value, i;
unsigned int flip, count;
NdbConnection* theTransaction;
NdbOperation* theOperation;
if ( !aNdb ) return -1 ;
theTransaction = aNdb->startTransaction();
for (i = 0; i < tNoOfOpsPerExecute; i++) {
if (long_short == 0)
theOperation = theTransaction->getNdbOperation("SHORT_REC"); // Use table SHORT_REC
else
theOperation = theTransaction->getNdbOperation("LONG_REC"); // Use table LONG_REC
if (theOperation == NULL) {
ndbout << "Table missing" << endl;
aNdb->closeTransaction(theTransaction) ;
return -1;
}//if
theOperation->interpretedUpdateTuple(); // Send interpreted program to NDB kernel
theOperation->equal((Uint32)0, key); // Search key
theOperation->getValue((Uint32)1, (char*)&flip); // Read value of flip
theOperation->getValue((Uint32)2, (char*)&count); // Read value of count
theOperation->getValue((Uint32)3, (char*)&placeholder[0]); // Read value of placeholder
theOperation->load_const_u32((Uint32)1, (Uint32)0); // Load register 1 with 0
theOperation->read_attr((Uint32)1, (Uint32)2); // Read Flip value into register 2
theOperation->branch_eq((Uint32)1, (Uint32)2, (Uint32)0); // If Flip (register 2) == 0 (register 1) goto label 0
theOperation->branch_label((Uint32)1); // Goto label 1
theOperation->def_label((Uint32)0); // Define label 0
theOperation->load_const_u32((Uint32)1, (Uint32)1); // Load register 1 with 1
theOperation->def_label((Uint32)1); // Define label 0
theOperation->write_attr((Uint32)1, (Uint32)1); // Write 1 (register 1) into Flip
ret_value = theOperation->incValue((Uint32)2, (Uint32)1); // Increment Count by 1
if (ret_value == -1) {
ndbout << "Error in definition phase " << endl;
aNdb->closeTransaction(theTransaction);
return ret_value;
}//if
}//for
ret_value = theTransaction->execute(NoCommit); // Perform the actual read and update
if (ret_value == -1) {
ndbout << "Error in update:" << theTransaction->getNdbError() << endl;
aNdb->closeTransaction(theTransaction);
return ret_value ;
}//if
aNdb->closeTransaction(theTransaction);
return ret_value;
}//update_bug()
int update_interpreter_test(Ndb* aNdb, unsigned int key, unsigned int long_short)
{
int placeholder[500];
int ret_value, i;
unsigned int flip, count;
NdbConnection* theTransaction;
NdbOperation* theOperation;
Uint32 Tlabel = 0;
if ( !aNdb ) return -1 ;
//------------------------------------------------------------------------------
// Start the transaction and get a unique transaction id
//------------------------------------------------------------------------------
theTransaction = aNdb->startTransaction();
for (i = 0; i < tNoOfOpsPerExecute; i++) {
//------------------------------------------------------------------------------
// Get the proper table object and load schema information if not already
// present.
//------------------------------------------------------------------------------
if (long_short == 0)
theOperation = theTransaction->getNdbOperation("SHORT_REC"); // Use table SHORT_REC
else
theOperation = theTransaction->getNdbOperation("LONG_REC"); // Use table LONG_REC
if (theOperation == NULL) {
ndbout << "Table missing" << endl;
aNdb->closeTransaction(theTransaction) ;
return -1;
}//if
//------------------------------------------------------------------------------
// Define the operation type and the tuple key (primary key in this case).
//------------------------------------------------------------------------------
theOperation->interpretedUpdateTuple(); // Send interpreted program to NDB kernel
theOperation->equal((Uint32)0, key); // Search key
//------------------------------------------------------------------------------
// Perform initial read of attributes before updating them
//------------------------------------------------------------------------------
theOperation->getValue((Uint32)1, (char*)&flip); // Read value of flip
theOperation->getValue((Uint32)2, (char*)&count); // Read value of count
theOperation->getValue((Uint32)3, (char*)&placeholder[0]); // Read value of placeholder
//------------------------------------------------------------------------------
// Test that the various branch operations can handle things correctly.
// Test first 2 + 3 = 5 with 32 bit registers
// Next test the same with 32 bit + 64 bit = 64
//------------------------------------------------------------------------------
theOperation->load_const_u32((Uint32)4, (Uint32)0); // Load register 4 with 0
theOperation->load_const_u32((Uint32)0, (Uint32)0);
theOperation->load_const_u32((Uint32)1, (Uint32)3);
theOperation->load_const_u32((Uint32)2, (Uint32)5);
theOperation->load_const_u32((Uint32)3, (Uint32)1);
theOperation->def_label(Tlabel++);
theOperation->def_label(Tlabel++);
theOperation->sub_reg((Uint32)2, (Uint32)3, (Uint32)2);
theOperation->branch_ne((Uint32)2, (Uint32)0, (Uint32)0);
theOperation->load_const_u32((Uint32)2, (Uint32)5);
theOperation->sub_reg((Uint32)1, (Uint32)3, (Uint32)1);
theOperation->branch_ne((Uint32)1, (Uint32)0, (Uint32)1);
theOperation->load_const_u32((Uint32)1, (Uint32)2); // Load register 1 with 2
theOperation->load_const_u32((Uint32)2, (Uint32)3); // Load register 2 with 3
theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1); // 2+3 = 5 into reg 1
theOperation->load_const_u32((Uint32)2, (Uint32)5); // Load register 2 with 5
theOperation->def_label(Tlabel++);
theOperation->branch_eq((Uint32)1, (Uint32)2, Tlabel);
theOperation->interpret_exit_nok((Uint32)6001);
theOperation->def_label(Tlabel++);
theOperation->branch_ne((Uint32)1, (Uint32)2, Tlabel);
theOperation->branch_label(Tlabel + 1);
theOperation->def_label(Tlabel++);
theOperation->interpret_exit_nok((Uint32)6002);
theOperation->def_label(Tlabel++);
theOperation->branch_lt((Uint32)1, (Uint32)2, Tlabel);
theOperation->branch_label(Tlabel + 1);
theOperation->def_label(Tlabel++);
theOperation->interpret_exit_nok((Uint32)6003);
theOperation->def_label(Tlabel++);
theOperation->branch_gt((Uint32)1, (Uint32)2, Tlabel);
theOperation->branch_label(Tlabel + 1);
theOperation->def_label(Tlabel++);
theOperation->interpret_exit_nok((Uint32)6005);
theOperation->def_label(Tlabel++);
theOperation->branch_eq_null((Uint32)1, Tlabel);
theOperation->branch_label(Tlabel + 1);
theOperation->def_label(Tlabel++);
theOperation->interpret_exit_nok((Uint32)6006);
theOperation->def_label(Tlabel++);
theOperation->branch_ne_null((Uint32)1,Tlabel);
theOperation->interpret_exit_nok((Uint32)6007);
theOperation->def_label(Tlabel++);
theOperation->branch_ge((Uint32)1, (Uint32)2, Tlabel);
theOperation->interpret_exit_nok((Uint32)6008);
theOperation->def_label(Tlabel++);
theOperation->branch_eq_null((Uint32)6,Tlabel);
theOperation->interpret_exit_nok((Uint32)6009);
theOperation->def_label(Tlabel++);
theOperation->branch_ne_null((Uint32)6, Tlabel);
theOperation->branch_label(Tlabel + 1);
theOperation->def_label(Tlabel++);
theOperation->interpret_exit_nok((Uint32)6010);
theOperation->def_label(Tlabel++);
theOperation->load_const_u32((Uint32)5, (Uint32)1);
theOperation->add_reg((Uint32)4, (Uint32)5, (Uint32)4);
theOperation->load_const_u32((Uint32)5, (Uint32)1);
theOperation->branch_eq((Uint32)4, (Uint32)5, Tlabel);
theOperation->load_const_u32((Uint32)5, (Uint32)2);
theOperation->branch_eq((Uint32)4, (Uint32)5, (Tlabel + 1));
theOperation->load_const_u32((Uint32)5, (Uint32)3);
theOperation->branch_eq((Uint32)4, (Uint32)5, (Tlabel + 2));
theOperation->load_const_u32((Uint32)5, (Uint32)4);
theOperation->branch_eq((Uint32)4, (Uint32)5, (Tlabel + 3));
theOperation->branch_label(Tlabel + 4);
theOperation->def_label(Tlabel++);
theOperation->load_const_u32((Uint32)1, (Uint32)200000);
theOperation->load_const_u32((Uint32)2, (Uint32)300000);
theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1);
theOperation->load_const_u32((Uint32)2, (Uint32)500000);
theOperation->branch_label((Uint32)2);
theOperation->def_label(Tlabel++);
theOperation->load_const_u32((Uint32)1, (Uint32)200000);
theOperation->load_const_u32((Uint32)2, (Uint32)300000);
theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1);
theOperation->load_const_u32((Uint32)2, (Uint32)500000);
theOperation->branch_label((Uint32)2);
theOperation->def_label(Tlabel++);
theOperation->load_const_u32((Uint32)1, (Uint32)2);
Uint64 x = 0;
theOperation->load_const_u64((Uint32)2, (Uint64)(x - 1));
theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1);
theOperation->load_const_u32((Uint32)2, (Uint32)1);
theOperation->branch_label((Uint32)2);
theOperation->def_label(Tlabel++);
theOperation->load_const_u32((Uint32)1, (Uint32)2);
theOperation->load_const_u64((Uint32)2, (Uint64)(x - 1));
theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1);
theOperation->load_const_u64((Uint32)2, (Uint64)1);
theOperation->branch_label((Uint32)2);
theOperation->def_label(Tlabel++);
theOperation->read_attr((Uint32)1, (Uint32)2);
theOperation->branch_eq((Uint32)1, (Uint32)2, Tlabel);
theOperation->load_const_u32((Uint32)1, (Uint32)0);
theOperation->branch_label(Tlabel + 1);
theOperation->def_label(Tlabel++);
theOperation->load_const_u32((Uint32)1, (Uint32)1);
theOperation->def_label(Tlabel++);
theOperation->write_attr((Uint32)1, (Uint32)1);
ret_value = theOperation->incValue((Uint32)2, (Uint32)1);
if (ret_value == -1) {
ndbout << "Error in definition phase " << endl;
ndbout << "Error = " << theOperation->getNdbError() << " on line = " << theOperation->getNdbErrorLine() << endl;
aNdb->closeTransaction(theTransaction);
return ret_value;
}//if
}//for
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
ret_value = theTransaction->execute(Commit); // Perform the actual read and update
if (ret_value == -1) {
ndbout << "Error in update:" << theTransaction->getNdbError() << endl;
aNdb->closeTransaction(theTransaction); // < epaulsa
return ret_value ;
}//if
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
aNdb->closeTransaction(theTransaction);
return ret_value;
}//update_interpreter_test()
void* ThreadExec(void* ThreadData){
ThreadNdb* tabThread = (ThreadNdb*)ThreadData;
Ndb* pMyNdb = NULL ;
myRandom48Init(NdbTick_CurrentMillisecond());
int Tsuccess = 0 ;
int check = 0 ;
int loop_count_ops = 0;
int count, i, Ti;
int tType = 0 ;
int remType = 0 ;
unsigned int thread_no = 0 ;
unsigned long total_milliseconds;
unsigned int key = 0 ;
unsigned int prob = 0 ;
unsigned long transaction_time = 0 ;
unsigned long transaction_max_time = 0 ;
unsigned long min_time, max_time[MAX_TIMERS];
double mean_time, mean_square_time, std_time;
thread_no = tabThread->ThreadNo;
pMyNdb = tabThread->NdbRef;
if (!pMyNdb) {
pMyNdb = new Ndb( "TEST_DB" );
pMyNdb->init();
}//if
for (;;){
min_time = 0xFFFFFFFF;
//for (Ti = 0; Ti < MAX_TIMERS ; Ti++) max_time[Ti] = 0;
memset(&max_time, 0, sizeof max_time) ;
mean_time = 0;
mean_square_time = 0;
ThreadReady[thread_no] = 1;
while (!ThreadStart[thread_no]){
NdbSleep_MilliSleep(1);
}
// Check if signal to exit is received
if (ThreadStart[thread_no] == 999){
delete pMyNdb;
pMyNdb = NULL ;
ThreadReady[thread_no] = 1;
return 0 ;
}//if
tType = ThreadStart[thread_no];
remType = tType;
ThreadStart[thread_no] = 0;
ThreadReady[thread_no] = 0 ;
// Start transaction, type of transaction
// is received in the array ThreadStart
loop_count_ops = tNoOfOperations;
START_TIMER_TOP
for (count=0 ; count < loop_count_ops ; count++) {
Tsuccess = 0;
//----------------------------------------------------
// Generate a random key between 0 and tNoOfRecords - 1
//----------------------------------------------------
key = myRandom48(tNoOfRecords);
//----------------------------------------------------
// Start time measurement of transaction.
//----------------------------------------------------
START_TIMER
//do {
switch (remType){
case 1:
//----------------------------------------------------
// Only lookups in short record table
//----------------------------------------------------
Tsuccess = lookup(pMyNdb, key, 0, 1);
break;
case 2:
//----------------------------------------------------
// Only lookups in long record table
//----------------------------------------------------
Tsuccess = lookup(pMyNdb, key, 1, 1);
break;
case 3:
//----------------------------------------------------
// Only updates in short record table
//----------------------------------------------------
Tsuccess = update(pMyNdb, key, 0, 1);
break;
case 4:
//----------------------------------------------------
// Only updates in long record table
//----------------------------------------------------
Tsuccess = update(pMyNdb, key, 1, 1);
break;
case 5:
//----------------------------------------------------
// 50% read/50 % update in short record table
//----------------------------------------------------
prob = myRandom48(100);
if (prob < 50)
Tsuccess = update(pMyNdb, key, 0, 1);
else
Tsuccess = lookup(pMyNdb, key, 0, 1);
break;
case 6:
//----------------------------------------------------
// 50% read/50 % update in long record table
//----------------------------------------------------
prob = myRandom48(100);
if (prob < 50)
Tsuccess = update(pMyNdb, key, 1, 1);
else
Tsuccess = lookup(pMyNdb, key, 1, 1);
break;
case 7:
//----------------------------------------------------
// 80 read/20 % update in short record table
//----------------------------------------------------
prob = myRandom48(100);
if (prob < 20)
Tsuccess = update(pMyNdb, key, 0, 1);
else
Tsuccess = lookup(pMyNdb, key, 0, 1);
break;
case 8:
//----------------------------------------------------
// 80 read/20 % update in long record table
//----------------------------------------------------
prob = myRandom48(100);
if (prob < 20)
Tsuccess = update(pMyNdb, key, 1, 1);
else
Tsuccess = lookup(pMyNdb, key, 1, 1);
break;
case 9:
//----------------------------------------------------
// 25 read short/25 % read long/25 % update short/25 % update long
//----------------------------------------------------
prob = myRandom48(100);
if (prob < 25)
Tsuccess = update(pMyNdb, key, 0, 1);
else if (prob < 50)
Tsuccess = update(pMyNdb, key, 1, 1);
else if (prob < 75)
Tsuccess = lookup(pMyNdb, key, 0, 1);
else
Tsuccess = lookup(pMyNdb, key, 1, 1);
break;
case 10:
//----------------------------------------------------
// Test bug with replicated interpreted update, short table
//----------------------------------------------------
Tsuccess = update_bug(pMyNdb, key, 0);
break;
case 11:
//----------------------------------------------------
// Test interpreter functions, short table
//----------------------------------------------------
Tsuccess = update_interpreter_test(pMyNdb, key, 0);
break;
case 12:
//----------------------------------------------------
// Test bug with replicated interpreted update, long table
//----------------------------------------------------
Tsuccess = update_bug(pMyNdb, key, 1);
break;
case 13:
//----------------------------------------------------
// Test interpreter functions, long table
//----------------------------------------------------
Tsuccess = update_interpreter_test(pMyNdb, key, 1);
break;
case 14:
//----------------------------------------------------
// Only lookups in short record table
//----------------------------------------------------
Tsuccess = lookup(pMyNdb, key, 0, 0);
break;
case 15:
//----------------------------------------------------
// Only lookups in long record table
//----------------------------------------------------
Tsuccess = lookup(pMyNdb, key, 1, 0);
break;
case 16:
//----------------------------------------------------
// Only updates in short record table
//----------------------------------------------------
Tsuccess = update(pMyNdb, key, 0, 0);
break;
case 17:
//----------------------------------------------------
// Only updates in long record table
//----------------------------------------------------
Tsuccess = update(pMyNdb, key, 1, 0);
break;
case 18:
Tsuccess = multiRecordTest(pMyNdb, key);
break;
default:
break;
}//switch
//} while (0);//
if(-1 == Tsuccess) {
NDBT_ProgramExit(NDBT_FAILED);
exit(-1);
} // for
//----------------------------------------------------
// Stop time measurement of transaction.
//----------------------------------------------------
STOP_TIMER
transaction_time = (unsigned long)timer.elapsedTime() ;//stopTimer(&theStartTime);
//----------------------------------------------------
// Perform calculations of time measurements.
//----------------------------------------------------
transaction_max_time = transaction_time;
for (Ti = 0; Ti < MAX_TIMERS; Ti++) {
if (transaction_max_time > max_time[Ti]) {
Uint32 tmp = max_time[Ti];
max_time[Ti] = transaction_max_time;
transaction_max_time = tmp;
}//if
}//if
if (transaction_time < min_time) min_time = transaction_time;
mean_time = (double)transaction_time + mean_time;
mean_square_time = (double)(transaction_time * transaction_time) + mean_square_time;
}//for
//----------------------------------------------------
// Calculate mean and standard deviation
//----------------------------------------------------
STOP_TIMER_TOP
total_milliseconds = (unsigned long)timer_top.elapsedTime() ;//stopTimer(&total_time);
mean_time = mean_time / loop_count_ops;
mean_square_time = mean_square_time / loop_count_ops;
std_time = sqrt(mean_square_time - (mean_time * mean_time));
//----------------------------------------------------
// Report statistics
//----------------------------------------------------
ndbout << "Thread = " << thread_no << " reporting:" << endl ;
ndbout << "------------------------------" << endl ;
ndbout << "Total time is " << (unsigned int)(total_milliseconds /1000);
ndbout << " seconds and " << (unsigned int)(total_milliseconds % 1000);
ndbout << " milliseconds" << endl;
ndbout << "Minimum time = " << (unsigned int)min_time << " milliseconds" << endl;
for (Ti = 0; Ti < MAX_TIMERS; Ti++) {
ndbout << "Maximum timer " << Ti << " = " << (unsigned int)max_time[Ti] << " milliseconds" << endl;
ndbout << "Mean time = " << (unsigned int)mean_time << " milliseconds" << endl;
ndbout << "Standard deviation on time = " << (unsigned int)std_time;
ndbout << " milliseconds" << endl << endl ;
}//for
ndbout << endl ;
} // for(;;)
delete pMyNdb ;
return 0 ;
}