Below is the list of changes that have just been committed into a local
5.1 repository of knielsen. When knielsen does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2006-11-30 12:43:57+01:00, knielsen@ymer.(none) +6 -0
WL#2223
Temporary prototype NdbRecord interface.
storage/ndb/include/ndbapi/NdbDictionary.hpp@stripped, 2006-11-30 12:43:52+01:00, knielsen@ymer.(none) +17 -0
Temporary prototype NdbRecord interface.
storage/ndb/include/ndbapi/NdbTransaction.hpp@stripped, 2006-11-30 12:43:52+01:00, knielsen@ymer.(none) +13 -0
Temporary prototype NdbRecord interface.
storage/ndb/src/ndbapi/NdbDictionary.cpp@stripped, 2006-11-30 12:43:52+01:00, knielsen@ymer.(none) +54 -0
Temporary prototype NdbRecord interface.
storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp@stripped, 2006-11-30 12:43:52+01:00, knielsen@ymer.(none) +131 -0
Temporary prototype NdbRecord interface.
storage/ndb/src/ndbapi/NdbTransaction.cpp@stripped, 2006-11-30 12:43:52+01:00, knielsen@ymer.(none) +252 -0
Temporary prototype NdbRecord interface.
storage/ndb/test/ndbapi/flexBench.cpp@stripped, 2006-11-30 12:43:52+01:00, knielsen@ymer.(none) +151 -86
Modify flexBench to use a temporary prototype NdbRecord interface.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: knielsen
# Host: ymer.(none)
# Root: /usr/local/mysql/mysql-5.1-wl2223
--- 1.52/storage/ndb/include/ndbapi/NdbTransaction.hpp 2006-11-30 12:44:04 +01:00
+++ 1.53/storage/ndb/include/ndbapi/NdbTransaction.hpp 2006-11-30 12:44:04 +01:00
@@ -131,6 +131,8 @@ enum ExecType {
*
*/
+class NdbRecord;
+
class NdbTransaction
{
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
@@ -568,6 +570,17 @@ public:
*/
Uint32 getConnectedNodeId(); // Get Connected node id
#endif
+
+
+ NdbOperation *readTuple(const char *tableName, const NdbRecord *rec, char *row, const Uint32 *mask= 0);
+ NdbOperation *insertTuple(const char *tableName, const NdbRecord *rec, const char *row, const Uint32 *mask= 0);
+ NdbOperation *updateTuple(const char *tableName, const NdbRecord *rec, const char *row, const Uint32 *mask= 0);
+ NdbOperation *deleteTuple(const char *tableName, const NdbRecord *rec, const char *row);
+ NdbOperation *dirtyWriteTuple(const char *tableName, const NdbRecord *rec, const char *row, const Uint32 *mask= 0);
+ NdbOperation *writeTuple(const char *tableName, const NdbRecord *rec, const char *row, const Uint32 *mask= 0);
+ NdbOperation *simpleReadTuple(const char *tableName, const NdbRecord *rec, char *row, const Uint32 *mask= 0);
+ NdbOperation *dirtyReadTuple(const char *tableName, const NdbRecord *rec, char *row, const Uint32 *mask= 0);
+ NdbOperation *dirtyUpdateTuple(const char *tableName, const NdbRecord *rec, const char *row, const Uint32 *mask= 0);
private:
/**
--- 1.85/storage/ndb/include/ndbapi/NdbDictionary.hpp 2006-11-30 12:44:04 +01:00
+++ 1.86/storage/ndb/include/ndbapi/NdbDictionary.hpp 2006-11-30 12:44:04 +01:00
@@ -23,6 +23,9 @@ class Ndb;
struct charset_info_st;
typedef struct charset_info_st CHARSET_INFO;
+/* Forward declaration only. */
+class NdbRecord;
+
/**
* @class NdbDictionary
* @brief Data dictionary class
@@ -1910,6 +1913,20 @@ public:
int removeIndexGlobal(const Index &ndbidx, int invalidate) const;
int removeTableGlobal(const Table &ndbtab, int invalidate) const;
#endif
+
+ NdbRecord *getRecord(const Table *table);
+ NdbRecord *getRecord(const char *tableName);
+ void releaseRecord(NdbRecord *rec);
+
+ void recAddAttrNotNULL(const char *tableName, NdbRecord *rec, Uint32 attrId, Uint32 offset);
+ void recAddAttrNotNULL(const char *tableName, NdbRecord *rec, const char *colName, Uint32 offset);
+
+ Uint32 *getRecAttrSet(const char *tableName, NdbRecord *rec);
+ void releaseRecAttrSet(Uint32 *attrSet);
+
+ void recAttrSetEnable(Uint32 *attrSet, const char *tableName, const NdbRecord *rec, Uint32 attrId);
+ void recAttrSetEnable(Uint32 *attrSet, const char *tableName, const NdbRecord *rec, const char *colName);
+
};
};
--- 1.66/storage/ndb/src/ndbapi/NdbTransaction.cpp 2006-11-30 12:44:04 +01:00
+++ 1.67/storage/ndb/src/ndbapi/NdbTransaction.cpp 2006-11-30 12:44:04 +01:00
@@ -21,6 +21,7 @@
#include <NdbScanOperation.hpp>
#include <NdbIndexScanOperation.hpp>
#include <NdbIndexOperation.hpp>
+#include <NdbDictionaryImpl.hpp>
#include "NdbApiSignal.hpp"
#include "TransporterFacade.hpp"
#include "API.hpp"
@@ -2148,6 +2149,257 @@ NdbTransaction::getNextCompletedOperatio
if(current == 0)
return theCompletedFirstOp;
return current->theNext;
+}
+
+NdbOperation *
+NdbTransaction::readTuple(const char *tableName, const NdbRecord *rec, char *row, const Uint32 *mask)
+{
+ NdbOperation *op= getNdbOperation(tableName);
+ if(!op)
+ return op;
+
+ op->readTuple();
+
+ /* First do equal on all of the primary key attributes. */
+ for(Uint32 i= 0; i<rec->noOfColumns; i++)
+ {
+ switch (rec->columns[i].type)
+ {
+ case NdbRecord::AttrUnused:
+ // ToDo: Report an error here if PK.
+ break;
+ case NdbRecord::AttrNotNULL:
+ if (rec->columns[i].flags & NdbRecord::IsPK)
+ op->equal(i, &(row[rec->columns[i].offset]), rec->columns[i].maxSize);
+ else if (!mask || (mask[i>>5] & (1<<(i&31))))
+ op->getValue(i, &(row[rec->columns[i].offset]));
+ break;
+ default:
+ assert(0);
+ }
+ }
+}
+
+NdbOperation *
+NdbTransaction::insertTuple(const char *tableName, const NdbRecord *rec, const char *row, const Uint32 *mask)
+{
+ NdbOperation *op= getNdbOperation(tableName);
+ if(!op)
+ return op;
+
+ op->insertTuple();
+ for(Uint32 i= 0; i<rec->noOfColumns; i++)
+ {
+ switch (rec->columns[i].type)
+ {
+ case NdbRecord::AttrUnused:
+ // ToDo: Report error if PK.
+ break;
+ case NdbRecord::AttrNotNULL:
+ if (rec->columns[i].flags & NdbRecord::IsPK)
+ op->equal(i, &(row[rec->columns[i].offset]), rec->columns[i].maxSize);
+ else if (!mask || (mask[i>>5] & (1<<(i&31))))
+ op->setValue(i, &(row[rec->columns[i].offset]));
+ break;
+ default:
+ assert(0);
+ }
+ }
+}
+
+NdbOperation *
+NdbTransaction::updateTuple(const char *tableName, const NdbRecord *rec, const char *row, const Uint32 *mask)
+{
+ NdbOperation *op= getNdbOperation(tableName);
+ if(!op)
+ return op;
+
+ op->updateTuple();
+
+ for(Uint32 i= 0; i<rec->noOfColumns; i++)
+ {
+ switch (rec->columns[i].type)
+ {
+ case NdbRecord::AttrUnused:
+ // ToDo: Report an error here if PK.
+ break;
+ case NdbRecord::AttrNotNULL:
+ if (rec->columns[i].flags & NdbRecord::IsPK)
+ op->equal(i, &(row[rec->columns[i].offset]), rec->columns[i].maxSize);
+ else if (!mask || (mask[i>>5] & (1<<(i&31))))
+ op->setValue(i, &(row[rec->columns[i].offset]));
+ break;
+ default:
+ assert(0);
+ }
+ }
+}
+
+NdbOperation *
+NdbTransaction::deleteTuple(const char *tableName, const NdbRecord *rec, const char *row)
+{
+ NdbOperation *op= getNdbOperation(tableName);
+ if(!op)
+ return op;
+
+ op->deleteTuple();
+
+ /* Do equal on all of the primary key attributes. */
+ for(Uint32 i= 0; i<rec->noOfColumns; i++)
+ {
+ switch (rec->columns[i].type)
+ {
+ case NdbRecord::AttrUnused:
+ // ToDo: Report an error here.
+ break;
+ case NdbRecord::AttrNotNULL:
+ if (rec->columns[i].flags & NdbRecord::IsPK)
+ op->equal(i, &(row[rec->columns[i].offset]), rec->columns[i].maxSize);
+ break;
+ default:
+ assert(0);
+ }
+ }
+}
+
+NdbOperation *
+NdbTransaction::dirtyWriteTuple(const char *tableName, const NdbRecord *rec, const char *row, const Uint32 *mask)
+{
+ NdbOperation *op= getNdbOperation(tableName);
+ if(!op)
+ return op;
+
+ op->dirtyWrite();
+ for(Uint32 i= 0; i<rec->noOfColumns; i++)
+ {
+ switch (rec->columns[i].type)
+ {
+ case NdbRecord::AttrUnused:
+ // ToDo: Report error if PK.
+ break;
+ case NdbRecord::AttrNotNULL:
+ if (rec->columns[i].flags & NdbRecord::IsPK)
+ op->equal(i, &(row[rec->columns[i].offset]), rec->columns[i].maxSize);
+ else if (!mask || (mask[i>>5] & (1<<(i&31))))
+ op->setValue(i, &(row[rec->columns[i].offset]));
+ break;
+ default:
+ assert(0);
+ }
+ }
+}
+
+NdbOperation *
+NdbTransaction::writeTuple(const char *tableName, const NdbRecord *rec, const char *row, const Uint32 *mask)
+{
+ NdbOperation *op= getNdbOperation(tableName);
+ if(!op)
+ return op;
+
+ op->writeTuple();
+ for(Uint32 i= 0; i<rec->noOfColumns; i++)
+ {
+ switch (rec->columns[i].type)
+ {
+ case NdbRecord::AttrUnused:
+ // ToDo: Report error if PK.
+ break;
+ case NdbRecord::AttrNotNULL:
+ if (rec->columns[i].flags & NdbRecord::IsPK)
+ op->equal(i, &(row[rec->columns[i].offset]), rec->columns[i].maxSize);
+ else if (!mask || (mask[i>>5] & (1<<(i&31))))
+ op->setValue(i, &(row[rec->columns[i].offset]));
+ break;
+ default:
+ assert(0);
+ }
+ }
+}
+
+NdbOperation *
+NdbTransaction::simpleReadTuple(const char *tableName, const NdbRecord *rec, char *row, const Uint32 *mask)
+{
+ NdbOperation *op= getNdbOperation(tableName);
+ if(!op)
+ return op;
+
+ op->simpleRead();
+
+ /* First do equal on all of the primary key attributes. */
+ for(Uint32 i= 0; i<rec->noOfColumns; i++)
+ {
+ switch (rec->columns[i].type)
+ {
+ case NdbRecord::AttrUnused:
+ // ToDo: Report an error here if PK.
+ break;
+ case NdbRecord::AttrNotNULL:
+ if (rec->columns[i].flags & NdbRecord::IsPK)
+ op->equal(i, &(row[rec->columns[i].offset]), rec->columns[i].maxSize);
+ else if (!mask || (mask[i>>5] & (1<<(i&31))))
+ op->getValue(i, &(row[rec->columns[i].offset]));
+ break;
+ default:
+ assert(0);
+ }
+ }
+}
+
+NdbOperation *
+NdbTransaction::dirtyReadTuple(const char *tableName, const NdbRecord *rec, char *row, const Uint32 *mask)
+{
+ NdbOperation *op= getNdbOperation(tableName);
+ if(!op)
+ return op;
+
+ op->dirtyRead();
+
+ /* First do equal on all of the primary key attributes. */
+ for(Uint32 i= 0; i<rec->noOfColumns; i++)
+ {
+ switch (rec->columns[i].type)
+ {
+ case NdbRecord::AttrUnused:
+ // ToDo: Report an error here if PK.
+ break;
+ case NdbRecord::AttrNotNULL:
+ if (rec->columns[i].flags & NdbRecord::IsPK)
+ op->equal(i, &(row[rec->columns[i].offset]), rec->columns[i].maxSize);
+ else if (!mask || (mask[i>>5] & (1<<(i&31))))
+ op->getValue(i, &(row[rec->columns[i].offset]));
+ break;
+ default:
+ assert(0);
+ }
+ }
+}
+
+NdbOperation *
+NdbTransaction::dirtyUpdateTuple(const char *tableName, const NdbRecord *rec, const char *row, const Uint32 *mask)
+{
+ NdbOperation *op= getNdbOperation(tableName);
+ if(!op)
+ return op;
+
+ op->dirtyUpdate();
+
+ for(Uint32 i= 0; i<rec->noOfColumns; i++)
+ {
+ switch (rec->columns[i].type)
+ {
+ case NdbRecord::AttrUnused:
+ // ToDo: Report an error here if PK.
+ break;
+ case NdbRecord::AttrNotNULL:
+ if (rec->columns[i].flags & NdbRecord::IsPK)
+ op->equal(i, &(row[rec->columns[i].offset]), rec->columns[i].maxSize);
+ else if (!mask || (mask[i>>5] & (1<<(i&31))))
+ op->setValue(i, &(row[rec->columns[i].offset]));
+ break;
+ default:
+ assert(0);
+ }
+ }
}
#ifdef VM_TRACE
--- 1.64/storage/ndb/src/ndbapi/NdbDictionary.cpp 2006-11-30 12:44:04 +01:00
+++ 1.65/storage/ndb/src/ndbapi/NdbDictionary.cpp 2006-11-30 12:44:04 +01:00
@@ -1480,6 +1480,60 @@ NdbDictionary::Dictionary::removeTableGl
return m_impl.releaseTableGlobal(NdbTableImpl::getImpl(ndbtab), invalidate);
}
+NdbRecord *
+NdbDictionary::Dictionary::getRecord(const Table *table)
+{
+ return m_impl.getRecord(&NdbTableImpl::getImpl(*table));
+}
+
+NdbRecord *
+NdbDictionary::Dictionary::getRecord(const char *tableName)
+{
+ return m_impl.getRecord(tableName);
+}
+
+void
+NdbDictionary::Dictionary::releaseRecord(NdbRecord *rec)
+{
+ m_impl.releaseRecord(rec);
+}
+
+void
+NdbDictionary::Dictionary::recAddAttrNotNULL(const char *tableName, NdbRecord *rec, Uint32 attrId, Uint32 offset)
+{
+ m_impl.recAddAttrNotNULL(tableName, rec, attrId, offset);
+}
+
+void
+NdbDictionary::Dictionary::recAddAttrNotNULL(const char *tableName, NdbRecord *rec, const char *colName, Uint32 offset)
+{
+ m_impl.recAddAttrNotNULL(tableName, rec, colName, offset);
+}
+
+Uint32 *
+NdbDictionary::Dictionary::getRecAttrSet(const char *tableName, NdbRecord *rec)
+{
+ m_impl.getRecAttrSet(tableName, rec);
+}
+
+void
+NdbDictionary::Dictionary::releaseRecAttrSet(Uint32 *attrSet)
+{
+ m_impl.releaseRecAttrSet(attrSet);
+}
+
+void
+NdbDictionary::Dictionary::recAttrSetEnable(Uint32 *attrSet, const char *tableName, const NdbRecord *rec, Uint32 attrId)
+{
+ m_impl.recAttrSetEnable(attrSet, tableName, rec, attrId);
+}
+
+void
+NdbDictionary::Dictionary::recAttrSetEnable(Uint32 *attrSet, const char *tableName, const NdbRecord *rec, const char *colName)
+{
+ m_impl.recAttrSetEnable(attrSet, tableName, rec, colName);
+}
+
void NdbDictionary::Dictionary::putTable(const NdbDictionary::Table * table)
{
NdbDictionary::Table *copy_table = new NdbDictionary::Table;
--- 1.69/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp 2006-11-30 12:44:04 +01:00
+++ 1.70/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp 2006-11-30 12:44:04 +01:00
@@ -572,6 +572,48 @@ public:
virtual int init(NdbTableImpl &tab) const = 0;
};
+class NdbRecord {
+public:
+ Uint32 tableId;
+ Uint32 tableVersion;
+
+ enum Flags
+ {
+ IsPK= 1,
+ };
+
+ enum RecAttrTypes
+ {
+ AttrUnused= 0,
+ AttrNotNULL,
+ };
+
+ struct Attr
+ {
+ /*
+ Type of this record attribute, determines which other members in the
+ struct are valid.
+ */
+ enum RecAttrTypes type;
+ /* Offset of data from the start of a row. */
+ Uint32 offset;
+ /*
+ Maximum size of the attribute. This is duplicated here to avoid having
+ to dig into Table object for every attribute fetch/store.
+ */
+ Uint32 maxSize;
+
+ Uint32 flags;
+ };
+
+ /*
+ The size of this array is the same as number of columns in the table.
+ */
+ Uint32 noOfColumns;
+ struct Attr *columns;
+};
+
+
class NdbDictionaryImpl : public NdbDictionary::Dictionary {
public:
NdbDictionaryImpl(Ndb &ndb);
@@ -666,6 +708,95 @@ public:
NdbTableImpl &prim);
NdbIndexImpl * getIndexImpl(const char * name,
const BaseString& internalName);
+
+
+ /* NdbRecord stuff. */
+ NdbRecord *getRecord(const NdbTableImpl *table)
+ {
+ NdbRecord *rec;
+
+ rec= (NdbRecord *)malloc(sizeof(*rec));
+ if (!rec)
+ return rec;
+ rec->noOfColumns= table->getNoOfColumns();
+ rec->columns= (NdbRecord::Attr *)calloc(rec->noOfColumns, sizeof(rec->columns[0]));
+ if (!rec->columns)
+ {
+ free(rec);
+ return NULL;
+ }
+
+ rec->tableId= table->getObjectId();
+ rec->tableVersion= table->getObjectVersion();
+
+ return rec;
+ }
+
+ NdbRecord *getRecord(const char *tableName)
+ {
+ NdbTableImpl *table= getTable(tableName);
+ if(table)
+ return getRecord(table);
+ else
+ return NULL;
+ }
+
+ void releaseRecord(NdbRecord *rec)
+ {
+ free(rec->columns);
+ free(rec);
+ }
+
+ /* ToDo: The interface for setting columns in NdbRecord needs updating. */
+ void recAddAttrNotNULL(const char *tableName, NdbRecord *rec, Uint32 attrId, Uint32 offset)
+ {
+ const NdbTableImpl *table= getTable(tableName);
+ rec->columns[attrId].type= NdbRecord::AttrNotNULL;
+ rec->columns[attrId].offset= offset;
+ const NdbDictionary::Column *col= table->getColumn(attrId);
+ rec->columns[attrId].maxSize= col->getSizeInBytes();
+ rec->columns[attrId].flags=
+ (col->getPrimaryKey() ? NdbRecord::IsPK : 0);
+ }
+
+ void recAddAttrNotNULL(const char *tableName, NdbRecord *rec, const char *colName, Uint32 offset)
+ {
+ const NdbTableImpl *table= getTable(tableName);
+ const NdbDictionary::Column *col= table->getColumn(colName);
+ Uint32 attrId= col->getAttrId();
+ rec->columns[attrId].type= NdbRecord::AttrNotNULL;
+ rec->columns[attrId].offset= offset;
+ rec->columns[attrId].maxSize= col->getSizeInBytes();
+ rec->columns[attrId].flags=
+ (col->getPrimaryKey() ? NdbRecord::IsPK : 0);
+ }
+
+ Uint32 *getRecAttrSet(const char *tableName, NdbRecord *rec)
+ {
+ Uint32 *attrSet;
+
+ attrSet= (Uint32 *)calloc((rec->noOfColumns+31)>>5, sizeof(*attrSet));
+ return attrSet;
+ }
+
+ void releaseRecAttrSet(Uint32 *attrSet)
+ {
+ free(attrSet);
+ }
+
+ void recAttrSetEnable(Uint32 *attrSet, const char *tableName, const NdbRecord *rec, Uint32 attrId)
+ {
+ attrSet[attrId>>5]|= 1<<(attrId&31);
+ }
+
+ void recAttrSetEnable(Uint32 *attrSet, const char *tableName, const NdbRecord *rec, const char *colName)
+ {
+ // ToDo: check table/column not found ...
+ const NdbTableImpl *table= getTable(tableName);
+ const NdbDictionary::Column *col= table->getColumn(colName);
+ recAttrSetEnable(attrSet, tableName, rec, col->getAttrId());
+ }
+
private:
NdbTableImpl * fetchGlobalTableImplRef(const GlobalCacheInitObject &obj);
};
--- 1.13/storage/ndb/test/ndbapi/flexBench.cpp 2006-11-30 12:44:04 +01:00
+++ 1.14/storage/ndb/test/ndbapi/flexBench.cpp 2006-11-30 12:44:04 +01:00
@@ -608,27 +608,33 @@ static void* flexBenchThread(void* pArg)
tNoOfTables * tNoOfAttributes * sizeof(int) * tAttributeSize ;
int nRefBuffSize =
tNoOfOperations * tNoOfAttributes * sizeof(int) * tAttributeSize ;
- unsigned*** longKeyAttrValue;
-
+ unsigned** longKeyAttrValue;
+ NdbRecord** pRec= NULL;
+ Uint32** pAttrSet= NULL;
+ int nRefOpOffset= 0;
+ NdbDictionary::Dictionary *dict= NULL;
threadNo = pThreadData->threadNo ;
+ /* Additional space in rows for long primaru keys. */
+ if (useLongKeys)
+ nReadBuffSize+= tNoOfTables*sizeof(unsigned)*tSizeOfLongPK*tNoOfLongPK;
+
attrValue = (int*)malloc(nReadBuffSize) ;
attrRefValue = (int*)malloc(nRefBuffSize) ;
pOps = (NdbOperation**)malloc(tNoOfTables*sizeof(NdbOperation*)) ;
pNdb = new Ndb(g_cluster_connection, "TEST_DB" );
+ pRec= (NdbRecord **)calloc(tNoOfTables, sizeof(*pRec));
+ pAttrSet= (Uint32 **)calloc(tNoOfTables, sizeof(*pAttrSet));
- if(!attrValue || !attrRefValue || !pOps || !pNdb){
+ if (!attrValue || !attrRefValue || !pOps || !pNdb || !pRec || !pAttrSet)
+ {
// Check allocations to make sure we got all the memory we asked for
ndbout << "One or more memory allocations failed when starting thread #";
ndbout << threadNo << endl ;
ndbout << "Thread #" << threadNo << " will now exit" << endl ;
tResult = 13 ;
- free(attrValue) ;
- free(attrRefValue) ;
- free(pOps) ;
- delete pNdb ;
- return 0; // thread exits
+ goto end;
}
pNdb->init();
@@ -638,33 +644,90 @@ static void* flexBenchThread(void* pArg)
// Calculate an "unique" number to use as primary key
threadBase = (threadNo * 2000000) + (tNodeId * 260000000);
+ /* Set up NdbRecord's for the tables. */
+ dict= pNdb->getDictionary();
+ for (int tab= 0; tab<tNoOfTables; tab++)
+ {
+ int firstCol= 0;
+ if(useLongKeys)
+ firstCol+= tNoOfLongPK;
+
+ pRec[tab]= dict->getRecord(tableName[tab]);
+ if (pRec[tab]==NULL) {
+ // This is a fatal error, abort program
+ ndbout << "Failed to allocate NdbRecord in thread" << threadNo;
+ ndbout << endl;
+ tResult = 13;
+ goto end;
+ }
+ for (Uint32 col= 0; col<tNoOfAttributes; col++)
+ dict->recAddAttrNotNULL(tableName[tab], pRec[tab], col+firstCol, sizeof(int)*tAttributeSize*col);
+ if (useLongKeys)
+ {
+ for (Uint32 col= 0; col<tNoOfLongPK; col++)
+ {
+ dict->recAddAttrNotNULL(tableName[tab], pRec[tab], longKeyAttrName[col],
+ sizeof(int)*tAttributeSize*tNoOfAttributes +
+ sizeof(unsigned)*tSizeOfLongPK*col);
+ }
+ }
+
+ /* Attribute set for reading just one attribute, when verifying delete. */
+ pAttrSet[tab]= dict->getRecAttrSet(tableName[tab], pRec[tab]);
+ if (pAttrSet[tab]==NULL) {
+ // This is a fatal error, abort program
+ ndbout << "Failed to allocate NdbRecAttrSet in thread" << threadNo;
+ ndbout << endl;
+ tResult = 13;
+ goto end;
+ }
+ if (useLongKeys)
+ dict->recAttrSetEnable(pAttrSet[tab], tableName[tab], pRec[tab], longKeyAttrName[0]);
+ else
+ dict->recAttrSetEnable(pAttrSet[tab], tableName[tab], pRec[tab], (Uint32)0);
+ }
+
if(useLongKeys){
// Allocate and populate the longkey array.
- longKeyAttrValue = (unsigned ***) malloc(sizeof(unsigned**) * tNoOfOperations );
+ longKeyAttrValue= (unsigned **) calloc(tNoOfOperations, sizeof(unsigned*));
+ if (longKeyAttrValue==NULL) {
+ ndbout << "Memory allocation failed for longKeyAttrValue in thread"
+ << threadNo;
+ ndbout << endl;
+ tResult = 13;
+ goto end;
+ }
Uint32 n;
for (n = 0; n < tNoOfOperations; n++)
- longKeyAttrValue[n] = (unsigned **) malloc(sizeof(unsigned*) * tNoOfLongPK );
- for (n = 0; n < tNoOfOperations; n++){
+ {
+ longKeyAttrValue[n]=
+ (unsigned *) malloc(sizeof(unsigned) * tSizeOfLongPK * tNoOfLongPK );
+ if (longKeyAttrValue[n]==NULL) {
+ ndbout << "Memory allocation failed for longKeyAttrValue in thread"
+ << threadNo;
+ ndbout << endl;
+ tResult = 13;
+ goto end;
+ }
+
for (Uint32 i = 0; i < tNoOfLongPK ; i++) {
- longKeyAttrValue[n][i] = (unsigned *) malloc(sizeof(unsigned) * tSizeOfLongPK);
- memset(longKeyAttrValue[n][i], 0, sizeof(unsigned) * tSizeOfLongPK);
for(Uint32 j = 0; j < tSizeOfLongPK; j++) {
// Repeat the unique value to fill up the long key.
- longKeyAttrValue[n][i][j] = threadBase + n;
+ longKeyAttrValue[n][i*tSizeOfLongPK+j]= threadBase + n;
}
}
}
}
- int nRefOpOffset = 0 ;
+ nRefOpOffset = 0 ;
//Assign reference attribute values to memory
for(Uint32 ops = 1 ; ops < tNoOfOperations ; ops++){
// Calculate offset value before going into the next loop
nRefOpOffset = tAttributeSize*tNoOfAttributes*(ops-1) ;
- for(Uint32 a = 0 ; a < tNoOfAttributes ; a++){
- *(int*)&attrRefValue[nRefOpOffset + tAttributeSize*a] =
- (int)(threadBase + ops + a) ;
- }
+ for(Uint32 a = 0 ; a < tNoOfAttributes ; a++)
+ for(Uint32 b= 0; b<tAttributeSize; b++)
+ attrRefValue[nRefOpOffset + tAttributeSize*a + b] =
+ (int)(threadBase + ops + a) ;
}
#ifdef CEBIT_STAT
@@ -700,6 +763,7 @@ static void* flexBenchThread(void* pArg)
loopCountTables = tNoOfTables;
loopCountAttributes = tNoOfAttributes;
+ /* Hm, I wonder why we do one operation less that tNoOfAttributes here? */
for (int count = 1; count < loopCountOps && tResult == 0;){
pTrans = pNdb->startTransaction();
@@ -718,94 +782,79 @@ static void* flexBenchThread(void* pArg)
for (int countTables = 0;
countTables < loopCountTables && tResult == 0;
countTables++) {
+ int nTableOffset= tAttributeSize*tNoOfAttributes*countTables;
+ int *pRow= &attrValue[nTableOffset];
- pOps[countTables] = pTrans->getNdbOperation(tableName[countTables]);
- if (pOps[countTables] == NULL) {
- // This is a fatal error, abort program
- ndbout << "getNdbOperation: " << pTrans->getNdbError();
- tResult = 2; // Indicate fatal error
- break;
- }//if
+ if ((tType==stInsert || tType==stUpdate) && tNoOfAttributes>1)
+ {
+ /* Copy the non-PK columns to send to the server. */
+ memcpy(&pRow[tAttributeSize],
+ &attrRefValue[nRefLocalOpOffset+tAttributeSize],
+ (tNoOfAttributes-1)*tAttributeSize*sizeof(int));
+ }
+ /* Copy the primary key(s). */
+ if (useLongKeys)
+ {
+ memcpy(pRow+tAttributeSize*tNoOfAttributes,
+ longKeyAttrValue[count-1],
+ tNoOfLongPK*tSizeOfLongPK*sizeof(unsigned));
+ }
+ else
+ {
+ pRow[0]= attrRefValue[nRefLocalOpOffset];
+ }
+
+ NdbRecord *record= pRec[countTables];
+ const char *tabName= tableName[countTables];
switch (tType) {
case stInsert: // Insert case
if (theWriteFlag == 1 && theDirtyFlag == 1)
- pOps[countTables]->dirtyWrite();
+ pOps[countTables]= pTrans->dirtyWriteTuple(tabName, record, (char *)pRow);
else if (theWriteFlag == 1)
- pOps[countTables]->writeTuple();
+ pOps[countTables]= pTrans->writeTuple(tabName, record, (char *)pRow);
else
- pOps[countTables]->insertTuple();
+ pOps[countTables]= pTrans->insertTuple(tabName, record, (char *)pRow);
break;
case stRead: // Read Case
if (theSimpleFlag == 1)
- pOps[countTables]->simpleRead();
+ pOps[countTables]= pTrans->simpleReadTuple(tabName, record, (char *)pRow);
else if (theDirtyFlag == 1)
- pOps[countTables]->dirtyRead();
+ pOps[countTables]= pTrans->dirtyReadTuple(tabName, record, (char *)pRow);
else
- pOps[countTables]->readTuple();
+ pOps[countTables]= pTrans->readTuple(tabName, record, (char *)pRow);
break;
case stUpdate: // Update Case
if (theWriteFlag == 1 && theDirtyFlag == 1)
- pOps[countTables]->dirtyWrite();
+ pOps[countTables]= pTrans->dirtyWriteTuple(tabName, record, (char *)pRow);
else if (theWriteFlag == 1)
- pOps[countTables]->writeTuple();
+ pOps[countTables]= pTrans->writeTuple(tabName, record, (char *)pRow);
else if (theDirtyFlag == 1)
- pOps[countTables]->dirtyUpdate();
+ pOps[countTables]= pTrans->dirtyUpdateTuple(tabName, record, (char *)pRow);
else
- pOps[countTables]->updateTuple();
+ pOps[countTables]= pTrans->updateTuple(tabName, record, (char *)pRow);
break;
case stDelete: // Delete Case
- pOps[countTables]->deleteTuple();
+ pOps[countTables]= pTrans->deleteTuple(tabName, record, (char *)pRow);
break;
case stVerify:
- pOps[countTables]->readTuple();
+ pOps[countTables]= pTrans->readTuple(tabName, record, (char *)pRow);
break;
case stVerifyDelete:
- pOps[countTables]->readTuple();
+ pOps[countTables]= pTrans->readTuple(tabName, record, (char *)pRow,
+ pAttrSet[countTables]);
break;
default:
assert(false);
}//switch
-
- if(useLongKeys){
- // Loop the equal call so the complete key is send to the kernel.
- for(Uint32 i = 0; i < tNoOfLongPK; i++)
- pOps[countTables]->equal(longKeyAttrName[i],
- (char *)longKeyAttrValue[count - 1][i], tSizeOfLongPK*4);
- }
- else
- pOps[countTables]->equal((Uint32)0,
- (char*)&attrRefValue[nRefLocalOpOffset]);
-
- if (tType == stInsert || tType == stUpdate){
- for (int ca = 1; ca < loopCountAttributes; ca++){
- pOps[countTables]->setValue((Uint32)ca,
- (char*)&attrRefValue[nRefLocalOpOffset + tAttributeSize*ca]);
- }//for
- } else if (tType == stRead || stVerify == tType) {
- int nTableOffset = tAttributeSize *
- loopCountAttributes *
- countTables ;
- for (int ca = 1; ca < loopCountAttributes; ca++) {
- tTmp = pOps[countTables]->getValue((Uint32)ca,
- (char*)&attrValue[nTableOffset + tAttributeSize*ca]);
- }//for
- } else if (stVerifyDelete == tType) {
- if(useLongKeys){
- int nTableOffset = tAttributeSize *
- loopCountAttributes *
- countTables ;
- tTmp = pOps[countTables]->getValue(longKeyAttrName[0],
- (char*)&attrValue[nTableOffset]);
- } else {
- int nTableOffset = tAttributeSize *
- loopCountAttributes *
- countTables ;
- tTmp = pOps[countTables]->getValue((Uint32)0,
- (char*)&attrValue[nTableOffset]);
- }
+ if (pOps[countTables] == NULL) {
+ // This is a fatal error, abort program
+ ndbout << "getNdbOperation: " << pTrans->getNdbError();
+ tResult = 2; // Indicate fatal error
+ break;
}//if
+
}//for Tables loop
if (tResult != 0)
@@ -928,20 +977,36 @@ static void* flexBenchThread(void* pArg)
}//if
#endif
}
+
+ end:
+ if(pAttrSet)
+ {
+ for (Uint32 i= 0; i<tNoOfTables; i++)
+ if (pAttrSet[i])
+ dict->releaseRecAttrSet(pAttrSet[i]);
+ free(pAttrSet);
+ }
+ if(pRec)
+ {
+ for (Uint32 i= 0; i<tNoOfTables; i++)
+ if (pRec[i])
+ dict->releaseRecord(pRec[i]);
+ free(pRec);
+ }
delete pNdb;
- free(attrValue) ;
- free(attrRefValue) ;
- free(pOps) ;
+ if(attrValue)
+ free(attrValue);
+ if(attrRefValue)
+ free(attrRefValue);
+ if(pOps)
+ free(pOps);
if (useLongKeys == true) {
// Only free these areas if they have been allocated
// Otherwise cores will occur
- for (Uint32 n = 0; n < tNoOfOperations; n++){
- for (Uint32 i = 0; i < tNoOfLongPK; i++) {
- free(longKeyAttrValue[n][i]);
- }
- free(longKeyAttrValue[n]);
- }
+ for (Uint32 n = 0; n < tNoOfOperations; n++)
+ if (longKeyAttrValue[n])
+ free(longKeyAttrValue[n]);
free(longKeyAttrValue);
} // if
| Thread |
|---|
| • bk commit into 5.1 tree (knielsen:1.2325) | knielsen | 30 Nov |