From a47260fa9db98bbf80224bd2831603daab516e5b Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Wed, 9 Feb 2005 15:18:13 +0100 Subject: [PATCH 01/10] removed extra comma at end of enum. cause compile error with gcc-3.4.3 --- sql/sql_parse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8462066dcff..59c75ebb77b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1310,7 +1310,7 @@ enum enum_mysql_completiontype { SAVEPOINT_NAME_ROLLBACK=2, SAVEPOINT_NAME_RELEASE=4, COMMIT_AND_CHAIN=6, - ROLLBACK_AND_CHAIN=7, + ROLLBACK_AND_CHAIN=7 }; int mysql_endtrans(THD *thd, enum enum_mysql_completiontype completion, From 0e07d4b5df47acd498680932200b6a119edf5cff Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Wed, 9 Feb 2005 17:06:14 +0100 Subject: [PATCH 02/10] #ifdef innodb specific code (for those who compile --without-innodb :-) --- sql/sql_parse.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 59c75ebb77b..0a0258465fb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2234,7 +2234,9 @@ mysql_execute_command(THD *thd) /* Locked closure of all tables */ TABLE_LIST *locked_tables= NULL; /* Saved variable value */ +#ifdef HAVE_INNOBASE_DB my_bool old_innodb_table_locks= thd->variables.innodb_table_locks; +#endif DBUG_ENTER("mysql_execute_command"); /* @@ -2330,7 +2332,9 @@ mysql_execute_command(THD *thd) { if ((locked_tables= sp_hash_to_table_list(thd, &lex->sptabs))) { +#ifdef HAVE_INNOBASE_DB thd->variables.innodb_table_locks= FALSE; +#endif sp_open_and_lock_tables(thd, locked_tables); } } @@ -4346,7 +4350,9 @@ cleanup: if (locked_tables) { +#ifdef HAVE_INNOBASE_DB thd->variables.innodb_table_locks= old_innodb_table_locks; +#endif if (thd->locked_tables) sp_unlock_tables(thd); } From 216c44e4b95f0117b3c6685d7b6bcde3cd635a6b Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Thu, 10 Feb 2005 11:40:32 +0100 Subject: [PATCH 03/10] ndb - Reenable old benchmark --- ndb/test/ndbapi/Makefile.am | 5 +- ndb/test/ndbapi/bench/asyncGenerator.cpp | 571 ++++++++++++ ndb/test/ndbapi/bench/dbGenerator.h | 63 ++ ndb/test/ndbapi/bench/dbPopulate.cpp | 244 ++++++ ndb/test/ndbapi/bench/dbPopulate.h | 59 ++ ndb/test/ndbapi/bench/macros.h | 51 ++ ndb/test/ndbapi/bench/mainAsyncGenerator.cpp | 503 +++++++++++ ndb/test/ndbapi/bench/mainPopulate.cpp | 84 ++ ndb/test/ndbapi/bench/ndb_async1.cpp | 647 ++++++++++++++ ndb/test/ndbapi/bench/ndb_async2.cpp | 757 ++++++++++++++++ ndb/test/ndbapi/bench/ndb_error.hpp | 81 ++ ndb/test/ndbapi/bench/ndb_schema.hpp | 78 ++ .../ndbapi/bench/ndb_user_transaction.cpp | 825 ++++++++++++++++++ .../ndbapi/bench/ndb_user_transaction2.cpp | 825 ++++++++++++++++++ .../ndbapi/bench/ndb_user_transaction3.cpp | 793 +++++++++++++++++ .../ndbapi/bench/ndb_user_transaction4.cpp | 770 ++++++++++++++++ .../ndbapi/bench/ndb_user_transaction5.cpp | 769 ++++++++++++++++ .../ndbapi/bench/ndb_user_transaction6.cpp | 561 ++++++++++++ ndb/test/ndbapi/bench/testData.h | 156 ++++ ndb/test/ndbapi/bench/testDefinitions.h | 90 ++ ndb/test/ndbapi/bench/userInterface.cpp | 745 ++++++++++++++++ ndb/test/ndbapi/bench/userInterface.h | 151 ++++ 22 files changed, 8827 insertions(+), 1 deletion(-) create mode 100644 ndb/test/ndbapi/bench/asyncGenerator.cpp create mode 100644 ndb/test/ndbapi/bench/dbGenerator.h create mode 100644 ndb/test/ndbapi/bench/dbPopulate.cpp create mode 100644 ndb/test/ndbapi/bench/dbPopulate.h create mode 100644 ndb/test/ndbapi/bench/macros.h create mode 100644 ndb/test/ndbapi/bench/mainAsyncGenerator.cpp create mode 100644 ndb/test/ndbapi/bench/mainPopulate.cpp create mode 100644 ndb/test/ndbapi/bench/ndb_async1.cpp create mode 100644 ndb/test/ndbapi/bench/ndb_async2.cpp create mode 100644 ndb/test/ndbapi/bench/ndb_error.hpp create mode 100644 ndb/test/ndbapi/bench/ndb_schema.hpp create mode 100644 ndb/test/ndbapi/bench/ndb_user_transaction.cpp create mode 100644 ndb/test/ndbapi/bench/ndb_user_transaction2.cpp create mode 100644 ndb/test/ndbapi/bench/ndb_user_transaction3.cpp create mode 100644 ndb/test/ndbapi/bench/ndb_user_transaction4.cpp create mode 100644 ndb/test/ndbapi/bench/ndb_user_transaction5.cpp create mode 100644 ndb/test/ndbapi/bench/ndb_user_transaction6.cpp create mode 100644 ndb/test/ndbapi/bench/testData.h create mode 100644 ndb/test/ndbapi/bench/testDefinitions.h create mode 100644 ndb/test/ndbapi/bench/userInterface.cpp create mode 100644 ndb/test/ndbapi/bench/userInterface.h diff --git a/ndb/test/ndbapi/Makefile.am b/ndb/test/ndbapi/Makefile.am index 33744cc0f51..0c84db8c068 100644 --- a/ndb/test/ndbapi/Makefile.am +++ b/ndb/test/ndbapi/Makefile.am @@ -30,7 +30,8 @@ testSystemRestart \ testTimeout \ testTransactions \ testDeadlock \ -test_event ndbapi_slow_select testReadPerf testLcp +test_event ndbapi_slow_select testReadPerf testLcp \ +DbCreate DbAsyncGenerator #flexTimedAsynch #testBlobs @@ -69,6 +70,8 @@ test_event_SOURCES = test_event.cpp ndbapi_slow_select_SOURCES = slow_select.cpp testReadPerf_SOURCES = testReadPerf.cpp testLcp_SOURCES = testLcp.cpp +DbCreate_SOURCES= bench/mainPopulate.cpp bench/dbPopulate.cpp bench/userInterface.cpp +DbAsyncGenerator_SOURCES= bench/mainAsyncGenerator.cpp bench/asyncGenerator.cpp bench/ndb_async2.cpp INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel diff --git a/ndb/test/ndbapi/bench/asyncGenerator.cpp b/ndb/test/ndbapi/bench/asyncGenerator.cpp new file mode 100644 index 00000000000..d91e38dff1a --- /dev/null +++ b/ndb/test/ndbapi/bench/asyncGenerator.cpp @@ -0,0 +1,571 @@ +/* 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 + +#include "dbGenerator.h" +#include +#include +#include + +/*************************************************************** +* 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(ThreadData * td, + int parallellism, + int millisSendPoll, + int minEventSendPoll, + int forceSendPoll); +static void doTransaction_T1(Ndb * pNDB, ThreadData * td, int async); +static void doTransaction_T2(Ndb * pNDB, ThreadData * td, int async); +static void doTransaction_T3(Ndb * pNDB, ThreadData * td, int async); +static void doTransaction_T4(Ndb * pNDB, ThreadData * td, int async); +static void doTransaction_T5(Ndb * pNDB, ThreadData * td, int async); + +/*************************************************************** +* 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->count = 0; + trans->branchExecuted = 0; + trans->rollbackExecuted = 0; + trans->latencyCounter = myRandom48(127); + trans->latency.reset(); +} + +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 ) { + ndbout_c("could not set the transaction types"); + exit(0); + } + + if( initSequence(&gen->rollbackSequenceT4, + rollbackDefinition) != 0 ) { + ndbout_c("could not set the rollback sequence"); + exit(0); + } + + if( initSequence(&gen->rollbackSequenceT5, + rollbackDefinition) != 0 ) { + ndbout_c("could not set the rollback sequence"); + 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(ThreadData * td, int p, int millis, int minEvents, int force) +{ + int i; + unsigned int transactionType; + int async = 1; + if (p == 1) { + async = 0; + }//if + for(i = 0; isendPollNdb(millis, minEvents, force); + }//if +} + +static +void +doTransaction_T1(Ndb * pNDB, ThreadData * td, int async) +{ + /*----------------*/ + /* Init arguments */ + /*----------------*/ + getRandomSubscriberNumber(td->transactionData.number); + getRandomChangedBy(td->transactionData.changed_by); + BaseString::snprintf(td->transactionData.changed_time, + sizeof(td->transactionData.changed_time), + "%ld - %d", td->changedTime++, myRandom48(65536*1024)); + //getRandomChangedTime(td->transactionData.changed_time); + td->transactionData.location = td->transactionData.changed_by[0]; + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[0].startLatency(); + + start_T1(pNDB, td, async); +} + +static +void +doTransaction_T2(Ndb * pNDB, ThreadData * td, int async) +{ + /*----------------*/ + /* Init arguments */ + /*----------------*/ + getRandomSubscriberNumber(td->transactionData.number); + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[1].startLatency(); + + start_T2(pNDB, td, async); +} + +static +void +doTransaction_T3(Ndb * pNDB, ThreadData * td, int async) +{ + SessionElement *se; + + /*----------------*/ + /* Init arguments */ + /*----------------*/ + se = getNextSession(&td->generator.activeSessions); + if( se ) { + strcpy(td->transactionData.number, se->subscriberNumber); + td->transactionData.server_id = se->serverId; + td->transactionData.sessionElement = 1; + } else { + getRandomSubscriberNumber(td->transactionData.number); + getRandomServerId(&td->transactionData.server_id); + td->transactionData.sessionElement = 0; + } + + td->transactionData.server_bit = (1 << td->transactionData.server_id); + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[2].startLatency(); + start_T3(pNDB, td, async); +} + +static +void +doTransaction_T4(Ndb * pNDB, ThreadData * td, int async) +{ + /*----------------*/ + /* Init arguments */ + /*----------------*/ + getRandomSubscriberNumber(td->transactionData.number); + getRandomServerId(&td->transactionData.server_id); + + td->transactionData.server_bit = (1 << td->transactionData.server_id); + td->transactionData.do_rollback = + getNextRandom(&td->generator.rollbackSequenceT4); + +#if 0 + memset(td->transactionData.session_details, + myRandom48(26)+'A', SESSION_DETAILS_LENGTH); +#endif + td->transactionData.session_details[SESSION_DETAILS_LENGTH] = 0; + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[3].startLatency(); + start_T4(pNDB, td, async); +} + +static +void +doTransaction_T5(Ndb * pNDB, ThreadData * td, int async) +{ + SessionElement * se; + se = getNextSession(&td->generator.activeSessions); + if( se ) { + strcpy(td->transactionData.number, se->subscriberNumber); + td->transactionData.server_id = se->serverId; + td->transactionData.sessionElement = 1; + } + else { + getRandomSubscriberNumber(td->transactionData.number); + getRandomServerId(&td->transactionData.server_id); + td->transactionData.sessionElement = 0; + } + + td->transactionData.server_bit = (1 << td->transactionData.server_id); + td->transactionData.do_rollback + = getNextRandom(&td->generator.rollbackSequenceT5); + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[4].startLatency(); + start_T5(pNDB, td, async); +} + +void +complete_T1(ThreadData * data){ + data->generator.transactions[0].stopLatency(); + data->generator.transactions[0].count++; + + data->runState = Runnable; + data->generator.totalTransactions++; +} + +void +complete_T2(ThreadData * data){ + data->generator.transactions[1].stopLatency(); + data->generator.transactions[1].count++; + + data->runState = Runnable; + data->generator.totalTransactions++; +} + +void +complete_T3(ThreadData * data){ + + data->generator.transactions[2].stopLatency(); + data->generator.transactions[2].count++; + + if(data->transactionData.branchExecuted) + data->generator.transactions[2].branchExecuted++; + + data->runState = Runnable; + data->generator.totalTransactions++; +} + +void +complete_T4(ThreadData * data){ + + data->generator.transactions[3].stopLatency(); + data->generator.transactions[3].count++; + + if(data->transactionData.branchExecuted) + data->generator.transactions[3].branchExecuted++; + if(data->transactionData.do_rollback) + data->generator.transactions[3].rollbackExecuted++; + + if(data->transactionData.branchExecuted && + !data->transactionData.do_rollback){ + insertSession(&data->generator.activeSessions, + data->transactionData.number, + data->transactionData.server_id); + } + + data->runState = Runnable; + data->generator.totalTransactions++; + +} +void +complete_T5(ThreadData * data){ + + data->generator.transactions[4].stopLatency(); + data->generator.transactions[4].count++; + + if(data->transactionData.branchExecuted) + data->generator.transactions[4].branchExecuted++; + if(data->transactionData.do_rollback) + data->generator.transactions[4].rollbackExecuted++; + + if(data->transactionData.sessionElement && + !data->transactionData.do_rollback){ + deleteSession(&data->generator.activeSessions); + } + + data->runState = Runnable; + data->generator.totalTransactions++; +} + +/*************************************************************** +**************************************************************** +* 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 +asyncGenerator(ThreadData *data, + int parallellism, + int millisSendPoll, + int minEventSendPoll, + int forceSendPoll) +{ + ThreadData * startUp; + + GeneratorStatistics *st; + double periodStop; + double benchTimeStart; + double benchTimeEnd; + int i, j, done; + + myRandom48Init(data->randomSeed); + + for(i = 0; isendPollNdb(); + } + } + ndbout_c("Benchmark period starts"); + + /*-------------------------*/ + /* normal benchmark period */ + /*-------------------------*/ + benchTimeStart = userGetTime(); + + periodStop = benchTimeStart + (double)data[0].testSeconds; + while(userGetTime() < periodStop) + doOneTransaction(data, parallellism, + millisSendPoll, minEventSendPoll, forceSendPoll); + + benchTimeEnd = userGetTime(); + + ndbout_c("Benchmark period done"); + + /** + * Wait for all transactions + */ + done = 0; + while(!done){ + done = 1; + for(i = 0; isendPollNdb(); + } + } + + /*------------------*/ + /* cool down period */ + /*------------------*/ + periodStop = userGetTime() + (double)data[0].coolDownSeconds; + while(userGetTime() < periodStop){ + doOneTransaction(startUp, parallellism, + millisSendPoll, minEventSendPoll, forceSendPoll); + } + + done = 0; + while(!done){ + done = 1; + for(i = 0; isendPollNdb(); + } + } + + + /*---------------------------------------------------------*/ + /* add the times for all transaction for inner loop timing */ + /*---------------------------------------------------------*/ + for(j = 0; jouterLoopTime = benchTimeEnd - benchTimeStart; + st->outerTps = getTps(st->totalTransactions, st->outerLoopTime); + } + /* ndbout_c("maxsize = %d\n",maxsize); */ + + free(startUp); +} + diff --git a/ndb/test/ndbapi/bench/dbGenerator.h b/ndb/test/ndbapi/bench/dbGenerator.h new file mode 100644 index 00000000000..2256498e151 --- /dev/null +++ b/ndb/test/ndbapi/bench/dbGenerator.h @@ -0,0 +1,63 @@ +/* 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 asyncGenerator(ThreadData *d, int parallellism, + int millisSendPoll, + int minEventSendPoll, + int forceSendPoll); + +#ifdef __cplusplus +} +#endif + +/*************************************************************** +* E X T E R N A L D A T A * +***************************************************************/ + + + +#endif /* DBGENERATOR_H */ + diff --git a/ndb/test/ndbapi/bench/dbPopulate.cpp b/ndb/test/ndbapi/bench/dbPopulate.cpp new file mode 100644 index 00000000000..42fbb52f3b2 --- /dev/null +++ b/ndb/test/ndbapi/bench/dbPopulate.cpp @@ -0,0 +1,244 @@ +/* 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 + +#include "userInterface.h" + +#include "dbPopulate.h" +#include +#include + +/*************************************************************** +* 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 getRandomSubscriberData(int subscriberNo, + SubscriberNumber number, + SubscriberName name); + +static void populate(char *title, + int count, + void (*func)(UserHandle*,int), + UserHandle *uh); + +static void populateServers(UserHandle *uh, int count); +static void populateSubscribers(UserHandle *uh, int count); +static void populateGroups(UserHandle *uh, int count); + +/*************************************************************** +* L O C A L D A T A * +***************************************************************/ + +static SequenceValues permissionsDefinition[] = { + {90, 1}, + {10, 0}, + {0, 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 getRandomSubscriberData(int subscriberNo, + SubscriberNumber number, + SubscriberName name) +{ + char sbuf[SUBSCRIBER_NUMBER_LENGTH + 1]; + sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_LENGTH, subscriberNo); + memcpy(number, sbuf, SUBSCRIBER_NUMBER_LENGTH); + + memset(name, myRandom48(26)+'A', SUBSCRIBER_NAME_LENGTH); +} + +static void populate(char *title, + int count, + void (*func)(UserHandle*, int), + UserHandle *uh) +{ + ndbout_c("Populating %d '%s' ... ",count, title); + /* fflush(stdout); */ + func(uh,count); + ndbout_c("done"); +} + +static void populateServers(UserHandle *uh, int count) +{ + int i, j; + int len; + char tmp[80]; + int suffix_length = 1; + ServerName serverName; + SubscriberSuffix suffix; + + int commitCount = 0; + + for(i = 0; i < SUBSCRIBER_NUMBER_SUFFIX_LENGTH; i++) + suffix_length *= 10; + + for(i = 0; i < count; i++) { + sprintf(tmp, "-Server %d-", i); + + len = strlen(tmp); + for(j = 0; j < SERVER_NAME_LENGTH; j++){ + serverName[j] = tmp[j % len]; + } + /* serverName[j] = 0; not null-terminated */ + + for(j = 0; j < suffix_length; j++){ + char sbuf[SUBSCRIBER_NUMBER_SUFFIX_LENGTH + 1]; + sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, j); + memcpy(suffix, sbuf, SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + userDbInsertServer(uh, i, suffix, serverName); + commitCount ++; + if((commitCount % OP_PER_TRANS) == 0) + userDbCommit(uh); + } + } + if((commitCount % OP_PER_TRANS) != 0) + userDbCommit(uh); +} + +static void populateSubscribers(UserHandle *uh, int count) +{ + SubscriberNumber number; + SubscriberName name; + int i, j, k; + int res; + + SequenceValues values[NO_OF_GROUPS+1]; + RandomSequence seq; + + for(i = 0; i < NO_OF_GROUPS; i++) { + values[i].length = 1; + values[i].value = i; + } + + values[i].length = 0; + values[i].value = 0; + + if( initSequence(&seq, values) != 0 ) { + ndbout_c("could not set the sequence of random groups"); + exit(0); + } + +#define RETRIES 25 + + for(i = 0; i < count; i+= OP_PER_TRANS) { + for(j = 0; j +#include + +#define ERROR(x) {ndbout_c((x));} +#define ERROR1(x,y) {ndbout_c((x), (y));} +#define ERROR2(x,y,z) {ndbout_c((x), (y), (z));} +#define ERROR3(x,y,z,u) {ndbout_c((x), (y), (z), (u));} +#define ERROR4(x,y,z,u,w) {ndbout_c((x), (y), (z), (u), (w));} + +#define INIT_RANDOM(x) srand48((x)) +#define UI_RANDOM(x) ((unsigned int)(lrand48()%(x))) + +#define ASSERT(cond, message) \ + { if(!(cond)) { ERROR(message); exit(-1); }} + +#ifdef DEBUG_ON +#define DEBUG(x) {ndbout_c((x));} +#define DEBUG1(x,y) {ndbout_c((x), (y));} +#define DEBUG2(x,y,z) {ndbout_c((x), (y), (z));} +#define DEBUG3(x,y,z,u) {ndbout_c((x), (y), (z), (u));} +#define DEBUG4(x,y,z,u,w) {ndbout_c((x), (y), (z), (u), (w));} +#define DEBUG5(x,y,z,u,w, v) {ndbout_c((x), (y), (z), (u), (w), (v));} +#else +#define DEBUG(x) +#define DEBUG1(x,y) +#define DEBUG2(x,y,z) +#define DEBUG3(x,y,z,u) +#define DEBUG4(x,y,z,u,w) +#define DEBUG5(x,y,z,u,w, v) +#endif + +#endif diff --git a/ndb/test/ndbapi/bench/mainAsyncGenerator.cpp b/ndb/test/ndbapi/bench/mainAsyncGenerator.cpp new file mode 100644 index 00000000000..828b924582f --- /dev/null +++ b/ndb/test/ndbapi/bench/mainAsyncGenerator.cpp @@ -0,0 +1,503 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include + +#include "userInterface.h" +#include "dbGenerator.h" + +static int numProcesses; +static int numSeconds; +static int numWarmSeconds; +static int parallellism; +static int millisSendPoll; +static int minEventSendPoll; +static int forceSendPoll; + +static ThreadData *data; +static Ndb_cluster_connection *g_cluster_connection= 0; + + +static void usage(const char *prog) +{ + const char *progname; + + /*--------------------------------------------*/ + /* Get the name of the program (without path) */ + /*--------------------------------------------*/ + progname = strrchr(prog, '/'); + + if (progname == 0) + progname = prog; + else + ++progname; + + ndbout_c( + "Usage: %s [-proc ] [-warm ] [-time ] [ -p ] " + "[-t ] [ -e ] [ -f ] \n" + " -proc Specifies that is the number of\n" + " threads. The default is 1.\n" + " -time Specifies that the test will run for sec.\n" + " The default is 10 sec\n" + " -warm Specifies the warm-up/cooldown period of " + "sec.\n" + " The default is 10 sec\n" + " -p The no of parallell transactions started by " + "one thread\n" + " -e Minimum no of events before wake up in call to " + "sendPoll\n" + " Default is 1\n" + " -f force parameter to sendPoll\n" + " Default is 0\n", + progname); +} + +static +int +parse_args(int argc, const char **argv) +{ + int i; + + numProcesses = 1; + numSeconds = 10; + numWarmSeconds = 10; + parallellism = 1; + millisSendPoll = 10000; + minEventSendPoll = 1; + forceSendPoll = 0; + + + i = 1; + while (i < argc){ + if (strcmp("-proc",argv[i]) == 0) { + if (i + 1 >= argc) { + return 1; + } + if (sscanf(argv[i+1], "%d", &numProcesses) == -1 || + numProcesses <= 0 || numProcesses > 127) { + ndbout_c("-proc flag requires a positive integer argument [1..127]"); + return 1; + } + i += 2; + } else if (strcmp("-p", argv[i]) == 0){ + if(i + 1 >= argc){ + usage(argv[0]); + return 1; + } + if (sscanf(argv[i+1], "%d", ¶llellism) == -1 || + parallellism <= 0){ + ndbout_c("-p flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else if (strcmp("-time",argv[i]) == 0) { + if (i + 1 >= argc) { + return 1; + } + if (sscanf(argv[i+1], "%d", &numSeconds) == -1 || + numSeconds < 0) { + ndbout_c("-time flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else if (strcmp("-warm",argv[i]) == 0) { + if (i + 1 >= argc) { + return 1; + } + if (sscanf(argv[i+1], "%d", &numWarmSeconds) == -1 || + numWarmSeconds < 0) { + ndbout_c("-warm flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else if (strcmp("-e",argv[i]) == 0) { + if (i + 1 >= argc) { + return 1; + } + if (sscanf(argv[i+1], "%d", &minEventSendPoll) == -1 || + minEventSendPoll < 0) { + ndbout_c("-e flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else if (strcmp("-f",argv[i]) == 0) { + if (i + 1 >= argc) { + usage(argv[0]); + return 1; + } + if (sscanf(argv[i+1], "%d", &forceSendPoll) == -1 || + forceSendPoll < 0) { + ndbout_c("-f flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else { + return 1; + } + } + + if(minEventSendPoll > parallellism){ + ndbout_c("minEventSendPoll(%d) > parallellism(%d)", + minEventSendPoll, parallellism); + ndbout_c("not very good..."); + ndbout_c("very bad..."); + ndbout_c("exiting..."); + return 1; + } + return 0; +} + +static +void +print_transaction(const char *header, + unsigned long totalCount, + TransactionDefinition *trans, + unsigned int printBranch, + unsigned int printRollback) +{ + double f; + + ndbout_c(" %s: %d (%.2f%%) " + "Latency(ms) avg: %d min: %d max: %d std: %d n: %d", + header, + trans->count, + (double)trans->count / (double)totalCount * 100.0, + (int)trans->latency.getMean(), + (int)trans->latency.getMin(), + (int)trans->latency.getMax(), + (int)trans->latency.getStddev(), + (int)trans->latency.getCount() + ); + + if( printBranch ){ + if( trans->count == 0 ) + f = 0.0; + else + f = (double)trans->branchExecuted / (double)trans->count * 100.0; + ndbout_c(" Branches Executed: %d (%.2f%%)", trans->branchExecuted, f); + } + + if( printRollback ){ + if( trans->count == 0 ) + f = 0.0; + else + f = (double)trans->rollbackExecuted / (double)trans->count * 100.0; + ndbout_c(" Rollback Executed: %d (%.2f%%)",trans->rollbackExecuted,f); + } +} + +void +print_stats(const char *title, + unsigned int length, + unsigned int transactionFlag, + GeneratorStatistics *gen, + int numProc, int parallellism) +{ + int i; + char buf[10]; + char name[MAXHOSTNAMELEN]; + + name[0] = 0; + NdbHost_GetHostName(name); + + ndbout_c("\n------ %s ------",title); + ndbout_c("Length : %d %s", + length, + transactionFlag ? "Transactions" : "sec"); + ndbout_c("Processor : %s", name); + ndbout_c("Number of Proc: %d",numProc); + ndbout_c("Parallellism : %d", parallellism); + ndbout_c("\n"); + + if( gen->totalTransactions == 0 ) { + ndbout_c(" No Transactions for this test"); + } + 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 ); + } + + ndbout_c("\n"); + ndbout_c(" Overall Statistics:"); + ndbout_c(" Transactions: %d", gen->totalTransactions); + ndbout_c(" Outer : %.0f TPS",gen->outerTps); + ndbout_c("\n"); + } +} + +static +void * +threadRoutine(void *arg) +{ + int i; + ThreadData *data = (ThreadData *)arg; + Ndb * pNDB; + + pNDB = asyncDbConnect(parallellism); + /* NdbSleep_MilliSleep(rand() % 10); */ + + for(i = 0; ipThread = pThread; + } else { + perror("Failed to create thread"); + rc = NDBT_FAILED; + } + } + + showTime(); + + /*--------------------------------*/ + /* Wait for all processes to exit */ + /*--------------------------------*/ + for(i = 0; i < numProcesses; i++) { + NdbThread_WaitFor(data[i*parallellism].pThread, &tmp); + NdbThread_Destroy(&data[i*parallellism].pThread); + } + + ndbout_c("All threads have finished"); + + /*-------------------------------------------*/ + /* Clear all structures for total statistics */ + /*-------------------------------------------*/ + stats.totalTransactions = 0; + stats.outerTps = 0.0; + + for(i = 0; i < NUM_TRANSACTION_TYPES; i++ ) { + stats.transactions[i].count = 0; + stats.transactions[i].branchExecuted = 0; + stats.transactions[i].rollbackExecuted = 0; + stats.transactions[i].latency.reset(); + } + + /*--------------------------------*/ + /* Add the values for all Threads */ + /*--------------------------------*/ + for(i = 0; i < numProcesses; i++) { + for(k = 0; ktotalTransactions; + stats.outerTps += p->outerTps; + + for(j = 0; j < NUM_TRANSACTION_TYPES; j++ ) { + stats.transactions[j].count += + p->transactions[j].count; + stats.transactions[j].branchExecuted += + p->transactions[j].branchExecuted; + stats.transactions[j].rollbackExecuted += + p->transactions[j].rollbackExecuted; + stats.transactions[j].latency += + p->transactions[j].latency; + } + } + } + + print_stats("Test Results", + numSeconds, + 0, + &stats, + numProcesses, + parallellism); + + free(data); + + NDBT_ProgramExit(rc); +} +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include +#include +#include +#include + +#include "ndb_schema.hpp" +#include "ndb_error.hpp" +#include "userInterface.h" +#include +#include +#include +#include +#include + +/*************************************************************** +* 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 * +***************************************************************/ + +#ifndef NDB_WIN32 +#include +#endif + +Ndb* +asyncDbConnect(int parallellism){ + Ndb * pNDB = new Ndb(g_cluster_connection, "TEST_DB"); + + pNDB->init(parallellism + 1); + + while(pNDB->waitUntilReady() != 0){ + } + + return pNDB; +} + +void +asyncDbDisconnect(Ndb* pNDB) +{ + delete pNDB; +} + +double +userGetTime(void) +{ + static bool initialized = false; + static NDB_TICKS initSecs = 0; + static Uint32 initMicros = 0; + double timeValue = 0; + + if ( !initialized ) { + initialized = true; + NdbTick_CurrentMicrosecond(&initSecs, &initMicros); + timeValue = 0.0; + } else { + NDB_TICKS secs = 0; + Uint32 micros = 0; + + NdbTick_CurrentMicrosecond(&secs, µs); + double s = (double)secs - (double)initSecs; + double us = (double)micros - (double)initMicros; + + timeValue = s + (us / 1000000.0); + } + return timeValue; +} + +void showTime() +{ + char buf[128]; + struct tm* tm_now; + time_t now; + now = ::time((time_t*)NULL); + tm_now = ::gmtime(&now); + + ::snprintf(buf, 128, + "%d-%.2d-%.2d %.2d:%.2d:%.2d", + tm_now->tm_year + 1900, + tm_now->tm_mon, + tm_now->tm_mday, + tm_now->tm_hour, + tm_now->tm_min, + tm_now->tm_sec); + + ndbout_c("Time: %s", buf); +} + diff --git a/ndb/test/ndbapi/bench/mainPopulate.cpp b/ndb/test/ndbapi/bench/mainPopulate.cpp new file mode 100644 index 00000000000..5f4b73a3eff --- /dev/null +++ b/ndb/test/ndbapi/bench/mainPopulate.cpp @@ -0,0 +1,84 @@ +/* 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 +#include + +#include "userInterface.h" +#include "dbPopulate.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +int useTableLogging; +int useIndexTables; +#ifdef __cplusplus +} +#endif + + +static void usage() +{ +} + +static +void usage(const char *prog) +{ + + ndbout_c( + "Usage: %s [-l]\n" + " -l Use logging and checkpointing on tables\n", + " -i Use index tables\n", + prog); + + exit(1); +} + +NDB_STD_OPTS_VARS; + +NDB_COMMAND(DbCreate, "DbCreate", "DbCreate", "DbCreate", 16384) +{ + int i; + UserHandle *uh; + + useTableLogging = useIndexTables = 0; + NDB_INIT(argv[0]); + + for(i = 1; i + +inline +NdbConnection * +startTransaction(Ndb * pNDB, + ServerId inServerId, + const SubscriberNumber inNumber){ + + const int keyDataLenBytes = sizeof(ServerId)+SUBSCRIBER_NUMBER_LENGTH; + const int keyDataLen_64Words = keyDataLenBytes >> 3; + + Uint64 keyDataBuf[keyDataLen_64Words+1]; // The "+1" is for rounding... + + char * keyDataBuf_charP = (char *)&keyDataBuf[0]; + Uint32 * keyDataBuf_wo32P = (Uint32 *)&keyDataBuf[0]; + + // Server Id comes first + keyDataBuf_wo32P[0] = inServerId; + // Then subscriber number + memcpy(&keyDataBuf_charP[sizeof(ServerId)], inNumber, + SUBSCRIBER_NUMBER_LENGTH); + + return pNDB->startTransaction(0, keyDataBuf_charP, keyDataLenBytes); +} + +void T1_Callback(int result, NdbConnection * pCon, void * threadData); +void T2_Callback(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_3(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_3(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_3(int result, NdbConnection * pCon, void * threadData); + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +void +start_T1(Ndb * pNDB, ThreadData * td){ + + DEBUG2("T1(%.*s): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + + int check; + NdbConnection * pCON = pNDB->startTransaction(); + if (pCON != NULL) { + NdbOperation *MyOp = pCON->getNdbOperation(SUBSCRIBER_TABLE); + if (MyOp != NULL) { + MyOp->updateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->setValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->setValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + pCON->executeAsynchPrepare( Commit , T1_Callback, td); + } else { + CHECK_NULL(MyOp, "T1: getNdbOperation", pCON); + }//if + } else { + error_handler("T1-1: startTranscation", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + }//if +} + +void +T1_Callback(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + + DEBUG2("T1(%.*s): - Completing\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + + CHECK_MINUS_ONE(result, "T1: Commit", + pCON); + td->pNDB->closeTransaction(pCON); + complete_T1(td); +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +void +start_T2(Ndb * pNDB, ThreadData * td){ + + DEBUG3("T2(%.*s, %p): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.location); + + int check; + NdbRecAttr * check2; + + NdbConnection * pCON = pNDB->startTransaction(); + if (pCON == NULL) + error_handler("T2-1: startTransaction", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T2: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_NAME, + td->transactionData.name); + pCON->executeAsynchPrepare( Commit, T2_Callback, td ); +} + +void +T2_Callback(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T2(%.*s, %p): - Completing\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.location); + + CHECK_MINUS_ONE(result, "T2: Commit", pCON); + td->pNDB->closeTransaction(pCON); + complete_T2(td); +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +void +start_T3(Ndb * pNDB, ThreadData * td){ + + DEBUG3("T3(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + int check; + NdbRecAttr * check2; + + NdbConnection * pCON = startTransaction(pNDB, + td->transactionData.server_id, + td->transactionData.number); + if (pCON == NULL) + error_handler("T3-1: startTranscation", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T3-1: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + pCON->executeAsynchPrepare( NoCommit , T3_Callback_1, td); +} + +void +T3_Callback_1(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T3(%.*s, %.2d): - Callback 1\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + CHECK_MINUS_ONE(result, "T3-1: NoCommit", pCON); + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T3-2: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_READ, + (char *)&td->transactionData.permission); + pCON->executeAsynchPrepare( NoCommit, T3_Callback_2, td ); +} + +void +T3_Callback_2(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + + CHECK_MINUS_ONE(result, "T3-2: NoCommit", pCON); + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == server_bit)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number + [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + DEBUG5("T3(%.*s, %.2d): - Callback 2 - reading(%.*s)\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T3-3: getNdbOperation", + pCON); + + MyOp->simpleRead(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + MyOp->getValue(IND_SESSION_DATA, + (char *)td->transactionData.session_details); + + /* Operation 4 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T3-4: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_READS, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + DEBUG3("T3(%.*s, %.2d): - Callback 2 - no read\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + td->transactionData.branchExecuted = 0; + } + pCON->executeAsynchPrepare( Commit, T3_Callback_3, td ); +} + +void +T3_Callback_3(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T3(%.*s, %.2d): - Completing\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + CHECK_MINUS_ONE(result, "T3-3: Commit", pCON); + + td->pNDB->closeTransaction(pCON); + complete_T3(td); +} + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +start_T4(Ndb * pNDB, ThreadData * td){ + + DEBUG3("T4(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + int check; + NdbRecAttr * check2; + + NdbConnection * pCON = startTransaction(pNDB, + td->transactionData.server_id, + td->transactionData.number); + if (pCON == NULL) + error_handler("T4-1: startTranscation", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T4-1: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + MyOp->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)td->transactionData.server_bit); + pCON->executeAsynchPrepare( NoCommit , T4_Callback_1, td); +} + +void +T4_Callback_1(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T4-1: NoCommit", pCON); + ThreadData * td = (ThreadData *)threadData; + + DEBUG3("T4(%.*s, %.2d): - Callback 1\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T4-2: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&td->transactionData.permission); + pCON->executeAsynchPrepare( NoCommit , T4_Callback_2, td); +} + +void +T4_Callback_2(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T4-2: NoCommit", pCON); + ThreadData * td = (ThreadData *)threadData; + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == 0)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number + [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG5("T4(%.*s, %.2d): - Callback 2 - inserting(%.*s)\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T4-3: getNdbOperation", + pCON); + + MyOp->insertTuple(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + MyOp->setValue(SESSION_DATA, + (char *)td->transactionData.session_details); + /* Operation 4 */ + + /* Operation 5 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T4-5: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_INSERTS, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + td->transactionData.branchExecuted = 0; + DEBUG5("T4(%.*s, %.2d): - Callback 2 - %s %s\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + ((permission & server_bit) ? + "permission - " : "no permission - "), + ((sessions & server_bit) ? + "in session - " : "no in session - ")); + } + + if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ + pCON->executeAsynchPrepare(Commit, T4_Callback_3, td); + } else { + pCON->executeAsynchPrepare(Rollback, T4_Callback_3, td); + } +} + +void +T4_Callback_3(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T4-3: Commit", pCON); + ThreadData * td = (ThreadData *)threadData; + + DEBUG3("T4(%.*s, %.2d): - Completing\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + td->pNDB->closeTransaction(pCON); + complete_T4(td); +} + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +start_T5(Ndb * pNDB, ThreadData * td){ + + DEBUG3("T5(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + int check; + NdbRecAttr * check2; + + NdbConnection * pCON = pNDB->startTransaction(); + if (pCON == NULL) + error_handler("T5-1: startTranscation", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + + NdbOperation * MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T5-1: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + MyOp->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)td->transactionData.server_bit); + pCON->executeAsynchPrepare( NoCommit, T5_Callback_1, td ); +} + +void +T5_Callback_1(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T5-1: NoCommit", pCON); + ThreadData * td = (ThreadData *)threadData; + + DEBUG3("T5(%.*s, %.2d): - Callback 1\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T5-2: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&td->transactionData.permission); + pCON->executeAsynchPrepare( NoCommit, T5_Callback_2, td ); +} + +void +T5_Callback_2(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T5-2: NoCommit", pCON); + ThreadData * td = (ThreadData *)threadData; + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == server_bit)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number + [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG5("T5(%.*s, %.2d): - Callback 2 - deleting(%.*s)\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T5-3: getNdbOperation", + pCON); + + MyOp->deleteTuple(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + /* Operation 4 */ + + /* Operation 5 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T5-5: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_DELETES, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + td->transactionData.branchExecuted = 0; + + DEBUG5("T5(%.*s, %.2d): - Callback 2 - no delete - %s %s\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + ((permission & server_bit) ? + "permission - " : "no permission - "), + ((sessions & server_bit) ? + "in session - " : "no in session - ")); + } + + if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ + pCON->executeAsynchPrepare(Commit, T5_Callback_3, td); + } else { + pCON->executeAsynchPrepare(Rollback, T5_Callback_3, td); + } +} + +void +T5_Callback_3(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T5-3: Commit", pCON); + ThreadData * td = (ThreadData *)threadData; + + DEBUG3("T5(%.*s, %.2d): - Completing\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + td->pNDB->closeTransaction(pCON); + complete_T5(td); +} diff --git a/ndb/test/ndbapi/bench/ndb_async2.cpp b/ndb/test/ndbapi/bench/ndb_async2.cpp new file mode 100644 index 00000000000..31cf1d8310a --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_async2.cpp @@ -0,0 +1,757 @@ +/* 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 */ + +//#define DEBUG_ON + +#include +#include "userInterface.h" + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" +#include + +#include + +void T1_Callback(int result, NdbConnection * pCon, void * threadData); +void T2_Callback(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_3(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_3(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_3(int result, NdbConnection * pCon, void * threadData); + +static int stat_async = 0; + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ + +#define SFX_START (SUBSCRIBER_NUMBER_LENGTH - SUBSCRIBER_NUMBER_SUFFIX_LENGTH) + +inline +NdbConnection * +startTransaction(Ndb * pNDB, ThreadData * td){ + return pNDB->startTransaction(); +#ifdef OLD_CODE + return pNDB->startTransactionDGroup (0, + &td->transactionData.number[SFX_START], + 1); +#endif +} + +void +start_T1(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG2("T1(%.*s): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + + NdbConnection * pCON = 0; + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation *MyOp = pCON->getNdbOperation(SUBSCRIBER_TABLE); + if (MyOp != NULL) { + MyOp->updateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->setValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->setValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + if (async == 1) { + pCON->executeAsynchPrepare( Commit , T1_Callback, td); + } else { + int result = pCON->execute(Commit); + T1_Callback(result, pCON, (void*)td); + return; + }//if + } else { + CHECK_NULL(MyOp, "T1: getNdbOperation", td, pCON->getNdbError()); + }//if +} + +void +T1_Callback(int result, NdbConnection * pCON, void * threadData) { + ThreadData * td = (ThreadData *)threadData; + + DEBUG2("T1(%.*s): - Completing", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + + if (result == -1) { + CHECK_ALLOWED_ERROR("T1: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T1(td->pNDB, td, stat_async); + return; + }//if + td->pNDB->closeTransaction(pCON); + complete_T1(td); +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +void +start_T2(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG3("T2(%.*s, %d): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.location); + + NdbConnection * pCON = 0; + + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T2-1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T2: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_NAME, + td->transactionData.name); + if (async == 1) { + pCON->executeAsynchPrepare( Commit , T2_Callback, td); + } else { + int result = pCON->execute(Commit); + T2_Callback(result, pCON, (void*)td); + return; + }//if +} + +void +T2_Callback(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T2(%.*s, %d): - Completing", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.location); + + if (result == -1) { + CHECK_ALLOWED_ERROR("T2: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T2(td->pNDB, td, stat_async); + return; + }//if + td->pNDB->closeTransaction(pCON); + complete_T2(td); +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +void +start_T3(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG3("T3(%.*s, %.2d): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbConnection * pCON = 0; + + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T3-1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T3-1: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + stat_async = async; + if (async == 1) { + pCON->executeAsynchPrepare( NoCommit , T3_Callback_1, td); + } else { + int result = pCON->execute( NoCommit ); + T3_Callback_1(result, pCON, (void*)td); + return; + }//if +} + +void +T3_Callback_1(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T3(%.*s, %.2d): - Callback 1", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + if (result == -1) { + CHECK_ALLOWED_ERROR("T3-1: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T3(td->pNDB, td, stat_async); + return; + }//if + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T3-2: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_READ, + (char *)&td->transactionData.permission); + if (stat_async == 1) { + pCON->executeAsynchPrepare( NoCommit , T3_Callback_2, td); + } else { + int result = pCON->execute( NoCommit ); + T3_Callback_2(result, pCON, (void*)td); + return; + }//if +} + +void +T3_Callback_2(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + + if (result == -1) { + CHECK_ALLOWED_ERROR("T3-2: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T3(td->pNDB, td, stat_async); + return; + }//if + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == server_bit)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number[SFX_START], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + DEBUG5("T3(%.*s, %.2d): - Callback 2 - reading(%.*s)", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T3-3: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->simpleRead(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + MyOp->getValue(IND_SESSION_DATA, + (char *)td->transactionData.session_details); + + /* Operation 4 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T3-4: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_READS, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + DEBUG3("T3(%.*s, %.2d): - Callback 2 - no read", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + td->transactionData.branchExecuted = 0; + } + if (stat_async == 1) { + pCON->executeAsynchPrepare( Commit , T3_Callback_3, td); + } else { + int result = pCON->execute( Commit ); + T3_Callback_3(result, pCON, (void*)td); + return; + }//if +} + +void +T3_Callback_3(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T3(%.*s, %.2d): - Completing", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + if (result == -1) { + CHECK_ALLOWED_ERROR("T3-3: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T3(td->pNDB, td, stat_async); + return; + }//if + td->pNDB->closeTransaction(pCON); + complete_T3(td); +} + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +start_T4(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG3("T4(%.*s, %.2d): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbConnection * pCON = 0; + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T4-1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T4-1: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + MyOp->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)td->transactionData.server_bit); + stat_async = async; + if (async == 1) { + pCON->executeAsynchPrepare( NoCommit , T4_Callback_1, td); + } else { + int result = pCON->execute( NoCommit ); + T4_Callback_1(result, pCON, (void*)td); + return; + }//if +} + +void +T4_Callback_1(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T4-1: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T4(td->pNDB, td, stat_async); + return; + }//if + + DEBUG3("T4(%.*s, %.2d): - Callback 1", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T4-2: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&td->transactionData.permission); + if (stat_async == 1) { + pCON->executeAsynchPrepare( NoCommit , T4_Callback_2, td); + } else { + int result = pCON->execute( NoCommit ); + T4_Callback_2(result, pCON, (void*)td); + return; + }//if +} + +void +T4_Callback_2(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T4-2: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T4(td->pNDB, td, stat_async); + return; + }//if + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == 0)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number[SFX_START], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG5("T4(%.*s, %.2d): - Callback 2 - inserting(%.*s)", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T4-3: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->insertTuple(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + MyOp->setValue(SESSION_DATA, + (char *)td->transactionData.session_details); + /* Operation 4 */ + + /* Operation 5 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T4-5: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_INSERTS, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + td->transactionData.branchExecuted = 0; + DEBUG5("T4(%.*s, %.2d): - Callback 2 - %s %s", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + ((permission & server_bit) ? + "permission - " : "no permission - "), + ((sessions & server_bit) ? + "in session - " : "no in session - ")); + } + + if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ + if (stat_async == 1) { + pCON->executeAsynchPrepare( Commit , T4_Callback_3, td); + } else { + int result = pCON->execute( Commit ); + T4_Callback_3(result, pCON, (void*)td); + return; + }//if + } else { + if (stat_async == 1) { + pCON->executeAsynchPrepare( Rollback , T4_Callback_3, td); + } else { + int result = pCON->execute( Rollback ); + T4_Callback_3(result, pCON, (void*)td); + return; + }//if + } +} + +void +T4_Callback_3(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T4-3: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T4(td->pNDB, td, stat_async); + return; + }//if + + DEBUG3("T4(%.*s, %.2d): - Completing", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + td->pNDB->closeTransaction(pCON); + complete_T4(td); +} + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +start_T5(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG3("T5(%.*s, %.2d): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbConnection * pCON = 0; + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T5-1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation * MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T5-1: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + MyOp->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)td->transactionData.server_bit); + stat_async = async; + if (async == 1) { + pCON->executeAsynchPrepare( NoCommit , T5_Callback_1, td); + } else { + int result = pCON->execute( NoCommit ); + T5_Callback_1(result, pCON, (void*)td); + return; + }//if +} + +void +T5_Callback_1(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T5-1: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T5(td->pNDB, td, stat_async); + return; + }//if + + DEBUG3("T5(%.*s, %.2d): - Callback 1", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T5-2: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&td->transactionData.permission); + if (stat_async == 1) { + pCON->executeAsynchPrepare( NoCommit , T5_Callback_2, td); + } else { + int result = pCON->execute( NoCommit ); + T5_Callback_2(result, pCON, (void*)td); + return; + }//if +} + +void +T5_Callback_2(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T5-2: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T5(td->pNDB, td, stat_async); + return; + }//if + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == server_bit)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number[SFX_START], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG5("T5(%.*s, %.2d): - Callback 2 - deleting(%.*s)", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T5-3: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->deleteTuple(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + /* Operation 4 */ + + /* Operation 5 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T5-5: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_DELETES, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + td->transactionData.branchExecuted = 0; + + DEBUG5("T5(%.*s, %.2d): - Callback 2 - no delete - %s %s", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + ((permission & server_bit) ? + "permission - " : "no permission - "), + ((sessions & server_bit) ? + "in session - " : "no in session - ")); + } + + if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ + if (stat_async == 1) { + pCON->executeAsynchPrepare( Commit , T5_Callback_3, td); + } else { + int result = pCON->execute( Commit ); + T5_Callback_3(result, pCON, (void*)td); + return; + }//if + } else { + if (stat_async == 1) { + pCON->executeAsynchPrepare( Rollback , T5_Callback_3, td); + } else { + int result = pCON->execute( Rollback ); + T5_Callback_3(result, pCON, (void*)td); + return; + }//if + } +} + +void +T5_Callback_3(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T5-3: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T5(td->pNDB, td, stat_async); + return; + }//if + + DEBUG3("T5(%.*s, %.2d): - Completing", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + td->pNDB->closeTransaction(pCON); + complete_T5(td); +} diff --git a/ndb/test/ndbapi/bench/ndb_error.hpp b/ndb/test/ndbapi/bench/ndb_error.hpp new file mode 100644 index 00000000000..d90f5506813 --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_error.hpp @@ -0,0 +1,81 @@ +/* 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 NDB_ERROR_H +#define NDB_ERROR_H + +#include +#include +#include "userInterface.h" +#include +#include + +#define error_handler(x,y, z) { \ + ndbout << x << " " << y << endl; \ + exit(-1); } + +#define CHECK_MINUS_ONE(x, y, z) if(x == -1) \ + error_handler(y,(z->getNdbError()), 0) + +inline +void +CHECK_ALLOWED_ERROR(const char * str, + const ThreadData * td, + const struct NdbError & error){ + + char buf[100]; + snprintf(buf, sizeof(buf), "subscriber = %.*s ", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + ndbout << str << " " << error << endl + << buf; + showTime(); + + switch(error.classification) { + case NdbError::TimeoutExpired: + case NdbError::OverloadError: + case NdbError::TemporaryResourceError: + case NdbError::NodeRecoveryError: + break; + default: + if(error.status != NdbError::TemporaryError) + exit(-1); + } +} + +inline +void +CHECK_NULL(void * null, + const char * str, + const ThreadData * td, + const struct NdbError & err){ + if(null == 0){ + CHECK_ALLOWED_ERROR(str, td, err); + exit(-1); + } +} + +inline +void +CHECK_NULL(void * null, const char* msg, NdbConnection* obj) +{ + if(null == 0) + { + error_handler(msg, obj->getNdbError(), 0); + } +} + +#endif diff --git a/ndb/test/ndbapi/bench/ndb_schema.hpp b/ndb/test/ndbapi/bench/ndb_schema.hpp new file mode 100644 index 00000000000..af08bc2eecd --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_schema.hpp @@ -0,0 +1,78 @@ +/* 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 NDB_SCHEMA_H +#define NDB_SCHEMA_H + +#include "testDefinitions.h" + +#define SUBSCRIBER_TABLE "SUBSCRIBER" +#define SUBSCRIBER_NUMBER "NUMBER" +#define SUBSCRIBER_LOCATION "LOCATION" +#define SUBSCRIBER_NAME "NAME" +#define SUBSCRIBER_GROUP "GROUP_ID" +#define SUBSCRIBER_SESSIONS "SESSIONS" +#define SUBSCRIBER_CHANGED_BY "CHANGED_BY" +#define SUBSCRIBER_CHANGED_TIME "CHANGED_TIME" + +#define SERVER_TABLE "SERVER" +#define SERVER_ID "SERVER_ID" +#define SERVER_SUBSCRIBER_SUFFIX "SUFFIX" +#define SERVER_NAME "NAME" +#define SERVER_READS "NO_OF_READ" +#define SERVER_INSERTS "NO_OF_INSERT" +#define SERVER_DELETES "NO_OF_DELETE" + +#define GROUP_TABLE "GROUP" +#define GROUP_ID "GROUP_ID" +#define GROUP_NAME "GROUP_NAME" +#define GROUP_ALLOW_READ "ALLOW_READ" +#define GROUP_ALLOW_INSERT "ALLOW_INSERT" +#define GROUP_ALLOW_DELETE "ALLOW_DELETE" + +#define SESSION_TABLE "SESSION" +#define SESSION_SERVER "SERVER_ID" +#define SESSION_SUBSCRIBER "NUMBER" +#define SESSION_DATA "DATA" + +/** Numbers */ + +#define IND_SUBSCRIBER_NUMBER (unsigned)0 +#define IND_SUBSCRIBER_NAME (unsigned)1 +#define IND_SUBSCRIBER_GROUP (unsigned)2 +#define IND_SUBSCRIBER_LOCATION (unsigned)3 +#define IND_SUBSCRIBER_SESSIONS (unsigned)4 +#define IND_SUBSCRIBER_CHANGED_BY (unsigned)5 +#define IND_SUBSCRIBER_CHANGED_TIME (unsigned)6 + +#define IND_SERVER_SUBSCRIBER_SUFFIX (unsigned)0 +#define IND_SERVER_ID (unsigned)1 +#define IND_SERVER_NAME (unsigned)2 +#define IND_SERVER_READS (unsigned)3 +#define IND_SERVER_INSERTS (unsigned)4 +#define IND_SERVER_DELETES (unsigned)5 + +#define IND_GROUP_ID (unsigned)0 +#define IND_GROUP_NAME (unsigned)1 +#define IND_GROUP_ALLOW_READ (unsigned)2 +#define IND_GROUP_ALLOW_INSERT (unsigned)3 +#define IND_GROUP_ALLOW_DELETE (unsigned)4 + +#define IND_SESSION_SUBSCRIBER (unsigned)0 +#define IND_SESSION_SERVER (unsigned)1 +#define IND_SESSION_DATA (unsigned)2 + +#endif diff --git a/ndb/test/ndbapi/bench/ndb_user_transaction.cpp b/ndb/test/ndbapi/bench/ndb_user_transaction.cpp new file mode 100644 index 00000000000..182f1f99586 --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_user_transaction.cpp @@ -0,0 +1,825 @@ +/* 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-4: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + NdbOperation * MyOperation = 0; + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-4: equal number", + MyTransaction); + + check = MyOperation->incValue(SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-4: NoCommit", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-5: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-4: equal number", + MyTransaction); + + check = MyOperation->subValue(SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-4: NoCommit", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-5: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/bench/ndb_user_transaction2.cpp b/ndb/test/ndbapi/bench/ndb_user_transaction2.cpp new file mode 100644 index 00000000000..df3c7a7989e --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_user_transaction2.cpp @@ -0,0 +1,825 @@ +/* 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-4: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + NdbOperation * MyOperation = 0; + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-4: equal number", + MyTransaction); + + check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-4: NoCommit", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-5: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-4: equal number", + MyTransaction); + + check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-4: NoCommit", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-5: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/bench/ndb_user_transaction3.cpp b/ndb/test/ndbapi/bench/ndb_user_transaction3.cpp new file mode 100644 index 00000000000..d2c92ecd424 --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_user_transaction3.cpp @@ -0,0 +1,793 @@ +/* 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + /* Operation 4 */ + + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + NdbOperation * MyOperation = 0; + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-4: equal number", + MyTransaction); + + check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-4: equal number", + MyTransaction); + + check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/bench/ndb_user_transaction4.cpp b/ndb/test/ndbapi/bench/ndb_user_transaction4.cpp new file mode 100644 index 00000000000..e652c7bfed8 --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_user_transaction4.cpp @@ -0,0 +1,770 @@ +/* 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + DEBUG2("T2(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit..."); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + DEBUG("done\n"); + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/bench/ndb_user_transaction5.cpp b/ndb/test/ndbapi/bench/ndb_user_transaction5.cpp new file mode 100644 index 00000000000..86580008d10 --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_user_transaction5.cpp @@ -0,0 +1,769 @@ +/* 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + DEBUG2("T2(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->simpleRead(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit..."); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + DEBUG("done\n"); + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/bench/ndb_user_transaction6.cpp b/ndb/test/ndbapi/bench/ndb_user_transaction6.cpp new file mode 100644 index 00000000000..262f38e9ffb --- /dev/null +++ b/ndb/test/ndbapi/bench/ndb_user_transaction6.cpp @@ -0,0 +1,561 @@ +/* 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 */ + +//#define DEBUG_ON + +#include +#include "userHandle.h" +#include "userInterface.h" + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include + + +void +userCheckpoint(UserHandle *uh){ +} + +inline +NdbConnection * +startTransaction(Ndb * pNDB, ServerId inServerId, const SubscriberNumber inNumber){ + + const int keyDataLenBytes = sizeof(ServerId)+SUBSCRIBER_NUMBER_LENGTH; + const int keyDataLen_64Words = keyDataLenBytes >> 3; + + Uint64 keyDataBuf[keyDataLen_64Words+1]; // The "+1" is for rounding... + + char * keyDataBuf_charP = (char *)&keyDataBuf[0]; + Uint32 * keyDataBuf_wo32P = (Uint32 *)&keyDataBuf[0]; + + // Server Id comes first + keyDataBuf_wo32P[0] = inServerId; + // Then subscriber number + memcpy(&keyDataBuf_charP[sizeof(ServerId)], inNumber, SUBSCRIBER_NUMBER_LENGTH); + + return pNDB->startTransaction(0, keyDataBuf_charP, keyDataLenBytes); +} + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +void +userTransaction_T1(UserHandle * uh, + SubscriberNumber number, + Location new_location, + ChangedBy changed_by, + ChangedTime changed_time){ + Ndb * pNDB = uh->pNDB; + + DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction != NULL) { + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + if (MyOperation != NULL) { + MyOperation->updateTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + check = MyTransaction->execute( Commit ); + if (check != -1) { + pNDB->closeTransaction(MyTransaction); + return; + } else { + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + }//if + } else { + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + }//if + } else { + error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); + }//if +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +void +userTransaction_T2(UserHandle * uh, + SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName){ + Ndb * pNDB = uh->pNDB; + + DEBUG2("T2(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2-1: startTransaction", pNDB->getNdbErrorString(), pNDB->getNdbError()); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + MyOperation->readTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + pNDB->closeTransaction(MyTransaction); +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +void +userTransaction_T3(UserHandle * uh, + SubscriberNumber inNumber, + ServerId inServerId, + ServerBit inServerBit, + SessionDetails outSessionDetails, + BranchExecuted * outBranchExecuted){ + Ndb * pNDB = uh->pNDB; + + char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))]; + char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))]; + Location outLocation; + GroupId groupId; + ActiveSessions sessions; + Permission permission; + SubscriberSuffix inSuffix; + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = startTransaction(pNDB, inServerId, inNumber); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + MyOperation->readTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&outLocation); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + MyOperation->readTuple(); + MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + memcpy(inSuffix, + &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + DEBUG2("reading(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + MyOperation->simpleRead(); + + MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + MyOperation->incValue(IND_SERVER_READS, (uint32)1); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit..."); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + DEBUG("done\n"); +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +userTransaction_T4(UserHandle * uh, + SubscriberNumber inNumber, + ServerId inServerId, + ServerBit inServerBit, + SessionDetails inSessionDetails, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted){ + + Ndb * pNDB = uh->pNDB; + + char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))]; + char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))]; + Location outLocation; + GroupId groupId; + ActiveSessions sessions; + Permission permission; + SubscriberSuffix inSuffix; + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = startTransaction(pNDB, inServerId, inNumber); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&outLocation); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + check = MyTransaction->execute( NoCommit ); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + MyOperation->readTuple(); + MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + memcpy(inSuffix, + &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG2("inserting(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + MyOperation->insertTuple(); + MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +userTransaction_T5(UserHandle * uh, + SubscriberNumber inNumber, + ServerId inServerId, + ServerBit inServerBit, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted){ + Ndb * pNDB = uh->pNDB; + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))]; + char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))]; + Location outLocation; + GroupId groupId; + ActiveSessions sessions; + Permission permission; + SubscriberSuffix inSuffix; + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&outLocation); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + &outChangedBy[0]); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + &outChangedTime[0]); + MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + MyTransaction->execute( NoCommit ); + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + MyOperation->readTuple(); + MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + memcpy(inSuffix, + &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG2("deleting(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + MyOperation->deleteTuple(); + MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); +} + diff --git a/ndb/test/ndbapi/bench/testData.h b/ndb/test/ndbapi/bench/testData.h new file mode 100644 index 00000000000..3db85e7342e --- /dev/null +++ b/ndb/test/ndbapi/bench/testData.h @@ -0,0 +1,156 @@ +/* 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 TESTDATA_H +#define TESTDATA_H + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ +#include +#include +#include +#include +#include "testDefinitions.h" + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +#define NUM_TRANSACTION_TYPES 5 +#define SESSION_LIST_LENGTH 1000 + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +typedef struct { + SubscriberNumber subscriberNumber; + ServerId serverId; +} SessionElement; + +typedef struct { + SessionElement list[SESSION_LIST_LENGTH]; + unsigned int readIndex; + unsigned int writeIndex; + unsigned int numberInList; +} SessionList; + +typedef struct { + unsigned int count; + unsigned int branchExecuted; + unsigned int rollbackExecuted; + + /** + * Latency measures + */ + NDB_TICKS startTime; + NDBT_Stats latency; + unsigned int latencyCounter; + + inline void startLatency(){ + if((latencyCounter & 127) == 127) + startTime = NdbTick_CurrentMillisecond(); + } + + inline void stopLatency(){ + if((latencyCounter & 127) == 127){ + const NDB_TICKS tmp = NdbTick_CurrentMillisecond() - startTime; + latency.addObservation(tmp); + } + latencyCounter++; + } +} TransactionDefinition; + +typedef struct { + RandomSequence transactionSequence; + RandomSequence rollbackSequenceT4; + RandomSequence rollbackSequenceT5; + + TransactionDefinition transactions[NUM_TRANSACTION_TYPES]; + + unsigned int totalTransactions; + + double outerLoopTime; + double outerTps; + + SessionList activeSessions; + +} GeneratorStatistics; + +typedef enum{ + Runnable, + Running +} RunState ; + +typedef struct { + SubscriberNumber number; + SubscriberSuffix suffix; + SubscriberName name; + Location location; + ChangedBy changed_by; + ChangedTime changed_time; + ServerId server_id; + ServerBit server_bit; + SessionDetails session_details; + + GroupId group_id; + ActiveSessions sessions; + Permission permission; + + unsigned int do_rollback; + + unsigned int branchExecuted; + unsigned int sessionElement; +} TransactionData ; + +typedef struct { + struct NdbThread* pThread; + + unsigned long randomSeed; + unsigned long changedTime; + + unsigned int warmUpSeconds; + unsigned int testSeconds; + unsigned int coolDownSeconds; + + GeneratorStatistics generator; + + /** + * For async execution + */ + RunState runState; + double startTime; + TransactionData transactionData; + struct Ndb * pNDB; +} ThreadData; + +/*************************************************************** + * P U B L I C F U N C T I O N S * + ***************************************************************/ + +/*************************************************************** + * E X T E R N A L D A T A * + ***************************************************************/ + + + +#endif /* TESTDATA_H */ + diff --git a/ndb/test/ndbapi/bench/testDefinitions.h b/ndb/test/ndbapi/bench/testDefinitions.h new file mode 100644 index 00000000000..2f4aeb30975 --- /dev/null +++ b/ndb/test/ndbapi/bench/testDefinitions.h @@ -0,0 +1,90 @@ +/* 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 TESTDEFINITIONS_H +#define TESTDEFINITIONS_H + +/***************************************************************/ +/* I N C L U D E D F I L E S */ +/***************************************************************/ + +#include + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +#define OP_PER_TRANS 200 +#define NO_OF_SUBSCRIBERS 500000 +#define NO_OF_GROUPS 100 +#define NO_OF_SERVERS 20 + +#define SUBSCRIBER_NUMBER_LENGTH 12 +#define SUBSCRIBER_NUMBER_SUFFIX_LENGTH 2 + +#define SUBSCRIBER_NAME_LENGTH 32 +#define CHANGED_BY_LENGTH 32 +#define CHANGED_TIME_LENGTH 32 +#define SESSION_DETAILS_LENGTH 2000 +#define SERVER_NAME_LENGTH 32 +#define GROUP_NAME_LENGTH 32 + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +#define PADDING 4 + +typedef char SubscriberNumber[SUBSCRIBER_NUMBER_LENGTH]; +typedef char SubscriberSuffix[SUBSCRIBER_NUMBER_SUFFIX_LENGTH + 2]; +typedef char SubscriberName[SUBSCRIBER_NAME_LENGTH]; +typedef char ServerName[SERVER_NAME_LENGTH]; +typedef char GroupName[GROUP_NAME_LENGTH]; +typedef char ChangedBy[CHANGED_BY_LENGTH]; +typedef char ChangedTime[CHANGED_TIME_LENGTH]; +typedef char SessionDetails[SESSION_DETAILS_LENGTH]; +typedef Uint32 ServerId; +typedef Uint32 ServerBit; +typedef Uint32 GroupId; +typedef Uint32 Location; +typedef Uint32 Permission; + +typedef Uint32 Counter; +typedef Uint32 ActiveSessions; +typedef unsigned int BranchExecuted; +typedef unsigned int DoRollback; + +/*************************************************************** +* P U B L I C F U N C T I O N S * +***************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +/*************************************************************** +* E X T E R N A L D A T A * +***************************************************************/ + + + +#endif /* TESTDEFINITIONS_H */ + diff --git a/ndb/test/ndbapi/bench/userInterface.cpp b/ndb/test/ndbapi/bench/userInterface.cpp new file mode 100644 index 00000000000..128d20dc9bb --- /dev/null +++ b/ndb/test/ndbapi/bench/userInterface.cpp @@ -0,0 +1,745 @@ +/* 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 +#ifndef NDB_WIN32 +#include +#endif + +#include "ndb_error.hpp" +#include "userInterface.h" +#include +#include +#include +#include +#include "ndb_schema.hpp" +#include +#include + +/*************************************************************** +* 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 * +***************************************************************/ + +extern int localDbPrepare(UserHandle *uh); + +static int dbCreate(UserHandle *uh); + +/*************************************************************** +* L O C A L D A T A * +***************************************************************/ + +/*************************************************************** +* 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 * +**************************************************************** +***************************************************************/ + +/*************************************************************** +**************************************************************** +* 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 * +**************************************************************** +***************************************************************/ + +/*-----------------------------------*/ +/* Time related Functions */ +/* */ +/* Returns a double value in seconds */ +/*-----------------------------------*/ +double userGetTimeSync(void) +{ + static int initialized = 0; + static NDB_TICKS initSecs = 0; + static Uint32 initMicros = 0; + double timeValue = 0; + + if ( !initialized ) { + initialized = 1; + NdbTick_CurrentMicrosecond(&initSecs, &initMicros); + timeValue = 0.0; + } else { + NDB_TICKS secs = 0; + Uint32 micros = 0; + + NdbTick_CurrentMicrosecond(&secs, µs); + + double s = (double)secs - (double)initSecs; + double us = (double)secs - (double)initMicros; + + timeValue = s + (us / 1000000.0); + } + + return timeValue; +} + +// 0 - OK +// 1 - Retry transaction +// 2 - Permanent +int +userDbCommit(UserHandle *uh){ + if(uh->pCurrTrans != 0){ + int check = uh->pCurrTrans->execute( Commit ); + NdbError err = uh->pCurrTrans->getNdbError(); + uh->pNDB->closeTransaction(uh->pCurrTrans); + uh->pCurrTrans = 0; + + if(err.status != NdbError::Success) + ndbout << err << endl; + + if(err.status == NdbError::TemporaryError && + err.classification == NdbError::OverloadError){ + NdbSleep_SecSleep(3); + } + + return err.status; + } + return 2; +} + +/** + * TRUE - Normal table + * FALSE - Table w.o. checkpoing and logging + */ + +#ifdef __cplusplus +extern "C" { +#endif +extern int useTableLogging; +extern int useIndexTables; +#ifdef __cplusplus +} +#endif + + +int +create_table_server(Ndb * pNdb){ + int check; + NdbSchemaCon * MySchemaTransaction = NdbSchemaCon::startSchemaTrans(pNdb); + if( MySchemaTransaction == NULL ) + error_handler("startSchemaTransaction", pNdb->getNdbError(), 0); + + NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler("getNdbSchemaOp", MySchemaTransaction->getNdbError(), 0); + + // Create table + check = MySchemaOp->createTable( SERVER_TABLE, + 8, // Table size + TupleKey, // Key Type + 1 // Nr of Pages + ,DistributionGroup, + 6, + 78, + 80, + 1, + useTableLogging + ); + if( check == -1 ) + error_handler("createTable", MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute + ( SERVER_SUBSCRIBER_SUFFIX, + TupleKey, + sizeof(char) << 3, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + String, + MMBased, + NotNullAttribute, + NormalStorageAttribute, + 0, + 1, + 16); + if( check == -1 ) + error_handler("createAttribute (subscriber suffix)", + MySchemaTransaction->getNdbError(), 0); + + // Create first column, primary key + check = MySchemaOp->createAttribute( SERVER_ID, + TupleKey, + sizeof(ServerId) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (serverid)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SERVER_NAME, + NoKey, + sizeof(char) << 3, + SERVER_NAME_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server name)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SERVER_READS, + NoKey, + sizeof(Counter) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server reads)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SERVER_INSERTS, + NoKey, + sizeof(Counter) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server inserts)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SERVER_DELETES, + NoKey, + sizeof(Counter) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server deletes)", + MySchemaTransaction->getNdbError(), 0); + + if( MySchemaTransaction->execute() == -1 ) { + error_handler("schemaTransaction->execute()", + MySchemaTransaction->getNdbError(), 0); + } + NdbSchemaCon::closeSchemaTrans(MySchemaTransaction); + return 0; +} + +int +create_table_group(Ndb * pNdb){ + int check; + + NdbSchemaCon * MySchemaTransaction = NdbSchemaCon::startSchemaTrans(pNdb); + if( MySchemaTransaction == NULL ) + error_handler("startSchemaTransaction", pNdb->getNdbError(), 0); + + NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler("getNdbSchemaOp", MySchemaTransaction->getNdbError(), 0); + + // Create table + check = MySchemaOp->createTable( GROUP_TABLE, + 8, // Table size + TupleKey, // Key Type + 1 // Nr of Pages + ,All, + 6, + 78, + 80, + 1, + useTableLogging + ); + + if( check == -1 ) + error_handler("createTable", MySchemaTransaction->getNdbError(), 0); + + // Create first column, primary key + check = MySchemaOp->createAttribute( GROUP_ID, + TupleKey, + sizeof(GroupId) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group id)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( GROUP_NAME, + NoKey, + sizeof(char) << 3, + GROUP_NAME_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group name)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( GROUP_ALLOW_READ, + NoKey, + sizeof(Permission) << 3, + 1, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group read)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( GROUP_ALLOW_INSERT, + NoKey, + sizeof(Permission) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group insert)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( GROUP_ALLOW_DELETE, + NoKey, + sizeof(Permission) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group delete)", + MySchemaTransaction->getNdbError(), 0); + + if( MySchemaTransaction->execute() == -1 ) { + error_handler("schemaTransaction->execute()", + MySchemaTransaction->getNdbError(), 0); + } + NdbSchemaCon::closeSchemaTrans(MySchemaTransaction); + return 0; +} + +int +create_table_subscriber(Ndb * pNdb){ + int check; + NdbSchemaCon * MySchemaTransaction = NdbSchemaCon::startSchemaTrans(pNdb); + if( MySchemaTransaction == NULL ) + error_handler("startSchemaTransaction", pNdb->getNdbError(), 0); + + NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler("getNdbSchemaOp", MySchemaTransaction->getNdbError(), 0); + + // Create table + check = MySchemaOp->createTable( SUBSCRIBER_TABLE, + 8, // Table size + TupleKey, // Key Type + 1 // Nr of Pages + ,DistributionGroup, + 6, + 78, + 80, + 1, + useTableLogging + ); + if( check == -1 ) + error_handler("createTable", MySchemaTransaction->getNdbError(), 0); + + // Create first column, primary key + check = MySchemaOp->createAttribute + ( SUBSCRIBER_NUMBER, + TupleKey, + sizeof(char) << 3, + SUBSCRIBER_NUMBER_LENGTH, + String, + MMBased, + NotNullAttribute, + (useIndexTables ? IndexStorageAttribute : NormalStorageAttribute), + 0, + 1, + 16); + if( check == -1 ) + error_handler("createAttribute (subscriber number)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SUBSCRIBER_NAME, + NoKey, + sizeof(char) << 3, + SUBSCRIBER_NAME_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber name)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SUBSCRIBER_GROUP, + NoKey, + sizeof(GroupId) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber_group)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SUBSCRIBER_LOCATION, + NoKey, + sizeof(Location) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server reads)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SUBSCRIBER_SESSIONS, + NoKey, + sizeof(ActiveSessions) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber_sessions)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SUBSCRIBER_CHANGED_BY, + NoKey, + sizeof(char) << 3, + CHANGED_BY_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber_changed_by)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SUBSCRIBER_CHANGED_TIME, + NoKey, + sizeof(char) << 3, + CHANGED_TIME_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber_changed_time)", + MySchemaTransaction->getNdbError(), 0); + + if( MySchemaTransaction->execute() == -1 ) { + error_handler("schemaTransaction->execute()", + MySchemaTransaction->getNdbError(), 0); + } + NdbSchemaCon::closeSchemaTrans(MySchemaTransaction); + return 0; +} + +int +create_table_session(Ndb * pNdb){ + int check; + NdbSchemaCon * MySchemaTransaction = NdbSchemaCon::startSchemaTrans(pNdb); + if( MySchemaTransaction == NULL ) + error_handler("startSchemaTransaction", pNdb->getNdbError(), 0); + + NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler("getNdbSchemaOp", + MySchemaTransaction->getNdbError(), 0); + + // Create table + check = MySchemaOp->createTable( SESSION_TABLE, + 8, // Table size + TupleKey, // Key Type + 1 // Nr of Pages + ,DistributionGroup, + 6, + 78, + 80, + 1, + useTableLogging + ); + if( check == -1 ) + error_handler("createTable", MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SESSION_SUBSCRIBER, + TupleKey, + sizeof(char) << 3, + SUBSCRIBER_NUMBER_LENGTH, + String, + MMBased, + NotNullAttribute, + NormalStorageAttribute, + 0, + 1, + 16); + if( check == -1 ) + error_handler("createAttribute (session_subscriber)", + MySchemaTransaction->getNdbError(), 0); + + // Create first column, primary key + check = MySchemaOp->createAttribute( SESSION_SERVER, + TupleKey, + sizeof(ServerId) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (session_server)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SESSION_DATA, + NoKey, + sizeof(char) << 3, + SESSION_DETAILS_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (session_data)", + MySchemaTransaction->getNdbError(), 0); + + if( MySchemaTransaction->execute() == -1 ) { + error_handler("schemaTransaction->execute()", + MySchemaTransaction->getNdbError(), 0); + } + NdbSchemaCon::closeSchemaTrans(MySchemaTransaction); + return 0; +} + +void +create_table(const char * name, int (* function)(Ndb * pNdb), Ndb* pNdb){ + printf("creating table %s...", name); + if(pNdb->getDictionary()->getTable(name) != 0){ + printf(" it already exists\n"); + return; + } else { + printf("\n"); + } + function(pNdb); + printf("creating table %s... done\n", name); +} + +static int dbCreate(Ndb * pNdb) +{ + create_table(SUBSCRIBER_TABLE, create_table_subscriber, pNdb); + create_table(GROUP_TABLE , create_table_group, pNdb); + create_table(SESSION_TABLE , create_table_session, pNdb); + create_table(SERVER_TABLE , create_table_server, pNdb); + return 0; +} + +#ifndef NDB_WIN32 +#include +#endif + +UserHandle* +userDbConnect(uint32 createDb, char *dbName) +{ + Ndb_cluster_connection *con= new Ndb_cluster_connection(); + if(con->connect(12, 5, 1) != 0) + { + ndbout << "Unable to connect to management server." << endl; + return 0; + } + if (con->wait_until_ready(30,0) < 0) + { + ndbout << "Cluster nodes not ready in 30 seconds." << endl; + return 0; + } + + Ndb * pNdb = new Ndb(con, dbName); + + //printf("Initializing...\n"); + pNdb->init(); + + //printf("Waiting..."); + while(pNdb->waitUntilReady() != 0){ + //printf("..."); + } + // printf("done\n"); + + if( createDb ) + dbCreate(pNdb); + + + UserHandle * uh = new UserHandle; + uh->pNCC = con; + uh->pNDB = pNdb; + uh->pCurrTrans = 0; + + return uh; +} + +void userDbDisconnect(UserHandle *uh) +{ + delete uh; +} + +int userDbInsertServer(UserHandle *uh, + ServerId serverId, + SubscriberSuffix suffix, + ServerName name) +{ + int check; + + uint32 noOfRead = 0; + uint32 noOfInsert = 0; + uint32 noOfDelete = 0; + + NdbConnection * MyTransaction = 0; + if(uh->pCurrTrans != 0){ + MyTransaction = uh->pCurrTrans; + } else { + uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); + } + if (MyTransaction == NULL) + error_handler("startTranscation", uh->pNDB->getNdbError(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "insert tuple", MyTransaction); + + check = MyOperation->equal(SERVER_ID, (char*)&serverId); + CHECK_MINUS_ONE(check, "setValue id", MyTransaction); + + check = MyOperation->setValue(SERVER_SUBSCRIBER_SUFFIX, suffix); + CHECK_MINUS_ONE(check, "setValue suffix", MyTransaction); + + check = MyOperation->setValue(SERVER_NAME, name); + CHECK_MINUS_ONE(check, "setValue name", MyTransaction); + + check = MyOperation->setValue(SERVER_READS, (char*)&noOfRead); + CHECK_MINUS_ONE(check, "setValue reads", MyTransaction); + + check = MyOperation->setValue(SERVER_INSERTS, (char*)&noOfInsert); + CHECK_MINUS_ONE(check, "setValue inserts", MyTransaction); + + check = MyOperation->setValue(SERVER_DELETES, (char*)&noOfDelete); + CHECK_MINUS_ONE(check, "setValue deletes", MyTransaction); + + return 0; +} + +int userDbInsertSubscriber(UserHandle *uh, + SubscriberNumber number, + uint32 groupId, + SubscriberName name) +{ + int check; + uint32 activeSessions = 0; + Location l = 0; + ChangedBy changedBy; snprintf(changedBy, sizeof(changedBy), "ChangedBy"); + ChangedTime changedTime; snprintf(changedTime, sizeof(changedTime), "ChangedTime"); + + NdbConnection * MyTransaction = 0; + if(uh->pCurrTrans != 0){ + MyTransaction = uh->pCurrTrans; + } else { + uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); + } + if (MyTransaction == NULL) + error_handler("startTranscation", uh->pNDB->getNdbError(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, number); + CHECK_MINUS_ONE(check, "equal", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_NAME, name); + CHECK_MINUS_ONE(check, "setValue name", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_GROUP, (char*)&groupId); + CHECK_MINUS_ONE(check, "setValue group", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_LOCATION, (char*)&l); + CHECK_MINUS_ONE(check, "setValue location", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_SESSIONS, (char*)&activeSessions); + CHECK_MINUS_ONE(check, "setValue sessions", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_CHANGED_BY, changedBy); + CHECK_MINUS_ONE(check, "setValue changedBy", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_CHANGED_TIME, changedTime); + CHECK_MINUS_ONE(check, "setValue changedTime", MyTransaction); + + return 0; +} + +int userDbInsertGroup(UserHandle *uh, + GroupId groupId, + GroupName name, + Permission allowRead, + Permission allowInsert, + Permission allowDelete) +{ + int check; + + NdbConnection * MyTransaction = 0; + if(uh->pCurrTrans != 0){ + MyTransaction = uh->pCurrTrans; + } else { + uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); + } + if (MyTransaction == NULL) + error_handler("startTranscation", uh->pNDB->getNdbError(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); + + check = MyOperation->equal(GROUP_ID, (char*)&groupId); + CHECK_MINUS_ONE(check, "equal", MyTransaction); + + check = MyOperation->setValue(GROUP_NAME, name); + CHECK_MINUS_ONE(check, "setValue name", MyTransaction); + + check = MyOperation->setValue(GROUP_ALLOW_READ, (char*)&allowRead); + CHECK_MINUS_ONE(check, "setValue allowRead", MyTransaction); + + check = MyOperation->setValue(GROUP_ALLOW_INSERT, (char*)&allowInsert); + CHECK_MINUS_ONE(check, "setValue allowInsert", MyTransaction); + + check = MyOperation->setValue(GROUP_ALLOW_DELETE, (char*)&allowDelete); + CHECK_MINUS_ONE(check, "setValue allowDelete", MyTransaction); + + return 0; +} + diff --git a/ndb/test/ndbapi/bench/userInterface.h b/ndb/test/ndbapi/bench/userInterface.h new file mode 100644 index 00000000000..9e3b6f8f2a5 --- /dev/null +++ b/ndb/test/ndbapi/bench/userInterface.h @@ -0,0 +1,151 @@ +/* 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 DBINTERFACE_H +#define DBINTERFACE_H + +/***************************************************************/ +/* I N C L U D E D F I L E S */ +/***************************************************************/ + +#include "testDefinitions.h" +#include "testData.h" + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +/*-----------------------*/ +/* Default Database Name */ +/*-----------------------*/ +#define DEFAULTDB "TestDbClient" + +/*************************************************************** +* 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 * +***************************************************************/ + +typedef struct Ndb Ndb; + +#ifdef __cplusplus +extern "C" { +#endif + extern void showTime(); + extern double userGetTime(void); + extern Ndb *asyncDbConnect(int parallellism); + extern void asyncDbDisconnect(Ndb* pNDB); + + extern void start_T1(Ndb * uh, ThreadData * data, int async); + extern void start_T2(Ndb * uh, ThreadData * data, int async); + extern void start_T3(Ndb * uh, ThreadData * data, int async); + extern void start_T4(Ndb * uh, ThreadData * data, int async); + extern void start_T5(Ndb * uh, ThreadData * data, int async); + + extern void complete_T1(ThreadData * data); + extern void complete_T2(ThreadData * data); + extern void complete_T3(ThreadData * data); + extern void complete_T4(ThreadData * data); + extern void complete_T5(ThreadData * data); + + + +#ifdef __cplusplus +} +#endif + + + +/***************************************************************/ +/* I N C L U D E D F I L E S */ +/***************************************************************/ + +#include "testDefinitions.h" + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +/*-----------------------*/ +/* Default Database Name */ +/*-----------------------*/ +#define DEFAULTDB "TestDbClient" + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +typedef struct { + struct Ndb_cluster_connection* pNCC; + struct Ndb * pNDB; + struct NdbConnection * pCurrTrans; +} UserHandle; + +/*************************************************************** +* P U B L I C F U N C T I O N S * +***************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +extern double userGetTimeSync(void); + +extern void userCheckpoint(UserHandle *uh); + +extern UserHandle *userDbConnect(uint32 createDb, char *dbName); +extern void userDbDisconnect(UserHandle *uh); + +extern int userDbInsertServer(UserHandle *uh, + ServerId serverId, + SubscriberSuffix suffix, + ServerName name); + +extern int userDbInsertSubscriber(UserHandle *uh, + SubscriberNumber number, + uint32 groupId, + SubscriberName name); + +extern int userDbInsertGroup(UserHandle *uh, + GroupId groupId, + GroupName name, + Permission allowRead, + Permission allowInsert, + Permission allowDelete); + + extern int userDbCommit(UserHandle *uh); + extern int userDbRollback(UserHandle *uh); + +#ifdef __cplusplus +} +#endif + +/*************************************************************** +* E X T E R N A L D A T A * +***************************************************************/ + +#endif /* DBINTERFACE_H */ + From f02115a3716677ca39f1972611f12f918148fc81 Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Thu, 10 Feb 2005 17:07:14 +0100 Subject: [PATCH 04/10] ndb - adapt old testprg to changes in ndbapi --- ndb/test/ndbapi/bench/userInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndb/test/ndbapi/bench/userInterface.h b/ndb/test/ndbapi/bench/userInterface.h index 9e3b6f8f2a5..bad61fcf171 100644 --- a/ndb/test/ndbapi/bench/userInterface.h +++ b/ndb/test/ndbapi/bench/userInterface.h @@ -101,7 +101,7 @@ extern "C" { typedef struct { struct Ndb_cluster_connection* pNCC; struct Ndb * pNDB; - struct NdbConnection * pCurrTrans; + struct NdbTransaction * pCurrTrans; } UserHandle; /*************************************************************** From e0cd99c298156cdea3abe3455a5bac723ef6a7a2 Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Thu, 10 Feb 2005 18:15:15 +0100 Subject: [PATCH 05/10] ndb - add more tests to autotest --- ndb/test/run-test/daily-basic-tests.txt | 2 +- ndb/test/run-test/daily-devel-tests.txt | 29 +++++++++++++++++++++++++ ndb/test/run-test/main.cpp | 9 ++++++-- ndb/test/run-test/run-test.hpp | 1 + 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt index c62908ae999..453fe1ad7ae 100644 --- a/ndb/test/run-test/daily-basic-tests.txt +++ b/ndb/test/run-test/daily-basic-tests.txt @@ -1,4 +1,4 @@ -max-time: 25000 +max-time: 3600 cmd: atrt-mysql-test-run args: --force diff --git a/ndb/test/run-test/daily-devel-tests.txt b/ndb/test/run-test/daily-devel-tests.txt index 5c9b36fb836..69c27ca229f 100644 --- a/ndb/test/run-test/daily-devel-tests.txt +++ b/ndb/test/run-test/daily-devel-tests.txt @@ -204,3 +204,32 @@ max-time: 2500 cmd: test_event args: -n BasicEventOperation T1 T6 +max-time: 300 +cmd: DbCreate +args: + +max-time: 180 +cmd: DbAsyncGenerator +args: -t 60 -p 1 +type: bench + +max-time: 180 +cmd: DbAsyncGenerator +args: -t 60 -p 25 +type: bench + +max-time: 180 +cmd: DbAsyncGenerator +args: -t 60 -p 100 +type: bench + +max-time: 180 +cmd: DbAsyncGenerator +args: -t 60 -p 200 +type: bench + +max-time: 180 +cmd: DbAsyncGenerator +args: -t 60 -p 1 -proc 25 +type: bench + diff --git a/ndb/test/run-test/main.cpp b/ndb/test/run-test/main.cpp index fb6754dae7a..02c2cc862a3 100644 --- a/ndb/test/run-test/main.cpp +++ b/ndb/test/run-test/main.cpp @@ -219,7 +219,7 @@ main(int argc, const char ** argv){ fflush(g_report_file); } - if(g_mode_bench || (g_mode_regression && result)){ + if(test_case.m_report || g_mode_bench || (g_mode_regression && result)){ BaseString tmp; tmp.assfmt("result.%d", test_no); if(rename("result", tmp.c_str()) != 0){ @@ -228,7 +228,7 @@ main(int argc, const char ** argv){ goto end; } } - + if(g_mode_interactive && result){ g_logger.info ("Encountered failed test in interactive mode - terminating"); @@ -908,6 +908,11 @@ read_test_case(FILE * file, atrt_testcase& tc, int& line){ tc.m_max_time = 60000; else tc.m_max_time = atoi(mt); + + if(p.get("type", &mt) && strcmp(mt, "bench") == 0) + tc.m_report= true; + else + tc.m_report= false; return true; } diff --git a/ndb/test/run-test/run-test.hpp b/ndb/test/run-test/run-test.hpp index 8d00a7b6a55..ff7f916d4ef 100644 --- a/ndb/test/run-test/run-test.hpp +++ b/ndb/test/run-test/run-test.hpp @@ -68,6 +68,7 @@ struct atrt_config { }; struct atrt_testcase { + bool m_report; time_t m_max_time; BaseString m_command; BaseString m_args; From 6039a50e0069bcd5441bcc6f9ed65bda27b0d605 Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Fri, 11 Feb 2005 06:39:00 +0100 Subject: [PATCH 06/10] ndb - old bench rescue --- ndb/test/ndbapi/bench/mainPopulate.cpp | 15 ++++++--------- ndb/test/ndbapi/bench/userInterface.cpp | 3 +-- ndb/test/run-test/daily-devel-tests.txt | 10 +++++----- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/ndb/test/ndbapi/bench/mainPopulate.cpp b/ndb/test/ndbapi/bench/mainPopulate.cpp index 5f4b73a3eff..d017c2a3f4b 100644 --- a/ndb/test/ndbapi/bench/mainPopulate.cpp +++ b/ndb/test/ndbapi/bench/mainPopulate.cpp @@ -22,12 +22,12 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { #endif int useTableLogging; -int useIndexTables; #ifdef __cplusplus } #endif @@ -44,7 +44,6 @@ void usage(const char *prog) ndbout_c( "Usage: %s [-l]\n" " -l Use logging and checkpointing on tables\n", - " -i Use index tables\n", prog); exit(1); @@ -57,28 +56,26 @@ NDB_COMMAND(DbCreate, "DbCreate", "DbCreate", "DbCreate", 16384) int i; UserHandle *uh; - useTableLogging = useIndexTables = 0; + useTableLogging = 0; NDB_INIT(argv[0]); for(i = 1; i Date: Fri, 11 Feb 2005 08:09:47 +0100 Subject: [PATCH 07/10] ndb - fix compiler warning (error using gcc-3.4.3) --- ndb/test/ndbapi/bench/mainPopulate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndb/test/ndbapi/bench/mainPopulate.cpp b/ndb/test/ndbapi/bench/mainPopulate.cpp index d017c2a3f4b..5ab1a5b015d 100644 --- a/ndb/test/ndbapi/bench/mainPopulate.cpp +++ b/ndb/test/ndbapi/bench/mainPopulate.cpp @@ -53,11 +53,11 @@ NDB_STD_OPTS_VARS; NDB_COMMAND(DbCreate, "DbCreate", "DbCreate", "DbCreate", 16384) { + ndb_init(); int i; UserHandle *uh; useTableLogging = 0; - NDB_INIT(argv[0]); for(i = 1; i Date: Sat, 12 Feb 2005 15:05:33 +0100 Subject: [PATCH 08/10] wl1292 - ndb autotest link to log if it exists, regardless of test result --- ndb/test/run-test/make-html-reports.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ndb/test/run-test/make-html-reports.sh b/ndb/test/run-test/make-html-reports.sh index 89f13a4b62a..6278b835dea 100755 --- a/ndb/test/run-test/make-html-reports.sh +++ b/ndb/test/run-test/make-html-reports.sh @@ -154,9 +154,13 @@ do ts=`time_spec $time` res_txt="" case $res in - 0) pass; res_txt="PASSED"; res_dir=" ";; + 0) pass; res_txt="PASSED";; *) fail; res_txt="FAILED";; esac + + if [ ! -d "result.$no" ]; then res_dir=" "; fi + + total=`expr $total + $time` ( From 9b50ee3adae5ab15d6209691c622843b6f695243 Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Sat, 12 Feb 2005 15:12:53 +0100 Subject: [PATCH 09/10] wl1292 - ndb autotest Fix 4.1 memleak in Hugo --- ndb/test/include/HugoOperations.hpp | 2 +- ndb/test/src/HugoTransactions.cpp | 15 --------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/ndb/test/include/HugoOperations.hpp b/ndb/test/include/HugoOperations.hpp index 9ca2772e768..a23d3018f47 100644 --- a/ndb/test/include/HugoOperations.hpp +++ b/ndb/test/include/HugoOperations.hpp @@ -100,7 +100,7 @@ protected: struct RsPair { NdbResultSet* m_result_set; int records; }; Vector m_result_sets; Vector m_executed_result_sets; -private: + NdbConnection* pTrans; }; diff --git a/ndb/test/src/HugoTransactions.cpp b/ndb/test/src/HugoTransactions.cpp index 85c96ef0f7f..5d5b2fa99df 100644 --- a/ndb/test/src/HugoTransactions.cpp +++ b/ndb/test/src/HugoTransactions.cpp @@ -40,7 +40,6 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, int retryAttempt = 0; const int retryMax = 100; int check, a; - NdbConnection *pTrans; NdbScanOperation *pOp; while (true){ @@ -196,7 +195,6 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, int retryAttempt = 0; const int retryMax = 100; int check, a; - NdbConnection *pTrans; NdbIndexScanOperation *pOp; while (true){ @@ -369,7 +367,6 @@ HugoTransactions::scanUpdateRecords1(Ndb* pNdb, int retryAttempt = 0; const int retryMax = 100; int check, a; - NdbConnection *pTrans; NdbOperation *pOp; @@ -536,7 +533,6 @@ HugoTransactions::scanUpdateRecords2(Ndb* pNdb, int retryAttempt = 0; const int retryMax = 100; int check, a; - NdbConnection *pTrans; NdbOperation *pOp; @@ -619,7 +615,6 @@ HugoTransactions::scanUpdateRecords2(Ndb* pNdb, int eof; int rows = 0; - NdbConnection* pUpTrans; while((eof = pTrans->nextScanResult(true)) == 0){ pUpTrans = pNdb->startTransaction(); @@ -702,7 +697,6 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb, int retryAttempt = 0; const int retryMax = 100; int check, a; - NdbConnection *pTrans; NdbScanOperation *pOp; @@ -846,7 +840,6 @@ HugoTransactions::loadTable(Ndb* pNdb, int check, a; int retryAttempt = 0; int retryMax = 5; - NdbConnection *pTrans; NdbOperation *pOp; bool first_batch = true; @@ -992,7 +985,6 @@ HugoTransactions::fillTable(Ndb* pNdb, int check, a, b; int retryAttempt = 0; int retryMax = 5; - NdbConnection *pTrans; NdbOperation *pOp; g_info << "|- Inserting records..." << endl; @@ -1384,7 +1376,6 @@ HugoTransactions::pkReadRecords(Ndb* pNdb, int retryAttempt = 0; const int retryMax = 100; int check, a; - NdbConnection *pTrans; NdbOperation *pOp; if (batchsize == 0) { @@ -1521,7 +1512,6 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb, int retryAttempt = 0; const int retryMax = 100; int check, a, b; - NdbConnection *pTrans; NdbOperation *pOp; allocRows(batch); @@ -1689,7 +1679,6 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb, int retryAttempt = 0; const int retryMax = 100; int check, a; - NdbConnection *pTrans; while (r < records){ @@ -1868,7 +1857,6 @@ HugoTransactions::pkDelRecords(Ndb* pNdb, int retryAttempt = 0; const int retryMax = 100; int check, a; - NdbConnection *pTrans; NdbOperation *pOp; g_info << "|- Deleting records..." << endl; @@ -1983,7 +1971,6 @@ HugoTransactions::lockRecords(Ndb* pNdb, int retryAttempt = 0; const int retryMax = 100; int check, a, b; - NdbConnection *pTrans; NdbOperation *pOp; // Calculate how many records to lock in each batch @@ -2130,7 +2117,6 @@ HugoTransactions::indexReadRecords(Ndb* pNdb, int retryAttempt = 0; const int retryMax = 100; int check, a; - NdbConnection *pTrans; NdbOperation *pOp; NdbIndexScanOperation *sOp; NdbResultSet * rs; @@ -2281,7 +2267,6 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb, int retryAttempt = 0; const int retryMax = 100; int check, a, b; - NdbConnection *pTrans; NdbOperation *pOp; NdbScanOperation * sOp; NdbResultSet * rs; From 93a7878c1536bc7ed9f291d3527490db6fb56c01 Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Mon, 14 Feb 2005 08:28:47 +0100 Subject: [PATCH 10/10] wl1292 - ndb autotest fix log reports --- ndb/test/run-test/make-html-reports.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ndb/test/run-test/make-html-reports.sh b/ndb/test/run-test/make-html-reports.sh index 6278b835dea..67395ceba47 100755 --- a/ndb/test/run-test/make-html-reports.sh +++ b/ndb/test/run-test/make-html-reports.sh @@ -158,8 +158,7 @@ do *) fail; res_txt="FAILED";; esac - if [ ! -d "result.$no" ]; then res_dir=" "; fi - + if [ ! -d "$src_dir/result.$no" ]; then res_dir=" "; fi total=`expr $total + $time`