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

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. #include <NdbApi.hpp>
  14. #include <NdbSchemaCon.hpp>
  15. #include <NdbMutex.h>
  16. #include <NdbOut.hpp>
  17. #include <NdbSleep.h>
  18. #include <NdbThread.h>
  19. #include <NdbTick.h>
  20. #include <NdbMain.h>
  21. #include <NdbTest.hpp>
  22. #include <random.h>
  23. //#define TRACE
  24. #define DEBUG
  25. //#define RELEASE
  26. #define NODE_REC // epaulsa: introduces pointer checks to help 'acid' keep core
  27. // during node recovery
  28. #ifdef TRACE
  29. #define VerifyMethodInt(c, m) (ReportMethodInt(c->m, c, #c, #m, __FILE__, __LINE__))
  30. #define VerifyMethodPtr(v, c, m) (v=ReportMethodPtr(c->m, c, #v, #c, #m, __FILE__, __LINE__))
  31. #define VerifyMethodVoid(c, m) (c->m, ReportMethodVoid(c, #c, #m, __FILE__, __LINE__))
  32. int ReportMethodInt(int iRes, NdbConnection* pNdbConnection, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
  33. {
  34.   ndbout << szFile << "(" << iLine << ") : ";
  35.   ndbout << szClass << "->" << szMethod << " return " << iRes << " : ";
  36.   ndbout << pNdbConnection->getNdbError();
  37.   NdbOperation* pNdbOperation = pNdbConnection->getNdbErrorOperation();
  38.   if(pNdbOperation) {
  39.     ndbout << " : " << pNdbOperation->getNdbError();
  40.   }
  41.   ndbout << " : " << pNdbConnection->getNdbErrorLine();
  42.   ndbout << endl;
  43.   return iRes;
  44. }
  45. template <class C>
  46. int ReportMethodInt(int iRes, C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
  47. {
  48.   ndbout << szFile << "(" << iLine << ") : ";
  49.   ndbout << szClass << "->" << szMethod << " return " << iRes << " : ";
  50.   ndbout << pC->getNdbError();
  51.   ndbout << endl;
  52.   return iRes;
  53. }
  54. template <class R, class C>
  55. R* ReportMethodPtr(R* pR, C* pC, const char* szVariable, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
  56. {
  57.   ndbout << szFile << "(" << iLine << ") : ";
  58.   ndbout << szVariable << " = " << szClass << "->" << szMethod << " return " << (long)(void*)pR << " : ";
  59.   ndbout << pC->getNdbError();
  60.   ndbout << endl;
  61.   return pR;
  62. }
  63. template <class C>
  64. void ReportMethodVoid(C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
  65. {
  66.   ndbout << szFile << "(" << iLine << ") : ";
  67.   ndbout << szClass << "->" << szMethod << " : ";
  68.   ndbout << pC->getNdbError();
  69.   ndbout << endl;
  70. }
  71. #endif /* TRACE */
  72. #ifdef DEBUG
  73. #define VerifyMethodInt(c, m) (ReportMethodInt(c->m, c, #c, #m, __FILE__, __LINE__))
  74. #define VerifyMethodPtr(v, c, m) (v=ReportMethodPtr(c->m, c, #v, #c, #m, __FILE__, __LINE__))
  75. #define VerifyMethodVoid(c, m) (c->m, ReportMethodVoid(c, #c, #m, __FILE__, __LINE__))
  76. int ReportMethodInt(int iRes, NdbConnection* pNdbConnection, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
  77. {
  78.   if(iRes<0) {
  79.     ndbout << szFile << "(" << iLine << ") : ";
  80.     ndbout << szClass << "->" << szMethod << " return " << iRes << " : ";
  81.     ndbout << pNdbConnection->getNdbError();
  82.     NdbOperation* pNdbOperation = pNdbConnection->getNdbErrorOperation();
  83.     if(pNdbOperation) {
  84.       ndbout << " : " << pNdbOperation->getNdbError();
  85.     }
  86.     ndbout << " : " << pNdbConnection->getNdbErrorLine();
  87.     ndbout << " : ";
  88.     ndbout << endl;
  89.   }
  90.   return iRes;
  91. }
  92. template <class C>
  93. int ReportMethodInt(int iRes, C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
  94. {
  95.   if(iRes<0) {
  96.     ndbout << szFile << "(" << iLine << ") : ";
  97.     ndbout << szClass << "->" << szMethod << " return " << iRes << " : ";
  98.     ndbout << pC->getNdbError();
  99.     ndbout << endl;
  100.   }
  101.   return iRes;
  102. }
  103. template <class R, class C>
  104. R* ReportMethodPtr(R* pR, C* pC, const char* szVariable, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
  105. {
  106.   if(!pR) {
  107.     ndbout << szFile << "(" << iLine << ") : ";
  108.     ndbout << szVariable << " = " << szClass << "->" << szMethod << " return " << " : ";
  109.     ndbout << pC->getNdbError();
  110.     ndbout << endl;
  111.   }
  112.   return pR;
  113. }
  114. template <class C>
  115. void ReportMethodVoid(C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
  116. {
  117.   if(pC->getNdbError().code) {
  118.     ndbout << szFile << "(" << iLine << ") : ";
  119.     ndbout << szClass << "->" << szMethod << " : ";
  120.     ndbout << pC->getNdbError();
  121.     ndbout << endl;
  122.   }
  123. }
  124. #endif /* DEBUG */
  125. #ifdef RELEASE
  126. #define VerifyMethodInt(c, m) (c->m)
  127. #define VerifyMethodPtr(v, c, m) (v=(c->m))
  128. #define VerifyMethodVoid(c, m) (c->m)
  129. int ReportMethodInt(int iRes, NdbConnection* pNdbConnection, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
  130. {
  131.   if(iRes<0) {
  132.     ndbout << szFile << "(" << iLine << ") : ";
  133.     ndbout << szClass << "->" << szMethod << " return " << iRes << " : ";
  134.     ndbout << pNdbConnection->getNdbError();
  135.     NdbOperation* pNdbOperation = pNdbConnection->getNdbErrorOperation();
  136.     if(pNdbOperation) {
  137.       ndbout << " : " << pNdbOperation->getNdbError();
  138.     }
  139.     ndbout << " : " << pNdbConnection->getNdbErrorLine();
  140.     ndbout << endl;
  141.   }
  142.   return iRes;
  143. }
  144. #endif /* RELEASE */
  145. // epaulsa =>
  146. #ifndef NODE_REC
  147. #define CHK_TR(p)
  148. #else
  149. #define CHK_TR(p) if(!p){
  150. ndbout <<"startTransaction failed, returning now." << endl ;
  151. delete pNdb ;
  152. pNdb = NULL ;
  153. return 0 ;
  154. }
  155. #endif // NODE_REC
  156. // <= epaulsa
  157. const char* c_szWarehouse = "WAREHOUSE";
  158. const char* c_szWarehouseNumber = "W_ID";
  159. const char* c_szWarehouseSum = "W_SUM";
  160. const char* c_szWarehouseCount = "W_CNT";
  161. const char* c_szDistrict = "DISTRICT";
  162. const char* c_szDistrictWarehouseNumber = "D_W_ID";
  163. const char* c_szDistrictNumber = "D_ID";
  164. const char* c_szDistrictSum = "D_SUM";
  165. const char* c_szDistrictCount = "D_CNT";
  166. Uint32 g_nWarehouseCount = 10;
  167. Uint32 g_nDistrictPerWarehouse = 10;
  168. Uint32 g_nThreadCount = 1;
  169. NdbMutex* g_pNdbMutex = 0;
  170. extern "C" void* NdbThreadFuncInsert(void* pArg)
  171. {
  172.   myRandom48Init((long int)NdbTick_CurrentMillisecond());
  173.   unsigned nSucc = 0;
  174.   unsigned nFail = 0;
  175.   Ndb* pNdb = NULL ;
  176.   pNdb = new Ndb("TEST_DB");
  177.   VerifyMethodInt(pNdb, init());
  178.   VerifyMethodInt(pNdb, waitUntilReady());
  179.   while(NdbMutex_Trylock(g_pNdbMutex)) {
  180.     Uint32 nWarehouse = myRandom48(g_nWarehouseCount);
  181.     NdbConnection* pNdbConnection = NULL ;
  182.     VerifyMethodPtr(pNdbConnection, pNdb, startTransaction());
  183.     CHK_TR(pNdbConnection);
  184.     NdbOperation* pNdbOperationW = NULL ;
  185.     VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse));
  186.     VerifyMethodInt(pNdbOperationW, insertTuple());
  187.     VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse));
  188.     VerifyMethodInt(pNdbOperationW, setValue(c_szWarehouseCount, Uint32(1)));
  189.     Uint32 nWarehouseSum = 0;
  190.     for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
  191.       NdbOperation* pNdbOperationD = NULL ;
  192.       VerifyMethodPtr(pNdbOperationD, pNdbConnection, getNdbOperation(c_szDistrict));
  193.       VerifyMethodInt(pNdbOperationD, insertTuple());
  194.       VerifyMethodInt(pNdbOperationD, equal(c_szDistrictWarehouseNumber, nWarehouse));
  195.       VerifyMethodInt(pNdbOperationD, equal(c_szDistrictNumber, nDistrict));
  196.       VerifyMethodInt(pNdbOperationD, setValue(c_szDistrictCount, Uint32(1)));
  197.       Uint32 nDistrictSum = myRandom48(100);
  198.       nWarehouseSum += nDistrictSum;
  199.       VerifyMethodInt(pNdbOperationD, setValue(c_szDistrictSum, nDistrictSum));
  200.     }
  201.     VerifyMethodInt(pNdbOperationW, setValue(c_szWarehouseSum, nWarehouseSum));
  202.     int iExec = pNdbConnection->execute(Commit);
  203.     int iError = pNdbConnection->getNdbError().code;
  204.     if(iExec<0 && iError!=0 && iError!=266 && iError!=630) {
  205.       ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__);
  206.     }
  207.     if(iExec==0) {
  208.       ++nSucc;
  209.     } else {
  210.       ++nFail;
  211.     }
  212.     VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection));
  213.   }
  214.   ndbout << "insert: " << nSucc << " succeeded, " << nFail << " failed " << endl;
  215.   NdbMutex_Unlock(g_pNdbMutex);
  216.   delete pNdb;
  217.   pNdb = NULL ;
  218.   return NULL;
  219. }
  220. extern "C" void* NdbThreadFuncUpdate(void* pArg)
  221. {
  222.   myRandom48Init((long int)NdbTick_CurrentMillisecond());
  223.   unsigned nSucc = 0;
  224.   unsigned nFail = 0;
  225.   Ndb* pNdb = NULL ;
  226.   pNdb = new Ndb("TEST_DB");
  227.   VerifyMethodInt(pNdb, init());
  228.   VerifyMethodInt(pNdb, waitUntilReady());
  229.   while(NdbMutex_Trylock(g_pNdbMutex)) {
  230.     Uint32 nWarehouse = myRandom48(g_nWarehouseCount);
  231.     NdbConnection* pNdbConnection = NULL ;
  232.     VerifyMethodPtr(pNdbConnection, pNdb, startTransaction());
  233.     CHK_TR(pNdbConnection) ; // epaulsa
  234.     NdbOperation* pNdbOperationW = NULL ;
  235.     VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse));
  236.     VerifyMethodInt(pNdbOperationW, interpretedUpdateTuple());
  237.     VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse));
  238.     VerifyMethodInt(pNdbOperationW, incValue(c_szWarehouseCount, Uint32(1)));
  239.     Uint32 nWarehouseSum = 0;
  240.     for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
  241.       NdbOperation* pNdbOperationD = NULL ;
  242.       VerifyMethodPtr(pNdbOperationD, pNdbConnection, getNdbOperation(c_szDistrict));
  243.       VerifyMethodInt(pNdbOperationD, interpretedUpdateTuple());
  244.       VerifyMethodInt(pNdbOperationD, equal(c_szDistrictWarehouseNumber, nWarehouse));
  245.       VerifyMethodInt(pNdbOperationD, equal(c_szDistrictNumber, nDistrict));
  246.       VerifyMethodInt(pNdbOperationD, incValue(c_szDistrictCount, Uint32(1)));
  247.       Uint32 nDistrictSum = myRandom48(100);
  248.       nWarehouseSum += nDistrictSum;
  249.       VerifyMethodInt(pNdbOperationD, setValue(c_szDistrictSum, nDistrictSum));
  250.     }
  251.     VerifyMethodInt(pNdbOperationW, setValue(c_szWarehouseSum, nWarehouseSum));
  252.     int iExec = pNdbConnection->execute(Commit);
  253.     int iError = pNdbConnection->getNdbError().code;
  254.     if(iExec<0 && iError!=0 && iError!=266 && iError!=626) {
  255.       ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__);
  256.     }
  257.     if(iExec==0) {
  258.       ++nSucc;
  259.     } else {
  260.       ++nFail;
  261.     }
  262.     VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection));
  263.   }
  264.   ndbout << "update: " << nSucc << " succeeded, " << nFail << " failed " << endl;
  265.   NdbMutex_Unlock(g_pNdbMutex);
  266.   delete pNdb;
  267.   pNdb = NULL ;
  268.   return NULL;
  269. }
  270. extern "C" void* NdbThreadFuncDelete(void* pArg)
  271. {
  272.   myRandom48Init((long int)NdbTick_CurrentMillisecond());
  273.   unsigned nSucc = 0;
  274.   unsigned nFail = 0;
  275.   Ndb* pNdb = NULL ;
  276.   pNdb = new Ndb("TEST_DB");
  277.   VerifyMethodInt(pNdb, init());
  278.   VerifyMethodInt(pNdb, waitUntilReady());
  279.   while(NdbMutex_Trylock(g_pNdbMutex)) {
  280.     Uint32 nWarehouse = myRandom48(g_nWarehouseCount);
  281.     NdbConnection* pNdbConnection = NULL ;
  282.     VerifyMethodPtr(pNdbConnection, pNdb, startTransaction());
  283.     CHK_TR(pNdbConnection) ; // epaulsa
  284.     NdbOperation* pNdbOperationW = NULL ;
  285.     VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse));
  286.     VerifyMethodInt(pNdbOperationW, deleteTuple());
  287.     VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse));
  288.     for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
  289.       NdbOperation* pNdbOperationD = NULL ;
  290.       VerifyMethodPtr(pNdbOperationD, pNdbConnection, getNdbOperation(c_szDistrict));
  291.       VerifyMethodInt(pNdbOperationD, deleteTuple());
  292.       VerifyMethodInt(pNdbOperationD, equal(c_szDistrictWarehouseNumber, nWarehouse));
  293.       VerifyMethodInt(pNdbOperationD, equal(c_szDistrictNumber, nDistrict));
  294.     }
  295.     int iExec = pNdbConnection->execute(Commit);
  296.     int iError = pNdbConnection->getNdbError().code;
  297.     if(iExec<0 && iError!=0 && iError!=266 && iError!=626) {
  298.       ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__);
  299.     }
  300.     if(iExec==0) {
  301.       ++nSucc;
  302.     } else {
  303.       ++nFail;
  304.     }
  305.     VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection));
  306.   }
  307.   ndbout << "delete: " << nSucc << " succeeded, " << nFail << " failed " << endl;
  308.   NdbMutex_Unlock(g_pNdbMutex);
  309.   delete pNdb;
  310.   pNdb = NULL ;
  311.   return NULL;
  312. }
  313. extern "C" void* NdbThreadFuncRead(void* pArg)
  314. {
  315.   myRandom48Init((long int)NdbTick_CurrentMillisecond());
  316.   unsigned nSucc = 0;
  317.   unsigned nFail = 0;
  318.   NdbRecAttr** ppNdbRecAttrDSum = new NdbRecAttr*[g_nDistrictPerWarehouse];
  319.   NdbRecAttr** ppNdbRecAttrDCnt = new NdbRecAttr*[g_nDistrictPerWarehouse];
  320.   Ndb* pNdb = NULL ;
  321.   pNdb = new Ndb("TEST_DB");
  322.   VerifyMethodInt(pNdb, init());
  323.   VerifyMethodInt(pNdb, waitUntilReady());
  324.   while(NdbMutex_Trylock(g_pNdbMutex)) {
  325.     Uint32 nWarehouse = myRandom48(g_nWarehouseCount);
  326.     NdbConnection* pNdbConnection = NULL ;
  327.     VerifyMethodPtr(pNdbConnection, pNdb, startTransaction());
  328.     CHK_TR(pNdbConnection) ; // epaulsa
  329.     NdbOperation* pNdbOperationW = NULL ;
  330.     VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse));
  331.     VerifyMethodInt(pNdbOperationW, readTuple());
  332.     VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse));
  333.     NdbRecAttr* pNdbRecAttrWSum;
  334.     VerifyMethodPtr(pNdbRecAttrWSum, pNdbOperationW, getValue(c_szWarehouseSum, 0));
  335.     NdbRecAttr* pNdbRecAttrWCnt;
  336.     VerifyMethodPtr(pNdbRecAttrWCnt, pNdbOperationW, getValue(c_szWarehouseCount, 0));
  337.     for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
  338.       NdbOperation* pNdbOperationD = NULL ;
  339.       VerifyMethodPtr(pNdbOperationD, pNdbConnection, getNdbOperation(c_szDistrict));
  340.       VerifyMethodInt(pNdbOperationD, readTuple());
  341.       VerifyMethodInt(pNdbOperationD, equal(c_szDistrictWarehouseNumber, nWarehouse));
  342.       VerifyMethodInt(pNdbOperationD, equal(c_szDistrictNumber, nDistrict));
  343.       VerifyMethodPtr(ppNdbRecAttrDSum[nDistrict], pNdbOperationD, getValue(c_szDistrictSum, 0));
  344.       VerifyMethodPtr(ppNdbRecAttrDCnt[nDistrict], pNdbOperationD, getValue(c_szDistrictCount, 0));
  345.     }
  346.     int iExec = pNdbConnection->execute(Commit);
  347.     int iError = pNdbConnection->getNdbError().code;
  348.     
  349.     if(iExec<0 && iError!=0 && iError!=266 && iError!=626) {
  350.       ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__);
  351.     }
  352.     if(iExec==0) {
  353.       Uint32 nSum = 0;
  354.       Uint32 nCnt = 0;
  355.       for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
  356.         nSum += ppNdbRecAttrDSum[nDistrict]->u_32_value();
  357.         nCnt += ppNdbRecAttrDCnt[nDistrict]->u_32_value();
  358.       }
  359.       if(nSum!=pNdbRecAttrWSum->u_32_value()
  360.          || nCnt!=g_nDistrictPerWarehouse*pNdbRecAttrWCnt->u_32_value()) {
  361.         ndbout << "INCONSISTENT!" << endl;
  362.         ndbout << "iExec==" << iExec << endl;
  363.         ndbout << "iError==" << iError << endl;
  364.         ndbout << endl;
  365.         ndbout << c_szWarehouseSum << "==" << pNdbRecAttrWSum->u_32_value() << ", ";
  366.         ndbout << c_szWarehouseCount << "==" << pNdbRecAttrWCnt->u_32_value() << endl;
  367.         ndbout << "nSum==" << nSum << ", nCnt=" << nCnt << endl;
  368.         for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
  369.           ndbout << c_szDistrictSum << "[" << nDistrict << "]==" << ppNdbRecAttrDSum[nDistrict]->u_32_value() << ", ";
  370.           ndbout << c_szDistrictCount << "[" << nDistrict << "]==" << ppNdbRecAttrDCnt[nDistrict]->u_32_value() << endl;
  371.         }
  372.         VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection));
  373.         delete pNdb; pNdb = NULL ;
  374.         delete[] ppNdbRecAttrDSum; ppNdbRecAttrDSum = NULL ;
  375.         delete[] ppNdbRecAttrDCnt; ppNdbRecAttrDCnt = NULL ;
  376.         NDBT_ProgramExit(NDBT_FAILED);
  377.       }
  378.       ++nSucc;
  379.     } else {
  380.       ++nFail;
  381.     }
  382.     VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection));
  383.   }
  384.   ndbout << "read: " << nSucc << " succeeded, " << nFail << " failed " << endl;
  385.   NdbMutex_Unlock(g_pNdbMutex);
  386.   delete pNdb; pNdb = NULL ;
  387.   delete[] ppNdbRecAttrDSum; ppNdbRecAttrDSum = NULL ;
  388.   delete[] ppNdbRecAttrDCnt; ppNdbRecAttrDCnt = NULL ;
  389.   return NULL;
  390. }
  391. NDB_COMMAND(acid, "acid", "acid", "acid", 65535)
  392. {
  393.   ndb_init();
  394.   long nSeconds = 60;
  395.   int rc = NDBT_OK;
  396.   for(int i=1; i<argc; ++i) {
  397.     if(argv[i][0]=='-' || argv[i][0]=='/') {
  398.       switch(argv[i][1]) {
  399.       case 'w': g_nWarehouseCount=atol(argv[i]+2); break;
  400.       case 'd': g_nDistrictPerWarehouse=atol(argv[i]+2); break;
  401.       case 's': nSeconds=atol(argv[i]+2); break;
  402.       case 't': g_nThreadCount=atol(argv[i]+2); break;
  403.       default: ndbout << "invalid option" << endl; return 1;
  404.       }
  405.     } else {
  406.       ndbout << "invalid operand" << endl;
  407.       return 1;
  408.     }
  409.   }
  410.   ndbout << argv[0];
  411.   ndbout << " -w" << g_nWarehouseCount;
  412.   ndbout << " -d" << g_nDistrictPerWarehouse;
  413.   ndbout << " -s" << (int)nSeconds;
  414.   ndbout << " -t" << g_nThreadCount;
  415.   ndbout << endl;
  416.   Ndb* pNdb = NULL ;
  417.   pNdb = new Ndb("TEST_DB");
  418.   VerifyMethodInt(pNdb, init());
  419.   VerifyMethodInt(pNdb, waitUntilReady());
  420.   NdbSchemaCon* pNdbSchemaCon= NdbSchemaCon::startSchemaTrans(pNdb);
  421.   if(!pNdbSchemaCon){
  422.     ndbout <<"startSchemaTransaction failed, exiting now" << endl ;
  423.     delete pNdb ;
  424.     NDBT_ProgramExit(NDBT_FAILED) ;
  425.   }
  426.   NdbSchemaOp* pNdbSchemaOp = NULL ;
  427.   VerifyMethodPtr(pNdbSchemaOp, pNdbSchemaCon, getNdbSchemaOp());
  428. #if defined NDB_OSE || defined NDB_SOFTOSE
  429.   VerifyMethodInt(pNdbSchemaOp, createTable(
  430.                                             c_szWarehouse, 
  431.                                             (4+4+4+12)*1.02*g_nWarehouseCount/1024+1, 
  432.                                             TupleKey, 
  433.                                             (4+14)*g_nWarehouseCount/8/1024+1,
  434.                                             All, 
  435.                                             6,
  436.                                             78,
  437.                                             80,
  438.                                             1,
  439.                                             false));
  440. #else
  441.   VerifyMethodInt(pNdbSchemaOp, createTable(
  442.                                             c_szWarehouse, 
  443.                                             (4+4+4+12)*1.02*g_nWarehouseCount/1024+1, 
  444.                                             TupleKey, 
  445.                                             (4+14)*g_nWarehouseCount/8/1024+1));
  446. #endif
  447.   VerifyMethodInt(pNdbSchemaOp, createAttribute(c_szWarehouseNumber, TupleKey, 32, 1, UnSigned, MMBased, false));
  448.   VerifyMethodInt(pNdbSchemaOp, createAttribute(c_szWarehouseSum, NoKey, 32, 1, UnSigned, MMBased, false));
  449.   VerifyMethodInt(pNdbSchemaOp, createAttribute(c_szWarehouseCount, NoKey, 32, 1, UnSigned, MMBased, false));
  450.   VerifyMethodInt(pNdbSchemaCon, execute());
  451.   NdbSchemaCon::closeSchemaTrans(pNdbSchemaCon);
  452.   pNdbSchemaCon= NdbSchemaCon::startSchemaTrans(pNdb);
  453.   VerifyMethodPtr(pNdbSchemaOp, pNdbSchemaCon, getNdbSchemaOp());
  454. #if defined NDB_OSE || defined NDB_SOFTOSE
  455.   VerifyMethodInt(pNdbSchemaOp, createTable(
  456.                                             c_szDistrict, 
  457.                                             (4+4+4+4+12)*1.02*g_nWarehouseCount*g_nDistrictPerWarehouse/1024+1, 
  458.                                             TupleKey, 
  459.                                             (4+4+14)*g_nWarehouseCount*g_nDistrictPerWarehouse/8/1024+1,
  460.                                             All, 
  461.                                             6,
  462.                                             78,
  463.                                             80,
  464.                                             1,
  465.                                             false));
  466. #else
  467.   VerifyMethodInt(pNdbSchemaOp, createTable(
  468.                                             c_szDistrict, 
  469.                                             (4+4+4+4+12)*1.02*g_nWarehouseCount*g_nDistrictPerWarehouse/1024+1, 
  470.                                             TupleKey, 
  471.                                             (4+4+14)*g_nWarehouseCount*g_nDistrictPerWarehouse/8/1024+1));
  472. #endif
  473.   VerifyMethodInt(pNdbSchemaOp, createAttribute(c_szDistrictWarehouseNumber, TupleKey, 32, 1, UnSigned, MMBased, false));
  474.   VerifyMethodInt(pNdbSchemaOp, createAttribute(c_szDistrictNumber, TupleKey, 32, 1, UnSigned, MMBased, false));
  475.   VerifyMethodInt(pNdbSchemaOp, createAttribute(c_szDistrictSum, NoKey, 32, 1, UnSigned, MMBased, false));
  476.   VerifyMethodInt(pNdbSchemaOp, createAttribute(c_szDistrictCount, NoKey, 32, 1, UnSigned, MMBased, false));
  477.   VerifyMethodInt(pNdbSchemaCon, execute());
  478.   NdbSchemaCon::closeSchemaTrans(pNdbSchemaCon);
  479.   g_pNdbMutex = NdbMutex_Create();
  480.   NdbMutex_Lock(g_pNdbMutex);
  481.   NdbThread** ppNdbThread = new NdbThread*[g_nThreadCount*4];
  482.   for(Uint32 nThread=0; nThread<g_nThreadCount; ++nThread) {
  483.     ppNdbThread[nThread*4+0] = NdbThread_Create(NdbThreadFuncInsert, 0, 65535, "insert",
  484.                                                 NDB_THREAD_PRIO_LOW);
  485.     ppNdbThread[nThread*4+1] = NdbThread_Create(NdbThreadFuncUpdate, 0, 65535, "update",
  486.                                                 NDB_THREAD_PRIO_LOW);
  487.     ppNdbThread[nThread*4+2] = NdbThread_Create(NdbThreadFuncDelete, 0, 65535, "delete",
  488.                                                 NDB_THREAD_PRIO_LOW);
  489.     ppNdbThread[nThread*4+3] = NdbThread_Create(NdbThreadFuncRead, 0, 65535, "read",
  490.                                                 NDB_THREAD_PRIO_LOW);
  491.   }
  492.   NdbSleep_SecSleep(nSeconds);
  493.   NdbMutex_Unlock(g_pNdbMutex);
  494.   void* pStatus;
  495.   for(Uint32 nThread=0; nThread<g_nThreadCount; ++nThread) {
  496.     NdbThread_WaitFor(ppNdbThread[nThread*4+0], &pStatus);
  497.     NdbThread_WaitFor(ppNdbThread[nThread*4+1], &pStatus);      
  498.     NdbThread_WaitFor(ppNdbThread[nThread*4+2], &pStatus);      
  499.     NdbThread_WaitFor(ppNdbThread[nThread*4+3], &pStatus);      
  500.   }
  501.   NdbMutex_Destroy(g_pNdbMutex);
  502.   delete[] ppNdbThread;
  503.   delete pNdb;
  504.   return NDBT_ProgramExit(rc);
  505. }