List:Commits« Previous MessageNext Message »
From:Martin Zaun Date:October 1 2010 4:10am
Subject:bzr commit into mysql-5.1-telco-7.1 branch (martin.zaun:3849)
View as plain text  
#At file:///Users/mz/mysql/ndb-7.1-opt64/ based on revid:jonas@stripped

 3849 Martin Zaun	2010-09-30
      crund - fixes and cleanups

    modified:
      storage/ndb/test/crund/config_samples/crundClusterj.properties
      storage/ndb/test/crund/config_samples/crundMysql.properties
      storage/ndb/test/crund/config_samples/crundNdbapi.properties
      storage/ndb/test/crund/config_samples/crundNdbjtie.properties
      storage/ndb/test/crund/config_samples/crundOpenjpaClusterj.properties
      storage/ndb/test/crund/config_samples/crundRun.properties
      storage/ndb/test/crund/config_samples/env.properties
      storage/ndb/test/crund/martins_little_helpers/src/utils/Makefile
      storage/ndb/test/crund/martins_little_helpers/src/utils/helpers.hpp
      storage/ndb/test/crund/martins_little_helpers/src/utils/string_helpers.hpp
      storage/ndb/test/crund/src/com/mysql/cluster/crund/Driver.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/com/mysql/cluster/crund/NdbJTieLoad.java
      storage/ndb/test/crund/src/crundndb/Driver.cpp
      storage/ndb/test/crund/src/crundndb/Operations.cpp
      storage/ndb/test/crund/src/crundndb/Operations.hpp
      storage/ndb/test/crund/src/crundndb/com_mysql_cluster_crund_NdbApiLoad.cpp
=== modified file 'storage/ndb/test/crund/config_samples/crundClusterj.properties'
--- a/storage/ndb/test/crund/config_samples/crundClusterj.properties	2010-02-25 15:00:17 +0000
+++ b/storage/ndb/test/crund/config_samples/crundClusterj.properties	2010-10-01 04:10:21 +0000
@@ -1,7 +1,7 @@
 
 # XXX NPE with clusterj if field = null
 #exclude=setVarbinary1,setVarbinary1_batch,getVarbinary1,getVarbinary1_batch,setVarbinary10,setVarbinary10_batch,getVarbinary10,getVarbinary10_batch,setVarbinary100,setVarbinary100_batch,getVarbinary100,getVarbinary100_batch
-exclude=navA->B0
+#exclude=navA->B0
 #exclude=
 
 com.mysql.clusterj.connectstring=localhost

=== modified file 'storage/ndb/test/crund/config_samples/crundMysql.properties'
--- a/storage/ndb/test/crund/config_samples/crundMysql.properties	2010-02-25 15:00:17 +0000
+++ b/storage/ndb/test/crund/config_samples/crundMysql.properties	2010-10-01 04:10:21 +0000
@@ -1,6 +1,6 @@
 
 # blobs seem to work but not implemented in other backends yet
-exclude=setBlob1000,getBlob1000,setBlob10000,getBlob10000,setBlob100000,getBlob100000,setText1000,getText1000,setText10000,getText10000,setText100000,getText100000
+exclude=setBlob1000,setBlob1000_batch,getBlob1000,getBlob1000_batch,setBlob10000,setBlob10000_batch,getBlob10000,getBlob10000_batch,setBlob100000,setBlob100000_batch,getBlob100000,getBlob100000_batch,setText1000,setText1000_batch,getText1000,getText1000_batch,setText10000,setText10000_batch,getText10000,getText10000_batch,setText100000,setText100000_batch,getText100000,getText100000_batch
 
 # JDBC - MySQL connection settings
 jdbc.url=jdbc:mysql://localhost/crunddb

=== modified file 'storage/ndb/test/crund/config_samples/crundNdbapi.properties'
--- a/storage/ndb/test/crund/config_samples/crundNdbapi.properties	2010-02-25 15:00:17 +0000
+++ b/storage/ndb/test/crund/config_samples/crundNdbapi.properties	2010-10-01 04:10:21 +0000
@@ -3,6 +3,7 @@
 #exclude=navA->B0_alt,navA->B0_alt_forceSend
 #exclude=navA->B0_alt_forceSend
 #exclude=navA->B0,navA->B0alt
+#exclude=getAByPK_ar,getB0ByPK_ar,getAByPK_ar_batch,getB0ByPK_ar_batch
 
 # NDBAPI connection settings
 ndb.mgmdConnect=localhost

=== modified file 'storage/ndb/test/crund/config_samples/crundNdbjtie.properties'
--- a/storage/ndb/test/crund/config_samples/crundNdbjtie.properties	2010-02-25 15:00:17 +0000
+++ b/storage/ndb/test/crund/config_samples/crundNdbjtie.properties	2010-10-01 04:10:21 +0000
@@ -2,7 +2,7 @@
 # XXX not yet implemented by NdbJTie
 #exclude=setVarbinary1,setVarbinary1_batch,getVarbinary1,getVarbinary1_batch,setVarchar1,setVarchar1_batch,getVarchar1,getVarchar1_batch,setVarbinary10,setVarbinary10_batch,getVarbinary10,getVarbinary10_batch,setVarchar10,setVarchar10_batch,getVarchar10,getVarchar10_batch,setVarbinary100,setVarbinary100_batch,getVarbinary100,getVarbinary100_batch,setVarchar100,setVarchar100_batch,getVarchar100,getVarchar100_batch,setB0->A,setB0->A_batch,navB0->A,navB0->A_batch,navB0->A_alt,navB0->A_alt_batch,navA->B0,navA->B0_forceSend,navA->B0_alt,navA->B0_alt_forceSend,nullB0->A,nullB0->A_batch
 #exclude=navA->B0,navA->B0_forceSend,navA->B0_alt,navA->B0_alt_forceSend
-#exclude=
+#exclude=getAByPK_bb,getB0ByPK_bb,getAByPK_bb_batch,getB0ByPK_bb_batch
 
 # NDBJTIE connection settings
 ndb.mgmdConnect=localhost

=== modified file 'storage/ndb/test/crund/config_samples/crundOpenjpaClusterj.properties'
--- a/storage/ndb/test/crund/config_samples/crundOpenjpaClusterj.properties	2010-02-25 15:00:17 +0000
+++ b/storage/ndb/test/crund/config_samples/crundOpenjpaClusterj.properties	2010-10-01 04:10:21 +0000
@@ -1,5 +1,6 @@
 
 #exclude=navA->B0,navA->B0_opt
+#exclude=setAByPK_bulk,setB0ByPK_bulk,setAByPK,setB0ByPK,getAByPK,getB0ByPK
 
 # OpenJPA - MySQL JDBC connection settings
 openjpa.ConnectionURL=jdbc:mysql://localhost/crunddb

=== modified file 'storage/ndb/test/crund/config_samples/crundRun.properties'
--- a/storage/ndb/test/crund/config_samples/crundRun.properties	2010-02-25 15:00:17 +0000
+++ b/storage/ndb/test/crund/config_samples/crundRun.properties	2010-10-01 04:10:21 +0000
@@ -5,33 +5,35 @@ logMemUsage=false
 includeFullGC=false
 logSumOfOps=true
 
-# the number of rows for tables A in a transaction and a scale factor
+# optional number of rows per transaction with a scale factor
 #aStart=4
 #aStart=256
 #aStart=1024
-aStart=4096
+#aStart=4096
 #aStart=16384
+#aStart=65536
 #aEnd=4
 #aEnd=256
 #aEnd=1024
-aEnd=4096
+#aEnd=4096
 #aEnd=16384
 #aEnd=65536
-aIncr=4
+#aScale=4
 
-# the number of rows for tables B0 in a transaction and a scale factor
+# optional number of rows per transaction with a scale factor
 #bStart=4
 #bStart=256
 #bStart=1024
-bStart=4096
+#bStart=4096
 #bStart=16384
+#bStart=65536
 #bEnd=4
 #bEnd=256
 #bEnd=1024
-bEnd=4096
+#bEnd=4096
 #bEnd=16384
 #bEnd=65536
-bIncr=4
+#bScale=4
 
 # the max length (multiple of 10) up to which to scale up strings
 # CRUND CODE (AND SCHEMA) CURRENTLY DO NOT SUPPORT
@@ -50,7 +52,8 @@ allowExtendedPC=false
 
 # the number of warmup and finally recorded runs
 warmupRuns=0
-hotRuns=20
+hotRuns=1
+#hotRuns=20
 
 # CURRENT LIMITS:
 #

=== modified file 'storage/ndb/test/crund/config_samples/env.properties'
--- a/storage/ndb/test/crund/config_samples/env.properties	2010-09-29 10:02:15 +0000
+++ b/storage/ndb/test/crund/config_samples/env.properties	2010-10-01 04:10:21 +0000
@@ -48,8 +48,8 @@ MYSQL_LIBEXEC="$MYSQL_HOME/libexec"
 # - Martin's Little Helpers utilities (see below)
 
 #JAVA_INCLUDEOPTS=-I"/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Headers"
-#JAVA_INCLUDEOPTS=-I"/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Headers"
-JAVA_INCLUDEOPTS=-I"/usr/lib/jvm/java-6-sun/include" -I"/usr/lib/jvm/java-6-sun/include/linux"
+JAVA_INCLUDEOPTS=-I"/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Headers"
+#JAVA_INCLUDEOPTS=-I"/usr/lib/jvm/java-6-sun/include" -I"/usr/lib/jvm/java-6-sun/include/linux"
 
 # Comments:
 #

=== modified file 'storage/ndb/test/crund/martins_little_helpers/src/utils/Makefile'
--- a/storage/ndb/test/crund/martins_little_helpers/src/utils/Makefile	2010-09-29 10:02:15 +0000
+++ b/storage/ndb/test/crund/martins_little_helpers/src/utils/Makefile	2010-10-01 04:10:21 +0000
@@ -17,8 +17,10 @@ include	../../../env.properties
 #		 -DHRT_CPUTIME_METHOD=HRT_USE_GETRUSAGE \
 
   DDEFINES 	= \
-		 -DHRT_REALTIME_METHOD=HRT_USE_CLOCK_GETTIME \
-		 -DHRT_CPUTIME_METHOD=HRT_USE_CLOCK_GETTIME \
+		 -DHRT_REALTIME_METHOD=HRT_USE_GETTIMEOFDAY \
+		 -DHRT_CPUTIME_METHOD=HRT_USE_GETRUSAGE \
+		 #-DHRT_REALTIME_METHOD=HRT_USE_CLOCK_GETTIME \
+		 #-DHRT_CPUTIME_METHOD=HRT_USE_CLOCK_GETTIME \
 		 #-DHRT_REALTIME_METHOD=HRT_USE_GETTIMEOFDAY \
 		 #-DHRT_CPUTIME_METHOD=HRT_USE_GETRUSAGE \
 		 #-DHRT_REALTIME_METHOD=HRT_USE_TIMES \
@@ -66,8 +68,8 @@ include	../../../env.properties
 #   LOADLIBES for libs for the individual case
 # check with non-gnu makes: use of LOADLIBES, LDLIBS
 # CLOCK_GETTIME requires -lrt
-#  LDLIBS	=
-  LDLIBS	= -lrt
+  LDLIBS	=
+#  LDLIBS	= -lrt
 
 #------------------------------------------------------------------------------
 

=== modified file 'storage/ndb/test/crund/martins_little_helpers/src/utils/helpers.hpp'
--- a/storage/ndb/test/crund/martins_little_helpers/src/utils/helpers.hpp	2010-02-14 05:05:31 +0000
+++ b/storage/ndb/test/crund/martins_little_helpers/src/utils/helpers.hpp	2010-10-01 04:10:21 +0000
@@ -36,11 +36,11 @@ using std::flush;
  * Helper Macros & Functions
  ************************************************************/
 
-// gcc: crashes when printing source code file number:
-//               << ", line: " << (__LINE__)
+// JNI crashes with gcc & operator<<(ostream &, long/int)
 // so, we use C99's __func__ and also convert to string using sprintf()
 #define ABORT_ERROR(message)                                            \
-    do { char l[1024];                                                  \
+    do {                                                                \
+        char l[1024];                                                   \
         sprintf(l, "%d", __LINE__);                                     \
         cout << "!!! error, file: " << (__FILE__)                       \
              << ", function: " << (__func__)                            \

=== modified file 'storage/ndb/test/crund/martins_little_helpers/src/utils/string_helpers.hpp'
--- a/storage/ndb/test/crund/martins_little_helpers/src/utils/string_helpers.hpp	2010-02-14 05:05:31 +0000
+++ b/storage/ndb/test/crund/martins_little_helpers/src/utils/string_helpers.hpp	2010-10-01 04:10:21 +0000
@@ -8,6 +8,7 @@
 
 //#include <cstdio>
 #include <iostream>
+#include <sstream>
 #include <string>
 #include <set>
 
@@ -20,6 +21,7 @@ namespace utils {
 using std::string;
 using std::wstring;
 using std::ostream;
+using std::wistringstream;
 using std::set;
 
 /************************************************************
@@ -59,14 +61,47 @@ toBool(const wstring& ws)
 }
 
 /**
+ * Parses a wide character string as a (signed) decimal integer.
+ *
+ * Returns the integral value of a wide character string, the default value
+ * if the string is empty, or the error value if the conversion has failed.
+ */
+template< typename I >
+inline I
+toI(const wstring& ws, I vdefault, I verror)
+{
+    I val;
+    if (ws.length() == 0) {
+        val = vdefault;
+    } else {
+        wistringstream wiss(ws);
+        wiss >> val;
+        if (wiss.fail() || !wiss.eof()) {
+            val = verror;
+        }
+    }
+    return val;
+}
+
+inline int
+toInt(const wstring& ws, int vdefault, int verror)
+{
+    return toI< int >(ws, vdefault, verror);
+}
+
+/**
  * Returns the character representation of an int.
  */
 inline string
 toString(int i)
 {
-    std::ostringstream o;
-    o << i;
-    return o.str();
+    // JNI crashes with gcc & operator<<(ostream &, long/int)
+    //std::ostringstream o;
+    //o << i;
+    //return o.str();
+    char s[256];
+    snprintf(s, 256, "%d", i);
+    return string(s);
 }
 
 /**
@@ -86,36 +121,6 @@ toString(const wstring& ws) 
 }
 
 /**
- * Inserts all elements of a set s into the output stream os.
- */
-/*
-// neither matches operator<< in: set<string> s ; cout << s;
-
-inline ostream &
-operator<< (ostream & os, const set< string >& s)
-{
-    os << "{";
-    set< string >::iterator i = s.begin();
-    if (i != s.end()) {
-        os << *i;
-        while (++i != s.end())
-            os << "," << *i;
-    }
-    os << "}";
-    return os;
-}    
-
-template< typename T >
-inline ostream &
-operator<< (ostream& os, const set< T >& s)
-{
-    typename set< T >::iterator i = s.begin();
-...
-}    
-
-*/
-
-/**
  * Returns a string representation of all elements in the set.
  * 
  * This function is not very efficient in that it involves multiple
@@ -125,19 +130,19 @@ inline string
 toString(const set< string >& s)
 {
     string r;
-    r += "{";
+    r += "[";
     set< string >::iterator i = s.begin();
     if (i != s.end()) {
         r += "\"";
         r += *i;
         r += "\"";
         while (++i != s.end()) {
-            r += ",\"";
+            r += ", \"";
             r += *i;
             r += "\"";
         }
     }
-    r += "}";
+    r += "]";
     return r;
 }    
 

=== modified file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/Driver.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/Driver.java	2010-03-01 19:10:54 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/Driver.java	2010-10-01 04:10:21 +0000
@@ -89,23 +89,25 @@ abstract public class Driver {
     // benchmark settings
     protected final Properties props = new Properties();
     protected String descr = "";
-    protected boolean logRealTime = false;
-    protected boolean logMemUsage = false;
-    protected boolean includeFullGC = false;
-    protected boolean logSumOfOps = false;
-    protected boolean renewOperations = false;
-    protected boolean renewConnection = false;
-    protected boolean allowExtendedPC = false;
-    protected int aRows = (1 << 8);
-    protected int bRows = (1 << 8);
-    protected int aStart = (1 << 8), aEnd = (1 << 12), aIncr = (1 << 2);
-    protected int bStart = (1 << 8), bEnd = (1 << 12), bIncr = (1 << 2);
-    protected int maxVarbinaryBytes = 100;
-    protected int maxVarcharChars = 100;
-    protected int maxBlobBytes = 1000;
-    protected int maxTextChars = 1000;
-    protected int warmupRuns = 0;
-    protected int hotRuns = 0;
+    protected boolean logRealTime;
+    protected boolean logMemUsage;
+    protected boolean includeFullGC;
+    protected boolean logSumOfOps;
+    protected boolean renewOperations;
+    protected boolean renewConnection;
+    protected boolean allowExtendedPC;
+    protected int aStart;
+    protected int bStart;
+    protected int aEnd;
+    protected int bEnd;
+    protected int aScale;
+    protected int bScale;
+    protected int maxVarbinaryBytes;
+    protected int maxVarcharChars;
+    protected int maxBlobBytes;
+    protected int maxTextChars;
+    protected int warmupRuns;
+    protected int hotRuns;
     protected final Set<String> exclude = new HashSet<String>();
 
     // ----------------------------------------------------------------------
@@ -263,9 +265,10 @@ abstract public class Driver {
             init();
 
             // warmup runs
-            for (int i = 0; i < warmupRuns; i++)
+            for (int i = 0; i < warmupRuns; i++) {
                 runTests();
-
+            }
+            
             // truncate log file, reset log buffers
             out.println();
             out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
@@ -280,9 +283,10 @@ abstract public class Driver {
             openLogFile();
 
             // hot runs
-            for (int i = 0; i < hotRuns; i++)
+            for (int i = 0; i < hotRuns; i++) {
                 runTests();
-
+            }
+            
             // write log buffers
             if (logRealTime) {
                 log.println(descr + ", rtime[ms]"
@@ -311,7 +315,6 @@ abstract public class Driver {
         loadProperties();
         initProperties();
         printProperties();
-        checkProperties();
         openLogFile();
 
         // init log buffers
@@ -383,7 +386,12 @@ abstract public class Driver {
      * Initializes the benchmark properties.
      */
     protected void initProperties() {
-        // initialize boolean/numeric properties
+        //props.list(out);
+        out.print("initializing properties ... ");
+
+        final StringBuilder msg = new StringBuilder();        
+        final String eol = System.getProperty("line.separator");        
+
         logRealTime = parseBoolean("logRealTime");
         logMemUsage = parseBoolean("logMemUsage");
         includeFullGC = parseBoolean("includeFullGC");
@@ -391,14 +399,39 @@ abstract public class Driver {
         renewOperations = parseBoolean("renewOperations");
         renewConnection = parseBoolean("renewConnection");
         allowExtendedPC = parseBoolean("allowExtendedPC");
-        aRows = parseInt("aRows", 0);
-        bRows = parseInt("bRows", 0);
-        aStart = parseInt("aStart", 0);
-        aEnd = parseInt("aEnd", 0);
-        aIncr = parseInt("aIncr", 0);
-        bStart = parseInt("bStart", 0);
-        bEnd = parseInt("bEnd", 0);
-        bIncr = parseInt("bIncr", 0);
+
+        aStart = parseInt("aStart", 256);
+        if (aStart < 1) {
+            msg.append("[ignored] aStart:            " + aStart + eol);
+            aStart = 256;
+        }
+        aEnd = parseInt("aEnd", aStart);
+        if (aEnd < aStart) {
+            msg.append("[ignored] aEnd:              "+ aEnd + eol);
+            aEnd = aStart;
+        }
+        aScale = parseInt("aScale", 2);
+        if (aScale < 2) {
+            msg.append("[ignored] aScale:            " + aScale + eol);
+            aScale = 2;
+        }
+
+        bStart = parseInt("bStart", 256);
+        if (bStart < 1) {
+            msg.append("[ignored] bStart:            " + bStart + eol);
+            bStart = 256;
+        }
+        bEnd = parseInt("bEnd", bStart);
+        if (bEnd < bStart) {
+            msg.append("[ignored] bEnd:              " + bEnd + eol);
+            bEnd = bStart;
+        }
+        bScale = parseInt("bScale", 2);
+        if (bScale < 2) {
+            msg.append("[ignored] bScale:            " + bScale + eol);
+            bScale = 2;
+        }
+
         maxVarbinaryBytes = parseInt("maxVarbinaryBytes", 100);
         maxVarcharChars = parseInt("maxVarcharChars", 100);
         maxBlobBytes = parseInt("maxBlobBytes", 1000);
@@ -411,13 +444,22 @@ abstract public class Driver {
         for (int i = 0; i < e.length; i++) {
             exclude.add(e[i]);
         }
-    }
 
+        if (msg.length() == 0) {
+            out.println("[ok]");
+        } else {
+            out.println();
+            out.print(msg.toString());
+        }
+        out.println("data set:                   "
+                    + "[A=" + aStart + ".." + aEnd
+                    + ", B=" + bStart + ".." + bEnd + "]");
+    }
+    
     /**
      * Prints the benchmark's properties.
      */
     protected void printProperties() {
-        //props.list(out);
         out.println();
         out.println("main settings:");
         out.println("logRealTime:                " + logRealTime);
@@ -427,14 +469,12 @@ abstract public class Driver {
         out.println("renewOperations:            " + renewOperations);
         out.println("renewConnection:            " + renewConnection);
         out.println("allowExtendedPC:            " + allowExtendedPC);
-        out.println("aRows:                      " + aRows);
         out.println("aStart:                     " + aStart);
-        out.println("aEnd:                       " + aEnd);
-        out.println("aIncr:                      " + aIncr);
-        out.println("bRows:                      " + bRows);
         out.println("bStart:                     " + bStart);
+        out.println("aEnd:                       " + aEnd);
         out.println("bEnd:                       " + bEnd);
-        out.println("bIncr:                      " + bIncr);
+        out.println("aScale:                     " + aScale);
+        out.println("bScale:                     " + bScale);
         out.println("maxVarbinaryBytes:          " + maxVarbinaryBytes);
         out.println("maxVarcharChars:            " + maxVarcharChars);
         out.println("maxBlobBytes:               " + maxBlobBytes);
@@ -445,109 +485,6 @@ abstract public class Driver {
     }
 
     /**
-     * Checks the benchmark's properties.
-     */
-    protected void checkProperties() {
-        out.println();
-        out.print("checking properties ...     ");
-        final StringBuilder msg = new StringBuilder();        
-        final String eol = System.getProperty("line.separator");        
-        if (aRows > 0) {
-            if (aStart > 0) {
-                msg.append("[ignored] aStart:           ");
-                msg.append(aStart);
-                msg.append(eol);
-            }
-            if (aEnd > 0) {
-                msg.append("[ignored] aEnd:             ");
-                msg.append(aEnd);
-                msg.append(eol);
-            }
-            if (aIncr > 0) {
-                msg.append("[ignored] aIncr:            ");
-                msg.append(aIncr);
-                msg.append(eol);
-            }
-            aStart = aRows;
-            aEnd = aRows;
-            aIncr = 2;
-        } else {
-            if (aStart <= 0) {
-                aStart = (1 << 8);
-                msg.append("[changed] aStart:           ");
-                msg.append(aStart);
-                msg.append(eol);
-            }
-            if (aEnd < aStart) {
-                aEnd = aStart;
-                msg.append("[changed] aEnd:             ");
-                msg.append(aEnd);
-                msg.append(eol);
-            }
-            if (aIncr <= 1) {
-                aIncr = 2;
-                msg.append("[changed] aIncr:            ");
-                msg.append(aIncr);
-                msg.append(eol);
-            }
-        }
-        if (bRows > 0) {
-            if (bRows < aRows) {
-                bRows = aRows;
-                msg.append("[changed] bRows:            ");
-                msg.append(bRows);
-                msg.append(eol);
-            }
-            if (bStart > 0) {
-                msg.append("[ignored] bStart:           ");
-                msg.append(bStart);
-                msg.append(eol);
-            }
-            if (bEnd > 0) {
-                msg.append("[ignored] bEnd:             ");
-                msg.append(bEnd);
-                msg.append(eol);
-            }
-            if (bIncr > 0) {
-                msg.append("[ignored] bIncr:            ");
-                msg.append(bIncr);
-                msg.append(eol);
-            }
-            bStart = bRows;
-            bEnd = bRows;
-            bIncr = 2;
-        } else {
-            if (bStart < aStart) {
-                bStart = aStart;
-                msg.append("[changed] bStart:           ");
-                msg.append(bStart);
-                msg.append(eol);
-            }
-            if (bEnd < bStart) {
-                bEnd = bStart;
-                msg.append("[changed] bEnd:             ");
-                msg.append(bEnd);
-                msg.append(eol);
-            }
-            if (bIncr <= 1) {
-                bIncr = 2;
-                msg.append("[changed] bIncr:            ");
-                msg.append(bIncr);
-                msg.append(eol);
-            }
-        }
-        if (msg.length() == 0) {
-            out.println("[ok]");
-        } else {
-            out.println();
-            out.print(msg.toString());
-        }
-        out.println("data range:                 "
-                    + "[A=" + aStart + ".." + aEnd
-                    + ", B=" + bStart + ".." + bEnd + "]");
-    }
-    
-    /**
      * Opens the benchmark's data log file.
      */
     private void openLogFile() throws IOException {
@@ -578,9 +515,10 @@ abstract public class Driver {
         initConnection();
         initOperations();
 
-        for (int i = aStart; i <= aEnd; i *= aIncr) {
-            //for (int j = bBeg; j <= bEnd; j *= bIncr)
-            for (int j = (i > bStart ? i : bStart); j <= bEnd; j *= bIncr) {
+        assert (aStart <= aEnd && aScale > 1);
+        assert (bStart <= bEnd && bScale > 1);
+        for (int i = aStart; i <= aEnd; i *= aScale) {
+            for (int j = bStart; j <= bEnd; j *= bScale) {
                 try {
                     runOperations(i, j);
                 } catch (Exception ex) {
@@ -606,8 +544,14 @@ abstract public class Driver {
     protected void runOperations(int countA, int countB) throws Exception {
         out.println();
         out.println("------------------------------------------------------------");
-        out.println("countA = " + countA + ", countB = " + countB);
-        out.println();
+
+        if (countA > countB) {
+            out.println("skipping operations ...     "
+                        + "[A=" + countA + ", B=" + countB + "]");
+            return;
+        }
+        out.println("running operations ...      "
+                    + "[A=" + countA + ", B=" + countB + "]");
 
         // log buffers
         if (logRealTime) {
@@ -653,7 +597,8 @@ abstract public class Driver {
                 rtimes.append("\t" + ta);
                 out.println();
                 out.println("total");
-                out.println("tx real time      = " + ta + "\tms [begin..commit]");
+                out.println("tx real time\t\t= " + ta
+                            + "\tms [begin..commit]");
             }
             rtimes.append(endl);
         }
@@ -662,7 +607,7 @@ abstract public class Driver {
                 musage.append("\t" + ma);
                 out.println();
                 out.println("total");
-                out.println("net mem usage     = " + (ma >= 0 ? "+" : "") + ma
+                out.println("net mem usage\t\t= " + (ma >= 0 ? "+" : "") + ma
                             + "\tKiB");
             }
             musage.append(endl);
@@ -718,7 +663,8 @@ abstract public class Driver {
             //t1 = System.currentTimeMillis();
             t1 = System.nanoTime() / 1000000;
             final long t = t1 - t0;
-            out.println("tx real time      = " + t + "\tms [begin..commit]");
+            out.println("tx real time\t\t= " + t
+                        + "\tms [begin..commit]");
             //rtimes.append("\t" + (Math.round(t / 100.0) / 10.0));
             rtimes.append("\t" + t);
             ta += t;
@@ -731,16 +677,8 @@ abstract public class Driver {
             final long m0K = (m0 / 1024);
             final long m1K = (m1 / 1024);
             final long mK = m1K - m0K;
-            out.println("net mem usage     = " + (mK >= 0 ? "+" : "") + mK
+            out.println("net mem usage\t\t= " + (mK >= 0 ? "+" : "") + mK
                         + "\tKiB [" + m0K + "K->" + m1K + "K]");
-/*
-            out.println("allocated memory  = "
-                        + m1 + "\tK after commit");
-            out.println("total memory      = "
-                        + (rt.totalMemory() / 1024) + "\tK after commit");
-            out.println("max memory        = "
-                        + (rt.maxMemory() / 1024) + "\tK after commit");
-*/
             musage.append("\t" + mK);
             ma += mK;
         }

=== 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-03-01 19:10:54 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbApiLoad.java	2010-10-01 04:10:21 +0000
@@ -50,32 +50,23 @@ public class NdbApiLoad extends NdbBase 
         loadSystemLibrary("crundndb");
 
         // initialize NDB resources
-        out.println();
-        try {
-            final int ret = ndbinit(mgmdConnect);
-            if (ret != 0) {
-                err.println("NdbApiLoad: failed initializing NDBAPI;"
-                            + " return value = " + ret);
-            }
-        } catch (RuntimeException e) {
-            err.println("NdbApiLoad: failed initializing NDBAPI;"
-                        + " caught exception: " + e);
-            throw e;
+        final int ret = ndbinit(mgmdConnect);
+        if (ret != 0) {
+            String msg = ("NdbApiLoad: failed initializing NDBAPI;"
+                          + " return value = " + ret);
+            err.println(msg);
+            throw new Exception(msg);
         }
     }
 
     protected void close() throws Exception {
         // release NDB resources
-        try {
-            final int ret = ndbclose();
-            if (ret != 0) {
-                err.println("NdbApiLoad: failed closing NDBAPI;"
-                            + " return value = " + ret);
-            }
-        } catch (RuntimeException e) {
-            err.println("NdbApiLoad: failed closing NDBAPI;"
-                        + " caught exception: " + e);
-            throw e;
+        final int ret = ndbclose();
+        if (ret != 0) {
+            String msg = ("NdbApiLoad: failed closing NDBAPI;"
+                          + " return value = " + ret);
+            err.println(msg);
+            throw new Exception(msg);
         }
         super.close();
     }
@@ -107,10 +98,14 @@ public class NdbApiLoad extends NdbBase 
                                    boolean batch);
     protected native void setB0ByPK(int countA, int countB,
                                     boolean batch);
-    protected native void getAByPK(int countA, int countB,
-                                   boolean batch);
-    protected native void getB0ByPK(int countA, int countB,
-                                    boolean batch);
+    protected native void getAByPK_bb(int countA, int countB,
+                                      boolean batch);
+    protected native void getB0ByPK_bb(int countA, int countB,
+                                       boolean batch);
+    protected native void getAByPK_ar(int countA, int countB,
+                                      boolean batch);
+    protected native void getB0ByPK_ar(int countA, int countB,
+                                       boolean batch);
     protected native void setVarbinary(int countA, int countB,
                                        boolean batch, int length);
     protected native void getVarbinary(int countA, int countB,
@@ -171,16 +166,30 @@ public class NdbApiLoad extends NdbBase 
                 });
 
             ops.add(
-                new Op("getAByPK" + (batch ? "_batch" : "")) {
+                new Op("getAByPK_bb" + (batch ? "_batch" : "")) {
+                    public void run(int countA, int countB) {
+                        getAByPK_bb(countA, countB, batch);
+                    }
+                });
+
+            ops.add(
+                new Op("getAByPK_ar" + (batch ? "_batch" : "")) {
+                    public void run(int countA, int countB) {
+                        getAByPK_ar(countA, countB, batch);
+                    }
+                });
+
+            ops.add(
+                new Op("getB0ByPK_bb" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        getAByPK(countA, countB, batch);
+                        getB0ByPK_bb(countA, countB, batch);
                     }
                 });
 
             ops.add(
-                new Op("getB0ByPK" + (batch ? "_batch" : "")) {
+                new Op("getB0ByPK_ar" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        getB0ByPK(countA, countB, batch);
+                        getB0ByPK_ar(countA, countB, batch);
                     }
                 });
 

=== 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-02-14 05:05:31 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbBase.java	2010-10-01 04:10:21 +0000
@@ -53,8 +53,8 @@ abstract public class NdbBase extends Dr
 
     protected void printProperties() {
         super.printProperties();
-        out.println("ndb.mgmdConnect             " + mgmdConnect);
-        out.println("ndb.catalog                 " + catalog);
-        out.println("ndb.schema                  " + schema);
+        out.println("ndb.mgmdConnect             \"" + mgmdConnect + "\"");
+        out.println("ndb.catalog                 \"" + catalog + "\"");
+        out.println("ndb.schema                  \"" + schema + "\"");
     }
 }

=== modified file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbJTieLoad.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbJTieLoad.java	2010-09-27 05:31:17 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbJTieLoad.java	2010-10-01 04:10:21 +0000
@@ -182,12 +182,11 @@ public class NdbJTieLoad extends NdbBase
 
         // instantiate NDB cluster singleton
         out.println();
-        out.print("creating cluster conn...");
+        out.print("creating cluster conn ...");
         out.flush();
         mgmd = Ndb_cluster_connection.create(mgmdConnect);
         assert mgmd != null;
-        //out.println("    [ok]");
-        out.println("    [ok, mgmd=" + mgmd + "]");
+        out.println("   [ok, mgmd=" + mgmd + "]");
 
         // connect to cluster management node (ndb_mgmd)
         out.print("connecting to mgmd ...");
@@ -222,7 +221,6 @@ public class NdbJTieLoad extends NdbBase
         out.flush();
         final int initial_wait = 10; // secs to wait until first node detected
         final int final_wait = 0;    // secs 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) {
             final String msg = ("data nodes were not ready within "
@@ -232,10 +230,9 @@ public class NdbJTieLoad extends NdbBase
         }
         out.println("   [ok]");
 
-
         // connect to database
-        out.println();
-        out.println("connecting to database...");
+        out.print("connecting to database...");
+        out.flush();
         ndb = Ndb.create(mgmd, catalog, schema);
         final int max_no_tx = 10; // maximum number of parallel tx (<=1024)
         // note each scan or index scan operation uses one extra transaction
@@ -346,7 +343,7 @@ public class NdbJTieLoad extends NdbBase
                     });
 
                 ops.add(
-                    new Op("clearVarbinary" + (batch ? "_batch" : "")) {
+                    new Op("clearVarbinary" + l + (batch ? "_batch" : "")) {
                         public void run(int countA, int countB) {
                             setVarbinary(meta.table_B0, 1, countB, batch, null);
                         }
@@ -370,6 +367,13 @@ public class NdbJTieLoad extends NdbBase
                             getVarchar(meta.table_B0, 1, countB, batch, s);
                         }
                     });
+
+                ops.add(
+                    new Op("clearVarchar" + l + (batch ? "_batch" : "")) {
+                        public void run(int countA, int countB) {
+                            setVarchar(meta.table_B0, 1, countB, batch, null);
+                        }
+                    });
             }
 
             ops.add(

=== modified file 'storage/ndb/test/crund/src/crundndb/Driver.cpp'
--- a/storage/ndb/test/crund/src/crundndb/Driver.cpp	2010-02-14 05:05:31 +0000
+++ b/storage/ndb/test/crund/src/crundndb/Driver.cpp	2010-10-01 04:10:21 +0000
@@ -64,11 +64,14 @@ protected:
     bool logSumOfOps;
     bool renewConnection;
     bool renewOperations;
-    unsigned int aStart, aEnd, aIncr;
-    unsigned int bStart, bEnd, bIncr;
-    unsigned int maxStringLength;
-    unsigned int warmupRuns;
-    unsigned int hotRuns;
+    int aStart, aEnd, aScale;
+    int bStart, bEnd, bScale;
+    int maxVarbinaryBytes;
+    int maxVarcharChars;
+    int maxBlobBytes;
+    int maxTextChars;
+    int warmupRuns;
+    int hotRuns;
     set< string > exclude;
 
     // the NDB database connection
@@ -133,6 +136,16 @@ protected:
     void printProperties();
 
     /**
+     * Opens the benchmark's data log file.
+     */
+    void openLogFile();
+    
+    /**
+     * Closes the benchmark's data log file.
+     */
+    void closeLogFile();
+    
+    /**
      * Initializes the benchmark's resources.
      */
     void init();
@@ -187,27 +200,36 @@ protected:
     void clearData();
 
     // operation invocation templates
-    template< bool, bool > struct DelAllOp;
+    template< bool > struct ADelAllOp;
 
-    template< bool, bool, bool > struct InsOp;
+    template< bool > struct B0DelAllOp;
+
+    template< bool, bool > struct AInsOp;
+
+    template< bool, bool > struct B0InsOp;
+
+    template< const char** opName,
+              void (crund_ndb::Operations::*OP)(const NdbDictionary::Table*,
+                                                int,int,bool),
+              bool batch >
+    struct AByPKOp;
 
     template< const char** opName,
-              bool isTableA,
               void (crund_ndb::Operations::*OP)(const NdbDictionary::Table*,
                                                 int,int,bool),
               bool batch >
-    struct byPKOp;
+    struct B0ByPKOp;
 
     template< const char** opName,
               void (crund_ndb::Operations::*OP)(const NdbDictionary::Table*,
                                                 int,int,bool,int),
               bool batch >
-    struct lengthOp;
+    struct LengthOp;
 
     template< const char** opName,
               void (crund_ndb::Operations::*OP)(int,int,bool),
               bool forceSend >
-    struct relOp;
+    struct RelOp;
 };
 
 } // crund_ndb
@@ -224,6 +246,7 @@ using std::string;
 using std::wstring;
 
 using utils::toBool;
+using utils::toInt;
 using utils::toString;
 using crund_ndb::Driver;
 
@@ -242,23 +265,23 @@ Driver::run() {
     init();
 
     // warmup runs
-    for (unsigned int i = 0; i < warmupRuns; i++)
+    for (int i = 0; i < warmupRuns; i++) {
         runTests();
-
+    }
+    
     // truncate log file, reset log buffers
     cout << endl
          << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
          << "start logging results ..." << endl
          << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
          << endl;
-    log.close();
-    log.open(logFileName.c_str(), ios_base::out | ios_base::trunc);
-    assert (log.good());
     header.rdbuf()->str("");
     rtimes.rdbuf()->str("");
+    closeLogFile();
+    openLogFile();
 
     // hot runs
-    for (unsigned int i = 0; i < hotRuns; i++) {
+    for (int i = 0; i < hotRuns; i++) {
         runTests();
     }    
 
@@ -284,22 +307,17 @@ Driver::init() {
     loadProperties();
     initProperties();
     printProperties();
-
-    // initialize the benchmark's resources
-    ops = new crund_ndb::Operations();
-    assert (!mgmdConnect.empty());
-    ops->init(mgmdConnect.c_str());
-
-    // open the benchmark's data log file
-    cout << endl;
-    cout << "writing results to file:    " << logFileName << endl;
-    log.open(logFileName.c_str());
-    assert (log.good());
+    openLogFile();
 
     // clear log buffers
     logHeader = true;
     header.rdbuf()->str("");
     rtimes.rdbuf()->str("");
+
+    // initialize the benchmark's resources
+    ops = new crund_ndb::Operations();
+    assert (!mgmdConnect.empty());
+    ops->init(mgmdConnect.c_str());
 }
 
 void
@@ -308,16 +326,13 @@ Driver::close() {
     header.rdbuf()->str("");
     rtimes.rdbuf()->str("");
 
-    // close the benchmark's data log file
-    cout << "closing files ...    " << flush;
-    log.close();
-    cout << "       [ok]" << endl;
-
     // release the benchmark's resources
     assert (!mgmdConnect.empty());
     ops->close();
     delete ops;
     ops = NULL;
+
+    closeLogFile();
 }
 
 void
@@ -338,38 +353,95 @@ Driver::loadProperties() {
 
 void
 Driver::initProperties() {
-    descr = "";
-    logRealTime = false;
-    logCpuTime = false;
-    logSumOfOps = false;
-    renewConnection = false;
-    renewOperations = false;
-    aStart = (1 << 8), aEnd = (1 << 12), aIncr = (1 << 2);
-    bStart = (1 << 8), bEnd = (1 << 12), bIncr = (1 << 2);
-    maxStringLength = 100;
-    warmupRuns = 0;
-    hotRuns = 1;
-    mgmdConnect = "localhost";
-    catalog = "";
-    schema = "";
+    cout << "initializing properties ... " << flush;
+
+    ostringstream msg;
 
-    // initialize boolean properties
     logRealTime = toBool(props[L"logRealTime"]);
     logCpuTime = toBool(props[L"logCpuTime"]);
     logSumOfOps = toBool(props[L"logSumOfOps"]);
     renewOperations = toBool(props[L"renewOperations"]);
     renewConnection = toBool(props[L"renewConnection"]);
-    
-    // initialize numeric properties
-    wistringstream(props[L"aStart"]) >> aStart;
-    wistringstream(props[L"aEnd"]) >> aEnd;
-    wistringstream(props[L"aIncr"]) >> aIncr;
-    wistringstream(props[L"bStart"]) >> bStart;
-    wistringstream(props[L"bEnd"]) >> bEnd;
-    wistringstream(props[L"bIncr"]) >> bIncr;
-    wistringstream(props[L"maxStringLength"]) >> maxStringLength;
-    wistringstream(props[L"warmupRuns"]) >> warmupRuns;
-    wistringstream(props[L"hotRuns"]) >> hotRuns;
+
+    aStart = toInt(props[L"aStart"], 256, 0);
+    if (aStart < 1) {
+        msg << "[ignored] aStart:            '"
+            << toString(props[L"aStart"]) << "'" << endl;
+        aStart = 256;
+    }
+    aEnd = toInt(props[L"aEnd"], aStart, 0);
+    if (aEnd < aStart) {
+        msg << "[ignored] aEnd:              '"
+            << toString(props[L"aEnd"]) << "'" << endl;
+        aEnd = aStart;
+    }
+    aScale = toInt(props[L"aScale"], 2, 0);
+    if (aScale < 2) {
+        msg << "[ignored] aScale:            '"
+            << toString(props[L"aScale"]) << "'" << endl;
+        aScale = 2;
+    }
+
+    bStart = toInt(props[L"bStart"], aStart, 0);
+    if (bStart < 1) {
+        msg << "[ignored] bStart:            '"
+            << toString(props[L"bStart"]) << "'" << endl;
+        bStart = aStart;
+    }
+    bEnd = toInt(props[L"bEnd"], bStart, 0);
+    if (bEnd < bStart) {
+        msg << "[ignored] bEnd:              '"
+            << toString(props[L"bEnd"]) << "'" << endl;
+        bEnd = bStart;
+    }
+    bScale = toInt(props[L"bScale"], 2, 0);
+    if (bScale < 2) {
+        msg << "[ignored] bScale:            '"
+            << toString(props[L"bScale"]) << "'" << endl;
+        bScale = 2;
+    }
+
+    maxVarbinaryBytes = toInt(props[L"maxVarbinaryBytes"], 100, 0);
+    if (maxVarbinaryBytes < 1) {
+        msg << "[ignored] maxVarbinaryBytes: '"
+            << toString(props[L"maxVarbinaryBytes"]) << "'" << endl;
+        maxVarbinaryBytes = 100;
+    }
+
+    maxVarcharChars = toInt(props[L"maxVarcharChars"], 100, 0);
+    if (maxVarcharChars < 1) {
+        msg << "[ignored] maxVarcharChars:   '"
+            << toString(props[L"maxVarcharChars"]) << "'" << endl;
+        maxVarcharChars = 100;
+    }
+
+    maxBlobBytes = toInt(props[L"maxBlobBytes"], 1000, 0);
+    if (maxBlobBytes < 1) {
+        msg << "[ignored] maxBlobBytes:      '"
+            << toString(props[L"maxBlobBytes"]) << "'" << endl;
+        maxBlobBytes = 1000;
+    }
+
+    maxTextChars = toInt(props[L"maxTextChars"], 1000, 0);
+    if (maxTextChars < 1) {
+        msg << "[ignored] maxTextChars:      '"
+            << toString(props[L"maxTextChars"]) << "'" << endl;
+        maxTextChars = 1000;
+    }
+
+    warmupRuns = toInt(props[L"warmupRuns"], 0, -1);
+    if (warmupRuns < 0) {
+        msg << "[ignored] warmupRuns:        '"
+            << toString(props[L"warmupRuns"]) << "'" << endl;
+        warmupRuns = 0;
+    }
+
+    hotRuns = toInt(props[L"hotRuns"], 1, -1);
+    if (hotRuns < 0) {
+        msg << "[ignored] hotRuns:           '"
+            << toString(props[L"hotRuns"]) << "'" << endl;
+        hotRuns = 1;
+    }
 
     // initialize exclude set
     const wstring& estr = props[L"exclude"];
@@ -397,11 +469,18 @@ Driver::initProperties() {
     schema = toString(props[L"ndb.schema"]);
 
     descr = "C++->NDBAPI(" + mgmdConnect + ")";
+
+    if (msg.tellp() == 0) {
+        cout << "[ok]" << endl;
+    } else {
+        cout << endl << msg.str() << endl;
+    }
+
+    cout << "data set:                   "
+         << "[A=" << aStart << ".." << aEnd
+         << ", B=" << bStart << ".." << bEnd << "]" << endl;
 }
 
-/**
- * Prints the benchmark's properties.
- */
 void
 Driver::printProperties() {
     const ios_base::fmtflags f = cout.flags();    
@@ -409,19 +488,22 @@ Driver::printProperties() {
     //cout << ios_base::boolalpha;
     cout.flags(ios_base::boolalpha);
     
-    cout << "main settings:" << endl;
+    cout << endl << "main settings:" << endl;
     cout << "logRealTime:                " << logRealTime << endl;
     cout << "logCpuTime:                 " << logCpuTime << endl;
     cout << "logSumOfOps:                " << logSumOfOps << endl;
     cout << "renewOperations:            " << renewOperations << endl;
     cout << "renewConnection:            " << renewConnection << endl;
     cout << "aStart:                     " << aStart << endl;
-    cout << "aEnd:                       " << aEnd << endl;
-    cout << "aIncr:                      " << aIncr << endl;
     cout << "bStart:                     " << bStart << endl;
+    cout << "aEnd:                       " << aEnd << endl;
     cout << "bEnd:                       " << bEnd << endl;
-    cout << "bIncr:                      " << bIncr << endl;
-    cout << "maxStringLength:            " << maxStringLength << endl;
+    cout << "aScale:                     " << aScale << endl;
+    cout << "bScale:                     " << bScale << endl;
+    cout << "maxVarbinaryBytes:          " << maxVarbinaryBytes << endl;
+    cout << "maxVarcharChars:            " << maxVarcharChars << endl;
+    cout << "maxBlobBytes:               " << maxBlobBytes << endl;
+    cout << "maxTextChars:               " << maxTextChars << endl;
     cout << "warmupRuns:                 " << warmupRuns << endl;
     cout << "hotRuns:                    " << hotRuns << endl;
     cout << "exclude:                    " << toString(exclude) << endl;
@@ -432,6 +514,22 @@ Driver::printProperties() {
     cout.flags(f);
 }
 
+void
+Driver::openLogFile() {
+    cout << endl
+         << "writing results to file:    " << logFileName << endl;
+    //log.open(logFileName.c_str());
+    log.open(logFileName.c_str(), ios_base::out | ios_base::trunc);
+    assert (log.good());
+}
+
+void
+Driver::closeLogFile() {
+    cout << "closing files ...    " << flush;
+    log.close();
+    cout << "       [ok]" << endl;
+}
+
 // ----------------------------------------------------------------------
 
 void
@@ -439,9 +537,10 @@ Driver::runTests() {
     initConnection();
     initOperations();
 
-    for (unsigned int i = aStart; i <= aEnd; i *= aIncr) {
-        //for (int j = bBeg; j <= bEnd; j *= bIncr)
-        for (unsigned int j = (i > bStart ? i : bStart); j <= bEnd; j *= bIncr) {
+    assert(aStart <= aEnd && aScale > 1);
+    assert(bStart <= bEnd && bScale > 1);
+    for (int i = aStart; i <= aEnd; i *= aScale) {
+        for (int j = bStart; j <= bEnd; j *= bScale) {
             runOperations(i, j);
         }
     }
@@ -458,9 +557,15 @@ Driver::runTests() {
 void
 Driver::runOperations(int countA, int countB) {
     cout << endl
-         << "------------------------------------------------------------" << endl
-         << "countA = " << countA << ", countB = " << countB << endl
-         << endl;
+         << "------------------------------------------------------------" << endl;
+    
+    if (countA > countB) {
+        cout << "skipping operations ...     "
+             << "[A=" << countA << ", B=" << countB << "]" << endl;
+        return;
+    }
+    cout << "running operations ...      "
+         << "[A=" << countA << ", B=" << countB << "]" << endl;            
 
     // log buffers
     if (logRealTime) {
@@ -507,7 +612,7 @@ Driver::runOperations(int countA, int co
             rtimes << "\t" << rta;
             cout << endl
                  << "total" << endl
-                 << "tx real time     = " << rta
+                 << "tx real time\t\t= " << rta
                  << "\tms [begin..commit]" << endl;
         }
         rtimes << endl;
@@ -517,7 +622,7 @@ Driver::runOperations(int countA, int co
             ctimes << "\t" << cta;
             cout << endl
                  << "total" << endl
-                 << "tx cpu time      = " << cta
+                 << "tx cpu time\t\t= " << cta
                  << "\tms [begin..commit]" << endl;
         }
         ctimes << endl;
@@ -570,7 +675,7 @@ Driver::commit(const string& name) {
             rtimes << "\tERROR";
         } else {
             long t = long(hrt_rtmicros(&t1.rtstamp, &t0.rtstamp)/1000);
-            cout << "tx real time     = " << t
+            cout << "tx real time\t\t= " << t
                  << "\tms [begin..commit]" << endl;
             rtimes << "\t" << t;
             rta += t;
@@ -583,7 +688,7 @@ Driver::commit(const string& name) {
             ctimes << "\tERROR";
         } else {
             long t = long(hrt_ctmicros(&t1.ctstamp, &t0.ctstamp)/1000);
-            cout << "tx cpu time      = " << t
+            cout << "tx cpu time\t\t= " << t
                  << "\tms [begin..commit]" << endl;
             ctimes << "\t" << t;
             cta += t;
@@ -620,47 +725,81 @@ Driver::initOperations() {
 // the operation invocation templates look a bit complex, but they help
 // a lot to factorize code over the operations' parameter signatures
 
-template< bool tableA, bool batch >
-struct Driver::DelAllOp : Op {
-    DelAllOp() : Op(string(string(tableA ? "delAllA" : "delAllB0")
-                            + (batch ? "_batch" : ""))) {
+template< bool batch >
+struct Driver::ADelAllOp : Op {
+    ADelAllOp() : Op(string("delAllA")
+                     + (batch ? "_batch" : "")) {
+    }
+            
+    virtual void run(int countA, int countB) const {
+        int count;
+        ops->delByScan(ops->meta->table_A, count, batch);
+        assert (count == countA);
+    }
+};
+
+template< bool batch >
+struct Driver::B0DelAllOp : Op {
+    B0DelAllOp() : Op(string("delAllB0")
+                      + (batch ? "_batch" : "")) {
     }
             
     virtual void run(int countA, int countB) const {
         int count;
-        ops->delByScan((tableA ? ops->meta->table_A :  ops->meta->table_B0),
-                       count, batch);
-        assert (count == (tableA ? countA : countB));
+        ops->delByScan(ops->meta->table_B0, count, batch);
+        assert (count == countB);
+    }
+};
+
+template< bool setAttrs, bool batch >
+struct Driver::AInsOp : Op {
+    AInsOp() : Op(string("insA")
+                  + (setAttrs ? "_attr" : "")
+                  + (batch ? "_batch" : "")) {
+    }
+            
+    virtual void run(int countA, int countB) const {
+        ops->ins(ops->meta->table_A, 1, countA, setAttrs, batch);
     }
 };
 
-template< bool tableA, bool setAttrs, bool batch >
-struct Driver::InsOp : Op {
-    InsOp() : Op(string(string(tableA ? "insA" : "insB0")
-                        + (setAttrs ? "_attr" : "")
-                        + (batch ? "_batch" : ""))) {
+template< bool setAttrs, bool batch >
+struct Driver::B0InsOp : Op {
+    B0InsOp() : Op(string("insB0")
+                   + (setAttrs ? "_attr" : "")
+                   + (batch ? "_batch" : "")) {
     }
             
     virtual void run(int countA, int countB) const {
-        ops->ins((tableA ? ops->meta->table_A :  ops->meta->table_B0),
-                 1, (tableA ? countA : countB), setAttrs, batch);
+        ops->ins(ops->meta->table_B0, 1, countB, setAttrs, batch);
     }
 };
 
 template< const char** opName,
-          bool isTableA,
           void (crund_ndb::Operations::*OP)(const NdbDictionary::Table*,
                                             int,int,bool),
           bool batch >
-struct Driver::byPKOp : Op {
-    byPKOp() : Op(string(*opName)
-                   + string(isTableA ? "AByPK" : "B0ByPK")
+struct Driver::AByPKOp : Op {
+    AByPKOp() : Op(string(*opName)
                    + (batch ? "_batch" : "")) {
     }
             
     virtual void run(int countA, int countB) const {
-        (ops->*OP)((isTableA ? ops->meta->table_A :  ops->meta->table_B0),
-                     1, (isTableA ? countA : countB), batch);
+        (ops->*OP)(ops->meta->table_A, 1, countA, batch);
+    }
+};
+
+template< const char** opName,
+          void (crund_ndb::Operations::*OP)(const NdbDictionary::Table*,
+                                            int,int,bool),
+          bool batch >
+struct Driver::B0ByPKOp : Op {
+    B0ByPKOp() : Op(string(*opName)
+                    + (batch ? "_batch" : "")) {
+    }
+            
+    virtual void run(int countA, int countB) const {
+        (ops->*OP)(ops->meta->table_B0, 1, countB, batch);
     }
 };
 
@@ -668,10 +807,10 @@ template< const char** opName,
           void (crund_ndb::Operations::*OP)(const NdbDictionary::Table*,
                                             int,int,bool,int),
           bool batch >
-struct Driver::lengthOp : Op {
+struct Driver::LengthOp : Op {
     const int length;
 
-    lengthOp(int length) : Op(string(*opName)
+    LengthOp(int length) : Op(string(*opName)
                               + toString(length)
                               + (batch ? "_batch" : "")),
                            length(length) {
@@ -685,8 +824,8 @@ struct Driver::lengthOp : Op {
 template< const char** opName,
           void (crund_ndb::Operations::*OP)(int x,int y,bool z),
           bool forceSend >
-struct Driver::relOp : Op {
-    relOp() : Op(string(*opName) + (forceSend ? "_forceSend" : "")) {
+struct Driver::RelOp : Op {
+    RelOp() : Op(string(*opName) + (forceSend ? "_forceSend" : "")) {
     }
             
     virtual void run(int countA, int countB) const {
@@ -700,15 +839,22 @@ struct Driver::relOp : Op {
 //
 // Until then, we have to allocate the operation names as variables
 // (which are external at file scope by default).
-const char* del_s = "del";
-const char* set_s = "set";
-const char* get_s = "get";
+const char* delAByPK_s = "delAByPK";
+const char* delB0ByPK_s = "delB0ByPK";
+const char* setAByPK_s = "setAByPK";
+const char* setB0ByPK_s = "setB0ByPK";
+const char* getAByPK_bb_s = "getAByPK_bb";
+const char* getB0ByPK_bb_s = "getB0ByPK_bb";
+const char* getAByPK_ar_s = "getAByPK_ar";
+const char* getB0ByPK_ar_s = "getB0ByPK_ar";
+
 const char* setVarbinary_s = "setVarbinary";
 const char* getVarbinary_s = "getVarbinary";
 const char* clearVarbinary_s = "clearVarbinary";
 const char* setVarchar_s = "setVarchar";
 const char* getVarchar_s = "getVarchar";
 const char* clearVarchar_s = "clearVarchar";
+
 const char* setB0ToA_s = "setB0->A";
 const char* navB0ToA_s = "navB0->A";
 const char* navB0ToAalt_s = "navB0->A_alt";
@@ -719,84 +865,92 @@ const char* nullB0ToA_s = "nullB0->A";
 template< bool feat > void
 Driver::initOperationsFeat() {
 
-    const bool tableA = true;
     const bool setAttr = true;
     operations.push_back(
-        new InsOp< tableA, !setAttr, feat >());
+        new AInsOp< !setAttr, feat >());
+
+    operations.push_back(
+        new B0InsOp< !setAttr, feat >());
 
     operations.push_back(
-        new InsOp< !tableA, !setAttr, feat >());
+        new AByPKOp< &setAByPK_s, &crund_ndb::Operations::setByPK, feat >());
 
     operations.push_back(
-        new byPKOp< &set_s, tableA, &crund_ndb::Operations::setByPK, feat >());
+        new B0ByPKOp< &setB0ByPK_s, &crund_ndb::Operations::setByPK, feat >());
 
     operations.push_back(
-        new byPKOp< &set_s, !tableA, &crund_ndb::Operations::setByPK, feat >());
+        new AByPKOp< &getAByPK_bb_s, &crund_ndb::Operations::getByPK_bb, feat >());
 
     operations.push_back(
-        new byPKOp< &get_s, tableA, &crund_ndb::Operations::getByPK, feat >());
+        new AByPKOp< &getAByPK_ar_s, &crund_ndb::Operations::getByPK_ar, feat >());
 
     operations.push_back(
-        new byPKOp< &get_s, !tableA, &crund_ndb::Operations::getByPK, feat >());
+        new B0ByPKOp< &getB0ByPK_bb_s, &crund_ndb::Operations::getByPK_bb, feat >());
 
-    for (unsigned int i = 1; i <= maxStringLength; i *= 10) {
+    operations.push_back(
+        new B0ByPKOp< &getB0ByPK_ar_s, &crund_ndb::Operations::getByPK_ar, feat >());
+
+    for (int i = 1; i <= maxVarbinaryBytes; i *= 10) {
         const int length = i;
 
         operations.push_back(
-            new lengthOp< &setVarbinary_s, &crund_ndb::Operations::setVarbinary, feat >(length));
+            new LengthOp< &setVarbinary_s, &crund_ndb::Operations::setVarbinary, feat >(length));
 
         operations.push_back(
-            new lengthOp< &getVarbinary_s, &crund_ndb::Operations::getVarbinary, feat >(length));
+            new LengthOp< &getVarbinary_s, &crund_ndb::Operations::getVarbinary, feat >(length));
 
         operations.push_back(
-            new lengthOp< &clearVarbinary_s, &crund_ndb::Operations::setVarbinary, feat >(0));
+            new LengthOp< &clearVarbinary_s, &crund_ndb::Operations::setVarbinary, feat >(0));
+    }
+    
+    for (int i = 1; i <= maxVarcharChars; i *= 10) {
+        const int length = i;
 
         operations.push_back(
-            new lengthOp< &setVarchar_s, &crund_ndb::Operations::setVarchar, feat >(length));
+            new LengthOp< &setVarchar_s, &crund_ndb::Operations::setVarchar, feat >(length));
 
         operations.push_back(
-            new lengthOp< &getVarchar_s, &crund_ndb::Operations::getVarchar, feat >(length));
+            new LengthOp< &getVarchar_s, &crund_ndb::Operations::getVarchar, feat >(length));
 
         operations.push_back(
-            new lengthOp< &clearVarchar_s, &crund_ndb::Operations::setVarchar, feat >(0));
-
+            new LengthOp< &clearVarchar_s, &crund_ndb::Operations::setVarchar, feat >(0));
     }
 
     operations.push_back(
-        new relOp< &setB0ToA_s, &crund_ndb::Operations::setB0ToA, feat >());
+        new RelOp< &setB0ToA_s, &crund_ndb::Operations::setB0ToA, feat >());
 
     operations.push_back(
-        new relOp< &navB0ToA_s, &crund_ndb::Operations::navB0ToA, feat >());
+        new RelOp< &navB0ToA_s, &crund_ndb::Operations::navB0ToA, feat >());
 
     operations.push_back(
-        new relOp< &navB0ToAalt_s, &crund_ndb::Operations::navB0ToAalt, feat >());
+        new RelOp< &navB0ToAalt_s, &crund_ndb::Operations::navB0ToAalt, feat >());
 
     operations.push_back(
-        new relOp< &navAToB0_s, &crund_ndb::Operations::navAToB0, feat >());
+        new RelOp< &navAToB0_s, &crund_ndb::Operations::navAToB0, feat >());
 
     operations.push_back(
-        new relOp< &navAToB0alt_s, &crund_ndb::Operations::navAToB0alt, feat >());
+        new RelOp< &navAToB0alt_s, &crund_ndb::Operations::navAToB0alt, feat >());
 
     operations.push_back(
-        new relOp< &nullB0ToA_s, &crund_ndb::Operations::nullB0ToA, feat >());
+        new RelOp< &nullB0ToA_s, &crund_ndb::Operations::nullB0ToA, feat >());
 
     operations.push_back(
-        new byPKOp< &del_s, !tableA, &crund_ndb::Operations::delByPK, feat >());
+        new B0ByPKOp< &setAByPK_s, &crund_ndb::Operations::delByPK, feat >());
 
     operations.push_back(
-        new byPKOp< &del_s, tableA, &crund_ndb::Operations::delByPK, feat >());
+        new AByPKOp< &setB0ByPK_s, &crund_ndb::Operations::delByPK, feat >());
 
     operations.push_back(
-        new InsOp< tableA, setAttr, feat >());
+        new AInsOp< setAttr, feat >());
 
     operations.push_back(
-        new InsOp< !tableA, setAttr, feat >());
+        new B0InsOp< setAttr, feat >());
 
     operations.push_back(
-        new DelAllOp< !tableA, feat >());
+        new ADelAllOp< feat >());
 
     operations.push_back(
-        new DelAllOp< tableA, feat >());
+        new B0DelAllOp< feat >());
 }
 
 void
@@ -813,14 +967,7 @@ Driver::closeOperations() {
 void
 Driver::clearData()
 {
-    cout << "deleting all rows ..." << flush;
-    int delB0 = -1;
-    const bool batch = true;
-    ops->delByScan(ops->meta->table_B0, delB0, batch);
-    cout << "       [B0: " << delB0 << flush;
-    int delA = -1;
-    ops->delByScan(ops->meta->table_A, delA, batch);
-    cout << ", A: " << delA << "]" << endl;
+    ops->clearData();
 }
 
 //---------------------------------------------------------------------------

=== modified file 'storage/ndb/test/crund/src/crundndb/Operations.cpp'
--- a/storage/ndb/test/crund/src/crundndb/Operations.cpp	2010-09-29 10:02:15 +0000
+++ b/storage/ndb/test/crund/src/crundndb/Operations.cpp	2010-10-01 04:10:21 +0000
@@ -15,6 +15,7 @@
 #include <NdbError.hpp>
 
 #include "helpers.hpp"
+#include "string_helpers.hpp"
 #include "Operations.hpp"
 
 //using namespace std;
@@ -26,6 +27,9 @@ using std::endl;
 using crund_ndb::Meta;
 using crund_ndb::Operations;
 
+// JNI crashes with gcc & operator<<(ostream &, long/int)
+using utils::toString;
+
 /************************************************************
  * Helper Macros & Functions
  ************************************************************/
@@ -35,8 +39,8 @@ using crund_ndb::Operations;
 // - all errors are reported and then followed by a process exit
 
 /*
-// runtime/compiler bug? macro aborts during into->string conversion
-#define ABORT_NDB_ERROR0(error)                                          \
+// JNI crashes with gcc & operator<<(ostream &, long/int)
+#define ABORT_NDB_ERROR0(error)                                         \
     do { cout << "!!! error in " << __FILE__ << ", line: " << __LINE__  \
               << ", code: " << (int)error.code                          \
               << ", msg: " << error.message << "." << endl;             \
@@ -59,14 +63,6 @@ using crund_ndb::Operations;
 #define VERIFY(cond)                                                    \
     if (cond); else ABORT_ERROR("wrong data; verification failed")
 
-/*
-static ostream& operator<<(ostream& s, const NdbError& e)
-{
-    s << "code: " << e.code << ", msg: " << e.message << ".";
-    return s;
-}
-*/
-
 /************************************************************
  * Member Functions of Class Meta
  ************************************************************/
@@ -168,14 +164,17 @@ Operations::init(const char* mgmd_conn_s
     assert (mgmd_conn_str);
 
     // ndb_init must be called first
-    cout << "initializing NDBAPI..." << flush;
+    cout << endl
+         << "initializing NDBAPI ..." << flush;
     int stat = ndb_init();
     if (stat != 0)
         ABORT_ERROR("ndb_init() returned: " << stat);
-    cout << "      [ok]" << endl;
+    cout << "     [ok]" << endl;
 
     // instantiate NDB cluster singleton
+    cout << "creating cluster conn ..." << flush;
     mgmd = new Ndb_cluster_connection(mgmd_conn_str);
+    cout << "   [ok]" << endl; // no useful mgmd->string conversion
 
     // connect to cluster management node (ndb_mgmd)
     cout << "connecting to mgmd ..." << flush;
@@ -219,10 +218,10 @@ Operations::initConnection(const char* c
     // connect to database
     cout << "connecting to database..." << flush;
     ndb = new Ndb(mgmd, catalog, schema);
-    //const int max_no_tx = 10; // maximum number of parallel tx (<=1024)
+    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(max_no_tx) != 0)
-    if (ndb->init() != 0)
+    //if (ndb->init() != 0)
+    if (ndb->init(max_no_tx) != 0)
         ABORT_NDB_ERROR(ndb->getNdbError());
     cout << "   [ok]" << endl;
 
@@ -291,6 +290,19 @@ Operations::closeTransaction()
 
 // ----------------------------------------------------------------------
 
+void
+Operations::clearData()
+{
+    cout << "deleting all rows ..." << flush;
+    const bool batch = true;
+    int delB0 = -1;
+    delByScan(meta->table_B0, delB0, batch);
+    cout << "       [B0: " << toString(delB0) << flush;
+    int delA = -1;
+    delByScan(meta->table_A, delA, batch);
+    cout << ", A: " << toString(delA) << "]" << endl;
+}
+
 struct CommonAB {
     Int32 id;
     Int32 cint;
@@ -439,7 +451,7 @@ Operations::delByScan(const NdbDictionar
     const bool forceSend_ = false;
     const bool releaseOp = false;
     op->close(forceSend_, releaseOp);
-    //CDBG << "    deleted " << count << " rows" << endl;
+    //CDBG << "!!! deleted " << toString(count) << " rows" << endl;
 
     commitTransaction();
     closeTransaction();
@@ -506,9 +518,9 @@ Operations::setByPK(const NdbDictionary:
 }
 
 void
-Operations::getByPK(const NdbDictionary::Table* table,
-                    int from, int to,
-                    bool batch)
+Operations::getByPK_bb(const NdbDictionary::Table* table,
+                       int from, int to,
+                       bool batch)
 {
     // allocate attributes holder
     const int count = (to - from) + 1;
@@ -556,7 +568,7 @@ Operations::getByPK(const NdbDictionary:
         VERIFY(id == i);
 
         Int32 j = getCommonAB(pab);
-        //CDBG << "!!! id=" << id << ", i=" << i << endl;
+        //CDBG << "!!! id=" << toString(id) << ", i=" << toString(i) << endl;
         VERIFY(j == id);
     }
 
@@ -564,7 +576,6 @@ Operations::getByPK(const NdbDictionary:
     delete[] ab;
 }
 
-// XXX
 struct CommonAB_AR {
     NdbRecAttr* id;
     NdbRecAttr* cint;
@@ -573,7 +584,6 @@ struct CommonAB_AR {
     NdbRecAttr* cdouble;
 };
 
-// XXX
 static inline Int32
 getCommonAB(const CommonAB_AR* const ab)
 {
@@ -587,7 +597,6 @@ getCommonAB(const CommonAB_AR* const ab)
     return cint;
 }
 
-// XXX
 void
 Operations::getByPK_ar(const NdbDictionary::Table* table,
                        int from, int to,
@@ -639,7 +648,7 @@ Operations::getByPK_ar(const NdbDictiona
         VERIFY(id == i);
 
         Int32 j = getCommonAB(pab);
-        //CDBG << "!!! id=" << id << ", i=" << i << endl;
+        //CDBG << "!!! id=" << toString(id) << ", i=" << toString(i) << endl;
         VERIFY(j == id);
     }
 
@@ -695,11 +704,9 @@ Operations::setVar(const NdbDictionary::
         buf = new char[sbuf];
         buf[0] = (char)slen;
         memcpy(buf + 1, str, slen);
-#if 0
-        CDBG << "!!! buf[0]=" << (int)buf[0] << endl;
-        CDBG << "!!! buf[1]=" << (int)buf[1] << endl;
-        CDBG << "!!! buf[" << slen << "]=" << (int)buf[slen] << endl;
-#endif
+        //CDBG << "!!! buf[0]=" << toString(buf[0]) << endl;
+        //CDBG << "!!! buf[1]=" << toString(buf[1]) << endl;
+        //CDBG << "!!! buf[" << toString(slen) << "]=" << toString(buf[slen]) << endl;
     }
     
     beginTransaction();
@@ -743,13 +750,11 @@ Operations::getVar(const NdbDictionary::
     const size_t sline = (1 + slen);
     const size_t sbuf = count * sline;
     char* const buf = new char[sbuf];
-#if 0
-    memset(buf, 1, sbuf);
-    CDBG << "!!! buf[0]=" << (int)buf[0] << endl;
-    CDBG << "!!! buf[1]=" << (int)buf[1] << endl;
-    CDBG << "!!! buf[" << slen << "]=" << (int)buf[slen] << endl;
-    CDBG << "!!! buf[" << (slen+1) << "]=" << (int)buf[slen + 1] << endl;
-#endif
+    //memset(buf, 1, sbuf);
+    //CDBG << "!!! buf[0]=" << toString(buf[0]) << endl;
+    //CDBG << "!!! buf[1]=" << toString(buf[1]) << endl;
+    //CDBG << "!!! buf[" << toString(slen) << "]=" << toString(buf[slen]) << endl;
+    //CDBG << "!!! buf[" << toString(slen+1) << "]=" << toString(buf[slen+1]) << endl;
 
     // fetch string attribute by key
     char* s = buf;
@@ -781,12 +786,11 @@ Operations::getVar(const NdbDictionary::
     // copy (move) the strings to make them aligned and 0-terminated
     s = buf;
     for (int i = from; i <= to; i++, s += sline) {
-#if 0
-        CDBG << "!!! s[0]=" << (int)s[0] << endl;
-        CDBG << "!!! s[1]=" << (int)s[1] << endl;
-        CDBG << "!!! s[" << slen << "]=" << (int)s[slen] << endl;
-        CDBG << "!!! s[" << (slen+1) << "]=" << (int)s[slen + 1] << endl;
-#endif
+        //CDBG << "!!! s[0]=" << toString(s[0]) << endl;
+        //CDBG << "!!! s[1]=" << toString(s[1]) << endl;
+        //CDBG << "!!! s[" << toString(slen) << "]=" << toString(s[slen]) << endl;
+        //CDBG << "!!! s[" << toString(slen+1) << "]=" << toString(s[slen + 1]) << endl;
+
         const size_t n = s[0];
         VERIFY(n < sline);
 
@@ -795,7 +799,6 @@ Operations::getVar(const NdbDictionary::
         s[n] = 0;
         
         // check fetched values
-        //CDBG << "!!! s=" << (void*)s << ", '" << s << "'" << endl;
         VERIFY(strcmp(s, str) == 0);
     }
     assert (s == buf + sbuf);
@@ -936,7 +939,7 @@ Operations::navB0ToA(int count_A, int co
         VERIFY(id == ((i - 1) % count_A) + 1);
 
         Int32 j = getCommonAB(pab);
-        //CDBG << "!!! id=" << id << ", i=" << i << endl;
+        //CDBG << "!!! id=" << toString(id) << ", i=" << toString(i) << endl;
         VERIFY(j == id);
     }
 
@@ -1025,7 +1028,7 @@ Operations::navB0ToAalt(int count_A, int
         VERIFY(id == ((i - 1) % count_A) + 1);
 
         Int32 j = getCommonAB(pab);
-        //CDBG << "!!! id=" << id << ", i=" << i << endl;
+        //CDBG << "!!! id=" << toString(id) << ", i=" << toString(i) << endl;
         VERIFY(j == id);
     }
 
@@ -1098,21 +1101,19 @@ Operations::navAToB0(int count_A, int co
     }
     commitTransaction();
     closeTransaction();
-    //CDBG << "!!! pab - ab =" << (pab-ab) << endl;
+    //CDBG << "!!! pab - ab =" << toString(pab-ab) << endl;
     assert (pab == ab + count_B);
 
     // check fetched values
-    // XXX this is may not be the most efficient way of testing...
-// #ifndef NDEBUG
+    // XXX this is not the most efficient way of testing...
     vector<CommonAB> b(ab, ab + count_B);
     sort(b.begin(), b.end(), compare);
     vector<CommonAB>::const_iterator it = b.begin();
     for (int i = 1; i <= count_B; i++, it++) {
         Int32 id = getCommonAB(&it[0]);
-        //CDBG << "!!! id=" << id << ", i=" << i << endl;
+        //CDBG << "!!! id=" << toString(id) << ", i=" << toString(i) << endl;
         VERIFY(id == i);
     }
-//#endif
 
     // release attributes holder
     delete[] ab;
@@ -1199,22 +1200,20 @@ Operations::navAToB0alt(int count_A, int
     }
     commitTransaction();
     closeTransaction();
-    //CDBG << "!!! a_id=" << a_id << ", pab - ab =" << (pab-ab) << endl;
+    //CDBG << "!!! pab - ab =" << toString(pab-ab) << endl;
     assert (a_id == count_A + 1);
     assert (pab == ab + count_B);
 
     // check fetched values
-    // XXX this is may not be the most efficient way of testing...
-// #ifndef NDEBUG
+    // XXX this is not the most efficient way of testing...
     vector<CommonAB> b(ab, ab + count_B);
     sort(b.begin(), b.end(), compare);
     vector<CommonAB>::const_iterator it = b.begin();
     for (int i = 1; i <= count_B; i++, it++) {
         Int32 id = getCommonAB(&it[0]);
-        //CDBG << "!!! id=" << id << ", i=" << i << endl;
+        //CDBG << "!!! id=" << toString(id) << ", i=" << toString(i) << endl;
         VERIFY(id == i);
     }
-//#endif
 
     // release attributes holder
     delete[] ab;

=== modified file 'storage/ndb/test/crund/src/crundndb/Operations.hpp'
--- a/storage/ndb/test/crund/src/crundndb/Operations.hpp	2010-02-14 05:05:31 +0000
+++ b/storage/ndb/test/crund/src/crundndb/Operations.hpp	2010-10-01 04:10:21 +0000
@@ -88,6 +88,8 @@ public:
 
     void rollbackTransaction();
 
+    void clearData();
+
     void delByScan(const NdbDictionary::Table* table, int& count,
                    bool batch);
 
@@ -100,10 +102,9 @@ public:
     void setByPK(const NdbDictionary::Table* table, int from, int to,
                  bool batch);
 
-    void getByPK(const NdbDictionary::Table* table, int from, int to,
-                 bool batch);
+    void getByPK_bb(const NdbDictionary::Table* table, int from, int to,
+                    bool batch);
 
-    // XXX
     void getByPK_ar(const NdbDictionary::Table* table, int from, int to,
                     bool batch);
 

=== 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-02-14 05:05:31 +0000
+++ b/storage/ndb/test/crund/src/crundndb/com_mysql_cluster_crund_NdbApiLoad.cpp	2010-10-01 04:10:21 +0000
@@ -4,7 +4,6 @@
  */
 
 #include <jni.h>
-#include <iostream>
 #include <cassert>
 
 #include "com_mysql_cluster_crund_NdbApiLoad.h"
@@ -93,13 +92,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                                   jobject obj)
 {
     TRACE("clearData()");
-    cout << "deleting all rows ..." << flush;
-    int delB0;
-    ops->delByScan(ops->meta->table_B0, delB0, true);
-    cout << "       [B0: " << delB0 << flush;
-    int delA;
-    ops->delByScan(ops->meta->table_A, delA, true);
-    cout << ", A: " << delA << "]" << endl;
+    ops->clearData();
 }
 
 JNIEXPORT void JNICALL
@@ -223,25 +216,47 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
 }
 
 JNIEXPORT void JNICALL
-Java_com_mysql_cluster_crund_NdbApiLoad_getAByPK(JNIEnv* env,
-                                                 jobject obj,
-                                                 jint count_A,
-                                                 jint count_B,
-                                                 jboolean batch)
+Java_com_mysql_cluster_crund_NdbApiLoad_getAByPK_1bb(JNIEnv* env,
+                                                     jobject obj,
+                                                     jint count_A,
+                                                     jint count_B,
+                                                     jboolean batch)
 {
-    TRACE("getAByPK()");
-    ops->getByPK(ops->meta->table_A, 1, count_A, batch == JNI_TRUE);
+    TRACE("getAByPK_bb()");
+    ops->getByPK_bb(ops->meta->table_A, 1, count_A, batch == JNI_TRUE);
 }
 
 JNIEXPORT void JNICALL
-Java_com_mysql_cluster_crund_NdbApiLoad_getB0ByPK(JNIEnv* env,
-                                                  jobject obj,
-                                                  jint count_A,
-                                                  jint count_B,
-                                                  jboolean batch)
+Java_com_mysql_cluster_crund_NdbApiLoad_getB0ByPK_1bb(JNIEnv* env,
+                                                      jobject obj,
+                                                      jint count_A,
+                                                      jint count_B,
+                                                      jboolean batch)
+{
+    TRACE("getB0ByPK_bb()");
+    ops->getByPK_bb(ops->meta->table_B0, 1, count_B, batch == JNI_TRUE);
+}
+
+JNIEXPORT void JNICALL
+Java_com_mysql_cluster_crund_NdbApiLoad_getAByPK_1ar(JNIEnv* env,
+                                                     jobject obj,
+                                                     jint count_A,
+                                                     jint count_B,
+                                                     jboolean batch)
+{
+    TRACE("getAByPK_ar()");
+    ops->getByPK_ar(ops->meta->table_A, 1, count_A, batch == JNI_TRUE);
+}
+
+JNIEXPORT void JNICALL
+Java_com_mysql_cluster_crund_NdbApiLoad_getB0ByPK_1ar(JNIEnv* env,
+                                                      jobject obj,
+                                                      jint count_A,
+                                                      jint count_B,
+                                                      jboolean batch)
 {
-    TRACE("getB0ByPK()");
-    ops->getByPK(ops->meta->table_B0, 1, count_B, batch == JNI_TRUE);
+    TRACE("getB0ByPK_ar()");
+    ops->getByPK_ar(ops->meta->table_B0, 1, count_B, batch == JNI_TRUE);
 }
 
 JNIEXPORT void JNICALL


Attachment: [text/bzr-bundle] bzr/martin.zaun@oracle.com-20101001041021-jquwli36md5rkvmw.bundle
Thread
bzr commit into mysql-5.1-telco-7.1 branch (martin.zaun:3849) Martin Zaun1 Oct