mariadb/ndb/test/ndbapi/flexTimedAsynch.cpp
unknown f5b95d0be1 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?


config/ac-macros/large_file.m4:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (2)
  
  we no longer declare anything large-file on AIX.  the
  GNU C++ compiler declares _LARGE_FILE_API all of its
  own, and either way we're now pulling in <standards.h>
  when on AIX, which defines _LARGE_FILE_API (if not
  already defined).
configure.in:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (1)
  
  build NDB binaries as static on AIX. because that actually
  *works*.
  
  when building dynamic, with the IBM compiler (xlC_r), and
  the build breaks on AIX due to missing symbols
  (__vec__delete2 et al.), try adding -lhC to the Makefile.
include/mysql.h:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (2)
  
  we're now pulling in <standards.h> when on AIX, which
  defines _LARGE_FILE_API (if not already defined).
ndb/src/common/util/File.cpp:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (3)
  
  do not de-scope the standards, for they may be funky macros
ndb/src/mgmclient/Makefile.am:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (4)
  
  make IBM C++ compiler happy on AIX
ndb/src/mgmsrv/Makefile.am:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (5)
  
  GNU compiler has no sense of humour about this
ndb/test/ndbapi/benchronja.cpp:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (6)
  
  MAXTHREADS collides with a #define from <sys/thread.h> on AIX
  (IBM compiler).  Call it NDB_MAXTHREADS instead.  Also explicitly
  #undef it here lest someone use it by habit and get really funny
  results.  (K&R says we may #undef non-existent symbols.)
ndb/test/ndbapi/flexAsynch.cpp:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (6)
  
  MAXTHREADS collides with a #define from <sys/thread.h> on AIX
  (IBM compiler).  Call it NDB_MAXTHREADS instead.  Also explicitly
  #undef it here lest someone use it by habit and get really funny
  results.  (K&R says we may #undef non-existent symbols.)
ndb/test/ndbapi/flexHammer.cpp:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (6)
  
  MAXTHREADS collides with a #define from <sys/thread.h> on AIX
  (IBM compiler).  Call it NDB_MAXTHREADS instead.  Also explicitly
  #undef it here lest someone use it by habit and get really funny
  results.  (K&R says we may #undef non-existent symbols.)
ndb/test/ndbapi/flexScan.cpp:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (6)
  
  MAXTHREADS collides with a #define from <sys/thread.h> on AIX
  (IBM compiler).  Call it NDB_MAXTHREADS instead.  Also explicitly
  #undef it here lest someone use it by habit and get really funny
  results.  (K&R says we may #undef non-existent symbols.)
ndb/test/ndbapi/flexTT.cpp:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (6)
  
  MAXTHREADS collides with a #define from <sys/thread.h> on AIX
  (IBM compiler).  Call it NDB_MAXTHREADS instead.  Also explicitly
  #undef it here lest someone use it by habit and get really funny
  results.  (K&R says we may #undef non-existent symbols.)
ndb/test/ndbapi/flexTimedAsynch.cpp:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (6)
  
  MAXTHREADS collides with a #define from <sys/thread.h> on AIX
  (IBM compiler).  Call it NDB_MAXTHREADS instead.  Also explicitly
  #undef it here lest someone use it by habit and get really funny
  results.  (K&R says we may #undef non-existent symbols.)
ndb/test/ndbapi/initronja.cpp:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (6)
  
  MAXTHREADS collides with a #define from <sys/thread.h> on AIX
  (IBM compiler).  Call it NDB_MAXTHREADS instead.  Also explicitly
  #undef it here lest someone use it by habit and get really funny
  results.  (K&R says we may #undef non-existent symbols.)
ndb/test/ndbapi/testOperations.cpp:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (7)
  
  IBM C compiler on AIX is not happy with the re-def.
ndb/test/ndbapi/testScanFilter.cpp:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (8)
  
  The IBM C++ compiler on AIX doesn't like initializing from pow().
  This works, but breaks a VAL (bool res_cal[TUPLE_NUM] ...) later on.
ndb/test/odbc/SQL99_test/SQL99_test.cpp:
  Bug #10776: Failure to compile ndb ReadNodesConf.cpp on AIX 5.2 (6)
  
  MAXTHREADS collides with a #define from <sys/thread.h> on AIX
  (IBM compiler).  Call it NDB_MAXTHREADS instead.  Also explicitly
  #undef it here lest someone use it by habit and get really funny
  results.  (K&R says we may #undef non-existent symbols.)
2007-08-01 04:56:58 +02:00

858 lines
25 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 */
/* ***************************************************
FLEXTIMEDASYNCH
Perform benchmark of insert, update and delete transactions.
Arguments:
-t Number of threads to start, i.e., number of parallel loops, default 1
-p Number of transactions in a batch, default 32
-o Number of batches per loop, default 200
-i Time between batch starts, default 0
-l Number of loops to run, default 1, 0=infinite
-a Number of attributes, default 25
-c Number of operations per transaction
-s Size of each attribute in 32 bit word, default 1 (Primary Key is always of size 1,
independent of this value)
-simple Use simple read to read from database
-dirty Use dirty read to read from database
-write Use writeTuple in insert and update
-n Use standard table names
-no_table_create Don't create tables in db
-temp Use temporary tables, no writing to disk.
Returns:
0 - Test passed
-1 - Test failed
1 - Invalid arguments
* *************************************************** */
#include "NdbApi.hpp"
#include <NdbThread.h>
#include <NdbSleep.h>
#include <NdbTick.h>
#include <NdbOut.hpp>
#include <NdbTimer.hpp>
#include <string.h>
#include <NdbMain.h>
#include <NdbTest.hpp>
#include <NDBT_Error.hpp>
#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 1000
#define PKSIZE 1
enum StartType { stIdle,
stInsert,
stRead,
stUpdate,
stDelete,
stStop } ;
ErrorData * flexTimedAsynchErrorData;
struct ThreadNdb
{
int NoOfOps;
int ThreadNo;
unsigned int threadBase;
unsigned int transactionCompleted;
};
extern "C" void* threadLoop(void*);
void setAttrNames(void);
void setTableNames(void);
void readArguments(int argc, const char** argv);
void createAttributeSpace();
void createTables(Ndb*);
void defineOperation(NdbConnection* aTransObject, StartType aType, unsigned int key, int *);
void execute(StartType aType);
void executeThread(StartType aType, Ndb* aNdbObject, ThreadNdb* threadInfo);
void executeCallback(int result, NdbConnection* NdbObject, void* aObject);
/* epaulsa > *************************************************************/
bool error_handler(const NdbError &) ; //replaces 'goto' things
static int failed = 0 ; // lame global variable that keeps track of failed transactions
// incremented in executeCallback() and reset in main()
/************************************************************* < epaulsa */
static NdbThread* threadLife[NDB_MAXTHREADS];
static int tNodeId;
static int ThreadReady[NDB_MAXTHREADS];
static StartType ThreadStart[NDB_MAXTHREADS];
static char tableName[MAXTABLES][MAXSTRLEN+1];
static char attrName[MAXATTR][MAXSTRLEN+1];
static int *getAttrValueTable;
// Program Parameters
static int tNoOfLoops = 1;
static int tAttributeSize = 1;
static unsigned int tNoOfThreads = 1;
static unsigned int tNoOfTransInBatch = 32;
static unsigned int tNoOfAttributes = 25;
static unsigned int tNoOfBatchesInLoop = 200;
static unsigned int tNoOfOpsPerTrans = 1;
static unsigned int tTimeBetweenBatches = 0;
//Program Flags
static int theTestFlag = 0;
static int theTempFlag = 1;
static int theSimpleFlag = 0;
static int theDirtyFlag = 0;
static int theWriteFlag = 0;
static int theStdTableNameFlag = 0;
static int theTableCreateFlag = 0;
#define START_REAL_TIME NdbTimer timer; timer.doStart();
#define STOP_REAL_TIME timer.doStop();
#define START_TIMER { NdbTimer timer; timer.doStart();
#define STOP_TIMER timer.doStop();
#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); };
void
resetThreads(){
for (int i = 0; i < tNoOfThreads ; i++) {
ThreadReady[i] = 0;
ThreadStart[i] = stIdle;
}
}
void
waitForThreads(void)
{
int cont;
do {
cont = 0;
NdbSleep_MilliSleep(20);
for (int i = 0; i < tNoOfThreads ; i++) {
if (ThreadReady[i] == 0) {
cont = 1;
}
}
} while (cont == 1);
}
void
tellThreads(StartType what)
{
for (int i = 0; i < tNoOfThreads ; i++)
ThreadStart[i] = what;
}
void createAttributeSpace(){
getAttrValueTable = new int[tAttributeSize*
tNoOfThreads *
tNoOfAttributes ];
}
void deleteAttributeSpace(){
delete [] getAttrValueTable;
}
NDB_COMMAND(flexTimedAsynch, "flexTimedAsynch", "flexTimedAsynch [-tpoilcas]", "flexTimedAsynch", 65535)
{
ndb_init();
ThreadNdb tabThread[NDB_MAXTHREADS];
int tLoops=0;
int returnValue;
//NdbOut flexTimedAsynchNdbOut;
flexTimedAsynchErrorData = new ErrorData;
flexTimedAsynchErrorData->resetErrorCounters();
Ndb* pNdb;
pNdb = new Ndb( "TEST_DB" );
pNdb->init();
readArguments(argc, argv);
createAttributeSpace();
ndbout << endl << "FLEXTIMEDASYNCH - Starting normal mode" << endl;
ndbout << "Perform benchmark of insert, update and delete transactions" << endl << endl;
if(theTempFlag == 0)
ndbout << " " << "Using temporary tables. " << endl;
// -t, tNoOfThreads
ndbout << " " << tNoOfThreads << " number of concurrent threads " << endl;
// -c, tNoOfOpsPerTrans
ndbout << " " << tNoOfOpsPerTrans << " operations per transaction " << endl;
// -p, tNoOfTransInBatch
ndbout << " " << tNoOfTransInBatch << " number of transactions in a batch per thread " << endl;
// -o, tNoOfBatchesInLoop
ndbout << " " << tNoOfBatchesInLoop << " number of batches per loop " << endl;
// -i, tTimeBetweenBatches
ndbout << " " << tTimeBetweenBatches << " milli seconds at least between batch starts " << endl;
// -l, tNoOfLoops
ndbout << " " << tNoOfLoops << " loops " << endl;
// -a, tNoOfAttributes
ndbout << " " << tNoOfAttributes << " attributes per table " << endl;
// -s, tAttributeSize
ndbout << " " << tAttributeSize << " is the number of 32 bit words per attribute " << endl << endl;
NdbThread_SetConcurrencyLevel(2 + tNoOfThreads);
/* print Setting */
flexTimedAsynchErrorData->printSettings(ndbout);
setAttrNames();
setTableNames();
ndbout << "Waiting for ndb to become ready..." <<endl;
if (pNdb->waitUntilReady() == 0) {
tNodeId = pNdb->getNodeId();
ndbout << " NdbAPI node with id = " << tNodeId << endl;
createTables(pNdb);
/****************************************************************
* Create NDB objects. *
****************************************************************/
resetThreads();
for (int i = 0; i < tNoOfThreads ; i++) {
tabThread[i].ThreadNo = i;
threadLife[i] = NdbThread_Create(threadLoop,
(void**)&tabThread[i],
32768,
"flexTimedAsynchThread",
NDB_THREAD_PRIO_LOW);
}
ndbout << endl << "All NDB objects and table created" << endl << endl;
int noOfTransacts = tNoOfTransInBatch*tNoOfBatchesInLoop*tNoOfThreads;
/****************************************************************
* Execute program. *
****************************************************************/
for(;;) {
int loopCount = tLoops + 1 ;
ndbout << endl << "Loop # " << loopCount << endl << endl ;
/****************************************************************
* Perform inserts. *
****************************************************************/
failed = 0 ;
START_TIMER;
execute(stInsert);
STOP_TIMER;
PRINT_TIMER("insert", noOfTransacts, tNoOfOpsPerTrans);
if (0 < failed) {
ndbout << failed << " of the transactions returned errors!, moving on now..."<<endl ;
}
/****************************************************************
* Perform read. *
****************************************************************/
failed = 0 ;
START_TIMER;
execute(stRead);
STOP_TIMER;
PRINT_TIMER("read", noOfTransacts, tNoOfOpsPerTrans);
if (0 < failed) {
ndbout << failed << " of the transactions returned errors!, moving on now..."<<endl ;
}
/****************************************************************
* Perform update. *
***************************************************************/
failed = 0 ;
START_TIMER;
execute(stUpdate);
STOP_TIMER;
PRINT_TIMER("update", noOfTransacts, tNoOfOpsPerTrans) ;
if (0 < failed) {
ndbout << failed << " of the transactions returned errors!, moving on now..."<<endl ;
}
/****************************************************************
* Perform read after update.
****************************************************************/
failed = 0 ;
START_TIMER;
execute(stRead);
STOP_TIMER;
PRINT_TIMER("read", noOfTransacts, tNoOfOpsPerTrans);
if (0 < failed) {
ndbout << failed << " of the transactions returned errors!, moving on now..."<<endl ;
}
/****************************************************************
* Perform delete. *
****************************************************************/
failed = 0;
START_TIMER;
execute(stDelete);
STOP_TIMER;
PRINT_TIMER("delete", noOfTransacts, tNoOfOpsPerTrans);
if (0 < failed) {
ndbout << failed << " of the transactions returned errors!, moving on now..."<<endl ;
}
tLoops++;
ndbout << "--------------------------------------------------" << endl;
if(tNoOfLoops != 0){
if(tNoOfLoops <= tLoops)
break ;
}
}
ndbout << endl << "Benchmark completed!" << endl;
returnValue = NDBT_OK;
execute(stStop);
void * tmp;
for(int i = 0; i<tNoOfThreads; i++){
NdbThread_WaitFor(threadLife[i], &tmp);
NdbThread_Destroy(&threadLife[i]);
}
} else {
ndbout << "NDB is not ready" << endl;
ndbout << "Benchmark failed!" << endl;
returnValue = NDBT_FAILED;
}
deleteAttributeSpace();
delete pNdb;
//printing errorCounters
flexTimedAsynchErrorData->printErrorCounters(ndbout);
return NDBT_ProgramExit(returnValue);
}//main()
////////////////////////////////////////
void execute(StartType aType)
{
resetThreads();
tellThreads(aType);
waitForThreads();
}
void*
threadLoop(void* ThreadData)
{
// Do work until signaled to stop.
Ndb* localNdb;
StartType tType;
ThreadNdb* threadInfo = (ThreadNdb*)ThreadData;
int threadNo = threadInfo->ThreadNo;
localNdb = new Ndb("TEST_DB");
localNdb->init(512);
localNdb->waitUntilReady();
threadInfo->threadBase = (threadNo * 2000000) + (tNodeId * 260000000);
for (;;) {
while (ThreadStart[threadNo] == stIdle) {
NdbSleep_MilliSleep(10);
}
// Check if signal to exit is received
if (ThreadStart[threadNo] == stStop) {
break;
}
tType = ThreadStart[threadNo];
ThreadStart[threadNo] = stIdle;
executeThread(tType, localNdb, threadInfo);
ThreadReady[threadNo] = 1;
}
delete localNdb;
ThreadReady[threadNo] = 1;
return NULL; // thread exits
}
void executeThread(StartType aType, Ndb* aNdbObject, ThreadNdb* threadInfo)
{
// Do all batch job in loop with start specified delay
int i, j, k;
NdbConnection* tConArray[1024];
unsigned int tBase;
unsigned int tBase2;
int threadId = threadInfo->ThreadNo;
int *getValueRowAddress = NULL;
NdbTimer timer;
timer.doStart();
for (i = 0; i < tNoOfBatchesInLoop; i++) {
//tBase = threadBase + (i * tNoOfTransInBatch * tNoOfOpsPerTrans);
tBase = threadInfo->threadBase + (i * tNoOfTransInBatch * tNoOfOpsPerTrans);
//tCompleted = 0;
threadInfo->transactionCompleted = 0;
for (j = 0; j < tNoOfTransInBatch; j++) {
tBase2 = tBase + (j * tNoOfOpsPerTrans);
tConArray[j] = aNdbObject->startTransaction();
if ( tConArray[j] == NULL && !error_handler(aNdbObject->getNdbError())) {
ndbout << endl << "Unable to recover! Quiting now" << endl ;
exit (-1) ;
return ;
}
for (k = 0; k < tNoOfOpsPerTrans; k++) {
//-------------------------------------------------------
// Define the operation, but do not execute it yet.
//-------------------------------------------------------
if(aType == stRead){
getValueRowAddress = getAttrValueTable +
threadId * tNoOfAttributes * tAttributeSize;
}
defineOperation(tConArray[j], aType, (tBase2 + k), getValueRowAddress);
}
tConArray[j]->executeAsynchPrepare(Commit, &executeCallback, threadInfo);
}
//-------------------------------------------------------
// Now we have defined a set of transactions (= batch), it is now time
// to execute all of them.
//-------------------------------------------------------
aNdbObject->sendPollNdb(3000, 0, 0);
//while (tCompleted < tNoOfTransInBatch) {
while (threadInfo->transactionCompleted < tNoOfTransInBatch) {
aNdbObject->pollNdb(3000, 0);
ndbout << "threadInfo->transactionCompleted = " <<
threadInfo->transactionCompleted << endl;
}
for (j = 0 ; j < tNoOfTransInBatch ; j++) {
aNdbObject->closeTransaction(tConArray[j]);
}
// Control the elapsed time since the last batch start.
// Wait at least tTimeBetweenBatches milli seconds.
timer.doStop();
while(timer.elapsedTime() < tTimeBetweenBatches){
NdbSleep_MilliSleep(1);
timer.doStop();
}
// Ready to start new batch
timer.doStart();
}
return;
}
void
executeCallback(int result, NdbConnection* NdbObject, void* aObject)
{
//tCompleted++;
ThreadNdb *threadInfo = (ThreadNdb *)aObject;
threadInfo->transactionCompleted++;
if (result == -1) {
// Add complete error handling here
int retCode = flexTimedAsynchErrorData->handleErrorCommon(NdbObject->getNdbError());
if (retCode == 1) {
if (NdbObject->getNdbError().code != 626 && NdbObject->getNdbError().code != 630){
ndbout_c("execute: %s", NdbObject->getNdbError().message);
ndbout_c("Error code = %d", NdbObject->getNdbError().code);}
} else if (retCode == 2) {
ndbout << "4115 should not happen in flexAsynch" << endl;
} else if (retCode == 3) {
/* What can we do here? */
ndbout_c("execute: %s", NdbObject->getNdbError().message);
}//if(retCode == 3)
// ndbout << "Error occured in poll:" << NdbObject->getNdbError() <<
// " ErrorCode = " << NdbObject->getNdbError() << endl;
ndbout << "executeCallback threadInfo->transactionCompleted = " <<
threadInfo->transactionCompleted << endl;
failed++ ;
return;
}
return;
}
void
defineOperation(NdbConnection* localNdbConnection,
StartType aType,
unsigned int threadBase,
int *pRow )
{
NdbOperation* localNdbOperation;
unsigned int loopCountAttributes = tNoOfAttributes;
unsigned int countAttributes;
int attrValue[MAXATTRSIZE];
//-------------------------------------------------------
// Set-up the attribute values for this operation.
//-------------------------------------------------------
for (int k = 0; k < loopCountAttributes; k++) {
*(int *)&attrValue[k] = (int)threadBase;
}
localNdbOperation = localNdbConnection->getNdbOperation(tableName[0]);
if (localNdbOperation == NULL) {
error_handler(localNdbOperation->getNdbError()) ;
}
switch (aType) {
case stInsert: { // Insert case
if (theWriteFlag == 1 && theDirtyFlag == 1) {
localNdbOperation->dirtyWrite();
} else if (theWriteFlag == 1) {
localNdbOperation->writeTuple();
} else {
localNdbOperation->insertTuple();
}
break;
}
case stRead: { // Read Case
if (theSimpleFlag == 1) {
localNdbOperation->simpleRead();
} else if (theDirtyFlag == 1) {
localNdbOperation->dirtyRead();
} else {
localNdbOperation->readTuple();
}
break;
}
case stUpdate: { // Update Case
if (theWriteFlag == 1 && theDirtyFlag == 1) {
localNdbOperation->dirtyWrite();
} else if (theWriteFlag == 1) {
localNdbOperation->writeTuple();
} else if (theDirtyFlag == 1) {
localNdbOperation->dirtyUpdate();
} else {
localNdbOperation->updateTuple();
}
break;
}
case stDelete: { // Delete Case
localNdbOperation->deleteTuple();
break;
}
default: {
error_handler(localNdbOperation->getNdbError());
}
}
localNdbOperation->equal((char*)attrName[0],(char*)&attrValue[0]);
switch (aType) {
case stInsert: // Insert case
case stUpdate: // Update Case
{
for (countAttributes = 1; countAttributes < loopCountAttributes; countAttributes++) {
localNdbOperation->setValue( (char*)attrName[countAttributes],(char*)&attrValue[0]);
}
break;
}
case stRead: { // Read Case
for (countAttributes = 1; countAttributes < loopCountAttributes; countAttributes++) {
//localNdbOperation->getValue((char*)attrName[countAttributes],(char*)&attrValue[0]);
localNdbOperation->getValue((char*)attrName[countAttributes],
(char *) (pRow + countAttributes*tAttributeSize));
}
break;
}
case stDelete: { // Delete Case
break;
}
default: {
error_handler(localNdbOperation->getNdbError());
}
}
return;
}
void readArguments(int argc, const char** argv)
{
int i = 1;
while (argc > 1)
{
if (strcmp(argv[i], "-t") == 0)
{
tNoOfThreads = atoi(argv[i+1]);
// if ((tNoOfThreads < 1) || (tNoOfThreads > NDB_MAXTHREADS))
if ((tNoOfThreads < 1) || (tNoOfThreads > NDB_MAXTHREADS))
exit(-1);
}
else if (strcmp(argv[i], "-i") == 0)
{
tTimeBetweenBatches = atoi(argv[i+1]);
if (tTimeBetweenBatches < 0)
exit(-1);
}
else if (strcmp(argv[i], "-p") == 0)
{
tNoOfTransInBatch = atoi(argv[i+1]);
//if ((tNoOfTransInBatch < 1) || (tNoOfTransInBatch > NDB_MAXTHREADS))
if ((tNoOfTransInBatch < 1) || (tNoOfTransInBatch > 10000))
exit(-1);
}
else if (strcmp(argv[i], "-c") == 0)
{
tNoOfOpsPerTrans = atoi(argv[i+1]);
if (tNoOfOpsPerTrans < 1)
exit(-1);
}
else if (strcmp(argv[i], "-o") == 0)
{
tNoOfBatchesInLoop = atoi(argv[i+1]);
if (tNoOfBatchesInLoop < 1)
exit(-1);
}
else if (strcmp(argv[i], "-a") == 0)
{
tNoOfAttributes = atoi(argv[i+1]);
if ((tNoOfAttributes < 2) || (tNoOfAttributes > MAXATTR))
exit(-1);
}
else if (strcmp(argv[i], "-n") == 0)
{
theStdTableNameFlag = 1;
argc++;
i--;
}
else if (strcmp(argv[i], "-l") == 0)
{
tNoOfLoops = atoi(argv[i+1]);
if ((tNoOfLoops < 0) || (tNoOfLoops > 100000))
exit(-1);
}
else if (strcmp(argv[i], "-s") == 0)
{
tAttributeSize = atoi(argv[i+1]);
if ((tAttributeSize < 1) || (tAttributeSize > MAXATTRSIZE))
exit(-1);
}
else if (strcmp(argv[i], "-simple") == 0)
{
theSimpleFlag = 1;
argc++;
i--;
}
else if (strcmp(argv[i], "-write") == 0)
{
theWriteFlag = 1;
argc++;
i--;
}
else if (strcmp(argv[i], "-dirty") == 0)
{
theDirtyFlag = 1;
argc++;
i--;
}
else if (strcmp(argv[i], "-test") == 0)
{
theTestFlag = 1;
argc++;
i--;
}
else if (strcmp(argv[i], "-temp") == 0)
{
theTempFlag = 0; // 0 if temporary tables.
argc++;
i--;
}
else if (strcmp(argv[i], "-no_table_create") == 0)
{
theTableCreateFlag = 1;
argc++;
i--;
}
else
{
ndbout << "Arguments: " << endl;
ndbout << "-t Number of threads to start, i.e., number of parallel loops, default 1 " << endl;
ndbout << "-p Number of transactions in a batch, default 32 " << endl;
ndbout << "-o Number of batches per loop, default 200 " << endl;
ndbout << "-i Minimum time between batch starts in milli seconds, default 0 " << endl;
ndbout << "-l Number of loops to run, default 1, 0=infinite " << endl;
ndbout << "-a Number of attributes, default 25 " << endl;
ndbout << "-c Number of operations per transaction, default 1 " << endl;
ndbout << "-s Size of each attribute in 32 bit word, default 1"
"(Primary Key is always of size 1, independent of this value) " << endl;
ndbout << "-simple Use simple read to read from database " << endl;
ndbout << "-dirty Use dirty read to read from database " << endl;
ndbout << "-write Use writeTuple in insert and update " << endl;
ndbout << "-n Use standard table names " << endl;
ndbout << "-no_table_create Don't create tables in db " << endl;
ndbout << "-temp Use temporary tables, no writing to disk. " << endl;
exit(-1);
}
argc -= 2;
i = i + 2;
}
}
void setAttrNames()
{
int i;
for (i = 0; i < MAXATTR ; i++)
{
sprintf(attrName[i], "COL%d", i);
}
}
void setTableNames()
{
// Note! Uses only uppercase letters in table name's
// so that we can look at the tables with SQL
int i;
for (i = 0; i < MAXTABLES ; i++)
{
if (theStdTableNameFlag==1)
{
sprintf(tableName[i], "TAB%d_%d", tNoOfAttributes,
NdbTick_CurrentMillisecond()/1000);
} else {
sprintf(tableName[i], "TAB%d_%d", tNoOfAttributes, tAttributeSize*4);
}
}
}
void createTables(Ndb* pMyNdb)
{
NdbSchemaCon *MySchemaTransaction;
NdbSchemaOp *MySchemaOp;
int check;
if (theTableCreateFlag == 0)
{
for(int i=0; i < 1 ;i++)
{
ndbout << "Creating " << tableName[i] << "..." << endl;
MySchemaTransaction = pMyNdb->startSchemaTransaction();
if( MySchemaTransaction ==
NULL && (!error_handler(MySchemaTransaction->getNdbError())))
exit(-1) ;/*goto error_handler; <epaulsa*/
MySchemaOp = MySchemaTransaction->getNdbSchemaOp();
if( MySchemaOp == NULL
&& (!error_handler(MySchemaTransaction->getNdbError())))
exit(-1) ;
check = MySchemaOp->createTable( tableName[i],
8, // Table Size
TupleKey, // Key Type
40, // Nr of Pages
All, // FragmentType
6,
78,
80,
1, // MemoryType
theTempFlag // 0 if temporary tables else 1
);
if ( check == -1 && (!error_handler(MySchemaTransaction->getNdbError())))
exit(-1) ; /* epaulsa > goto error_handler; < epaulsa */
check = MySchemaOp->createAttribute( (char*)attrName[0],
TupleKey,
32,
PKSIZE,
UnSigned,
MMBased,
NotNullAttribute );
if ( check == -1 &&(!error_handler(MySchemaTransaction->getNdbError())))
exit(-1) ; /* epaulsa > goto error_handler; < epaulsa */
for (int j = 1; j < tNoOfAttributes ; j++)
{
check = MySchemaOp->createAttribute( (char*)attrName[j],
NoKey,
32,
tAttributeSize,
UnSigned,
MMBased,
NotNullAttribute );
if ( check == -1
&& (!error_handler(MySchemaTransaction->getNdbError())))
exit(-1) ; /* epaulsa > goto error_handler; < epaulsa */
}
if ( MySchemaTransaction->execute() == -1
&&(!error_handler(MySchemaTransaction->getNdbError())))
exit(-1) ; /* epaulsa > goto error_handler; < epaulsa */
pMyNdb->closeSchemaTransaction(MySchemaTransaction);
}
}
return;
}
bool error_handler(const NdbError & err) {
ndbout << err << endl ;
if ( 4008==err.code || 721==err.code || 266==err.code ){
ndbout << endl << "Attempting to recover and continue now..." << endl ;
return true ; // return true to retry
}
return false ; // return false to abort
}
//*******************************************************************************************