#At file:///Users/mz/mysql/ndb-7.1-opt64/ based on revid:martin.zaun@stripped
3864 Martin Zaun 2010-10-08
crund - fixes, improvements, cleanups flowing from new TWS code.
modified:
.bzrignore
storage/ndb/test/crund/Makefile
storage/ndb/test/crund/Makefile.defaults
storage/ndb/test/crund/build.xml
storage/ndb/test/crund/martins_little_helpers/src/utils/Properties.hpp
storage/ndb/test/crund/scripts/load_shema.sh
storage/ndb/test/crund/src/com/mysql/cluster/crund/CrundDriver.java
storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbApiLoad.java
storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbBase.java
storage/ndb/test/crund/src/crundndb/CrundDriver.cpp
storage/ndb/test/crund/src/crundndb/CrundDriver.hpp
storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.cpp
storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.hpp
storage/ndb/test/crund/src/crundndb/Driver.cpp
storage/ndb/test/crund/src/crundndb/Driver.hpp
storage/ndb/test/crund/src/crundndb/NdbApiDriver.cpp
storage/ndb/test/crund/src/crundndb/NdbApiDriver.hpp
storage/ndb/test/crund/src/crundndb/com_mysql_cluster_crund_NdbApiLoad.cpp
=== modified file '.bzrignore'
--- a/.bzrignore 2010-10-05 08:48:30 +0000
+++ b/.bzrignore 2010-10-08 11:17:35 +0000
@@ -3134,10 +3134,12 @@ storage/ndb/test/crund/scripts/ndblog
storage/ndb/test/crund/scripts/results
storage/ndb/test/crund/src/crundndb/NdbApiDriver
storage/ndb/test/crund/src/crundndb/com_mysql_cluster_crund_NdbApiLoad.h
-storage/ndb/test/crund/tws_benchmark/build/
-storage/ndb/test/crund/tws_benchmark/nbproject/configs/
-storage/ndb/test/crund/tws_benchmark/nbproject/private/
-storage/ndb/test/crund/tws_benchmark/run.properties
+storage/ndb/test/crund/tws/tws_java/build/
+storage/ndb/test/crund/tws/tws_java/nbproject/configs/
+storage/ndb/test/crund/tws/tws_java/nbproject/private/
+storage/ndb/test/crund/tws/tws_java/run.properties
+storage/ndb/test/crund/tws/*.properties
+storage/ndb/test/crund/tws/tws_cpp/TwsDriver
libmysqld/examples/mysqltest.cc
libmysqld/debug_sync.cc
=== modified file 'storage/ndb/test/crund/Makefile'
--- a/storage/ndb/test/crund/Makefile 2010-09-27 05:31:17 +0000
+++ b/storage/ndb/test/crund/Makefile 2010-10-08 11:17:35 +0000
@@ -2,7 +2,7 @@
SRC = ./src
-.PHONY: all help dep dbg opt prf clean clobber distclean check
+.PHONY: all help dep dbg opt prf clean mostlclean clobber distclean check
all: dbg
help:
@@ -16,7 +16,7 @@ help:
@echo "distclean -- delete also database and server log files"
@echo "check -- perform self-tests (if any)"
-dep dbg opt prf clean mostlyclean check:
+dep dbg opt prf clean mostlyclean clobber check:
ant $@
@cd $(SRC)/crundndb && $(MAKE) $(MFLAGS) $@
=== modified file 'storage/ndb/test/crund/Makefile.defaults'
--- a/storage/ndb/test/crund/Makefile.defaults 2010-09-29 10:02:15 +0000
+++ b/storage/ndb/test/crund/Makefile.defaults 2010-10-08 11:17:35 +0000
@@ -144,7 +144,9 @@
# Default Targets Section:
-.PHONY: dep depend dbg opt prf clean mostlyclean distclean check
+.PHONY: dep depend dbg opt prf clean mostlyclean clobber distclean check
+
+help:
dep depend:
@set -e; \
@@ -180,7 +182,7 @@ clean:
# library-archiving removes .o files with empty .depend file,
# so, better delete it only as part of mostlyclean
-mostlyclean: clean
+mostlyclean clobber: clean
rm -rf $(MOSTLYCLEAN) .depend
distclean: mostlyclean
=== modified file 'storage/ndb/test/crund/build.xml'
--- a/storage/ndb/test/crund/build.xml 2010-10-05 08:48:30 +0000
+++ b/storage/ndb/test/crund/build.xml 2010-10-08 11:17:35 +0000
@@ -198,14 +198,15 @@
</target>
<!-- deletes also log files -->
- <target name="clobber" depends="clean">
+ <target name="clobber" depends="mostlyclean"/>
+ <target name="mostlyclean" depends="clean">
<delete includeEmptyDirs="true" quiet="true" >
<fileset dir="${basedir}" includes="log_*"/>
</delete>
</target>
<!-- deletes also database files -->
- <target name="distclean" depends="clobber">
+ <target name="distclean" depends="mostlyclean">
<delete verbose="true">
<fileset dir="${src.java}" includes="**/*~" defaultexcludes="no"/>
</delete>
=== modified file 'storage/ndb/test/crund/martins_little_helpers/src/utils/Properties.hpp'
--- a/storage/ndb/test/crund/martins_little_helpers/src/utils/Properties.hpp 2010-10-06 06:15:04 +0000
+++ b/storage/ndb/test/crund/martins_little_helpers/src/utils/Properties.hpp 2010-10-08 11:17:35 +0000
@@ -23,8 +23,11 @@ using std::map;
using std::wstring;
using std::ios_base;
using std::istream;
+//using std::wistream;
using std::ostream;
+//using std::wostream;
using std::streambuf;
+//using std::wstreambuf;
/**
* The Properties class is a specialized map container that stores
@@ -66,22 +69,22 @@ class Properties : public map<wstring, w
{
public:
/**
- * Reads properties from the file and adds them to this
+ * Reads properties from the character file and adds them to this
* property table.
*/
void load(const char* filename)
throw (ios_base::failure);
/**
- * Reads properties from the input stream and adds them to this
- * property table.
+ * Reads properties from the character input stream and adds them
+ * to this property table.
*/
void load(istream& is)
throw (ios_base::failure);
/**
- * Reads properties from the input byte buffer and adds them to this
- * property table.
+ * Reads properties from the character buffer and adds them
+ * to this property table.
*
* The line-oriented format is the same as used by Java Properties.
* The byte stream is read under the ISO 8859-1 character encoding,
@@ -92,19 +95,39 @@ public:
throw (ios_base::failure);
/**
- * Writes this property table to the file.
+ * Reads properties from the wide character input stream and adds them
+ * to this property table.
+ */
+ // not implemented yet
+ //void load(wistream& is)
+ // throw (ios_base::failure);
+
+ /**
+ * Reads properties from the wide character buffer and adds them
+ * to this property table.
+ *
+ * The byte stream is read under the UTF-32/UCS-4 character encoding,
+ * and characters of the key and value strings are not parsed as an
+ * escape sequence.
+ */
+ // not implemented yet
+ //void load(wstreambuf& ib)
+ // throw (ios_base::failure);
+
+ /**
+ * Writes this property table to the character file.
*/
void store(const char* filename, const wstring* header = NULL) const
throw (ios_base::failure);
/**
- * Writes this property table to the output stream.
+ * Writes this property table to the character output stream.
*/
void store(ostream& os, const wstring* header = NULL) const
throw (ios_base::failure);
/**
- * Writes this property table to the output byte buffer.
+ * Writes this property table to the character buffer.
*
* The format is suitable for reading the properties using the load
* function. The stream is written using the ISO 8859-1 character
@@ -118,6 +141,29 @@ public:
void store(streambuf& ob, const wstring* header = NULL) const
throw (ios_base::failure);
+ /**
+ * Writes this property table to the wide character output stream.
+ */
+ // not implemented yet
+ //void store(wostream& os, const wstring* header = NULL) const
+ // throw (ios_base::failure);
+
+ /**
+ * Writes this property table to the wide character buffer.
+ *
+ * The format is suitable for reading the properties using the load
+ * function. The stream is written using the UTF-32/UCS-4 character
+ * encoding, and characters of the key and value strings are not
+ * rendered as an escape sequence.
+ *
+ * If the header argument is not null, then an ASCII # character, the
+ * header string, and a line separator are first written to the output
+ * stream. Thus, the header can serve as an identifying comment.
+ */
+ // not implemented yet
+ //void store(wstreambuf& ob, const wstring* header = NULL) const
+ // throw (ios_base::failure);
+
protected:
static bool isWS(int c);
static bool isNL(int c);
@@ -146,6 +192,16 @@ operator>>(istream& s, Properties& p)
return s;
}
+/*
+// not implemented yet
+inline wistream&
+operator>>(wistream& s, Properties& p)
+{
+ p.load(s);
+ return s;
+}
+*/
+
inline ostream&
operator<<(ostream& s, const Properties& p)
{
@@ -153,6 +209,17 @@ operator<<(ostream& s, const Properties&
return s;
}
+/*
+// not implemented yet
+inline wostream&
+operator<<(wostream& s, const Properties& p)
+{
+ p.store(s);
+ return s;
+}
+*/
+
+
// ---------------------------------------------------------------------------
// Properties Implementation
// ---------------------------------------------------------------------------
=== modified file 'storage/ndb/test/crund/scripts/load_shema.sh'
--- a/storage/ndb/test/crund/scripts/load_shema.sh 2010-09-27 05:31:17 +0000
+++ b/storage/ndb/test/crund/scripts/load_shema.sh 2010-10-08 11:17:35 +0000
@@ -51,7 +51,7 @@ for ((i=3; i>=0; i--)) ; do
echo
echo "load tws schema..."
- "$MYSQL_BIN/mysql" -v < ../tws_benchmark/schema.sql
+ "$MYSQL_BIN/mysql" -v < ../tws/schema.sql
s=$?
echo "mysql exit status: $s"
=== modified file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/CrundDriver.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/CrundDriver.java 2010-10-05 08:48:30 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/CrundDriver.java 2010-10-08 11:17:35 +0000
@@ -275,10 +275,6 @@ abstract public class CrundDriver extend
}
runOp(op, countA, countB);
}
- if (logHeader) {
- if (logSumOfOps)
- header.append("\ttotal");
- }
if (logSumOfOps) {
out.println();
@@ -295,7 +291,12 @@ abstract public class CrundDriver extend
}
// log buffers
- logHeader = false;
+ if (logHeader) {
+ if (logSumOfOps) {
+ header.append("\ttotal");
+ }
+ logHeader = false;
+ }
if (logRealTime) {
rtimes.append(endl);
if (logSumOfOps) {
=== modified file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbApiLoad.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbApiLoad.java 2010-10-05 08:48:30 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbApiLoad.java 2010-10-08 11:17:35 +0000
@@ -332,9 +332,15 @@ public class NdbApiLoad extends NdbBase
// NDB API datastore operations
// ----------------------------------------------------------------------
- protected native void initConnection(String catalog, String schema);
+ protected native void initConnection(String catalog,
+ String schema,
+ int defaultLockMode);
protected void initConnection() {
- initConnection(catalog, schema);
+ // XXX add lockMode property to CrundDriver, switch then here
+ final int LM_Read = 0;
+ final int LM_Exclusive = 1;
+ final int LM_CommittedRead = 2;
+ initConnection(catalog, schema, LM_CommittedRead);
}
protected native void closeConnection();
protected native void clearData();
=== modified file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbBase.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbBase.java 2010-10-05 08:48:30 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbBase.java 2010-10-08 11:17:35 +0000
@@ -47,11 +47,11 @@ abstract public class NdbBase extends Cr
assert mgmdConnect != null;
// the database
- catalog = props.getProperty("ndb.catalog", "");
+ catalog = props.getProperty("ndb.catalog", "crunddb");
assert catalog != null;
// the schema
- schema = props.getProperty("ndb.schema", "");
+ schema = props.getProperty("ndb.schema", "def");
assert schema != null;
if (msg.length() == 0) {
=== modified file 'storage/ndb/test/crund/src/crundndb/CrundDriver.cpp'
--- a/storage/ndb/test/crund/src/crundndb/CrundDriver.cpp 2010-10-05 08:48:30 +0000
+++ b/storage/ndb/test/crund/src/crundndb/CrundDriver.cpp 2010-10-08 11:17:35 +0000
@@ -45,14 +45,29 @@ using utils::toString;
void
CrundDriver::initProperties() {
Driver::initProperties();
-
+
cout << "setting crund properties ..." << flush;
ostringstream msg;
renewOperations = toBool(props[L"renewOperations"], false);
+
+ string lm = toString(props[L"lockMode"]);
+ if (lm.empty()) {
+ lockMode = READ_COMMITTED;
+ } else if (lm.compare("READ_COMMITTED") == 0) {
+ lockMode = READ_COMMITTED;
+ } else if (lm.compare("SHARED") == 0) {
+ lockMode = SHARED;
+ } else if (lm.compare("EXCLUSIVE") == 0) {
+ lockMode = EXCLUSIVE;
+ } else {
+ msg << "[ignored] lockMode: '" << lm << "'" << endl;
+ lockMode = READ_COMMITTED;
+ }
+
logSumOfOps = toBool(props[L"logSumOfOps"], true);
- //logSumOfOps = toBool(props[L"allowExtendedPC"], false); // not used
+ //allowExtendedPC = toBool(props[L"allowExtendedPC"], false); // not used
aStart = toInt(props[L"aStart"], 256, 0);
if (aStart < 1) {
@@ -150,7 +165,7 @@ CrundDriver::initProperties() {
void
CrundDriver::printProperties() {
Driver::printProperties();
-
+
const ios_base::fmtflags f = cout.flags();
// no effect calling manipulator function, not sure why
//cout << ios_base::boolalpha;
@@ -158,6 +173,7 @@ CrundDriver::printProperties() {
cout << endl << "crund settings ..." << endl;
cout << "renewOperations: " << renewOperations << endl;
+ cout << "lockMode: " << toStr(lockMode) << endl;
cout << "logSumOfOps: " << logSumOfOps << endl;
//cout << "allowExtendedPC: " << allowExtendedPC << endl;
cout << "aStart: " << aStart << endl;
@@ -186,21 +202,21 @@ CrundDriver::runTests() {
assert(bStart <= bEnd && bScale > 1);
for (int i = aStart; i <= aEnd; i *= aScale) {
for (int j = bStart; j <= bEnd; j *= bScale) {
- runOperations(i, j);
+ runLoads(i, j);
}
}
cout << endl
<< "------------------------------------------------------------" << endl
<< endl;
-
+
clearData();
closeOperations();
closeConnection();
}
void
-CrundDriver::runOperations(int countA, int countB) {
+CrundDriver::runLoads(int countA, int countB) {
cout << endl
<< "------------------------------------------------------------" << endl;
@@ -234,21 +250,7 @@ CrundDriver::runOperations(int countA, i
}
clearData();
- // run operations
- for (Operations::const_iterator i = operations.begin();
- i != operations.end(); ++i) {
- // no need for pre-tx cleanup with NDBAPI-based loads
- //if (!allowExtendedPC) {
- // // effectively prevent caching beyond Tx scope by clearing
- // // any data/result caches before the next transaction
- // clearPersistenceContext();
- //}
- runOp(**i, countA, countB);
- }
- if (logHeader) {
- if (logSumOfOps)
- header << "\ttotal";
- }
+ runOperations(countA, countB);
if (logSumOfOps) {
cout << endl
@@ -264,7 +266,12 @@ CrundDriver::runOperations(int countA, i
}
// log buffers
- logHeader = false;
+ if (logHeader) {
+ if (logSumOfOps) {
+ header << "\ttotal";
+ }
+ logHeader = false;
+ }
if (logRealTime) {
if (logSumOfOps) {
rtimes << "\t" << rta;
@@ -280,6 +287,20 @@ CrundDriver::runOperations(int countA, i
}
void
+CrundDriver::runOperations(int countA, int countB) {
+ for (Operations::const_iterator i = operations.begin();
+ i != operations.end(); ++i) {
+ // no need for pre-tx cleanup with NDBAPI-based loads
+ //if (!allowExtendedPC) {
+ // // effectively prevent caching beyond Tx scope by clearing
+ // // any data/result caches before the next transaction
+ // clearPersistenceContext();
+ //}
+ runOp(**i, countA, countB);
+ }
+}
+
+void
CrundDriver::runOp(const Op& op, int countA, int countB) {
const string& name = op.name;
if (exclude.find(name) == exclude.end()) {
@@ -289,4 +310,34 @@ CrundDriver::runOp(const Op& op, int cou
}
}
+const char*
+CrundDriver::toStr(XMode mode) {
+ switch (mode) {
+ case SINGLE:
+ return "single";
+ case BULK:
+ return "bulk";
+ case BATCH:
+ return "batch";
+ default:
+ assert(false);
+ return "<invalid value>";
+ };
+}
+
+const char*
+CrundDriver::toStr(LockMode mode) {
+ switch (mode) {
+ case SINGLE:
+ return "read_committed";
+ case SHARED:
+ return "shared";
+ case EXCLUSIVE:
+ return "exclusive";
+ default:
+ assert(false);
+ return "<invalid value>";
+ };
+}
+
//---------------------------------------------------------------------------
=== modified file 'storage/ndb/test/crund/src/crundndb/CrundDriver.hpp'
--- a/storage/ndb/test/crund/src/crundndb/CrundDriver.hpp 2010-10-05 08:48:30 +0000
+++ b/storage/ndb/test/crund/src/crundndb/CrundDriver.hpp 2010-10-08 11:17:35 +0000
@@ -37,7 +37,12 @@ class CrundDriver : public Driver {
protected:
// benchmark settings
+ enum LockMode { READ_COMMITTED, SHARED, EXCLUSIVE };
+ static const char* toStr(LockMode mode);
+ enum XMode { SINGLE, BULK, BATCH }; // XXX not used yet
+ static const char* toStr(XMode mode); // XXX not used yet
bool renewOperations;
+ LockMode lockMode;
bool logSumOfOps;
//bool allowExtendedPC; // not used
int aStart;
@@ -56,7 +61,7 @@ protected:
virtual void initProperties();
virtual void printProperties();
- // a database operation to be benchmarked
+ // measured units of work
struct Op {
const string name;
@@ -66,8 +71,6 @@ protected:
virtual ~Op() {}
};
-
- // the list of database operations to be benchmarked
typedef vector< const Op* > Operations;
Operations operations;
@@ -75,11 +78,9 @@ protected:
virtual void initOperations() = 0;
virtual void closeOperations() = 0;
virtual void runTests();
+ virtual void runLoads(int countA, int countB);
virtual void runOperations(int countA, int countB);
virtual void runOp(const Op& op, int countA, int countB);
-
- // reports an error if a condition is not met // XXX not covered yet
- //static void verify(bool cond);
};
#endif // CrundDriver_hpp
=== modified file 'storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.cpp'
--- a/storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.cpp 2010-10-05 08:48:30 +0000
+++ b/storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.cpp 2010-10-08 11:17:35 +0000
@@ -21,6 +21,7 @@
#include <iostream>
#include <vector>
#include <algorithm>
+#include <string>
#include <cstring>
#include <cassert>
@@ -36,6 +37,7 @@
using std::cout;
using std::flush;
using std::endl;
+using std::string;
using std::vector;
// JNI crashes with gcc & operator<<(ostream &, long/int)
@@ -172,7 +174,8 @@ CrundModel::init(Ndb* ndb)
void
CrundNdbApiOperations::init(const char* mgmd_conn_str)
{
- assert (mgmd_conn_str);
+ assert(mgmd == NULL);
+ assert(mgmd_conn_str);
// ndb_init must be called first
cout << endl
@@ -183,9 +186,10 @@ CrundNdbApiOperations::init(const char*
cout << " [ok]" << endl;
// instantiate NDB cluster singleton
- cout << "creating cluster conn ..." << flush;
+ cout << "creating cluster connection ..." << flush;
+ assert(mgmd_conn_str);
mgmd = new Ndb_cluster_connection(mgmd_conn_str);
- cout << " [ok]" << endl; // no useful mgmd->string conversion
+ cout << " [ok]" << endl; // no useful mgmd->string conversion
// connect to cluster management node (ndb_mgmd)
cout << "connecting to mgmd ..." << flush;
@@ -202,10 +206,12 @@ CrundNdbApiOperations::init(const char*
void
CrundNdbApiOperations::close()
{
- cout << "closing mgmd conn ..." << flush;
+ assert(mgmd != NULL);
+
+ cout << "closing cluster connection ..." << flush;
delete mgmd;
mgmd = NULL;
- cout << " [ok]" << endl;
+ cout << " [ok]" << endl;
// ndb_close must be called last
cout << "closing NDBAPI ... " << flush;
@@ -214,49 +220,86 @@ CrundNdbApiOperations::close()
}
void
-CrundNdbApiOperations::initConnection(const char* catalog, const char* schema)
+CrundNdbApiOperations::initConnection(const char* catalog, const char* schema,
+ NdbOperation::LockMode defaultLockMode)
{
+ assert(mgmd != NULL);
+ assert(ndb == NULL);
+ assert(tx == NULL);
+ assert(model == NULL);
+
// optionally, connect and wait for reaching the data nodes (ndbds)
- cout << "waiting for data nodes..." << flush;
+ cout << "waiting for data nodes ..." << flush;
const int initial_wait = 10; // seconds to wait until first node detected
const int final_wait = 0; // seconds to wait after first node detected
// returns: 0 all nodes live, > 0 at least one node live, < 0 error
if (mgmd->wait_until_ready(initial_wait, final_wait) < 0)
ABORT_ERROR("data nodes were not ready within "
<< (initial_wait + final_wait) << "s.");
- cout << " [ok]" << endl;
+ cout << " [ok]" << endl;
// connect to database
- cout << "connecting to database..." << flush;
+ cout << "connecting to database ..." << flush;
ndb = new Ndb(mgmd, catalog, schema);
const int max_no_tx = 10; // maximum number of parallel tx (<=1024)
// note each scan or index scan operation uses one extra transaction
//if (ndb->init() != 0)
if (ndb->init(max_no_tx) != 0)
ABORT_NDB_ERROR(ndb->getNdbError());
- cout << " [ok]" << endl;
+ cout << " [ok: " << catalog << "." << schema << "]" << endl;
- // initialize the schema shortcuts
+ cout << "caching metadata ..." << flush;
CrundModel* m = new CrundModel();
m->init(ndb);
model = m;
+ cout << " [ok]" << endl;
+
+ cout << "using lock mode for reads ..." << flush;
+ ndbOpLockMode = defaultLockMode;
+ string lm;
+ switch (defaultLockMode) {
+ case NdbOperation::LM_CommittedRead:
+ lm = "LM_CommittedRead";
+ break;
+ case NdbOperation::LM_Read:
+ lm = "LM_Read";
+ break;
+ case NdbOperation::LM_Exclusive:
+ lm = "LM_Exclusive";
+ break;
+ default:
+ ndbOpLockMode = NdbOperation::LM_CommittedRead;
+ lm = "LM_CommittedRead";
+ assert(false);
+ }
+ cout << " [ok: " + lm + "]" << endl;
}
void
CrundNdbApiOperations::closeConnection()
{
- cout << "closing database conn ..." << flush;
+ assert(mgmd != NULL);
+ assert(ndb != NULL);
+ assert(tx == NULL);
+ assert(model != NULL);
+
+ cout << "clearing metadata cache ..." << flush;
delete model;
model = NULL;
+ cout << " [ok]" << endl;
+
+ cout << "closing database connection ..." << flush;
// no ndb->close();
delete ndb;
ndb = NULL;
- cout << " [ok]" << endl;
+ cout << " [ok]" << endl;
}
void
CrundNdbApiOperations::beginTransaction()
{
+ assert(tx == NULL);
+
// start a transaction
// must be closed with Ndb::closeTransaction or NdbTransaction::close
if ((tx = ndb->startTransaction()) == NULL)
@@ -266,6 +309,8 @@ CrundNdbApiOperations::beginTransaction(
void
CrundNdbApiOperations::executeOperations()
{
+ assert(tx != NULL);
+
// execute but don't commit the current transaction
if (tx->execute(NdbTransaction::NoCommit) != 0
|| tx->getNdbError().status != NdbError::Success)
@@ -275,6 +320,8 @@ CrundNdbApiOperations::executeOperations
void
CrundNdbApiOperations::commitTransaction()
{
+ assert(tx != NULL);
+
// commit the current transaction
if (tx->execute(NdbTransaction::Commit) != 0
|| tx->getNdbError().status != NdbError::Success)
@@ -282,17 +329,10 @@ CrundNdbApiOperations::commitTransaction
}
void
-CrundNdbApiOperations::rollbackTransaction()
-{
- // abort the current transaction
- if (tx->execute(NdbTransaction::Rollback) != 0
- || tx->getNdbError().status != NdbError::Success)
- ABORT_NDB_ERROR(tx->getNdbError());
-}
-
-void
CrundNdbApiOperations::closeTransaction()
{
+ assert(tx != NULL);
+
// close the current transaction
// to be called irrespectively of success or failure
ndb->closeTransaction(tx);
@@ -357,7 +397,7 @@ selectString(int length)
case 100: return astring100;
case 1000: return astring1000;
default:
- assert (false);
+ assert(false);
return "";
}
}
@@ -417,11 +457,6 @@ CrundNdbApiOperations::delByScan(const N
if (op->readTuples(lock_mode, scan_flags, parallel, batch_) != 0)
ABORT_NDB_ERROR(tx->getNdbError());
- // define a read scan with exclusive locks
- // XXX deprecated: readTuplesExclusive(int parallell = 0);
- //if (op->readTuplesExclusive() != 0)
- // ABORT_NDB_ERROR(tx->getNdbError());
-
// start the scan; don't commit yet
executeOperations();
@@ -501,7 +536,7 @@ CrundNdbApiOperations::setByPK(const Ndb
{
beginTransaction();
for (int i = from; i <= to; i++) {
- // get an insert operation for the table
+ // get an update operation for the table
NdbOperation* op = tx->getNdbOperation(table);
if (op == NULL)
ABORT_NDB_ERROR(tx->getNdbError());
@@ -545,7 +580,7 @@ CrundNdbApiOperations::getByPK_bb(const
NdbOperation* op = tx->getNdbOperation(table);
if (op == NULL)
ABORT_NDB_ERROR(tx->getNdbError());
- if (op->readTuple(NdbOperation::LM_CommittedRead) != 0)
+ if (op->readTuple(ndbOpLockMode) != 0)
ABORT_NDB_ERROR(tx->getNdbError());
// set key attribute
@@ -625,7 +660,7 @@ CrundNdbApiOperations::getByPK_ar(const
NdbOperation* op = tx->getNdbOperation(table);
if (op == NULL)
ABORT_NDB_ERROR(tx->getNdbError());
- if (op->readTuple(NdbOperation::LM_CommittedRead) != 0)
+ if (op->readTuple(ndbOpLockMode) != 0)
ABORT_NDB_ERROR(tx->getNdbError());
// set key attribute
@@ -711,7 +746,7 @@ CrundNdbApiOperations::setVar(const NdbD
// XXX assumes column declared as VARBINARY/CHAR(<255)
size_t sbuf = 1 + slen;
// XXX buffer overflow if slen >255!!!
- assert (slen < 255);
+ assert(slen < 255);
buf = new char[sbuf];
buf[0] = (char)slen;
memcpy(buf + 1, str, slen);
@@ -722,7 +757,7 @@ CrundNdbApiOperations::setVar(const NdbD
beginTransaction();
for (int i = from; i <= to; i++) {
- // get an insert operation for the table
+ // get an update operation for the table
NdbOperation* op = tx->getNdbOperation(table);
if (op == NULL)
ABORT_NDB_ERROR(tx->getNdbError());
@@ -753,7 +788,7 @@ CrundNdbApiOperations::getVar(const NdbD
int from, int to,
bool batch, const char* str)
{
- assert (str);
+ assert(str);
// allocate attributes holder
const int count = (to - from) + 1;
@@ -775,7 +810,7 @@ CrundNdbApiOperations::getVar(const NdbD
NdbOperation* op = tx->getNdbOperation(table);
if (op == NULL)
ABORT_NDB_ERROR(tx->getNdbError());
- if (op->readTuple(NdbOperation::LM_CommittedRead) != 0)
+ if (op->readTuple(ndbOpLockMode) != 0)
ABORT_NDB_ERROR(tx->getNdbError());
// set key attribute
@@ -792,7 +827,7 @@ CrundNdbApiOperations::getVar(const NdbD
}
commitTransaction();
closeTransaction();
- assert (s == buf + sbuf);
+ assert(s == buf + sbuf);
// copy (move) the strings to make them aligned and 0-terminated
s = buf;
@@ -812,7 +847,7 @@ CrundNdbApiOperations::getVar(const NdbD
// check fetched values
VERIFY(strcmp(s, str) == 0);
}
- assert (s == buf + sbuf);
+ assert(s == buf + sbuf);
// release attributes holder
delete[] buf;
@@ -895,7 +930,7 @@ CrundNdbApiOperations::navB0ToA(int coun
NdbOperation* op = tx->getNdbOperation(model->table_B0);
if (op == NULL)
ABORT_NDB_ERROR(tx->getNdbError());
- if (op->readTuple(NdbOperation::LM_CommittedRead) != 0)
+ if (op->readTuple(ndbOpLockMode) != 0)
ABORT_NDB_ERROR(tx->getNdbError());
// set key attribute
@@ -914,11 +949,11 @@ CrundNdbApiOperations::navB0ToA(int coun
NdbOperation* op = tx->getNdbOperation(model->table_A);
if (op == NULL)
ABORT_NDB_ERROR(tx->getNdbError());
- if (op->readTuple(NdbOperation::LM_CommittedRead) != 0)
+ if (op->readTuple(ndbOpLockMode) != 0)
ABORT_NDB_ERROR(tx->getNdbError());
// set key attribute
- assert (a_id == ((i - 1) % count_A) + 1);
+ assert(a_id == ((i - 1) % count_A) + 1);
if (op->equal(model->attr_id, a_id) != 0)
ABORT_NDB_ERROR(tx->getNdbError());
@@ -973,7 +1008,7 @@ CrundNdbApiOperations::navB0ToAalt(int c
NdbOperation* op = tx->getNdbOperation(model->table_B0);
if (op == NULL)
ABORT_NDB_ERROR(tx->getNdbError());
- if (op->readTuple(NdbOperation::LM_CommittedRead) != 0)
+ if (op->readTuple(ndbOpLockMode) != 0)
ABORT_NDB_ERROR(tx->getNdbError());
// set key attribute
@@ -1001,11 +1036,11 @@ CrundNdbApiOperations::navB0ToAalt(int c
NdbOperation* op = tx->getNdbOperation(model->table_A);
if (op == NULL)
ABORT_NDB_ERROR(tx->getNdbError());
- if (op->readTuple(NdbOperation::LM_CommittedRead) != 0)
+ if (op->readTuple(ndbOpLockMode) != 0)
ABORT_NDB_ERROR(tx->getNdbError());
// set key attribute
- assert (*pa_id == ((i - 1) % count_A) + 1);
+ assert(*pa_id == ((i - 1) % count_A) + 1);
if (op->equal(model->attr_id, (Int32)*pa_id) != 0)
ABORT_NDB_ERROR(tx->getNdbError());
@@ -1067,8 +1102,7 @@ CrundNdbApiOperations::navAToB0(int coun
if (op == NULL)
ABORT_NDB_ERROR(tx->getNdbError());
- // define a read scan without locks (LM_CommittedRead)
- if (op->readTuples(NdbOperation::LM_CommittedRead) != 0)
+ if (op->readTuples(ndbOpLockMode) != 0)
ABORT_NDB_ERROR(tx->getNdbError());
// define the scan's bounds (more efficient than using a scan filter)
@@ -1102,7 +1136,7 @@ CrundNdbApiOperations::navAToB0(int coun
int stat;
const bool allowFetch = true; // request new batches when exhausted
while ((stat = op->nextResult(allowFetch, forceSend)) == 0) {
- assert (ab <= pab && pab < ab + count_B);
+ assert(ab <= pab && pab < ab + count_B);
*pab++ = h;
}
if (stat != 1)
@@ -1113,7 +1147,7 @@ CrundNdbApiOperations::navAToB0(int coun
commitTransaction();
closeTransaction();
//CDBG << "!!! pab - ab =" << toString(pab-ab) << endl;
- assert (pab == ab + count_B);
+ assert(pab == ab + count_B);
// check fetched values
// XXX this is not the most efficient way of testing...
@@ -1158,8 +1192,7 @@ CrundNdbApiOperations::navAToB0alt(int c
ABORT_NDB_ERROR(tx->getNdbError());
// XXX ? no locks (LM_CommittedRead) or shared locks (LM_Read)
- // define a read scan without locks
- if (op[i]->readTuples(NdbOperation::LM_CommittedRead) != 0)
+ if (op[i]->readTuples(ndbOpLockMode) != 0)
ABORT_NDB_ERROR(tx->getNdbError());
// define the scan's bounds (more efficient than using a scan filter)
@@ -1197,7 +1230,7 @@ CrundNdbApiOperations::navAToB0alt(int c
int stat;
const bool allowFetch = true; // request new batches when exhausted
while ((stat = op[i]->nextResult(allowFetch, forceSend)) == 0) {
- assert (ab <= pab && pab < ab + count_B);
+ assert(ab <= pab && pab < ab + count_B);
*pab++ = h;
}
if (stat != 1)
@@ -1212,8 +1245,8 @@ CrundNdbApiOperations::navAToB0alt(int c
commitTransaction();
closeTransaction();
//CDBG << "!!! pab - ab =" << toString(pab-ab) << endl;
- assert (a_id == count_A + 1);
- assert (pab == ab + count_B);
+ assert(a_id == count_A + 1);
+ assert(pab == ab + count_B);
// check fetched values
// XXX this is not the most efficient way of testing...
=== modified file 'storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.hpp'
--- a/storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.hpp 2010-10-05 08:48:30 +0000
+++ b/storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.hpp 2010-10-08 11:17:35 +0000
@@ -73,34 +73,50 @@ class CrundNdbApiOperations
// But for now, having all in one class is good enough.
public:
- // the benchmark's metadata shortcuts
+
+ CrundNdbApiOperations()
+ : model(NULL), mgmd(NULL), ndb(NULL), tx(NULL) {
+ }
+
+ ~CrundNdbApiOperations() {
+ assert(model == NULL);
+ assert(mgmd == NULL); assert(ndb == NULL); assert(tx == NULL);
+ }
+
+ // NDB Api metadata resources
const CrundModel* model;
-//protected:
- // singleton object representing the NDB cluster (one per process)
- Ndb_cluster_connection* mgmd;
+protected:
- // object representing a connection to an NDB database
+ // NDB API resources
+ Ndb_cluster_connection* mgmd;
Ndb* ndb;
-
- // object representing an NDB database transaction
NdbTransaction* tx;
+ NdbOperation::LockMode ndbOpLockMode;
+
+ // NDB Api data resources
+ // XXX not used yet, see TwsDriver
+ //char* bb;
+ //char* bb_pos;
+ //NdbRecAttr** ra;
+ //NdbRecAttr** ra_pos;
+
+private:
+
+ CrundNdbApiOperations(const CrundNdbApiOperations&);
+ CrundNdbApiOperations& operator=(const CrundNdbApiOperations&);
public:
+
void init(const char* mgmd_conn_str);
void close();
- void initConnection(const char* catalog, const char* schema);
+ void initConnection(const char* catalog, const char* schema,
+ NdbOperation::LockMode defaultLockMode);
void closeConnection();
- void beginTransaction();
-
- void commitTransaction();
-
- void rollbackTransaction();
-
void clearData();
void delByScan(const NdbDictionary::Table* table, int& count,
@@ -152,10 +168,15 @@ public:
bool batch);
protected:
- // executes the operations in the current transaction
- void executeOperations();
- // closes the current transaction
+ // XXX not used yet, see TwsDriver
+ //void ndbapiBeginTransaction();
+ //void ndbapiExecuteTransaction();
+ //void ndbapiCommitTransaction();
+ //void ndbapiCloseTransaction();
+ void beginTransaction();
+ void executeOperations();
+ void commitTransaction();
void closeTransaction();
void setVar(const NdbDictionary::Table* table, int attr_cvar,
@@ -163,6 +184,10 @@ protected:
void getVar(const NdbDictionary::Table* table, int attr_cvar,
int from, int to, bool batch, const char* str);
+
+ // XXX not used yet, see TwsDriver
+ //static void ndbapiToBuffer1blp(void* to, const char* from, size_t width);
+ //static void ndbapiToString1blp(char* to, const void* from, size_t width);
};
#endif // CrundNdbApiOperations_hpp
=== modified file 'storage/ndb/test/crund/src/crundndb/Driver.cpp'
--- a/storage/ndb/test/crund/src/crundndb/Driver.cpp 2010-10-05 08:48:30 +0000
+++ b/storage/ndb/test/crund/src/crundndb/Driver.cpp 2010-10-08 11:17:35 +0000
@@ -100,13 +100,13 @@ Driver::parseArguments(int argc, const c
// get time, convert to timeinfo (statically allocated) then to string
const time_t now = time(0);
const int nchars = strftime(dest, size, format, localtime(&now));
- assert (nchars == size-1);
+ assert(nchars == size-1);
(void)nchars;
logFileName += dest;
logFileName += ".txt";
- //cout << "logFileName='" << logFileName << "'" << endl;
}
+ //cout << "logFileName='" << logFileName << "'" << endl;
}
// ----------------------------------------------------------------------
@@ -115,40 +115,39 @@ void
Driver::run() {
init();
- // warmup runs
- for (int i = 0; i < warmupRuns; i++) {
- runTests();
- }
+ if (warmupRuns > 0) {
+ cout << endl
+ << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
+ << "warmup runs ..." << endl
+ << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
- // truncate log file, reset log buffers
- cout << endl
- << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
- << "start logging results ..." << endl
- << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
- << endl;
- header.rdbuf()->str("");
- rtimes.rdbuf()->str("");
- closeLogFile();
- openLogFile();
+ for (int i = 0; i < warmupRuns; i++) {
+ runTests();
+ }
- // hot runs
- for (int i = 0; i < hotRuns; i++) {
- runTests();
- }
+ // truncate log file, reset log buffers
+ closeLogFile();
+ openLogFile();
+ header.rdbuf()->str("");
+ rtimes.rdbuf()->str("");
+ logHeader = true;
+ }
+
+ if (hotRuns > 0) {
+ cout << endl
+ << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
+ << "hot runs ..." << endl
+ << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
- // write log buffers
- if (logRealTime) {
- // doesn't work: ostream << ostringstream->rdbuf()
+ for (int i = 0; i < hotRuns; i++) {
+ runTests();
+ }
+
+ // write log buffers
log << descr << ", rtime[ms]"
<< header.rdbuf()->str() << endl
<< rtimes.rdbuf()->str() << endl << endl << endl;
}
- if (logCpuTime) {
- // doesn't work: ostream << ostringstream->rdbuf()
- log << descr << ", ctime[ms]"
- << header.rdbuf()->str() << endl
- << ctimes.rdbuf()->str() << endl << endl << endl;
- }
close();
}
@@ -182,8 +181,7 @@ Driver::loadProperties() {
i != propFileNames.end(); ++i) {
cout << "reading properties file: " << *i << endl;
props.load(i->c_str());
- props.load(i->c_str());
- //wcout << props << endl;
+ //cout << "props = {" << endl << props << "}" << endl;
}
}
@@ -211,7 +209,8 @@ Driver::initProperties() {
hotRuns = 1;
}
- if (msg.tellp() == 0) {
+ //if (msg.tellp() == 0) // netbeans reports amibuities
+ if (msg.str().empty()) {
cout << " [ok]" << endl;
} else {
cout << endl << msg.str() << endl;
@@ -238,17 +237,18 @@ Driver::printProperties() {
void
Driver::openLogFile() {
cout << endl
- << "writing results to file: " << logFileName << endl;
- //log.open(logFileName.c_str());
+ << "opening results file:" << flush;
log.open(logFileName.c_str(), ios_base::out | ios_base::trunc);
- assert (log.good());
+ assert(log.good());
+ cout << " [ok: " << logFileName << "]" << endl;
}
void
Driver::closeLogFile() {
- cout << "closing files ..." << flush;
+ cout << endl
+ << "closing results file:" << flush;
log.close();
- cout << " [ok]" << endl;
+ cout << " [ok: " << logFileName << "]" << endl;
}
// ----------------------------------------------------------------------
=== modified file 'storage/ndb/test/crund/src/crundndb/Driver.hpp'
--- a/storage/ndb/test/crund/src/crundndb/Driver.hpp 2010-10-05 08:48:30 +0000
+++ b/storage/ndb/test/crund/src/crundndb/Driver.hpp 2010-10-08 11:17:35 +0000
@@ -51,13 +51,18 @@ public:
Driver() {}
/**
+ * Deletes an instance.
+ */
+ virtual ~Driver() {}
+
+ /**
* Runs the benchmark.
*/
void run();
protected:
- // driver command-line arguments
+ // command-line arguments
static vector< string > propFileNames;
static string logFileName;
=== modified file 'storage/ndb/test/crund/src/crundndb/NdbApiDriver.cpp'
--- a/storage/ndb/test/crund/src/crundndb/NdbApiDriver.cpp 2010-10-05 08:48:30 +0000
+++ b/storage/ndb/test/crund/src/crundndb/NdbApiDriver.cpp 2010-10-08 11:17:35 +0000
@@ -104,10 +104,22 @@ NdbApiDriver::initProperties() {
ostringstream msg;
mgmdConnect = toString(props[L"ndb.mgmdConnect"]);
+ if (mgmdConnect.empty()) {
+ mgmdConnect = string("localhost");
+ }
+
catalog = toString(props[L"ndb.catalog"]);
+ if (catalog.empty()) {
+ catalog = string("crunddb");
+ }
+
schema = toString(props[L"ndb.schema"]);
+ if (schema.empty()) {
+ schema = string("def");
+ }
- if (msg.tellp() == 0) {
+ //if (msg.tellp() == 0) {
+ if (msg.str().empty()) {
cout << " [ok]" << endl;
} else {
cout << endl << msg.str() << endl;
@@ -119,7 +131,7 @@ NdbApiDriver::initProperties() {
void
NdbApiDriver::printProperties() {
CrundDriver::printProperties();
-
+
const ios_base::fmtflags f = cout.flags();
// no effect calling manipulator function, not sure why
//cout << ios_base::boolalpha;
@@ -133,15 +145,7 @@ NdbApiDriver::printProperties() {
cout.flags(f);
}
-void
-NdbApiDriver::initConnection() {
- ops->initConnection(catalog.c_str(), schema.c_str());
-}
-
-void
-NdbApiDriver::closeConnection() {
- ops->closeConnection();
-}
+//---------------------------------------------------------------------------
void
NdbApiDriver::initOperations() {
@@ -377,9 +381,37 @@ NdbApiDriver::closeOperations() {
cout << " [ok]" << endl;
}
+//---------------------------------------------------------------------------
+
+void
+NdbApiDriver::initConnection() {
+ NdbOperation::LockMode ndbOpLockMode;
+ switch (lockMode) {
+ case READ_COMMITTED:
+ ndbOpLockMode = NdbOperation::LM_CommittedRead;
+ break;
+ case SHARED:
+ ndbOpLockMode = NdbOperation::LM_Read;
+ break;
+ case EXCLUSIVE:
+ ndbOpLockMode = NdbOperation::LM_Exclusive;
+ break;
+ default:
+ ndbOpLockMode = NdbOperation::LM_CommittedRead;
+ assert(false);
+ }
+
+ ops->initConnection(catalog.c_str(), schema.c_str(), ndbOpLockMode);
+}
+
+void
+NdbApiDriver::closeConnection() {
+ ops->closeConnection();
+}
+
void
NdbApiDriver::clearPersistenceContext() {
- // XXX not implemented yet
+ assert(false); // XXX not implemented yet
}
void
=== modified file 'storage/ndb/test/crund/src/crundndb/NdbApiDriver.hpp'
--- a/storage/ndb/test/crund/src/crundndb/NdbApiDriver.hpp 2010-10-05 08:48:30 +0000
+++ b/storage/ndb/test/crund/src/crundndb/NdbApiDriver.hpp 2010-10-08 11:17:35 +0000
@@ -32,6 +32,14 @@ using std::string;
typedef const NdbDictionary::Table* NdbTable;
class NdbApiDriver : public CrundDriver {
+public:
+
+ // the generated features are OK
+ //NdbApiDriver() {}
+ //virtual ~NdbApsDriver() {}
+ //NdbApiDriver(const NdbApiDriver&) {}
+ //NdbApiDriver& operator=(const NdbApiDriver&) {}
+
protected:
// NDB API resources
@@ -47,12 +55,6 @@ protected:
virtual void printProperties();
virtual void init();
virtual void close();
- virtual void initConnection();
- virtual void closeConnection();
- virtual void initOperations();
- virtual void closeOperations();
- virtual void clearPersistenceContext();
- virtual void clearData();
// NDB API operations
template< bool feat > void initOperationsFeat();
@@ -80,6 +82,14 @@ protected:
void (CrundNdbApiOperations::*)(int,int,bool),
bool >
struct RelOp;
+ virtual void initOperations();
+ virtual void closeOperations();
+
+ // NDB API datastore operations
+ virtual void initConnection();
+ virtual void closeConnection();
+ virtual void clearPersistenceContext();
+ virtual void clearData();
};
#endif // Driver_hpp
=== modified file 'storage/ndb/test/crund/src/crundndb/com_mysql_cluster_crund_NdbApiLoad.cpp'
--- a/storage/ndb/test/crund/src/crundndb/com_mysql_cluster_crund_NdbApiLoad.cpp 2010-10-05 08:48:30 +0000
+++ b/storage/ndb/test/crund/src/crundndb/com_mysql_cluster_crund_NdbApiLoad.cpp 2010-10-08 11:17:35 +0000
@@ -73,7 +73,8 @@ JNIEXPORT void JNICALL
Java_com_mysql_cluster_crund_NdbApiLoad_initConnection(JNIEnv* env,
jobject obj,
jstring catalog_jstr,
- jstring schema_jstr)
+ jstring schema_jstr,
+ jint defaultLockMode)
{
TRACE("initConnection()");
assert (catalog_jstr);
@@ -82,8 +83,9 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
// get native strings from the Java strings
const char* catalog_cstr = env->GetStringUTFChars(catalog_jstr, NULL);
const char* schema_cstr = env->GetStringUTFChars(schema_jstr, NULL);
+ NdbOperation::LockMode dlm = (NdbOperation::LockMode)defaultLockMode;
- ops->initConnection(catalog_cstr, schema_cstr);
+ ops->initConnection(catalog_cstr, schema_cstr, dlm);
// release the native and Java strings
env->ReleaseStringUTFChars(schema_jstr, schema_cstr);
@@ -107,30 +109,6 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
}
JNIEXPORT void JNICALL
-Java_com_mysql_cluster_crund_NdbApiLoad_beginTransaction(JNIEnv* env,
- jobject obj)
-{
- TRACE("beginTransaction()");
- ops->beginTransaction();
-}
-
-JNIEXPORT void JNICALL
-Java_com_mysql_cluster_crund_NdbApiLoad_commitTransaction(JNIEnv* env,
- jobject obj)
-{
- TRACE("commitTransaction()");
- ops->commitTransaction();
-}
-
-JNIEXPORT void JNICALL
-Java_com_mysql_cluster_crund_NdbApiLoad_rollbackTransaction(JNIEnv* env,
- jobject obj)
-{
- TRACE("rollbackTransaction()");
- ops->rollbackTransaction();
-}
-
-JNIEXPORT void JNICALL
Java_com_mysql_cluster_crund_NdbApiLoad_delAllA(JNIEnv* env,
jobject obj,
jint count_A,
Attachment: [text/bzr-bundle] bzr/martin.zaun@oracle.com-20101008111735-0cuzafmrp8jvh2p5.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1-telco-7.1 branch (martin.zaun:3864) | Martin Zaun | 8 Oct |