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