summaryrefslogtreecommitdiff
path: root/storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator
diff options
context:
space:
mode:
Diffstat (limited to 'storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator')
-rw-r--r--storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/Makefile17
-rw-r--r--storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.c543
-rw-r--r--storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.h61
-rw-r--r--storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/mainGenerator.c323
4 files changed, 944 insertions, 0 deletions
diff --git a/storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/Makefile b/storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/Makefile
new file mode 100644
index 00000000000..143d9ba655e
--- /dev/null
+++ b/storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/Makefile
@@ -0,0 +1,17 @@
+include .defs.mk
+
+TYPE := ndbapitest
+
+SOURCES = mainGenerator.c dbGenerator.c
+
+CCFLAGS_LOC := -I../include -I../../include
+
+OBJECTS = \
+ mainGenerator.o\
+ dbGenerator.o
+
+BIN_TARGET := DbGenerator
+BIN_TARGET_ARCHIVES := lmc_User
+
+include $(NDB_TOP)/Epilogue.mk
+
diff --git a/storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.c b/storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.c
new file mode 100644
index 00000000000..7484c7647f5
--- /dev/null
+++ b/storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.c
@@ -0,0 +1,543 @@
+/* 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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 */
+
+/***************************************************************
+* I N C L U D E D F I L E S *
+***************************************************************/
+
+#include <ndb_global.h>
+#include "dbGenerator.h"
+
+/***************************************************************
+* L O C A L C O N S T A N T S *
+***************************************************************/
+
+/***************************************************************
+* L O C A L D A T A S T R U C T U R E S *
+***************************************************************/
+
+/***************************************************************
+* L O C A L F U N C T I O N S *
+***************************************************************/
+
+static void getRandomSubscriberNumber(SubscriberNumber number);
+static void getRandomServerId(ServerId *serverId);
+static void getRandomChangedBy(ChangedBy changedBy);
+static void getRandomChangedTime(ChangedTime changedTime);
+
+static void clearTransaction(TransactionDefinition *trans);
+static void initGeneratorStatistics(GeneratorStatistics *gen);
+
+static void doOneTransaction(UserHandle *uh, GeneratorStatistics *gen);
+static void doTransaction_T1(UserHandle *uh, GeneratorStatistics *gen);
+static void doTransaction_T2(UserHandle *uh, GeneratorStatistics *gen);
+static void doTransaction_T3(UserHandle *uh, GeneratorStatistics *gen);
+static void doTransaction_T4(UserHandle *uh, GeneratorStatistics *gen);
+static void doTransaction_T5(UserHandle *uh, GeneratorStatistics *gen);
+
+/***************************************************************
+* L O C A L D A T A *
+***************************************************************/
+
+static SequenceValues transactionDefinition[] = {
+ {25, 1},
+ {25, 2},
+ {20, 3},
+ {15, 4},
+ {15, 5},
+ {0, 0}
+};
+
+static SequenceValues rollbackDefinition[] = {
+ {98, 0},
+ {2 , 1},
+ {0, 0}
+};
+
+static int maxsize = 0;
+
+/***************************************************************
+* P U B L I C D A T A *
+***************************************************************/
+
+/***************************************************************
+****************************************************************
+* L O C A L F U N C T I O N S C O D E S E C T I O N *
+****************************************************************
+***************************************************************/
+
+static void getRandomSubscriberNumber(SubscriberNumber number)
+{
+ uint32 tmp;
+ char sbuf[SUBSCRIBER_NUMBER_LENGTH + 1];
+ tmp = myRandom48(NO_OF_SUBSCRIBERS);
+ sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_LENGTH, tmp);
+ memcpy(number, sbuf, SUBSCRIBER_NUMBER_LENGTH);
+}
+
+static void getRandomServerId(ServerId *serverId)
+{
+ *serverId = myRandom48(NO_OF_SERVERS);
+}
+
+static void getRandomChangedBy(ChangedBy changedBy)
+{
+ memset(changedBy, myRandom48(26)+'A', CHANGED_BY_LENGTH);
+ changedBy[CHANGED_BY_LENGTH] = 0;
+}
+
+static void getRandomChangedTime(ChangedTime changedTime)
+{
+ memset(changedTime, myRandom48(26)+'A', CHANGED_TIME_LENGTH);
+ changedTime[CHANGED_TIME_LENGTH] = 0;
+}
+
+static void clearTransaction(TransactionDefinition *trans)
+{
+ trans->benchTime = 0.0;
+ trans->count = 0;
+ trans->branchExecuted = 0;
+ trans->rollbackExecuted = 0;
+}
+
+static int listFull(SessionList *list)
+{
+ return(list->numberInList == SESSION_LIST_LENGTH);
+}
+
+static int listEmpty(SessionList *list)
+{
+ return(list->numberInList == 0);
+}
+
+static void insertSession(SessionList *list,
+ SubscriberNumber number,
+ ServerId serverId)
+{
+ SessionElement *e;
+ if( listFull(list) ) return;
+
+ e = &list->list[list->writeIndex];
+
+ strcpy(e->subscriberNumber, number);
+ e->serverId = serverId;
+
+ list->writeIndex = (list->writeIndex + 1) % SESSION_LIST_LENGTH;
+ list->numberInList++;
+
+if( list->numberInList > maxsize )
+maxsize = list->numberInList;
+}
+
+static SessionElement *getNextSession(SessionList *list)
+{
+ if( listEmpty(list) ) return(0);
+
+ return(&list->list[list->readIndex]);
+}
+
+static void deleteSession(SessionList *list)
+{
+ if( listEmpty(list) ) return;
+
+ list->readIndex = (list->readIndex + 1) % SESSION_LIST_LENGTH;
+ list->numberInList--;
+}
+
+static void initGeneratorStatistics(GeneratorStatistics *gen)
+{
+ int i;
+
+ if( initSequence(&gen->transactionSequence,
+ transactionDefinition) != 0 ) {
+ printf("could not set the transaction types\n");
+ exit(0);
+ }
+
+ if( initSequence(&gen->rollbackSequenceT4,
+ rollbackDefinition) != 0 ) {
+ printf("could not set the rollback sequence\n");
+ exit(0);
+ }
+
+ if( initSequence(&gen->rollbackSequenceT5,
+ rollbackDefinition) != 0 ) {
+ printf("could not set the rollback sequence\n");
+ exit(0);
+ }
+
+ for(i = 0; i < NUM_TRANSACTION_TYPES; i++ )
+ clearTransaction(&gen->transactions[i]);
+
+ gen->totalTransactions = 0;
+
+ gen->activeSessions.numberInList = 0;
+ gen->activeSessions.readIndex = 0;
+ gen->activeSessions.writeIndex = 0;
+}
+
+
+static void doOneTransaction(UserHandle *uh, GeneratorStatistics *gen)
+{
+ unsigned int transactionType;
+
+ transactionType = getNextRandom(&gen->transactionSequence);
+
+ switch(transactionType) {
+ case 1:
+ doTransaction_T1(uh, gen);
+ break;
+ case 2:
+ doTransaction_T2(uh, gen);
+ break;
+ case 3:
+ doTransaction_T3(uh, gen);
+ break;
+ case 4:
+ doTransaction_T4(uh, gen);
+ break;
+ case 5:
+ doTransaction_T5(uh, gen);
+ break;
+ default:
+ printf("Unknown transaction type: %d\n", transactionType);
+ }
+
+ gen->totalTransactions++;
+}
+
+static void doTransaction_T1(UserHandle *uh, GeneratorStatistics *gen)
+{
+ SubscriberNumber number;
+ Location new_location;
+ ChangedBy changed_by;
+ ChangedTime changed_time;
+
+ double start_time;
+ double end_time;
+ double transaction_time;
+
+ unsigned int tid = 0;
+
+ /*----------------*/
+ /* Init arguments */
+ /*----------------*/
+ getRandomSubscriberNumber(number);
+ getRandomChangedBy(changed_by);
+ getRandomChangedTime(changed_time);
+ new_location = changed_by[0];
+
+ /*-----------------*/
+ /* Run transaction */
+ /*-----------------*/
+ start_time = userGetTimeSync();
+ userTransaction_T1(uh,
+ number,
+ new_location,
+ changed_by,
+ changed_time);
+ end_time = userGetTimeSync();
+
+ /*-------------------*/
+ /* Update Statistics */
+ /*-------------------*/
+ transaction_time = end_time - start_time;
+ gen->transactions[tid].benchTime += transaction_time;
+ gen->transactions[tid].count++;
+}
+
+static void doTransaction_T2(UserHandle *uh, GeneratorStatistics *gen)
+{
+ SubscriberNumber number;
+ Location new_location;
+ ChangedBy changed_by;
+ ChangedTime changed_time;
+ SubscriberName subscriberName;
+
+ double start_time;
+ double end_time;
+ double transaction_time;
+
+ unsigned int tid = 1;
+
+ /*----------------*/
+ /* Init arguments */
+ /*----------------*/
+ getRandomSubscriberNumber(number);
+
+ /*-----------------*/
+ /* Run transaction */
+ /*-----------------*/
+ start_time = userGetTimeSync();
+ userTransaction_T2(uh,
+ number,
+ &new_location,
+ changed_by,
+ changed_time,
+ subscriberName);
+ end_time = userGetTimeSync();
+
+ /*-------------------*/
+ /* Update Statistics */
+ /*-------------------*/
+ transaction_time = end_time - start_time;
+ gen->transactions[tid].benchTime += transaction_time;
+ gen->transactions[tid].count++;
+}
+
+static void doTransaction_T3(UserHandle *uh, GeneratorStatistics *gen)
+{
+ SubscriberNumber number;
+ ServerId serverId;
+ ServerBit serverBit;
+ SessionDetails sessionDetails;
+ unsigned int branchExecuted;
+ SessionElement *se;
+
+ double start_time;
+ double end_time;
+ double transaction_time;
+
+ unsigned int tid = 2;
+
+ /*----------------*/
+ /* Init arguments */
+ /*----------------*/
+ se = getNextSession(&gen->activeSessions);
+ if( se ) {
+ strcpy(number, se->subscriberNumber);
+ serverId = se->serverId;
+ }
+ else {
+ getRandomSubscriberNumber(number);
+ getRandomServerId(&serverId);
+ }
+
+ serverBit = 1 << serverId;
+
+ /*-----------------*/
+ /* Run transaction */
+ /*-----------------*/
+ start_time = userGetTimeSync();
+ userTransaction_T3(uh,
+ number,
+ serverId,
+ serverBit,
+ sessionDetails,
+ &branchExecuted);
+ end_time = userGetTimeSync();
+
+ /*-------------------*/
+ /* Update Statistics */
+ /*-------------------*/
+ transaction_time = end_time - start_time;
+ gen->transactions[tid].benchTime += transaction_time;
+ gen->transactions[tid].count++;
+
+ if(branchExecuted)
+ gen->transactions[tid].branchExecuted++;
+}
+
+static void doTransaction_T4(UserHandle *uh, GeneratorStatistics *gen)
+{
+ SubscriberNumber number;
+ ServerId serverId;
+ ServerBit serverBit;
+ SessionDetails sessionDetails;
+ unsigned int branchExecuted;
+ unsigned int rollback;
+
+ double start_time;
+ double end_time;
+ double transaction_time;
+
+ unsigned int tid = 3;
+
+ /*----------------*/
+ /* Init arguments */
+ /*----------------*/
+ getRandomSubscriberNumber(number);
+ getRandomServerId(&serverId);
+
+ serverBit = 1 << serverId;
+ rollback = getNextRandom(&gen->rollbackSequenceT4);
+
+ memset(sessionDetails, myRandom48(26)+'A', SESSION_DETAILS_LENGTH);
+ sessionDetails[SESSION_DETAILS_LENGTH] = 0;
+
+ /*-----------------*/
+ /* Run transaction */
+ /*-----------------*/
+ start_time = userGetTimeSync();
+ userTransaction_T4(uh,
+ number,
+ serverId,
+ serverBit,
+ sessionDetails,
+ rollback,
+ &branchExecuted);
+ end_time = userGetTimeSync();
+
+ /*-------------------*/
+ /* Update Statistics */
+ /*-------------------*/
+ transaction_time = end_time - start_time;
+ gen->transactions[tid].benchTime += transaction_time;
+ gen->transactions[tid].count++;
+
+ if(branchExecuted)
+ gen->transactions[tid].branchExecuted++;
+ if(rollback)
+ gen->transactions[tid].rollbackExecuted++;
+
+ if( branchExecuted && !rollback ) {
+ insertSession(&gen->activeSessions, number, serverId);
+ }
+}
+
+static void doTransaction_T5(UserHandle *uh, GeneratorStatistics *gen)
+{
+ SubscriberNumber number;
+ ServerId serverId;
+ ServerBit serverBit;
+ unsigned int branchExecuted;
+ unsigned int rollback;
+ SessionElement *se;
+
+ double start_time;
+ double end_time;
+ double transaction_time;
+
+ unsigned int tid = 4;
+
+ /*----------------*/
+ /* Init arguments */
+ /*----------------*/
+ se = getNextSession(&gen->activeSessions);
+ if( se ) {
+ strcpy(number, se->subscriberNumber);
+ serverId = se->serverId;
+ }
+ else {
+ getRandomSubscriberNumber(number);
+ getRandomServerId(&serverId);
+ }
+
+ serverBit = 1 << serverId;
+ rollback = getNextRandom(&gen->rollbackSequenceT5);
+
+ /*-----------------*/
+ /* Run transaction */
+ /*-----------------*/
+ start_time = userGetTimeSync();
+ userTransaction_T5(uh,
+ number,
+ serverId,
+ serverBit,
+ rollback,
+ &branchExecuted);
+ end_time = userGetTimeSync();
+
+ /*-------------------*/
+ /* Update Statistics */
+ /*-------------------*/
+ transaction_time = end_time - start_time;
+ gen->transactions[tid].benchTime += transaction_time;
+ gen->transactions[tid].count++;
+
+ if(branchExecuted)
+ gen->transactions[tid].branchExecuted++;
+ if(rollback)
+ gen->transactions[tid].rollbackExecuted++;
+
+ if( se && !rollback) {
+ deleteSession(&gen->activeSessions);
+ }
+}
+
+/***************************************************************
+****************************************************************
+* P U B L I C F U N C T I O N S C O D E S E C T I O N *
+****************************************************************
+***************************************************************/
+
+
+void dbGenerator(UserHandle *uh, ThreadData *data)
+{
+ GeneratorStatistics rg_warmUp;
+ GeneratorStatistics rg_coolDown;
+ GeneratorStatistics *st;
+ double periodStop;
+ double benchTimeStart;
+ double benchTimeEnd;
+ int i;
+
+ myRandom48Init(data->randomSeed);
+
+ initGeneratorStatistics(&rg_warmUp);
+ initGeneratorStatistics(&data->generator);
+ initGeneratorStatistics(&rg_coolDown);
+
+ /*----------------*/
+ /* warm up period */
+ /*----------------*/
+ periodStop = userGetTimeSync() + (double)data->warmUpSeconds;
+ while(userGetTimeSync() < periodStop){
+ doOneTransaction(uh, &rg_warmUp);
+ }
+
+ /*-------------------------*/
+ /* normal benchmark period */
+ /*-------------------------*/
+ benchTimeStart = userGetTimeSync();
+
+ if( data->numTransactions > 0 ) {
+ for(i = 0; i < data->numTransactions; i++)
+ doOneTransaction(uh, &data->generator);
+ }
+ else {
+ periodStop = benchTimeStart + (double)data->testSeconds;
+ while(userGetTimeSync() < periodStop)
+ doOneTransaction(uh, &data->generator);
+ }
+
+ benchTimeEnd = userGetTimeSync();
+
+ /*------------------*/
+ /* cool down period */
+ /*------------------*/
+ periodStop = benchTimeEnd + data->coolDownSeconds;
+ while(userGetTimeSync() < periodStop){
+ doOneTransaction(uh, &rg_coolDown);
+ }
+
+ /*---------------------------------------------------------*/
+ /* add the times for all transaction for inner loop timing */
+ /*---------------------------------------------------------*/
+ st = &data->generator;
+ st->innerLoopTime = 0.0;
+ for(i = 0 ; i < NUM_TRANSACTION_TYPES; i++) {
+ st->innerLoopTime += st->transactions[i].benchTime;
+ st->transactions[i].tps = getTps(st->transactions[i].count,
+ st->transactions[i].benchTime);
+ }
+
+ st->outerLoopTime = benchTimeEnd - benchTimeStart;
+ st->outerTps = getTps(st->totalTransactions, st->outerLoopTime);
+ st->innerTps = getTps(st->totalTransactions, st->innerLoopTime);
+
+ /* printf("maxsize = %d\n",maxsize); */
+}
diff --git a/storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.h b/storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.h
new file mode 100644
index 00000000000..824688b6cf9
--- /dev/null
+++ b/storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.h
@@ -0,0 +1,61 @@
+/* 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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 */
+
+#ifndef DBGENERATOR_H
+#define DBGENERATOR_H
+
+/***************************************************************
+* I N C L U D E D F I L E S *
+***************************************************************/
+
+#include "testData.h"
+#include "userInterface.h"
+
+/***************************************************************
+* M A C R O S *
+***************************************************************/
+
+/***************************************************************/
+/* C O N S T A N T S */
+/***************************************************************/
+
+/***************************************************************
+* D A T A S T R U C T U R E S *
+***************************************************************/
+
+/***************************************************************
+* P U B L I C F U N C T I O N S *
+***************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void dbGenerator(UserHandle *uh, ThreadData *data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/***************************************************************
+* E X T E R N A L D A T A *
+***************************************************************/
+
+
+
+#endif /* DBGENERATOR_H */
+
diff --git a/storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/mainGenerator.c b/storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/mainGenerator.c
new file mode 100644
index 00000000000..4a31db0b4e9
--- /dev/null
+++ b/storage/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/mainGenerator.c
@@ -0,0 +1,323 @@
+/* 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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 */
+
+#include <ndb_global.h>
+
+#include <NdbHost.h>
+#include <NdbSleep.h>
+#include <NdbThread.h>
+#include <NdbMain.h>
+
+#include "userInterface.h"
+#include "dbGenerator.h"
+
+
+static int numProcesses;
+static int numTransactions;
+static int numSeconds;
+static int numWarmSeconds;
+static char *testDbName;
+
+static ThreadData data[100];
+
+typedef struct {
+ pthread_t threadId;
+ int waitSeconds;
+ int toExit;
+}CheckpointData;
+
+static void usage(char *prog)
+{
+ char *progname;
+
+ /*--------------------------------------------*/
+ /* Get the name of the program (without path) */
+ /*--------------------------------------------*/
+ progname = strrchr(prog, '/');
+
+ if (progname == 0)
+ progname = prog;
+ else
+ ++progname;
+
+ fprintf(stderr,
+ "Usage: %s [-db <name>] [-proc <num>] [-transactions <num>] [-time <num>]\n"
+ " -db <name> Specifies the database name\n"
+ " default = '%s'\n"
+ " -proc <num> Specifies that <num> is the number of\n"
+ " concurrent processes. The default is 1.\n"
+ " -transactions <num> Specifies that <num> transactions will be\n"
+ " performed. The default is to do a specific time interval\n"
+ " -time <num> Specifies that the test will run for <num> sec.\n"
+ " The default is 10 sec\n"
+ " -warm <num> Specifies the warm-up/cooldown period of <num> sec.\n"
+ " The default is 10 sec\n",
+ progname, DEFAULTDB);
+ exit(1);
+}
+
+static void parse_args(int argc,char **argv)
+{
+ int i;
+
+ testDbName = DEFAULTDB;
+ numProcesses = 1;
+ numTransactions = 0;
+ numSeconds = 10;
+ numWarmSeconds = 10;
+
+ i = 1;
+ while (i < argc){
+ if (strcmp("-db",argv[i]) == 0) {
+ if (i + 1 >= argc) {
+ usage(argv[0]);
+ exit(1);
+ }
+ testDbName = argv[i + 1];
+ i += 2;
+ }
+ else if (strcmp("-proc",argv[i]) == 0) {
+ if (i + 1 >= argc) {
+ usage(argv[0]);
+ exit(1);
+ }
+ if (sscanf(argv[i+1], "%d", &numProcesses) == -1 ||
+ numProcesses <= 0 || numProcesses > 99) {
+ fprintf(stderr, "-proc flag requires a positive integer argument [1..99]\n");
+ usage(argv[0]);
+ exit(1);
+ }
+ i += 2;
+ }
+ else if (strcmp("-transactions",argv[i]) == 0) {
+ if (i + 1 >= argc) {
+ usage(argv[0]);
+ exit(1);
+ }
+ if (sscanf(argv[i+1], "%d", &numTransactions) == -1 ||
+ numTransactions < 0) {
+ fprintf(stderr, "-transactions flag requires a positive integer argument\n");
+ usage(argv[0]);
+ exit(1);
+ }
+ i += 2;
+ }
+ else if (strcmp("-time",argv[i]) == 0) {
+ if (i + 1 >= argc) {
+ usage(argv[0]);
+ exit(1);
+ }
+ if (sscanf(argv[i+1], "%d", &numSeconds) == -1 ||
+ numSeconds < 0) {
+ fprintf(stderr, "-time flag requires a positive integer argument\n");
+ usage(argv[0]);
+ exit(1);
+ }
+ i += 2;
+ }
+ else if (strcmp("-warm",argv[i]) == 0) {
+ if (i + 1 >= argc) {
+ usage(argv[0]);
+ exit(1);
+ }
+ if (sscanf(argv[i+1], "%d", &numWarmSeconds) == -1 ||
+ numWarmSeconds < 0) {
+ fprintf(stderr, "-warm flag requires a positive integer argument\n");
+ usage(argv[0]);
+ exit(1);
+ }
+ i += 2;
+ }
+ else
+ usage(argv[0]);
+ }
+}
+
+static void print_transaction(const char *header,
+ unsigned long totalCount,
+ TransactionDefinition *trans,
+ unsigned int printBranch,
+ unsigned int printRollback)
+{
+ double f;
+
+ printf(" %s: %d (%.2f%%) Time: %.4f sec TPS = %.0f\n",
+ header,
+ trans->count,
+ (double)trans->count / (double)totalCount * 100.0,
+ trans->benchTime,
+ trans->tps);
+
+ if( printBranch ){
+ if( trans->count == 0 )
+ f = 0.0;
+ else
+ f = (double)trans->branchExecuted / (double)trans->count * 100.0;
+ printf(" Branches Executed: %d (%.2f%%)\n", trans->branchExecuted, f);
+ }
+
+ if( printRollback ){
+ if( trans->count == 0 )
+ f = 0.0;
+ else
+ f = (double)trans->rollbackExecuted / (double)trans->count * 100.0;
+ printf(" Rollback Executed: %d (%.2f%%)\n", trans->rollbackExecuted, f);
+ }
+}
+
+void print_stats_sync(const char *title,
+ unsigned int length,
+ unsigned int transactionFlag,
+ GeneratorStatistics *gen,
+ int numProc)
+{
+ int i;
+ char buf[10];
+ char name[100];
+
+ name[0] = 0;
+ NdbHost_GetHostName(name);
+
+ printf("\n------ %s ------\n",title);
+ printf("Length : %d %s\n",
+ length,
+ transactionFlag ? "Transactions" : "sec");
+ printf("Processor : %s\n", name);
+ printf("Number of Proc: %d\n",numProc);
+ printf("\n");
+
+ if( gen->totalTransactions == 0 ) {
+ printf(" No Transactions for this test\n");
+ }
+ else {
+ for(i = 0; i < 5; i++) {
+ sprintf(buf, "T%d",i+1);
+ print_transaction(buf,
+ gen->totalTransactions,
+ &gen->transactions[i],
+ i >= 2,
+ i >= 3 );
+ }
+
+ printf("\n");
+ printf(" Overall Statistics:\n");
+ printf(" Transactions: %d\n", gen->totalTransactions);
+ printf(" Inner : %.0f TPS\n",gen->innerTps);
+ printf(" Outer : %.0f TPS\n",gen->outerTps);
+ printf("\n");
+ }
+}
+
+static void *threadRoutine(void *arg)
+{
+ UserHandle *uh;
+ ThreadData *data = (ThreadData *)arg;
+
+ uh = userDbConnect(0, testDbName);
+ NdbSleep_MilliSleep(data->threadId);
+ dbGenerator(uh,data);
+ userDbDisconnect(uh);
+
+ pthread_exit(0);
+ return(0);
+}
+
+NDB_COMMAND(DbGenerator, "DbGenerator", "DbGenerator", "DbGenerator", 16384)
+{
+ int i;
+ int j;
+ GeneratorStatistics stats;
+ GeneratorStatistics *p;
+ CheckpointData cd;
+
+ parse_args(argc,argv);
+
+ printf("\nStarting Test with %d process(es) for %d %s\n",
+ numProcesses,
+ numTransactions ? numTransactions : numSeconds,
+ numTransactions ? "Transactions" : "sec");
+ printf(" WarmUp/coolDown = %d sec\n", numWarmSeconds);
+
+ /*
+ cd.waitSeconds = 300;
+ cd.toExit = 0;
+ pthread_create(&cd.threadId, 0, checkpointRoutine, &cd);
+ */
+
+ for(i = 0; i < numProcesses; i++) {
+ data[i].warmUpSeconds = numWarmSeconds;
+ data[i].testSeconds = numSeconds;
+ data[i].coolDownSeconds = numWarmSeconds;
+ data[i].numTransactions = numTransactions;
+ data[i].randomSeed = time(0)+i;
+ j = pthread_create(&data[i].threadId, 0, threadRoutine, &data[i]);
+ if(j != 0){
+ perror("Failed to create thread");
+ }
+ }
+
+ /*--------------------------------*/
+ /* Wait for all processes to exit */
+ /*--------------------------------*/
+ for(i = 0; i < numProcesses; i++)
+ pthread_join(data[i].threadId, 0);
+
+ printf("All threads have finished\n");
+
+ cd.toExit = 1;
+
+ /*-------------------------------------------*/
+ /* Clear all structures for total statistics */
+ /*-------------------------------------------*/
+ stats.totalTransactions = 0;
+ stats.outerTps = 0.0;
+ stats.innerTps = 0.0;
+
+ for(i = 0; i < NUM_TRANSACTION_TYPES; i++ ) {
+ stats.transactions[i].benchTime = 0.0;
+ stats.transactions[i].count = 0;
+ stats.transactions[i].tps = 0.0;
+ stats.transactions[i].branchExecuted = 0;
+ stats.transactions[i].rollbackExecuted = 0;
+ }
+
+ /*--------------------------------*/
+ /* Add the values for all Threads */
+ /*--------------------------------*/
+ for(i = 0; i < numProcesses; i++) {
+ p = &data[i].generator;
+
+ stats.totalTransactions += p->totalTransactions;
+ stats.outerTps += p->outerTps;
+ stats.innerTps += p->innerTps;
+
+ for(j = 0; j < NUM_TRANSACTION_TYPES; j++ ) {
+ stats.transactions[j].benchTime += p->transactions[j].benchTime;
+ stats.transactions[j].count += p->transactions[j].count;
+ stats.transactions[j].tps += p->transactions[j].tps;
+ stats.transactions[j].branchExecuted += p->transactions[j].branchExecuted;
+ stats.transactions[j].rollbackExecuted += p->transactions[j].rollbackExecuted;
+ }
+ }
+
+ print_stats_sync("Test Results",
+ numTransactions ? numTransactions : numSeconds,
+ numTransactions ? 1 : 0,
+ &stats,
+ numProcesses);
+
+ return(0);
+}