benchronja.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:43k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /* ***************************************************
  14.        NODEREC
  15.        Perform benchmark of insert, update and delete transactions
  16.        Arguments:
  17.         -t Number of threads to start, default 1
  18.         -o Number of loops per thread, default 100000
  19.  * *************************************************** */
  20. #include <ndb_global.h>
  21. #include <NdbApi.hpp>
  22. #include <NdbTest.hpp>
  23. #include <NdbOut.hpp>
  24. #include <NdbThread.h>
  25. #include <NdbSleep.h>
  26. #include <NdbMain.h>
  27. #include <NdbTimer.hpp>
  28. #include <NdbTick.h>
  29. #include <random.h>
  30. #define MAX_TIMERS 4 
  31. #define MAXSTRLEN 16 
  32. #define MAXATTR 64
  33. #define MAXTABLES 64
  34. #define MAXTHREADS 256
  35. #define MAXATTRSIZE 8000
  36. #define START_TIMER NdbTimer timer; timer.doStart();
  37. #define STOP_TIMER timer.doStop();
  38. #define START_TIMER_TOP NdbTimer timer_top; timer_top.doStart();
  39. #define STOP_TIMER_TOP timer_top.doStop();
  40. void* ThreadExec(void*);
  41. struct ThreadNdb
  42. {
  43.   int NoOfOps;
  44.   int ThreadNo;
  45.   Ndb* NdbRef;
  46. };
  47. static NdbThread* threadLife[MAXTHREADS];
  48. static unsigned int tNoOfThreads;
  49. static unsigned int tNoOfOpsPerExecute;
  50. static unsigned int tNoOfRecords;
  51. static unsigned int tNoOfOperations;
  52. static int ThreadReady[MAXTHREADS];
  53. static int ThreadStart[MAXTHREADS];
  54. NDB_COMMAND(benchronja, "benchronja", "benchronja", "benchronja", 65535){
  55.   ndb_init();
  56.   ThreadNdb tabThread[MAXTHREADS];
  57.   int i = 0 ;
  58.   int cont = 0 ;
  59.   Ndb* pMyNdb = NULL ; //( "TEST_DB" );
  60.   int           tmp = 0 ;
  61.   int nTest = 0 ;
  62.   char inp[100] ;
  63.   tNoOfThreads = 1; // Default Value
  64.   tNoOfOpsPerExecute = 1; // Default Value
  65.   tNoOfOperations = 100000; // Default Value
  66.   tNoOfRecords = 500 ; // Default Value <epaulsa: changed from original 500,000 to match 'initronja's' default  
  67.   i = 1;
  68.   while (argc > 1)
  69.   {
  70.     if (strcmp(argv[i], "-t") == 0){
  71.       tNoOfThreads = atoi(argv[i+1]);
  72.       if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)) goto error_input;
  73.     }else if (strcmp(argv[i], "-o") == 0){
  74.       tNoOfOperations = atoi(argv[i+1]);
  75.       if (tNoOfOperations < 1) goto error_input;
  76.     }else if (strcmp(argv[i], "-r") == 0){
  77.       tNoOfRecords = atoi(argv[i+1]);
  78.       if ((tNoOfRecords < 1) || (tNoOfRecords > 1000000000)) goto error_input;
  79. }else if (strcmp(argv[i], "-p") == 0){
  80. nTest = atoi(argv[i+1]) ;
  81. if (0 > nTest || 18 < nTest) goto error_input ;
  82.     }else if (strcmp(argv[i], "-c") == 0){
  83.       tNoOfOpsPerExecute = atoi(argv[i+1]);
  84.       if ((tNoOfOpsPerExecute < 1) || (tNoOfOpsPerExecute > 1024)) goto error_input;
  85.     }else{
  86.       goto error_input;
  87.     }
  88.     argc -= 2;
  89.     i = i + 2;
  90.   }
  91.   ndbout << "Initialisation started. " << endl;
  92.   pMyNdb = new Ndb("TEST_DB") ;
  93.   pMyNdb->init();
  94.   ndbout << "Initialisation completed. " << endl;
  95.   ndbout << endl << "Execute Ronja Benchmark" << endl;
  96.   ndbout << "  NdbAPI node with id = " << pMyNdb->getNodeId() << endl;
  97.   ndbout << "  " << tNoOfThreads << " thread(s) " << endl;
  98.   ndbout << "  " << tNoOfOperations << " transaction(s) per thread and round " << endl;
  99.   if (pMyNdb->waitUntilReady(120) != 0) {
  100.     ndbout << "Benchmark failed - NDB is not ready" << endl;
  101. delete pMyNdb ;
  102.     return NDBT_ProgramExit(NDBT_FAILED);
  103.   }//if
  104.   NdbThread_SetConcurrencyLevel(2 + tNoOfThreads);
  105.   for (i = 0; i < tNoOfThreads ; i++) {
  106.     ThreadReady[i] = 0;
  107.     ThreadStart[i] = 0;
  108.   }//for
  109.   for (i = 0; i < tNoOfThreads ; i++) {
  110.     tabThread[i].ThreadNo = i;
  111.     tabThread[i].NdbRef = NULL;
  112.     tabThread[i].NoOfOps = tNoOfOperations;
  113.     threadLife[i] = NdbThread_Create(ThreadExec,
  114.                                        (void**)&tabThread[i],
  115.                                        32768,
  116.                                        "RonjaThread",
  117.                                        NDB_THREAD_PRIO_LOW);
  118.   }//for
  119.   
  120.   cont = 1;
  121.   while (cont) {
  122. NdbSleep_MilliSleep(10);
  123.     cont = 0;
  124.     for (i = 0; i < tNoOfThreads ; i++)
  125.       if (!ThreadReady[i]) cont = 1;
  126.   }//while
  127.   ndbout << "All threads started" << endl;
  128.   
  129.   if(!nTest){
  130.   for (;;){
  131.   inp[0] = 0;
  132.   ndbout << endl << "What to do next:" << endl;
  133.   ndbout << "1 t=> Perform lookups in short table" << endl;
  134.   ndbout << "2 t=> Perform lookups in long table" << endl;
  135.   ndbout << "3 t=> Perform updates in short table" << endl;
  136.   ndbout << "4 t=> Perform updates in long table" << endl;
  137.   ndbout << "5 t=> Perform 50% lookups/50% updates in short table" << endl;
  138.   ndbout << "6 t=> Perform 50% lookups/50% updates in long table" << endl;
  139.   ndbout << "7 t=> Perform 80% lookups/20% updates in short table" << endl;
  140.   ndbout << "8 t=> Perform 80% lookups/20% updates in long table" << endl;
  141.   ndbout << "9 t=> Perform 25% lookups short/25% lookups long/25% updates short/25% updates long" << endl;
  142.   ndbout << "10t=> Test bug with replicated interpreted updates, short table" << endl;
  143.   ndbout << "11t=> Test interpreter functions, short table" << endl;
  144.   ndbout << "12t=> Test bug with replicated interpreted updates, long table" << endl;
  145.   ndbout << "13t=> Test interpreter functions, long table" << endl;
  146.   ndbout << "14t=> Perform lookups in short table, no guess of TC" << endl;
  147.   ndbout << "15t=> Perform lookups in long table, no guess of TC" << endl;
  148.   ndbout << "16t=> Perform updates in short table, no guess of TC" << endl;
  149.   ndbout << "17t=> Perform updates in long table, no guess of TC" << endl;
  150.   ndbout << "18t=> Multi record updates of transactions" << endl;
  151.   ndbout << "All other responses will exit" << endl;
  152.   ndbout << "_____________________________" << endl << endl ;
  153.   
  154.   int inp_i = 0;
  155.   do {
  156.     inp[inp_i] = (char) fgetc(stdin);     
  157.     if (inp[inp_i] == 'n' || inp[inp_i] == EOF) {
  158.       inp[inp_i] ='';
  159.       break;
  160.     }
  161.     inp_i++;
  162.   } while (inp[inp_i - 1] != 'n' && inp[inp_i - 1] != EOF);
  163.   
  164.   tmp = atoi(inp);
  165.   
  166.   if ((tmp > 18) || (tmp <= 0)) break;
  167.   
  168.   ndbout << "Starting test " << tmp << "..." << endl;
  169.   for (i = 0; i < tNoOfThreads ; i++){ ThreadStart[i] = tmp; }
  170.   
  171.   cont = 1;
  172.   while (cont) {
  173.   NdbSleep_MilliSleep(10);
  174.   cont = 0;
  175.   for (i = 0; i < tNoOfThreads ; i++){
  176.   if (!ThreadReady[i]) cont = 1;
  177.   }
  178.   }//while
  179.   }//for(;;)
  180.   }else{
  181.   if(19 == nTest){
  182.   ndbout << "Executing all 18 available tests..." << endl << endl;
  183.   for (int count = 1; count < nTest; count++){
  184.   ndbout << "Test " << count << endl ;
  185.   ndbout << "------" << endl << endl ;
  186.   for (i = 0; i < tNoOfThreads ; i++) { ThreadStart[i] = count ; }
  187.   cont = 1;
  188.   while (cont) {
  189.   NdbSleep_MilliSleep(10);
  190.   cont = 0;
  191.   for (i = 0; i < tNoOfThreads ; i++){
  192.   if (!ThreadReady[i]) cont = 1;
  193.   }
  194.   }
  195.   }//for
  196.   }else{
  197.   ndbout << endl << "Executing test " << nTest << endl << endl;
  198.   for (i = 0; i < tNoOfThreads ; i++) { ThreadStart[i] = nTest ; }
  199.   cont = 1;
  200.   while (cont) {
  201.   NdbSleep_MilliSleep(10);
  202.   cont = 0;
  203.   for (i = 0; i < tNoOfThreads ; i++){
  204.   if (!ThreadReady[i]) cont = 1;
  205.   }
  206.   }
  207.   }//if(18 == nTest)
  208.   } //if(!nTest)
  209.   ndbout << "--------------------------------------------------" << endl;
  210.   for (i = 0; i < tNoOfThreads ; i++) ThreadReady[i] = 0;
  211.   // Signaling threads to stop 
  212.   for (i = 0; i < tNoOfThreads ; i++) ThreadStart[i] = 999;
  213.     // Wait for threads to stop
  214.   cont = 1;
  215.   do {
  216.      NdbSleep_MilliSleep(1);
  217.  cont = 0;
  218.  for (i = 0; i < tNoOfThreads ; i++){
  219.       if (ThreadReady[i] == 0) cont = 1;
  220.  }
  221.   } while (cont == 1);
  222.   delete pMyNdb ;
  223.   ndbout << endl << "Ronja Benchmark completed" << endl;
  224.   return NDBT_ProgramExit(NDBT_OK) ;
  225. error_input:
  226.   ndbout << endl << "  Ivalid parameter(s)" << endl;
  227.   ndbout <<         "  Usage: benchronja [-t threads][-r rec] [-o ops] [-c ops_per_exec] [-p test], where:" << endl;
  228.   ndbout << "  threads - the number of threads to start; default: 1" << endl;
  229.   ndbout << "  rec - the number of records in the tables; default: 500" << endl;
  230.   ndbout << "  ops - the number of operations per transaction; default: 100000" << endl;
  231.   ndbout << "  ops_per_exec - the number of operations per execution; default: 1" << endl ;
  232.   ndbout << "  test - the number of test to execute; 19 executes all available tests; default: 0"<< endl ;
  233.   ndbout << "  which enters a loop expecting manual input of test number to execute." << endl << endl ;
  234.   delete pMyNdb ;
  235.   return NDBT_ProgramExit(NDBT_WRONGARGS) ;
  236.   }
  237. ////////////////////////////////////////
  238. void commitTrans(Ndb* aNdb, NdbConnection* aCon)
  239. {
  240.   int ret = aCon->execute(Commit);
  241.   assert (ret != -1);
  242.   aNdb->closeTransaction(aCon);
  243. }
  244. void rollbackTrans(Ndb* aNdb, NdbConnection* aCon)
  245. {
  246.   int ret = aCon->execute(Rollback);
  247.   assert (ret != -1);
  248.   aNdb->closeTransaction(aCon);
  249. }
  250. void updateNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key)
  251. {
  252.   NdbOperation* theOperation;
  253.   *flip = *flip + 1;
  254.   theOperation = aCon->getNdbOperation("SHORT_REC");
  255.   theOperation->updateTuple();
  256.   theOperation->equal((Uint32)0, key);
  257.   theOperation->setValue((Uint32)1, (char*)flip);
  258.   int ret = aCon->execute(NoCommit);
  259.   assert (ret != -1);
  260. }
  261. void updateNoCommitFail(NdbConnection* aCon, unsigned int key)
  262. {
  263.   NdbOperation* theOperation;
  264.   Uint32 flip = 0;
  265.   theOperation = aCon->getNdbOperation("SHORT_REC");
  266.   theOperation->updateTuple();
  267.   theOperation->equal((Uint32)0, key);
  268.   theOperation->setValue((Uint32)1, (char*)flip);
  269.   int ret = aCon->execute(NoCommit);
  270.   assert (ret == -1);
  271. }
  272. void deleteNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key)
  273. {
  274.   NdbOperation* theOperation;
  275.   *flip = 0;
  276.   theOperation = aCon->getNdbOperation("SHORT_REC");
  277.   theOperation->deleteTuple();
  278.   theOperation->equal((Uint32)0, key);
  279.   int ret = aCon->execute(NoCommit);
  280.   assert (ret != -1);
  281. }
  282. void insertNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key)
  283. {
  284.   NdbOperation* theOperation;
  285.   Uint32 placeholder[100];
  286.   *flip = *flip + 1;
  287.   theOperation = aCon->getNdbOperation("SHORT_REC");
  288.   theOperation->insertTuple();
  289.   theOperation->equal((Uint32)0, key);
  290.   theOperation->setValue((Uint32)1, (char*)flip);
  291.   theOperation->setValue((Uint32)2, (char*)&placeholder[0]);
  292.   theOperation->setValue((Uint32)3, (char*)&placeholder[0]);
  293.   int ret = aCon->execute(NoCommit);
  294.   assert (ret != -1);
  295. }
  296. void writeNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key)
  297. {
  298.   NdbOperation* theOperation;
  299.   Uint32 placeholder[100];
  300.   *flip = *flip + 1;
  301.   theOperation = aCon->getNdbOperation("SHORT_REC");
  302.   theOperation->writeTuple();
  303.   theOperation->equal((Uint32)0, key);
  304.   theOperation->setValue((Uint32)1, (char*)flip);
  305.   theOperation->setValue((Uint32)2, (char*)&placeholder[0]);
  306.   theOperation->setValue((Uint32)3, (char*)&placeholder[0]);
  307.   int ret = aCon->execute(NoCommit);
  308.   assert (ret != -1);
  309. }
  310. void readNoCommit(NdbConnection* aCon, Uint32* flip, Uint32 key, int expected_ret)
  311. {
  312.   NdbOperation* theOperation;
  313.   Uint32 readFlip;
  314.   theOperation = aCon->getNdbOperation("SHORT_REC");
  315.   theOperation->readTuple();
  316.   theOperation->equal((Uint32)0, key);
  317.   theOperation->getValue((Uint32)1, (char*)&readFlip);
  318.   int ret = aCon->execute(NoCommit);
  319.   assert (ret == expected_ret);
  320.   if (ret == 0) 
  321.     assert (*flip == readFlip);
  322. }
  323. void readDirtyNoCommit(NdbConnection* aCon, Uint32* flip, Uint32 key, int expected_ret)
  324. {
  325.   NdbOperation* theOperation;
  326.   Uint32 readFlip;
  327.   theOperation = aCon->getNdbOperation("SHORT_REC");
  328.   theOperation->committedRead();
  329.   theOperation->equal((Uint32)0, key);
  330.   theOperation->getValue((Uint32)1, (char*)&readFlip);
  331.   int ret = aCon->execute(NoCommit);
  332.   assert (ret == expected_ret);
  333.   if (ret == 0) 
  334.     assert (*flip == readFlip);
  335. }
  336. void readVerify(Ndb* aNdb, Uint32* flip, Uint32 key, int expected_ret)
  337. {
  338.   NdbConnection* theTransaction;
  339.   theTransaction = aNdb->startTransaction();
  340.   readNoCommit(theTransaction, flip, key, expected_ret);
  341.   commitTrans(aNdb, theTransaction);
  342. }
  343. void readDirty(Ndb* aNdb, Uint32* flip, Uint32 key, int expected_ret)
  344. {
  345.   NdbOperation* theOperation;
  346.   NdbConnection* theTransaction;
  347.   Uint32 readFlip;
  348.   theTransaction = aNdb->startTransaction();
  349.   theOperation = theTransaction->getNdbOperation("SHORT_REC");
  350.   theOperation->committedRead();
  351.   theOperation->equal((Uint32)0, key);
  352.   theOperation->getValue((Uint32)1, (char*)&readFlip);
  353.   int ret = theTransaction->execute(Commit);
  354.   assert (ret == expected_ret);
  355.   if (ret == 0) 
  356.     assert (*flip == readFlip);
  357.   aNdb->closeTransaction(theTransaction);
  358. }
  359. int multiRecordTest(Ndb* aNdb, unsigned int key)
  360. {
  361.   NdbConnection* theTransaction;
  362.   Uint32 flip = 0;
  363.   Uint32 save_flip;
  364.   ndbout << "0" << endl;
  365.   theTransaction = aNdb->startTransaction();
  366.   updateNoCommit(theTransaction, &flip, key);
  367.   readNoCommit(theTransaction, &flip, key, 0);
  368.   updateNoCommit(theTransaction, &flip, key);
  369.   readNoCommit(theTransaction, &flip, key, 0);
  370.   commitTrans(aNdb, theTransaction);
  371.   ndbout << "1 " << endl;
  372.   readVerify(aNdb, &flip, key, 0);
  373.   readDirty(aNdb, &flip, key, 0);
  374.   save_flip = flip;
  375.   ndbout << "1.1 " << endl;
  376.   theTransaction = aNdb->startTransaction();
  377.   deleteNoCommit(theTransaction, &flip, key);
  378.   readNoCommit(theTransaction, &flip, key, -1);
  379.   readDirty(aNdb, &save_flip, key, 0);           // COMMITTED READ!!!
  380.   readDirtyNoCommit(theTransaction, &flip, key, -1);
  381.   ndbout << "1.2 " << endl;
  382.   insertNoCommit(theTransaction, &flip, key);
  383.   readNoCommit(theTransaction, &flip, key, 0);
  384.   readDirtyNoCommit(theTransaction, &flip, key, 0);
  385.   readDirty(aNdb, &save_flip, key, 0);           // COMMITTED READ!!!
  386.   ndbout << "1.3 " << endl;
  387.   updateNoCommit(theTransaction, &flip, key);
  388.   readNoCommit(theTransaction, &flip, key, 0);
  389.   readDirtyNoCommit(theTransaction, &flip, key, 0);
  390.   readDirty(aNdb, &save_flip, key, 0);           // COMMITTED READ!!!
  391.   ndbout << "1.4 " << endl;
  392.   commitTrans(aNdb, theTransaction);
  393.   ndbout << "2 " << endl;
  394.   readDirty(aNdb, &flip, key, 0);           // COMMITTED READ!!!
  395.   readVerify(aNdb, &flip, key, 0);
  396.   save_flip = flip;
  397.   theTransaction = aNdb->startTransaction();
  398.   deleteNoCommit(theTransaction, &flip, key);
  399.   readDirty(aNdb, &save_flip, key, 0);                     // COMMITTED READ!!!
  400.   readDirtyNoCommit(theTransaction, &flip, key, -1);       // COMMITTED READ!!!
  401.   readNoCommit(theTransaction, &flip, key, -1);
  402.   insertNoCommit(theTransaction, &flip, key);
  403.   readNoCommit(theTransaction, &flip, key, 0);
  404.   updateNoCommit(theTransaction, &flip, key);
  405.   readNoCommit(theTransaction, &flip, key, 0);
  406.   readDirty(aNdb, &save_flip, key, 0);                     // COMMITTED READ!!!
  407.   readDirtyNoCommit(theTransaction, &flip, key, 0);        // COMMITTED READ!!!
  408.   deleteNoCommit(theTransaction, &flip, key);
  409.   readNoCommit(theTransaction, &flip, key, -1);
  410.   readDirty(aNdb, &save_flip, key, 0);                     // COMMITTED READ!!!
  411.   readDirtyNoCommit(theTransaction, &flip, key, -1);
  412.   rollbackTrans(aNdb, theTransaction);
  413.   ndbout << "3 " << endl;
  414.   flip = save_flip;
  415.   readDirty(aNdb, &save_flip, key, 0);                     // COMMITTED READ!!!
  416.   readVerify(aNdb, &flip, key, 0);
  417.   theTransaction = aNdb->startTransaction();
  418.   updateNoCommit(theTransaction, &flip, key);
  419.   readDirty(aNdb, &save_flip, key, 0);                     // COMMITTED READ!!!
  420.   readDirtyNoCommit(theTransaction, &flip, key, 0);
  421.   readNoCommit(theTransaction, &flip, key, 0);
  422.   deleteNoCommit(theTransaction, &flip, key);
  423.   readNoCommit(theTransaction, &flip, key, -1);
  424.   readDirtyNoCommit(theTransaction, &flip, key, -1);
  425.   readDirty(aNdb, &save_flip, key, 0);                     // COMMITTED READ!!!
  426.   insertNoCommit(theTransaction, &flip, key);
  427.   readNoCommit(theTransaction, &flip, key, 0);
  428.   readDirtyNoCommit(theTransaction, &flip, key, 0);
  429.   readDirty(aNdb, &save_flip, key, 0);                     // COMMITTED READ!!!
  430.   updateNoCommit(theTransaction, &flip, key);
  431.   readNoCommit(theTransaction, &flip, key, 0);
  432.   readDirtyNoCommit(theTransaction, &flip, key, 0);
  433.   readDirty(aNdb, &save_flip, key, 0);                     // COMMITTED READ!!!
  434.   deleteNoCommit(theTransaction, &flip, key);
  435.   readDirty(aNdb, &save_flip, key, 0);                     // COMMITTED READ!!!
  436.   readNoCommit(theTransaction, &flip, key, -1);
  437.   readDirtyNoCommit(theTransaction, &flip, key, -1);
  438.   commitTrans(aNdb, theTransaction);
  439.   ndbout << "4 " << endl;
  440.   readVerify(aNdb, &flip, key, -1);
  441.   theTransaction = aNdb->startTransaction();
  442.   insertNoCommit(theTransaction, &flip, key);
  443.   readDirty(aNdb, &save_flip, key, -1);                     // COMMITTED READ!!!
  444.   readNoCommit(theTransaction, &flip, key, 0);
  445.   readDirtyNoCommit(theTransaction, &flip, key, 0);
  446.   deleteNoCommit(theTransaction, &flip, key);
  447.   readDirty(aNdb, &save_flip, key, -1);                     // COMMITTED READ!!!
  448.   readNoCommit(theTransaction, &flip, key, -1);
  449.   readDirtyNoCommit(theTransaction, &flip, key, -1);
  450.   insertNoCommit(theTransaction, &flip, key);
  451.   readDirty(aNdb, &save_flip, key, -1);                     // COMMITTED READ!!!
  452.   readNoCommit(theTransaction, &flip, key, 0);
  453.   readDirtyNoCommit(theTransaction, &flip, key, 0);
  454.   updateNoCommit(theTransaction, &flip, key);
  455.   readDirty(aNdb, &save_flip, key, -1);                     // COMMITTED READ!!!
  456.   readNoCommit(theTransaction, &flip, key, 0);
  457.   readDirtyNoCommit(theTransaction, &flip, key, 0);
  458.   deleteNoCommit(theTransaction, &flip, key);
  459.   readDirty(aNdb, &save_flip, key, -1);                     // COMMITTED READ!!!
  460.   readNoCommit(theTransaction, &flip, key, -1);
  461.   readDirtyNoCommit(theTransaction, &flip, key, -1);
  462.   commitTrans(aNdb, theTransaction);
  463.   ndbout << "5 " << endl;
  464.   readDirty(aNdb, &flip, key, -1);                         // COMMITTED READ!!!
  465.   readVerify(aNdb, &flip, key, -1);
  466.   theTransaction = aNdb->startTransaction();
  467.   insertNoCommit(theTransaction, &flip, key);
  468.   readDirty(aNdb, &flip, key, -1);                         // COMMITTED READ!!!
  469.   readDirtyNoCommit(theTransaction, &flip, key, 0);        // COMMITTED READ!!!
  470.   commitTrans(aNdb, theTransaction);
  471.   readDirty(aNdb, &flip, key, 0);                          // COMMITTED READ!!!
  472.   ndbout << "6 " << endl;
  473.   theTransaction = aNdb->startTransaction();
  474.   deleteNoCommit(theTransaction, &flip, key);
  475.   updateNoCommitFail(theTransaction, key);
  476.   rollbackTrans(aNdb, theTransaction);
  477.   return 0;
  478. }
  479. int lookup(Ndb* aNdb, unsigned int key, unsigned int long_short, int guess){
  480.   int placeholder[500];
  481.   unsigned int flip, count;
  482.   int ret_value, i;
  483.   NdbConnection* theTransaction;
  484.   NdbOperation* theOperation;
  485.   if ( !aNdb ) return -1 ;
  486.   if (guess != 0)
  487.     theTransaction = aNdb->startTransaction((Uint32)0, (const char*)&key, (Uint32)4);
  488.   else
  489.     theTransaction = aNdb->startTransaction();
  490.   for (i = 0; i < tNoOfOpsPerExecute; i++) {
  491.     if (long_short == 0)
  492.       theOperation = theTransaction->getNdbOperation("SHORT_REC");
  493.     else
  494.       theOperation = theTransaction->getNdbOperation("LONG_REC");
  495.     if (theOperation == NULL) {
  496.       ndbout << "Table missing" << endl;
  497.   aNdb->closeTransaction(theTransaction) ;
  498.   return -1;
  499.     }//if
  500.     theOperation->simpleRead();
  501.     theOperation->equal((Uint32)0, key);
  502.     theOperation->getValue((Uint32)1, (char*)&flip);
  503.     theOperation->getValue((Uint32)2, (char*)&count);
  504.     if (theOperation->getValue((Uint32)3, (char*)&placeholder[0]) == NULL) {
  505.       ndbout << "Error in definition phase = " << theTransaction->getNdbError() << endl;  
  506.       aNdb->closeTransaction(theTransaction);
  507.       return -1;
  508.     }//if
  509.   }//for
  510.   ret_value = theTransaction->execute(Commit);
  511.   if (ret_value == -1)
  512.     ndbout << "Error in lookup:" << theTransaction->getNdbError() << endl;
  513.     aNdb->closeTransaction(theTransaction);
  514. return ret_value;
  515. }//lookup()
  516. int update(Ndb* aNdb, unsigned int key, unsigned int long_short, int guess)
  517. {
  518.   int placeholder[500];
  519.   int ret_value, i;
  520.   unsigned int flip, count;
  521.   NdbConnection* theTransaction;
  522.   NdbOperation* theOperation;
  523.   if ( !aNdb ) return -1 ;
  524.   if (guess != 0)
  525.     theTransaction = aNdb->startTransaction((Uint32)0, (const char*)&key, (Uint32)4);
  526.   else
  527.     theTransaction = aNdb->startTransaction();
  528.   for (i = 0; i < tNoOfOpsPerExecute; i++) {
  529.     if (long_short == 0)
  530.       theOperation = theTransaction->getNdbOperation("SHORT_REC"); // Use table SHORT_REC
  531.     else
  532.       theOperation = theTransaction->getNdbOperation("LONG_REC"); // Use table LONG_REC
  533.     if (theOperation == NULL) {
  534.       ndbout << "Table missing" << endl;
  535.   aNdb->closeTransaction(theTransaction) ;
  536.   delete aNdb ;
  537.       return -1;
  538.     }//if
  539.     theOperation->interpretedUpdateTuple();                       // Send interpreted program to NDB kernel
  540.     theOperation->equal((Uint32)0, key);                          // Search key
  541.     theOperation->getValue((Uint32)1, (char*)&flip);              // Read value of flip
  542.     theOperation->getValue((Uint32)2, (char*)&count);             // Read value of count
  543.     theOperation->getValue((Uint32)3, (char*)&placeholder[0]);    // Read value of placeholder
  544.     theOperation->load_const_u32((Uint32)1, (Uint32)0);           // Load register 1 with 0
  545.     theOperation->read_attr((Uint32)1, (Uint32)2);                // Read Flip value into register 2
  546.     theOperation->branch_eq((Uint32)1, (Uint32)2, (Uint32)0);     // If Flip (register 2) == 0 (register 1) goto label 0
  547.     theOperation->branch_label((Uint32)1);                        // Goto label 1
  548.     theOperation->def_label((Uint32)0);                           // Define label 0
  549.     theOperation->load_const_u32((Uint32)1, (Uint32)1);           // Load register 1 with 1
  550.     theOperation->def_label((Uint32)1);                           // Define label 0
  551.     theOperation->write_attr((Uint32)1, (Uint32)1);               // Write 1 (register 1) into Flip
  552.     ret_value = theOperation->incValue((Uint32)2, (Uint32)1);     // Increment Count by 1
  553.     if (ret_value == -1) {
  554.       ndbout << "Error in definition phase " << endl;  
  555.       aNdb->closeTransaction(theTransaction);
  556.       return ret_value;
  557.     }//if
  558.   }//for
  559.   ret_value = theTransaction->execute(Commit);                  // Perform the actual read and update
  560.   if (ret_value == -1) {
  561.     ndbout << "Error in update:" << theTransaction->getNdbError() << endl;
  562.     aNdb->closeTransaction(theTransaction); // < epaulsa
  563. return ret_value ;
  564.   }//if
  565.   aNdb->closeTransaction(theTransaction);
  566.   return ret_value;
  567. }//update()
  568. int update_bug(Ndb* aNdb, unsigned int key, unsigned int long_short)
  569. {
  570.   int placeholder[500];
  571.   int ret_value, i;
  572.   unsigned int flip, count;
  573.   NdbConnection* theTransaction;
  574.   NdbOperation* theOperation;
  575.   if ( !aNdb ) return -1 ;
  576.   theTransaction = aNdb->startTransaction();
  577.   for (i = 0; i < tNoOfOpsPerExecute; i++) {
  578.     if (long_short == 0)
  579.       theOperation = theTransaction->getNdbOperation("SHORT_REC"); // Use table SHORT_REC
  580.     else
  581.       theOperation = theTransaction->getNdbOperation("LONG_REC"); // Use table LONG_REC
  582.     if (theOperation == NULL) {
  583.       ndbout << "Table missing" << endl;
  584.      aNdb->closeTransaction(theTransaction) ;
  585.       return -1;
  586.     }//if
  587.     theOperation->interpretedUpdateTuple();                       // Send interpreted program to NDB kernel
  588.     theOperation->equal((Uint32)0, key);                          // Search key
  589.     theOperation->getValue((Uint32)1, (char*)&flip);              // Read value of flip
  590.     theOperation->getValue((Uint32)2, (char*)&count);             // Read value of count
  591.     theOperation->getValue((Uint32)3, (char*)&placeholder[0]);    // Read value of placeholder
  592.     theOperation->load_const_u32((Uint32)1, (Uint32)0);           // Load register 1 with 0
  593.     theOperation->read_attr((Uint32)1, (Uint32)2);                // Read Flip value into register 2
  594.     theOperation->branch_eq((Uint32)1, (Uint32)2, (Uint32)0);     // If Flip (register 2) == 0 (register 1) goto label 0
  595.     theOperation->branch_label((Uint32)1);                        // Goto label 1
  596.     theOperation->def_label((Uint32)0);                           // Define label 0
  597.     theOperation->load_const_u32((Uint32)1, (Uint32)1);           // Load register 1 with 1
  598.     theOperation->def_label((Uint32)1);                           // Define label 0
  599.     theOperation->write_attr((Uint32)1, (Uint32)1);               // Write 1 (register 1) into Flip
  600.     ret_value = theOperation->incValue((Uint32)2, (Uint32)1);     // Increment Count by 1
  601.     if (ret_value == -1) {
  602.       ndbout << "Error in definition phase " << endl;  
  603.       aNdb->closeTransaction(theTransaction);
  604.       return ret_value;
  605.     }//if
  606.   }//for
  607.   ret_value = theTransaction->execute(NoCommit);                  // Perform the actual read and update
  608.   if (ret_value == -1) {
  609.     ndbout << "Error in update:" << theTransaction->getNdbError() << endl;
  610.     aNdb->closeTransaction(theTransaction);
  611. return ret_value ;
  612.   }//if
  613.   aNdb->closeTransaction(theTransaction);
  614.   return ret_value;
  615. }//update_bug()
  616. int update_interpreter_test(Ndb* aNdb, unsigned int key, unsigned int long_short)
  617. {
  618.   int placeholder[500];
  619.   int ret_value, i;
  620.   unsigned int flip, count;
  621.   NdbConnection* theTransaction;
  622.   NdbOperation* theOperation;
  623.   Uint32 Tlabel = 0;
  624.   if ( !aNdb ) return -1 ; 
  625. //------------------------------------------------------------------------------
  626. // Start the transaction and get a unique transaction id
  627. //------------------------------------------------------------------------------
  628.   theTransaction = aNdb->startTransaction();
  629.   for (i = 0; i < tNoOfOpsPerExecute; i++) {
  630. //------------------------------------------------------------------------------
  631. // Get the proper table object and load schema information if not already
  632. // present.
  633. //------------------------------------------------------------------------------
  634.     if (long_short == 0)
  635.       theOperation = theTransaction->getNdbOperation("SHORT_REC"); // Use table SHORT_REC
  636.     else
  637.       theOperation = theTransaction->getNdbOperation("LONG_REC"); // Use table LONG_REC
  638.     if (theOperation == NULL) {
  639.       ndbout << "Table missing" << endl;
  640.      aNdb->closeTransaction(theTransaction) ;
  641.       return -1;
  642.     }//if
  643. //------------------------------------------------------------------------------
  644. // Define the operation type and the tuple key (primary key in this case).
  645. //------------------------------------------------------------------------------
  646.     theOperation->interpretedUpdateTuple();                       // Send interpreted program to NDB kernel
  647.     theOperation->equal((Uint32)0, key);                          // Search key
  648. //------------------------------------------------------------------------------
  649. // Perform initial read of attributes before updating them
  650. //------------------------------------------------------------------------------
  651.     theOperation->getValue((Uint32)1, (char*)&flip);              // Read value of flip
  652.     theOperation->getValue((Uint32)2, (char*)&count);             // Read value of count
  653.     theOperation->getValue((Uint32)3, (char*)&placeholder[0]);    // Read value of placeholder
  654. //------------------------------------------------------------------------------
  655. // Test that the various branch operations can handle things correctly.
  656. // Test first 2 + 3 = 5 with 32 bit registers
  657. // Next test the same with 32 bit + 64 bit = 64 
  658. //------------------------------------------------------------------------------
  659.     theOperation->load_const_u32((Uint32)4, (Uint32)0);           // Load register 4 with 0
  660.     theOperation->load_const_u32((Uint32)0, (Uint32)0);
  661.     theOperation->load_const_u32((Uint32)1, (Uint32)3);
  662.     theOperation->load_const_u32((Uint32)2, (Uint32)5);
  663.     theOperation->load_const_u32((Uint32)3, (Uint32)1);
  664.     theOperation->def_label(Tlabel++);
  665.     theOperation->def_label(Tlabel++);
  666.     theOperation->sub_reg((Uint32)2, (Uint32)3, (Uint32)2);
  667.     theOperation->branch_ne((Uint32)2, (Uint32)0, (Uint32)0);
  668.     theOperation->load_const_u32((Uint32)2, (Uint32)5);
  669.     theOperation->sub_reg((Uint32)1, (Uint32)3, (Uint32)1);
  670.     theOperation->branch_ne((Uint32)1, (Uint32)0, (Uint32)1);  
  671.     theOperation->load_const_u32((Uint32)1, (Uint32)2);           // Load register 1 with 2
  672.     theOperation->load_const_u32((Uint32)2, (Uint32)3);           // Load register 2 with 3
  673.     theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1);       // 2+3 = 5 into reg 1
  674.     theOperation->load_const_u32((Uint32)2, (Uint32)5);           // Load register 2 with 5
  675.     theOperation->def_label(Tlabel++);
  676.     theOperation->branch_eq((Uint32)1, (Uint32)2, Tlabel);
  677.     theOperation->interpret_exit_nok((Uint32)6001);
  678.     theOperation->def_label(Tlabel++);
  679.     theOperation->branch_ne((Uint32)1, (Uint32)2, Tlabel);
  680.     theOperation->branch_label(Tlabel + 1);
  681.     theOperation->def_label(Tlabel++);
  682.     theOperation->interpret_exit_nok((Uint32)6002);
  683.     theOperation->def_label(Tlabel++);
  684.     theOperation->branch_lt((Uint32)1, (Uint32)2, Tlabel);
  685.     theOperation->branch_label(Tlabel + 1);
  686.     theOperation->def_label(Tlabel++);
  687.     theOperation->interpret_exit_nok((Uint32)6003);
  688.     theOperation->def_label(Tlabel++);
  689.     theOperation->branch_gt((Uint32)1, (Uint32)2, Tlabel);
  690.     theOperation->branch_label(Tlabel + 1);
  691.     theOperation->def_label(Tlabel++);
  692.     theOperation->interpret_exit_nok((Uint32)6005);
  693.     theOperation->def_label(Tlabel++);
  694.     theOperation->branch_eq_null((Uint32)1, Tlabel);
  695.     theOperation->branch_label(Tlabel + 1);
  696.     theOperation->def_label(Tlabel++);
  697.     theOperation->interpret_exit_nok((Uint32)6006);
  698.     theOperation->def_label(Tlabel++);
  699.     theOperation->branch_ne_null((Uint32)1,Tlabel);
  700.     theOperation->interpret_exit_nok((Uint32)6007);
  701.     theOperation->def_label(Tlabel++);
  702.     theOperation->branch_ge((Uint32)1, (Uint32)2, Tlabel);
  703.     theOperation->interpret_exit_nok((Uint32)6008);
  704.     theOperation->def_label(Tlabel++);
  705.     theOperation->branch_eq_null((Uint32)6,Tlabel);
  706.     theOperation->interpret_exit_nok((Uint32)6009);
  707.     theOperation->def_label(Tlabel++);
  708.     theOperation->branch_ne_null((Uint32)6, Tlabel);
  709.     theOperation->branch_label(Tlabel + 1);
  710.     theOperation->def_label(Tlabel++);
  711.     theOperation->interpret_exit_nok((Uint32)6010);
  712.     theOperation->def_label(Tlabel++);
  713.     theOperation->load_const_u32((Uint32)5, (Uint32)1);
  714.     theOperation->add_reg((Uint32)4, (Uint32)5, (Uint32)4);
  715.     theOperation->load_const_u32((Uint32)5, (Uint32)1);
  716.     theOperation->branch_eq((Uint32)4, (Uint32)5, Tlabel);
  717.     theOperation->load_const_u32((Uint32)5, (Uint32)2);
  718.     theOperation->branch_eq((Uint32)4, (Uint32)5, (Tlabel + 1));
  719.     theOperation->load_const_u32((Uint32)5, (Uint32)3);
  720.     theOperation->branch_eq((Uint32)4, (Uint32)5, (Tlabel + 2));
  721.     theOperation->load_const_u32((Uint32)5, (Uint32)4);
  722.     theOperation->branch_eq((Uint32)4, (Uint32)5, (Tlabel + 3));
  723.        
  724.     theOperation->branch_label(Tlabel + 4);
  725.     theOperation->def_label(Tlabel++);
  726.     theOperation->load_const_u32((Uint32)1, (Uint32)200000);
  727.     theOperation->load_const_u32((Uint32)2, (Uint32)300000);
  728.     theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1);
  729.     theOperation->load_const_u32((Uint32)2, (Uint32)500000);
  730.     theOperation->branch_label((Uint32)2);
  731.     theOperation->def_label(Tlabel++);
  732.     theOperation->load_const_u32((Uint32)1, (Uint32)200000);
  733.     theOperation->load_const_u32((Uint32)2, (Uint32)300000);
  734.     theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1);
  735.     theOperation->load_const_u32((Uint32)2, (Uint32)500000);
  736.     theOperation->branch_label((Uint32)2);
  737.     theOperation->def_label(Tlabel++);
  738.     theOperation->load_const_u32((Uint32)1, (Uint32)2);
  739.     Uint64 x = 0;
  740.     theOperation->load_const_u64((Uint32)2, (Uint64)(x - 1));
  741.     theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1);
  742.     theOperation->load_const_u32((Uint32)2, (Uint32)1);
  743.     theOperation->branch_label((Uint32)2);
  744.     theOperation->def_label(Tlabel++);
  745.     theOperation->load_const_u32((Uint32)1, (Uint32)2);
  746.     theOperation->load_const_u64((Uint32)2, (Uint64)(x - 1));
  747.     theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1);
  748.     theOperation->load_const_u64((Uint32)2, (Uint64)1);
  749.     theOperation->branch_label((Uint32)2);
  750.     theOperation->def_label(Tlabel++);
  751.     theOperation->read_attr((Uint32)1, (Uint32)2);
  752.     theOperation->branch_eq((Uint32)1, (Uint32)2, Tlabel);
  753.     theOperation->load_const_u32((Uint32)1, (Uint32)0);
  754.     theOperation->branch_label(Tlabel + 1);
  755.     theOperation->def_label(Tlabel++);
  756.     theOperation->load_const_u32((Uint32)1, (Uint32)1);
  757.     theOperation->def_label(Tlabel++);
  758.     theOperation->write_attr((Uint32)1, (Uint32)1);
  759.     ret_value = theOperation->incValue((Uint32)2, (Uint32)1);
  760.     if (ret_value == -1) {
  761.       ndbout << "Error in definition phase " << endl;
  762.       ndbout << "Error = " << theOperation->getNdbError() << " on line = " << theOperation->getNdbErrorLine() << endl;
  763.       aNdb->closeTransaction(theTransaction);
  764.       return ret_value;
  765.     }//if
  766.   }//for
  767. //------------------------------------------------------------------------------
  768. //------------------------------------------------------------------------------
  769.   ret_value = theTransaction->execute(Commit);                  // Perform the actual read and update
  770.   if (ret_value == -1) {
  771.     ndbout << "Error in update:" << theTransaction->getNdbError() << endl;
  772.     aNdb->closeTransaction(theTransaction); // < epaulsa
  773. return ret_value ;
  774.   }//if
  775. //------------------------------------------------------------------------------
  776. //------------------------------------------------------------------------------
  777.   aNdb->closeTransaction(theTransaction);
  778.   return ret_value;
  779. }//update_interpreter_test()
  780. void* ThreadExec(void* ThreadData){
  781.   ThreadNdb* tabThread = (ThreadNdb*)ThreadData;
  782.   Ndb*    pMyNdb = NULL ;
  783.   myRandom48Init(NdbTick_CurrentMillisecond());
  784.   int    Tsuccess = 0 ;
  785.   int          check = 0 ;
  786.   int          loop_count_ops = 0;
  787.   int    count, i, Ti;
  788.   int    tType =  0 ;
  789.   int          remType = 0 ;
  790.   unsigned int thread_no = 0 ;
  791.   unsigned long total_milliseconds;
  792.   unsigned int key = 0 ;
  793.   unsigned int prob = 0 ;
  794.   unsigned long transaction_time = 0 ;
  795.   unsigned long transaction_max_time = 0 ;
  796.   unsigned long min_time, max_time[MAX_TIMERS];
  797.   double    mean_time, mean_square_time, std_time; 
  798.   
  799.   thread_no = tabThread->ThreadNo;
  800.   pMyNdb = tabThread->NdbRef;
  801.   if (!pMyNdb) {
  802.     pMyNdb = new Ndb( "TEST_DB" );
  803.     pMyNdb->init();
  804.   }//if
  805.   for (;;){
  806.     min_time = 0xFFFFFFFF;
  807.     //for (Ti = 0; Ti < MAX_TIMERS ; Ti++) max_time[Ti] = 0;
  808. memset(&max_time, 0, sizeof max_time) ;
  809.     mean_time = 0;
  810.     mean_square_time = 0;
  811.     ThreadReady[thread_no] = 1;
  812.     while (!ThreadStart[thread_no]){
  813. NdbSleep_MilliSleep(1);
  814. }
  815.     // Check if signal to exit is received
  816.     if (ThreadStart[thread_no] == 999){
  817. delete pMyNdb;
  818. pMyNdb = NULL ;
  819. ThreadReady[thread_no] = 1;
  820. return 0 ;
  821.     }//if
  822.     tType = ThreadStart[thread_no];
  823.     remType = tType;
  824.     ThreadStart[thread_no] = 0;
  825. ThreadReady[thread_no] = 0 ;
  826.     // Start transaction, type of transaction
  827.     // is received in the array ThreadStart
  828.     loop_count_ops = tNoOfOperations;
  829.     START_TIMER_TOP
  830.     for (count=0 ; count < loop_count_ops ; count++) {
  831.       
  832. Tsuccess = 0;
  833. //----------------------------------------------------
  834. // Generate a random key between 0 and tNoOfRecords - 1
  835. //----------------------------------------------------
  836.       key = myRandom48(tNoOfRecords); 
  837. //----------------------------------------------------
  838. // Start time measurement of transaction.
  839. //----------------------------------------------------
  840.       START_TIMER
  841.       //do {
  842.         switch (remType){
  843.           case 1:
  844. //----------------------------------------------------
  845. // Only lookups in short record table
  846. //----------------------------------------------------
  847.             Tsuccess = lookup(pMyNdb, key, 0, 1);
  848.             break;
  849.           case 2:
  850. //----------------------------------------------------
  851. // Only lookups in long record table
  852. //----------------------------------------------------
  853.             Tsuccess = lookup(pMyNdb, key, 1, 1);
  854.             break;
  855.           case 3:
  856. //----------------------------------------------------
  857. // Only updates in short record table
  858. //----------------------------------------------------
  859.             Tsuccess = update(pMyNdb, key, 0, 1);
  860.             break;
  861.           case 4:
  862. //----------------------------------------------------
  863. // Only updates in long record table
  864. //----------------------------------------------------
  865.             Tsuccess = update(pMyNdb, key, 1, 1);
  866.             break;
  867.           case 5:
  868. //----------------------------------------------------
  869. // 50% read/50 % update in short record table
  870. //----------------------------------------------------
  871.             prob = myRandom48(100);
  872.             if (prob < 50)
  873.               Tsuccess = update(pMyNdb, key, 0, 1);
  874.             else
  875.               Tsuccess = lookup(pMyNdb, key, 0, 1);
  876.             break;
  877.           case 6:
  878. //----------------------------------------------------
  879. // 50% read/50 % update in long record table
  880. //----------------------------------------------------
  881.             prob = myRandom48(100);
  882.             if (prob < 50)
  883.               Tsuccess = update(pMyNdb, key, 1, 1);
  884.             else
  885.               Tsuccess = lookup(pMyNdb, key, 1, 1);
  886.             break;
  887.           case 7:
  888. //----------------------------------------------------
  889. // 80 read/20 % update in short record table
  890. //----------------------------------------------------
  891.             prob = myRandom48(100);
  892.             if (prob < 20)
  893.               Tsuccess = update(pMyNdb, key, 0, 1);
  894.             else
  895.               Tsuccess = lookup(pMyNdb, key, 0, 1);
  896.             break;
  897.           case 8:
  898. //----------------------------------------------------
  899. // 80 read/20 % update in long record table
  900. //----------------------------------------------------
  901.             prob = myRandom48(100);
  902.             if (prob < 20)
  903.               Tsuccess = update(pMyNdb, key, 1, 1);
  904.             else
  905.               Tsuccess = lookup(pMyNdb, key, 1, 1);
  906.             break;
  907.           case 9:
  908. //----------------------------------------------------
  909. // 25 read short/25 % read long/25 % update short/25 % update long
  910. //----------------------------------------------------
  911.             prob = myRandom48(100);
  912.             if (prob < 25)
  913.               Tsuccess = update(pMyNdb, key, 0, 1);
  914.             else if (prob < 50)
  915.               Tsuccess = update(pMyNdb, key, 1, 1);
  916.             else if (prob < 75)
  917.               Tsuccess = lookup(pMyNdb, key, 0, 1);
  918.             else
  919.               Tsuccess = lookup(pMyNdb, key, 1, 1);
  920.             break;
  921.           case 10:
  922. //----------------------------------------------------
  923. // Test bug with replicated interpreted update, short table
  924. //----------------------------------------------------
  925.             Tsuccess = update_bug(pMyNdb, key, 0);
  926.             break;
  927.           case 11:
  928. //----------------------------------------------------
  929. // Test interpreter functions, short table
  930. //----------------------------------------------------
  931.             Tsuccess = update_interpreter_test(pMyNdb, key, 0);
  932.             break;
  933.           case 12:
  934. //----------------------------------------------------
  935. // Test bug with replicated interpreted update, long table
  936. //----------------------------------------------------
  937.             Tsuccess = update_bug(pMyNdb, key, 1);
  938.             break;
  939.           case 13:
  940. //----------------------------------------------------
  941. // Test interpreter functions, long table
  942. //----------------------------------------------------
  943.             Tsuccess = update_interpreter_test(pMyNdb, key, 1);
  944.             break;
  945.           case 14:
  946. //----------------------------------------------------
  947. // Only lookups in short record table
  948. //----------------------------------------------------
  949.             Tsuccess = lookup(pMyNdb, key, 0, 0);
  950.             break;
  951.           case 15:
  952. //----------------------------------------------------
  953. // Only lookups in long record table
  954. //----------------------------------------------------
  955.             Tsuccess = lookup(pMyNdb, key, 1, 0);
  956.             break;
  957.           case 16:
  958. //----------------------------------------------------
  959. // Only updates in short record table
  960. //----------------------------------------------------
  961.             Tsuccess = update(pMyNdb, key, 0, 0);
  962.             break;
  963.           case 17:
  964. //----------------------------------------------------
  965. // Only updates in long record table
  966. //----------------------------------------------------
  967.             Tsuccess = update(pMyNdb, key, 1, 0);
  968.             break;
  969.           case 18:
  970.             Tsuccess = multiRecordTest(pMyNdb, key);
  971.             break;
  972.           default:
  973.             break;
  974.         }//switch
  975.       //} while (0);//
  976.   if(-1 == Tsuccess) {
  977.   NDBT_ProgramExit(NDBT_FAILED);
  978.   exit(-1);
  979.   } // for
  980. //----------------------------------------------------
  981. // Stop time measurement of transaction.
  982. //----------------------------------------------------     
  983.   STOP_TIMER   
  984.   transaction_time = (unsigned long)timer.elapsedTime() ;//stopTimer(&theStartTime);
  985. //----------------------------------------------------
  986. // Perform calculations of time measurements.
  987. //----------------------------------------------------
  988.       transaction_max_time = transaction_time;
  989.       for (Ti = 0; Ti < MAX_TIMERS; Ti++) {
  990.         if (transaction_max_time > max_time[Ti]) {
  991.           Uint32 tmp = max_time[Ti];
  992.           max_time[Ti] = transaction_max_time;
  993.           transaction_max_time = tmp;
  994.         }//if
  995.       }//if
  996.       if (transaction_time < min_time) min_time = transaction_time;
  997.       mean_time = (double)transaction_time + mean_time;
  998.       mean_square_time = (double)(transaction_time * transaction_time) + mean_square_time;
  999.     }//for
  1000. //----------------------------------------------------
  1001. // Calculate mean and standard deviation
  1002. //----------------------------------------------------
  1003.     STOP_TIMER_TOP
  1004.     total_milliseconds = (unsigned long)timer_top.elapsedTime() ;//stopTimer(&total_time);
  1005.     mean_time = mean_time / loop_count_ops;
  1006.     mean_square_time = mean_square_time / loop_count_ops;
  1007.     std_time = sqrt(mean_square_time - (mean_time * mean_time));
  1008. //----------------------------------------------------
  1009. // Report statistics
  1010. //----------------------------------------------------
  1011. ndbout << "Thread = " << thread_no << " reporting:" << endl ;
  1012. ndbout << "------------------------------" << endl ;
  1013.     ndbout << "Total time is " << (unsigned int)(total_milliseconds /1000);
  1014.     ndbout << " seconds and " << (unsigned int)(total_milliseconds % 1000);
  1015.     ndbout << " milliseconds" << endl;
  1016.     ndbout << "Minimum time = " << (unsigned int)min_time << " milliseconds" << endl;
  1017.     for (Ti = 0; Ti < MAX_TIMERS; Ti++) {
  1018.       ndbout << "Maximum timer " << Ti << " = " << (unsigned int)max_time[Ti] << " milliseconds" << endl;
  1019.       ndbout << "Mean time = " << (unsigned int)mean_time << " milliseconds" << endl;
  1020.       ndbout << "Standard deviation on time = " << (unsigned int)std_time;
  1021.       ndbout << " milliseconds" << endl << endl ;
  1022.     }//for
  1023.     ndbout << endl ;
  1024.   
  1025.   } // for(;;)
  1026.   
  1027.   delete pMyNdb ;
  1028.   return 0 ;
  1029. }