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

 3860 Martin Zaun	2010-10-05
      crund - refactorization for code copying/sharing with TWS benchmark

    removed:
      storage/ndb/test/crund/src/com/mysql/cluster/crund/JdoLoad.java
    added:
      storage/ndb/test/crund/src/com/mysql/cluster/crund/CrundDriver.java
      storage/ndb/test/crund/src/crundndb/CrundDriver.cpp
      storage/ndb/test/crund/src/crundndb/CrundDriver.hpp
      storage/ndb/test/crund/src/crundndb/Driver.hpp
      storage/ndb/test/crund/src/crundndb/NdbApiDriver.cpp
      storage/ndb/test/crund/src/crundndb/NdbApiDriver.hpp
    renamed:
      storage/ndb/test/crund/src/crundndb/Operations.cpp => storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.cpp
      storage/ndb/test/crund/src/crundndb/Operations.hpp => storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.hpp
    modified:
      .bzrignore
      storage/ndb/test/crund/build.xml
      storage/ndb/test/crund/config_samples/env.properties
      storage/ndb/test/crund/martins_little_helpers/src/utils/string_helpers.hpp
      storage/ndb/test/crund/src/com/mysql/cluster/crund/A.java
      storage/ndb/test/crund/src/com/mysql/cluster/crund/ClusterjLoad.java
      storage/ndb/test/crund/src/com/mysql/cluster/crund/Driver.java
      storage/ndb/test/crund/src/com/mysql/cluster/crund/JdbcLoad.java
      storage/ndb/test/crund/src/com/mysql/cluster/crund/JpaLoad.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/com/mysql/cluster/crund/NdbjLoad.java
      storage/ndb/test/crund/src/crundndb/Driver.cpp
      storage/ndb/test/crund/src/crundndb/Makefile
      storage/ndb/test/crund/src/crundndb/com_mysql_cluster_crund_NdbApiLoad.cpp
      storage/ndb/test/crund/tws_benchmark/src/Main.java
      storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.cpp
      storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.hpp
=== modified file '.bzrignore'
--- a/.bzrignore	2010-09-29 10:02:15 +0000
+++ b/.bzrignore	2010-10-05 08:48:30 +0000
@@ -3124,7 +3124,7 @@ storage/ndb/test/crund/*.properties
 storage/ndb/test/crund/build/
 storage/ndb/test/crund/javadoc/
 storage/ndb/test/crund/lib/
-storage/ndb/test/crund/log*
+storage/ndb/test/crund/**/log*
 storage/ndb/test/crund/martins_little_helpers/src/utils/Properties_test
 storage/ndb/test/crund/martins_little_helpers/src/utils/hrt_stopwatch_test
 storage/ndb/test/crund/martins_little_helpers/src/utils/hrt_utils_test
@@ -3132,7 +3132,7 @@ storage/ndb/test/crund/martins_little_he
 storage/ndb/test/crund/martins_little_helpers/src/utils/utils_JniInstrumentationTest.h
 storage/ndb/test/crund/scripts/ndblog
 storage/ndb/test/crund/scripts/results
-storage/ndb/test/crund/src/crundndb/Driver
+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/

=== modified file 'storage/ndb/test/crund/build.xml'
--- a/storage/ndb/test/crund/build.xml	2010-10-01 08:58:08 +0000
+++ b/storage/ndb/test/crund/build.xml	2010-10-05 08:48:30 +0000
@@ -288,13 +288,13 @@
        # Driver
        ################################################################# -->
 
-  <!-- compiles the benchmark driver -->
+  <!-- compiles the benchmark drivers -->
   <target name="compile.driver" depends="set.compile,init">
     <javac srcdir="${src.java}" destdir="${build}" debug="${debug}"
-	   includes="com/mysql/cluster/crund/Driver.java"/>
+	   includes="com/mysql/cluster/crund/*Driver.java"/>
   </target>
 
-  <!-- compiles the benchmark driver with optimizations -->
+  <!-- compiles the benchmark drivers with optimizations -->
   <target name="compile.driver.opt" depends="set.compile.opt,compile.driver"/>
 
   <!-- #################################################################
@@ -881,7 +881,7 @@
     <taskdef name="openjpac"
     classname="org.apache.openjpa.ant.PCEnhancerTask"/>
 
-    <- invoke enhancer on all .jdo files below the current directory ->
+    <- invoke enhancer on all .java files below the current directory ->
     <openjpac>
       <fileset dir=".">
         <include name="**/model/*.java" />

=== modified file 'storage/ndb/test/crund/config_samples/env.properties'
--- a/storage/ndb/test/crund/config_samples/env.properties	2010-10-01 04:10:21 +0000
+++ b/storage/ndb/test/crund/config_samples/env.properties	2010-10-05 08:48:30 +0000
@@ -197,26 +197,6 @@ COMMONS_POOL_JAR=${HOME}/mysql/lib/commo
 # The Following are Obsolete:
 # ----------------------------------------------------------------------
 
-#
-# The JDO API Jar File
-#
-
-# Must be set & valid when building/running
-# - ClusterjLoad (annotation processing)
-
-JDO_API_JAR=${HOME}/mysql/lib/jdo2-api-2.1.1.jar
-
-# Comments:
-# - get from here:
-#   http://db.apache.org/jdo/releases/release-2.1.1.cgi
-# (- merged the jdo2-api-..., jdo2-model-... jar files all into one?)
-
-#
-# The NDB/J (ndb-bindings) Jar and Library Paths
-#
-
-# ----------------------------------------------------------------------
-
 # Must be set & valid when building/running
 # - NdbjLoad
 # - ClusterjLoad

=== 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-10-01 04:10:21 +0000
+++ b/storage/ndb/test/crund/martins_little_helpers/src/utils/string_helpers.hpp	2010-10-05 08:48:30 +0000
@@ -35,7 +35,7 @@ using std::set;
  * "true"; otherwise, false.
  */
 inline bool
-toBool(const wstring& ws)
+toBool(const wstring& ws, bool vdefault)
 {
     // can't get manipulators to compile
     //bool r;
@@ -52,12 +52,18 @@ toBool(const wstring& ws)
     //std::transform(ws.begin(), ws.end(), t.begin(),
     //               static_cast< int (*)(int) >(std::tolower));
 
-    // short & simple
-    return  ((ws.length() == 4)
-             && (ws[0] == L'T' || ws[0] == L't')
-             && (ws[1] == L'R' || ws[1] == L'r')
-             && (ws[2] == L'U' || ws[2] == L'u')
-             && (ws[3] == L'E' || ws[3] == L'e'));
+    bool val;
+    if (ws.length() == 0) {
+        val = vdefault;
+    } else {
+        // short & simple
+        val = ((ws.length() == 4)
+               && (ws[0] == L'T' || ws[0] == L't')
+               && (ws[1] == L'R' || ws[1] == L'r')
+               && (ws[2] == L'U' || ws[2] == L'u')
+               && (ws[3] == L'E' || ws[3] == L'e'));
+    }
+    return val;
 }
 
 /**

=== modified file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/A.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/A.java	2010-02-14 05:05:31 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/A.java	2010-10-05 08:48:30 +0000
@@ -101,7 +101,7 @@ public class A implements Serializable {
 
     // while implementing Serializable...
     static private final long serialVersionUID = -3359921162347129079L;
-     
+
     // while implementing Serializable...
     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
         in.defaultReadObject();

=== modified file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/ClusterjLoad.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/ClusterjLoad.java	2010-09-27 05:31:17 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/ClusterjLoad.java	2010-10-05 08:48:30 +0000
@@ -39,45 +39,59 @@ import java.util.Set;
 /**
  * A benchmark implementation against a ClusterJ database.
  */
-public class ClusterjLoad extends Driver {
+public class ClusterjLoad extends CrundDriver {
+
+    // ----------------------------------------------------------------------
+    // ClusterJ resources
+    // ----------------------------------------------------------------------
 
-    // ClusterJ connection
     protected String mgmdConnect;
     protected SessionFactory sessionFactory;
     protected Session session;
 
-    protected abstract class ClusterjOp extends Op {
-        public ClusterjOp(String name) {
-            super(name);
-        }
-
-        public void init() {}
-
-        public void close() {}
-    };
+    // ----------------------------------------------------------------------
+    // ClusterJ intializers/finalizers
+    // ----------------------------------------------------------------------
 
     @Override
     protected void initProperties() {
         super.initProperties();
 
+        out.print("setting clusterj properties ...");
+
+        final StringBuilder msg = new StringBuilder();
+        final String eol = System.getProperty("line.separator");
+
         // check required properties
         mgmdConnect
             = props.getProperty(Constants.PROPERTY_CLUSTER_CONNECTSTRING);
-        descr = "->ClusterJ->NDB JTie->NDBAPI(" + mgmdConnect + ")";
+
+        if (msg.length() == 0) {
+            out.println(" [ok]");
+        } else {
+            out.println();
+            out.print(msg.toString());
+        }
+
+        // have mgmdConnect initialized first
+        descr = "->clusterj(" + mgmdConnect + ")";
     }
 
     @Override
     protected void printProperties() {
         super.printProperties();
-        out.println("ndb.mgmdConnect             " + mgmdConnect);
+
+        out.println();
+        out.println("clusterj settings ...");
+        out.println("ndb.mgmdConnect                 " + mgmdConnect);
         for (Iterator<Map.Entry<Object,Object>> i
                  = props.entrySet().iterator(); i.hasNext();) {
             Map.Entry<Object,Object> e = i.next();
             final String k = (String)e.getKey();
             if (k.startsWith("com.mysql.clusterj")) {
                 final StringBuilder s = new StringBuilder("..");
-                s.append(k, 10, k.length());
-                while (s.length() < 27) s.append(' ');
+                s.append(k, 18, k.length());
+                while (s.length() < 31) s.append(' ');
                 out.println(s + " " + e.getValue());
             }
         }
@@ -86,6 +100,7 @@ public class ClusterjLoad extends Driver
     @Override
     protected void init() throws Exception {
         super.init();
+
         // load native library (better diagnostics doing it explicitely)
         out.println();
         //loadSystemLibrary("ndbj");
@@ -96,7 +111,7 @@ public class ClusterjLoad extends Driver
         out.print("creating SessionFactory ...");
         out.flush();
         sessionFactory = ClusterJHelper.getSessionFactory(props);
-        out.println(" [SessionFactory: 1]");
+        out.println("     [SessionFactory: 1]");
     }
 
     @Override
@@ -106,25 +121,24 @@ public class ClusterjLoad extends Driver
         if (sessionFactory != null)
             sessionFactory.close();
         sessionFactory = null;
-        out.println("  [ok]");
+        out.println("      [ok]");
+
         super.close();
     }
 
-    protected void initConnection() {
-        out.print("creating Session ...");
-        out.flush();
-        session = sessionFactory.getSession();
-        out.println("        [Session: 1]");
-    }
+    // ----------------------------------------------------------------------
+    // ClusterJ operations
+    // ----------------------------------------------------------------------
 
-    protected void closeConnection() {
-        out.print("closing Session ...");
-        out.flush();
-        if (session != null)
-            session.close();
-        session = null;
-        out.println("         [ok]");
-    }
+    protected abstract class ClusterjOp extends Op {
+        public ClusterjOp(String name) {
+            super(name);
+        }
+
+        public void init() {}
+
+        public void close() {}
+    };
 
     protected int checkFields(IA o) {
         final int cint = o.getCint();
@@ -155,18 +169,21 @@ public class ClusterjLoad extends Driver
         ops.add(
             new ClusterjOp("insA") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countA; i++) {
                         final IA o = session.newInstance(IA.class);
                         assert o != null;
                         o.setId(i);
                         session.persist(o);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new ClusterjOp("insB0") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         final IB0 o = session.newInstance(IB0.class);
                         assert o != null;
@@ -174,12 +191,14 @@ public class ClusterjLoad extends Driver
                         o.setCvarbinary_def(null);
                         session.persist(o);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new ClusterjOp("setAByPK") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countA; i++) {
                         // blind update
                         final IA o = session.newInstance(IA.class);
@@ -191,12 +210,14 @@ public class ClusterjLoad extends Driver
                         o.setCdouble((double)i);
                         session.updatePersistent(o);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new ClusterjOp("setB0ByPK") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         // blind update
                         final IB0 o = session.newInstance(IB0.class);
@@ -208,12 +229,14 @@ public class ClusterjLoad extends Driver
                         o.setCdouble((double)i);
                         session.updatePersistent(o);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new ClusterjOp("getAByPK") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countA; i++) {
                         final IA o = session.find(IA.class, i);
                         assert o != null;
@@ -222,12 +245,14 @@ public class ClusterjLoad extends Driver
                         final int j = checkFields(o);
                         verify(j == id);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new ClusterjOp("getB0ByPK") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         final IB0 o = session.find(IB0.class, i);
                         assert o != null;
@@ -236,6 +261,7 @@ public class ClusterjLoad extends Driver
                         final int j = checkFields(o);
                         verify(j == id);
                     }
+                    commitTransaction();
                 }
             });
 
@@ -246,6 +272,7 @@ public class ClusterjLoad extends Driver
             ops.add(
                 new ClusterjOp("setVarbinary" + l) {
                     public void run(int countA, int countB) {
+                        beginTransaction();
                         for (int i = 0; i < countB; i++) {
                             // blind update
                             final IB0 o = session.newInstance(IB0.class);
@@ -254,23 +281,27 @@ public class ClusterjLoad extends Driver
                             o.setCvarbinary_def(b);
                             session.updatePersistent(o);
                         }
+                        commitTransaction();
                     }
                 });
 
             ops.add(
                 new ClusterjOp("getVarbinary" + l) {
                     public void run(int countA, int countB) {
+                        beginTransaction();
                         for (int i = 0; i < countB; i++) {
                             final IB0 o = session.find(IB0.class, i);
                             assert o != null;
                             verify(Arrays.equals(b, o.getCvarbinary_def()));
                         }
+                        commitTransaction();
                     }
                 });
 
             ops.add(
                 new ClusterjOp("clearVarbinary" + l) {
                     public void run(int countA, int countB) {
+                        beginTransaction();
                         for (int i = 0; i < countB; i++) {
                             // blind update
                             final IB0 o = session.newInstance(IB0.class);
@@ -279,10 +310,11 @@ public class ClusterjLoad extends Driver
                             o.setCvarbinary_def(null);
                             session.updatePersistent(o);
                         }
+                        commitTransaction();
                     }
                 });
-        }        
-        
+        }
+
         for (int i = 0, l = 1; l <= maxVarcharChars; l *= 10, i++) {
             final String s = strings[i];
             assert l == s.length();
@@ -290,6 +322,7 @@ public class ClusterjLoad extends Driver
             ops.add(
                 new ClusterjOp("setVarchar" + l) {
                     public void run(int countA, int countB) {
+                        beginTransaction();
                         for (int i = 0; i < countB; i++) {
                             // blind update
                             final IB0 o = session.newInstance(IB0.class);
@@ -298,23 +331,27 @@ public class ClusterjLoad extends Driver
                             o.setCvarchar_def(s);
                             session.updatePersistent(o);
                         }
+                        commitTransaction();
                     }
                 });
 
             ops.add(
                 new ClusterjOp("getVarchar" + l) {
                     public void run(int countA, int countB) {
+                        beginTransaction();
                         for (int i = 0; i < countB; i++) {
                             final IB0 o = session.find(IB0.class, i);
                             assert o != null;
                             verify(s.equals(o.getCvarchar_def()));
                         }
+                        commitTransaction();
                     }
                 });
 
             ops.add(
                 new ClusterjOp("clearVarchar" + l) {
                     public void run(int countA, int countB) {
+                        beginTransaction();
                         for (int i = 0; i < countB; i++) {
                             // blind update
                             final IB0 o = session.newInstance(IB0.class);
@@ -323,13 +360,15 @@ public class ClusterjLoad extends Driver
                             o.setCvarchar_def(null);
                             session.updatePersistent(o);
                         }
+                        commitTransaction();
                     }
                 });
         }
-        
+
         ops.add(
             new ClusterjOp("setB0->A") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         // blind update
                         final IB0 b0 = session.newInstance(IB0.class);
@@ -339,12 +378,14 @@ public class ClusterjLoad extends Driver
                         b0.setAid(aId);
                         session.updatePersistent(b0);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new ClusterjOp("navB0->A") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         final IB0 b0 = session.find(IB0.class, i);
                         assert b0 != null;
@@ -356,6 +397,7 @@ public class ClusterjLoad extends Driver
                         final int j = checkFields(a);
                         verify(j == id);
                     }
+                    commitTransaction();
                 }
             });
 
@@ -373,6 +415,7 @@ public class ClusterjLoad extends Driver
                 }
 
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     // QueryBuilder is the sessionFactory for queries
                     final QueryBuilder builder
                         = session.getQueryBuilder();
@@ -399,12 +442,14 @@ public class ClusterjLoad extends Driver
                             verify(j == id);
                         }
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new ClusterjOp("nullB0->A") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         // blind update
                         final IB0 b0 = session.newInstance(IB0.class);
@@ -412,12 +457,14 @@ public class ClusterjLoad extends Driver
                         assert b0 != null;
                         b0.setAid(0);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new ClusterjOp("delB0ByPK") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         // blind delete
                         final IB0 o = session.newInstance(IB0.class);
@@ -425,12 +472,14 @@ public class ClusterjLoad extends Driver
                         o.setId(i);
                         session.remove(o);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new ClusterjOp("delAByPK") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countA; i++) {
                         // blind delete
                         final IA o = session.newInstance(IA.class);
@@ -438,12 +487,14 @@ public class ClusterjLoad extends Driver
                         o.setId(i);
                         session.remove(o);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new ClusterjOp("insA_attr") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countA; i++) {
                         final IA o = session.newInstance(IA.class);
                         assert o != null;
@@ -454,12 +505,14 @@ public class ClusterjLoad extends Driver
                         o.setCdouble((double)-i);
                         session.persist(o);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new ClusterjOp("insB0_attr") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         final IB0 o = session.newInstance(IB0.class);
                         assert o != null;
@@ -471,31 +524,36 @@ public class ClusterjLoad extends Driver
                         o.setCvarbinary_def(null);
                         session.persist(o);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new ClusterjOp("delAllB0") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     int del = session.deletePersistentAll(IB0.class);
                     assert del == countB;
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new ClusterjOp("delAllA") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     int del = session.deletePersistentAll(IA.class);
                     assert del == countA;
+                    commitTransaction();
                 }
             });
 
         // prepare queries
-        for (Iterator<Driver.Op> i = ops.iterator(); i.hasNext();) {
+        for (Iterator<CrundDriver.Op> i = ops.iterator(); i.hasNext();) {
             ((ClusterjOp)i.next()).init();
         }
 
-        out.println(" [ClusterjOp: " + ops.size() + "]");
+        out.println("     [ClusterjOp: " + ops.size() + "]");
     }
 
     protected void closeOperations() {
@@ -503,12 +561,12 @@ public class ClusterjLoad extends Driver
         out.flush();
 
         // close all queries
-        for (Iterator<Driver.Op> i = ops.iterator(); i.hasNext();) {
+        for (Iterator<CrundDriver.Op> i = ops.iterator(); i.hasNext();) {
             ((ClusterjOp)i.next()).close();
         }
         ops.clear();
 
-        out.println("      [ok]");
+        out.println("          [ok]");
     }
 
     protected void beginTransaction() {
@@ -519,8 +577,24 @@ public class ClusterjLoad extends Driver
         session.currentTransaction().commit();
     }
 
-    protected void rollbackTransaction() {
-        session.currentTransaction().rollback();
+    // ----------------------------------------------------------------------
+    // ClusterJ datastore operations
+    // ----------------------------------------------------------------------
+
+    protected void initConnection() {
+        out.print("creating Session ...");
+        out.flush();
+        session = sessionFactory.getSession();
+        out.println("            [Session: 1]");
+    }
+
+    protected void closeConnection() {
+        out.print("closing Session ...");
+        out.flush();
+        if (session != null)
+            session.close();
+        session = null;
+        out.println("             [ok]");
     }
 
     protected void clearPersistenceContext() {
@@ -533,7 +607,7 @@ public class ClusterjLoad extends Driver
 
         session.currentTransaction().begin();
         int delB0 = session.deletePersistentAll(IB0.class);
-        out.print("    [B0: " + delB0);
+        out.print("        [B0: " + delB0);
         out.flush();
         int delA = session.deletePersistentAll(IA.class);
         out.print(", A: " + delA);

=== added file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/CrundDriver.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/CrundDriver.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/CrundDriver.java	2010-10-05 08:48:30 +0000
@@ -0,0 +1,390 @@
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
+ *
+ *  Copyright (C) 2008 MySQL
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+package com.mysql.cluster.crund;
+
+import java.util.Properties;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.ArrayList;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.InputStream;
+
+
+/**
+ * This class benchmarks standard database operations over a series
+ * of transactions on an increasing data set.
+ * <p>
+ * The abstract database operations are variations of: Create,
+ * Read, Update, Navigate, and Delete -- hence, the benchmark's name: CRUND.
+ * <p>
+ * The actual operations are defined by subclasses to allow measuring the
+ * operation performance across different datastore implementations.
+ *
+ * @see <a href="http://www.urbandictionary.com/define.php?term=crund">Urban Dictionary: crund</a>
+ * <ol>
+ * <li> used to debase people who torture others with their illogical
+ * attempts to make people laugh;
+ * <li> reference to cracking obsolete jokes;
+ * <li> a dance form;
+ * <li> to hit hard or smash.
+ * </ol>
+ */
+abstract public class CrundDriver extends Driver {
+
+    // benchmark settings
+    protected boolean renewOperations;
+    protected boolean logSumOfOps;
+    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 final Set<String> exclude = new HashSet<String>();
+
+    // ----------------------------------------------------------------------
+    // benchmark intializers/finalizers
+    // ----------------------------------------------------------------------
+
+    protected void initProperties() {
+        super.initProperties();
+
+        out.print("setting crund properties ...");
+
+        final StringBuilder msg = new StringBuilder();
+        final String eol = System.getProperty("line.separator");
+
+        renewOperations = parseBoolean("renewOperations", false);
+        logSumOfOps = parseBoolean("logSumOfOps", true);
+        allowExtendedPC = parseBoolean("allowExtendedPC", false);
+
+        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);
+        if (maxVarbinaryBytes < 0) {
+            msg.append("[ignored] maxVarbinaryBytes:    "
+                       + maxVarbinaryBytes + eol);
+            maxVarbinaryBytes = 100;
+        }
+        maxVarcharChars = parseInt("maxVarcharChars", 100);
+        if (maxVarcharChars < 0) {
+            msg.append("[ignored] maxVarcharChars:      "
+                       + maxVarcharChars + eol);
+            maxVarcharChars = 100;
+        }
+
+        maxBlobBytes = parseInt("maxBlobBytes", 1000);
+        if (maxBlobBytes < 0) {
+            msg.append("[ignored] maxBlobBytes:         "
+                       + maxBlobBytes + eol);
+            maxBlobBytes = 1000;
+        }
+        maxTextChars = parseInt("maxTextChars", 1000);
+        if (maxTextChars < 0) {
+            msg.append("[ignored] maxTextChars:         "
+                       + maxTextChars + eol);
+            maxTextChars = 1000;
+        }
+
+        // initialize exclude set
+        final String[] e = props.getProperty("exclude", "").split(",");
+        for (int i = 0; i < e.length; i++) {
+            exclude.add(e[i]);
+        }
+
+        if (msg.length() == 0) {
+            out.println("    [ok: "
+                        + "A=" + aStart + ".." + aEnd
+                        + ", B=" + bStart + ".." + bEnd + "]");
+        } else {
+            out.println();
+            out.print(msg.toString());
+        }
+    }
+
+    protected void printProperties() {
+        super.printProperties();
+
+        out.println();
+        out.println("crund settings ...");
+        out.println("renewOperations:                " + renewOperations);
+        out.println("logSumOfOps:                    " + logSumOfOps);
+        out.println("allowExtendedPC:                " + allowExtendedPC);
+        out.println("aStart:                         " + aStart);
+        out.println("bStart:                         " + bStart);
+        out.println("aEnd:                           " + aEnd);
+        out.println("bEnd:                           " + bEnd);
+        out.println("aScale:                         " + aScale);
+        out.println("bScale:                         " + bScale);
+        out.println("maxVarbinaryBytes:              " + maxVarbinaryBytes);
+        out.println("maxVarcharChars:                " + maxVarcharChars);
+        out.println("maxBlobBytes:                   " + maxBlobBytes);
+        out.println("maxTextChars:                   " + maxTextChars);
+        out.println("exclude:                        " + exclude);
+    }
+
+    // ----------------------------------------------------------------------
+    // benchmark operations
+    // ----------------------------------------------------------------------
+
+    // a database operation to be benchmarked
+    protected abstract class Op {
+        final protected String name;
+
+        public Op(String name) { this.name = name; }
+
+        public String getName() { return name; }
+
+        public abstract void run(int countA, int countB) throws Exception;
+    };
+
+    // the list of database operations to be benchmarked
+    protected final List<Op> ops = new ArrayList<Op>();
+
+    // manages list of database operations
+    abstract protected void initOperations() throws Exception;
+    abstract protected void closeOperations() throws Exception;
+
+    protected void runTests() throws Exception {
+        initConnection();
+        initOperations();
+
+        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) {
+                    // already in rollback for database/orm exceptions
+                    throw ex;
+                }
+            }
+        }
+
+        out.println();
+        out.println("------------------------------------------------------------");
+        out.println();
+
+        clearData();
+        closeOperations();
+        closeConnection();
+    }
+
+    protected void runOperations(int countA, int countB) throws Exception {
+        out.println();
+        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) {
+            rtimes.append("A=" + countA + ", B=" + countB);
+            ta = 0;
+        }
+        if (logMemUsage) {
+            musage.append("A=" + countA + ", B=" + countB);
+            ma = 0;
+        }
+
+        // pre-run cleanup
+        if (renewConnection) {
+            closeOperations();
+            closeConnection();
+            initConnection();
+            initOperations();
+        } else if (renewOperations) {
+            closeOperations();
+            initOperations();
+        }
+        clearData();
+
+        // run operations
+        for (Op op : ops) {
+            // pre-tx cleanup
+            if (!allowExtendedPC) {
+                // effectively prevent caching beyond Tx scope by clearing
+                // any data/result caches before the next transaction
+                clearPersistenceContext();
+            }
+            runOp(op, countA, countB);
+        }
+        if (logHeader) {
+            if (logSumOfOps)
+                header.append("\ttotal");
+        }
+
+        if (logSumOfOps) {
+            out.println();
+            out.println("total");
+            if (logRealTime) {
+                out.println("tx real time                    " + ta
+                            + "\tms");
+            }
+            if (logMemUsage) {
+                out.println("net mem usage                   "
+                            + (ma >= 0 ? "+" : "") + ma
+                            + "\tKiB");
+            }
+        }
+
+        // log buffers
+        logHeader = false;
+        if (logRealTime) {
+            rtimes.append(endl);
+            if (logSumOfOps) {
+                rtimes.append("\t" + ta);
+            }
+        }
+        if (logMemUsage) {
+            if (logSumOfOps) {
+                musage.append("\t" + ma);
+            }
+            musage.append(endl);
+        }
+    }
+
+    protected void runOp(Op op, int countA, int countB) throws Exception {
+        final String name = op.getName();
+        if (!exclude.contains(name)) {
+            begin(name);
+            op.run(countA, countB);
+            commit(name);
+        }
+    }
+
+    // reports an error if a condition is not met
+    static protected final void verify(boolean cond) {
+        //assert (cond);
+        if (!cond)
+            throw new RuntimeException("wrong data; verification failed");
+    }
+
+    // ----------------------------------------------------------------------
+    // helpers
+    // ----------------------------------------------------------------------
+
+    static final protected String myString(int n) {
+        final StringBuilder s = new StringBuilder();
+        switch (n) {
+        case 1:
+            s.append('i');
+            break;
+        case 2:
+            for (int i = 0; i < 10; i++) s.append('x');
+            break;
+        case 3:
+            for (int i = 0; i < 100; i++) s.append('c');
+            break;
+        case 4:
+            for (int i = 0; i < 1000; i++) s.append('m');
+            break;
+        case 5:
+            for (int i = 0; i < 10000; i++) s.append('X');
+            break;
+        case 6:
+            for (int i = 0; i < 100000; i++) s.append('C');
+            break;
+        case 7:
+            for (int i = 0; i < 1000000; i++) s.append('M');
+            break;
+        default:
+            throw new IllegalArgumentException("unsupported 10**n = " + n);
+        }
+        return s.toString();
+    }
+
+    static final protected byte[] myBytes(String s) {
+        final char[] c = s.toCharArray();
+        final int n = c.length;
+        final byte[] b = new byte[n];
+        for (int i = 0; i < n; i++) b[i] = (byte)c[i];
+        return b;
+    }
+
+    // some string and byte constants
+    static final protected String string1 = myString(1);
+    static final protected String string2 = myString(2);
+    static final protected String string3 = myString(3);
+    static final protected String string4 = myString(4);
+    static final protected String string5 = myString(5);
+    static final protected String string6 = myString(6);
+    static final protected String string7 = myString(7);
+    static final protected byte[] bytes1 = myBytes(string1);
+    static final protected byte[] bytes2 = myBytes(string2);
+    static final protected byte[] bytes3 = myBytes(string3);
+    static final protected byte[] bytes4 = myBytes(string4);
+    static final protected byte[] bytes5 = myBytes(string5);
+    static final protected byte[] bytes6 = myBytes(string6);
+    static final protected byte[] bytes7 = myBytes(string7);
+    static final protected String[] strings
+        = { string1, string2, string3, string4, string5, string6, string7 };
+    static final protected byte[][] bytes
+        = { bytes1, bytes2, bytes3, bytes4, bytes5, bytes6, bytes7 };
+}

=== 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-10-01 04:10:21 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/Driver.java	2010-10-05 08:48:30 +0000
@@ -22,8 +22,6 @@ package com.mysql.cluster.crund;
 
 import java.util.Properties;
 import java.util.List;
-import java.util.Set;
-import java.util.HashSet;
 import java.util.ArrayList;
 import java.util.Date;
 import java.text.SimpleDateFormat;
@@ -56,209 +54,94 @@ import java.io.InputStream;
  */
 abstract public class Driver {
 
-    /**
-     *  The stream to write messages to.
-     */
+    // console
     static protected final PrintWriter out = new PrintWriter(System.out, true);
-
-    /**
-     *  The stream to write error messages to.
-     */
     static protected final PrintWriter err = new PrintWriter(System.err, true);
 
-    /**
-     *  Shortcut to the end-of-line character sequence.
-     */
+    // shortcuts
     static protected final String endl = System.getProperty("line.separator");
+    static protected final Runtime rt = Runtime.getRuntime();
 
-    /**
-     *  Shortcut to the Runtime.
-     */
-    static private final Runtime rt = Runtime.getRuntime();
-
-    // command-line arguments
+    // driver command-line arguments
     static private final List<String> propFileNames = new ArrayList<String>();
-    static private String logFileName
-        = ("log_"
-           + new SimpleDateFormat("yyyyMMdd_HHMMss").format(new Date())
-           + ".txt");
-
-    // the data output writer
-    private PrintWriter log;
+    static private String logFileName;
 
-    // benchmark settings
+    // driver settings
     protected final Properties props = new Properties();
-    protected String descr = "";
     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>();
 
-    // ----------------------------------------------------------------------
+    // driver resources
+    protected PrintWriter log;
+    protected String descr = "";
+    protected boolean logHeader;
+    protected StringBuilder header;
+    protected StringBuilder rtimes;
+    protected StringBuilder musage;
+    protected long t0 = 0, t1 = 0, ta = 0;
+    protected long m0 = 0, m1 = 0, ma = 0;
 
-    static final protected String myString(int n) {
-        final StringBuilder s = new StringBuilder();
-        switch (n) {
-        case 1:
-            s.append('i');
-            break;
-        case 2:
-            for (int i = 0; i < 10; i++) s.append('x');
-            break;
-        case 3:
-            for (int i = 0; i < 100; i++) s.append('c');
-            break;
-        case 4:
-            for (int i = 0; i < 1000; i++) s.append('m');
-            break;
-        case 5:
-            for (int i = 0; i < 10000; i++) s.append('X');
-            break;
-        case 6:
-            for (int i = 0; i < 100000; i++) s.append('C');
-            break;
-        case 7:
-            for (int i = 0; i < 1000000; i++) s.append('M');
-            break;
-        default:
-            throw new IllegalArgumentException("unsupported 10**n = " + n);
-        }
-        return s.toString();
-    }
-    
-    static final protected byte[] myBytes(String s) {
-        final char[] c = s.toCharArray();
-        final int n = c.length;
-        final byte[] b = new byte[n];
-        for (int i = 0; i < n; i++) b[i] = (byte)c[i];
-        return b;
-    }
-    
-    // some string and byte constants
-    static final protected String string1 = myString(1);
-    static final protected String string2 = myString(2);
-    static final protected String string3 = myString(3);
-    static final protected String string4 = myString(4);
-    static final protected String string5 = myString(5);
-    static final protected String string6 = myString(6);
-    static final protected String string7 = myString(7);
-    static final protected byte[] bytes1 = myBytes(string1);
-    static final protected byte[] bytes2 = myBytes(string2);
-    static final protected byte[] bytes3 = myBytes(string3);
-    static final protected byte[] bytes4 = myBytes(string4);
-    static final protected byte[] bytes5 = myBytes(string5);
-    static final protected byte[] bytes6 = myBytes(string6);
-    static final protected byte[] bytes7 = myBytes(string7);
-    static final protected String[] strings
-        = { string1, string2, string3, string4, string5, string6, string7 };
-    static final protected byte[][] bytes
-        = { bytes1, bytes2, bytes3, bytes4, bytes5, bytes6, bytes7 };
-    
+    // ----------------------------------------------------------------------
+    // driver usage
     // ----------------------------------------------------------------------
 
     /**
-     * A database operation to be benchmarked.
+     * Prints a command-line usage message and exits.
      */
-    protected abstract class Op {
-        final protected String name;
-
-        public Op(String name) {
-            this.name = name;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public abstract void run(int countA, int countB) throws Exception;
-    };
+    static protected void exitUsage() {
+        out.println("usage: [options]");
+        out.println("    [-p <file name>]...    a properties file name");
+        out.println("    [-l <file name>]       log file name for data output");
+        out.println("    [-h|--help]            print usage message and exit");
+        out.println();
+        System.exit(1); // return an error code
+    }
 
     /**
-     * The list of database operations to be benchmarked.
-     * While the list instance is final, its content is managed by methods
-     * initOperations() and closeOperations() as defined by subclasses.
+     * Parses the benchmark's command-line arguments.
      */
-    protected final List<Op> ops = new ArrayList<Op>();
-
-    // buffers collecting the header and data lines written to log
-    boolean logHeader;
-    private StringBuilder header;
-    private StringBuilder rtimes;
-    private StringBuilder musage;
-
-    // benchmark data fields
-    private long t0 = 0, t1 = 0, ta = 0;
-    private long m0 = 0, m1 = 0, ma = 0;
+    static public void parseArguments(String[] args) {
+        for (int i = 0; i < args.length; i++) {
+            final String arg = args[i];
+            if (arg.equals("-p")) {
+                if (i >= args.length) {
+                    exitUsage();
+                }
+                propFileNames.add(args[++i]);
+            } else if (arg.equals("-l")) {
+                if (i >= args.length) {
+                    exitUsage();
+                }
+                logFileName = args[++i];
+            } else if (arg.equals("-h") || arg.equals("--help")) {
+                exitUsage();
+            } else {
+                out.println("unknown option: " + arg);
+                exitUsage();
+            }
+        }
 
-    // benchmark methods to be defined by subclasses
-    abstract protected void initConnection() throws Exception;
-    abstract protected void closeConnection() throws Exception;
-    abstract protected void initOperations() throws Exception;
-    abstract protected void closeOperations() throws Exception;
-    abstract protected void clearPersistenceContext() throws Exception;
-    abstract protected void clearData() throws Exception;
-    abstract protected void beginTransaction() throws Exception;
-    abstract protected void commitTransaction() throws Exception;
-    abstract protected void rollbackTransaction() throws Exception;
+        if (propFileNames.size() == 0) {
+            propFileNames.add("run.properties");
+        }
 
-    /**
-     * Reports an error if a condition is not met.
-     *
-     * An invariant method to ensure the consistent application
-     * of verifying read results.
-     */
-    static protected final void verify(boolean cond) {
-        //assert (cond);
-        if (!cond)
-            throw new RuntimeException("wrong data; verification failed");
+        if (logFileName == null) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHMMss");
+            logFileName = ("log_" + sdf.format(new Date()) + ".txt");
+        }
     }
 
     /**
-     * Loads a dynamically linked system library and reports any failures.
+     * Creates an instance.
      */
-    static protected void loadSystemLibrary(String name) {
-        out.print("loading libary ...");
-        out.flush();
-        try {
-            System.loadLibrary(name);
-        } catch (UnsatisfiedLinkError e) {
-            String path;
-            try {
-                path = System.getProperty("java.library.path");
-            } catch (Exception ex) {
-                path = "<exception caught: " + ex.getMessage() + ">";
-            }
-            err.println("NdbBase: failed loading library '"
-                        + name + "'; java.library.path='" + path + "'");
-            throw e;
-        } catch (SecurityException e) {
-            err.println("NdbBase: failed loading library '"
-                        + name + "'; caught exception: " + e);
-            throw e;
-        }
-        out.println("          [" + name + "]");
-    }
-
-    // ----------------------------------------------------------------------
+    public Driver() {}
 
     /**
-     * Runs the entire benchmark.
+     * Runs the benchmark.
      */
     public void run() {
         try {
@@ -268,7 +151,7 @@ abstract public class Driver {
             for (int i = 0; i < warmupRuns; i++) {
                 runTests();
             }
-            
+
             // truncate log file, reset log buffers
             out.println();
             out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
@@ -286,7 +169,7 @@ abstract public class Driver {
             for (int i = 0; i < hotRuns; i++) {
                 runTests();
             }
-            
+
             // write log buffers
             if (logRealTime) {
                 log.println(descr + ", rtime[ms]"
@@ -308,27 +191,72 @@ abstract public class Driver {
         }
     }
 
-    /**
-     * Initializes the benchmark's resources.
-     */
+    // ----------------------------------------------------------------------
+    // driver intializers/finalizers
+    // ----------------------------------------------------------------------
+
+    // loads a dynamically linked system library and reports any failures
+    static protected void loadSystemLibrary(String name) {
+        out.print("loading libary ...");
+        out.flush();
+        try {
+            System.loadLibrary(name);
+        } catch (UnsatisfiedLinkError e) {
+            String path;
+            try {
+                path = System.getProperty("java.library.path");
+            } catch (Exception ex) {
+                path = "<exception caught: " + ex.getMessage() + ">";
+            }
+            err.println("NdbBase: failed loading library '"
+                        + name + "'; java.library.path='" + path + "'");
+            throw e;
+        } catch (SecurityException e) {
+            err.println("NdbBase: failed loading library '"
+                        + name + "'; caught exception: " + e);
+            throw e;
+        }
+        out.println("              [" + name + "]");
+    }
+
+    // attempts to run the JVM's Garbage Collector
+    static private void gc() {
+        // empirically determined limit after which no further
+        // reduction in memory usage has been observed
+        //final int nFullGCs = 5;
+        final int nFullGCs = 10;
+        for (int i = 0; i < nFullGCs; i++) {
+            //out.print("gc: ");
+            long oldfree;
+            long newfree = rt.freeMemory();
+            do {
+                oldfree = newfree;
+                rt.runFinalization();
+                rt.gc();
+                newfree = rt.freeMemory();
+                //out.print('.');
+            } while (newfree > oldfree);
+            //out.println();
+        }
+    }
+
+    // initializes the driver's resources.
     protected void init() throws Exception {
         loadProperties();
         initProperties();
         printProperties();
         openLogFile();
 
-        // init log buffers
+        // clear log buffers
         logHeader = true;
         header = new StringBuilder();
         rtimes = new StringBuilder();
         musage = new StringBuilder();
     }
 
-    /**
-     * Releases the benchmark's resources.
-     */
+    // releases the driver's resources.
     protected void close() throws Exception {
-        // close log buffers
+        // clear log buffers
         header = null;
         rtimes = null;
         musage = null;
@@ -336,17 +264,11 @@ abstract public class Driver {
         closeLogFile();
     }
 
-    /**
-     * Loads the benchmark's properties from properties files.
-     */
+    // loads the benchmark's properties from properties files
     private void loadProperties() throws IOException {
-        if (propFileNames.size() == 0) {
-            propFileNames.add("crund.properties");
-        }
-        
         out.println();
         for (String fn : propFileNames) {
-            out.println("reading properties file:    " + fn);
+            out.println("reading properties file:        " + fn);
             InputStream is = null;
             try {
                 is = new FileInputStream(fn);
@@ -358,17 +280,13 @@ abstract public class Driver {
         }
     }
 
-    /**
-     * Retrieves a property's value and parses it as a boolean.
-     */
-    protected boolean parseBoolean(String k) {
-        return Boolean.parseBoolean(props.getProperty(k));
+    // retrieves a property's value and parses it as a boolean
+    protected boolean parseBoolean(String k, boolean vdefault) {
+        final String v = props.getProperty(k);
+        return (v == null ? vdefault : Boolean.parseBoolean(v));
     }
-    
-    /**
-     * Retrieves a property's value and parses it as a signed decimal integer.
-     * @throws NumberFormatException with a descriptive error message
-     */
+
+    // retrieves a property's value and parses it as a signed decimal integer
     protected int parseInt(String k, int vdefault) {
         final String v = props.getProperty(k);
         try {
@@ -381,254 +299,77 @@ abstract public class Driver {
             throw nfe;
         }
     }
-    
-    /**
-     * Initializes the benchmark properties.
-     */
+
+    // initializes the benchmark properties
     protected void initProperties() {
         //props.list(out);
-        out.print("initializing properties ... ");
+        out.print("setting driver properties ...");
+        out.flush();
 
-        final StringBuilder msg = new StringBuilder();        
-        final String eol = System.getProperty("line.separator");        
+        final StringBuilder msg = new StringBuilder();
+        final String eol = System.getProperty("line.separator");
+
+        logRealTime = parseBoolean("logRealTime", true);
+        logMemUsage = parseBoolean("logMemUsage", false);
+        includeFullGC = parseBoolean("includeFullGC", false);
+        renewConnection = parseBoolean("renewConnection", false);
 
-        logRealTime = parseBoolean("logRealTime");
-        logMemUsage = parseBoolean("logMemUsage");
-        includeFullGC = parseBoolean("includeFullGC");
-        logSumOfOps = parseBoolean("logSumOfOps");
-        renewOperations = parseBoolean("renewOperations");
-        renewConnection = parseBoolean("renewConnection");
-        allowExtendedPC = parseBoolean("allowExtendedPC");
-
-        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);
-        maxTextChars = parseInt("maxTextChars", 1000);
         warmupRuns = parseInt("warmupRuns", 0);
-        hotRuns = parseInt("hotRuns", 1);
+        if (warmupRuns < 0) {
+            msg.append("[ignored] warmupRuns:           " + warmupRuns + eol);
+            warmupRuns = 0;
+        }
 
-        // initialize exclude set
-        final String[] e = props.getProperty("exclude", "").split(",");
-        for (int i = 0; i < e.length; i++) {
-            exclude.add(e[i]);
+        hotRuns = parseInt("hotRuns", 1);
+        if (hotRuns < 1) {
+            msg.append("[ignored] hotRuns:              " + hotRuns + eol);
+            hotRuns = 1;
         }
 
         if (msg.length() == 0) {
-            out.println("[ok]");
+            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.
-     */
+
+    // prints the benchmark's properties
     protected void printProperties() {
         out.println();
-        out.println("main settings:");
-        out.println("logRealTime:                " + logRealTime);
-        out.println("logMemUsage:                " + logMemUsage);
-        out.println("includeFullGC:              " + includeFullGC);
-        out.println("logSumOfOps:                " + logSumOfOps);
-        out.println("renewOperations:            " + renewOperations);
-        out.println("renewConnection:            " + renewConnection);
-        out.println("allowExtendedPC:            " + allowExtendedPC);
-        out.println("aStart:                     " + aStart);
-        out.println("bStart:                     " + bStart);
-        out.println("aEnd:                       " + aEnd);
-        out.println("bEnd:                       " + bEnd);
-        out.println("aScale:                     " + aScale);
-        out.println("bScale:                     " + bScale);
-        out.println("maxVarbinaryBytes:          " + maxVarbinaryBytes);
-        out.println("maxVarcharChars:            " + maxVarcharChars);
-        out.println("maxBlobBytes:               " + maxBlobBytes);
-        out.println("maxTextChars:               " + maxTextChars);
-        out.println("warmupRuns:                 " + warmupRuns);
-        out.println("hotRuns:                    " + hotRuns);
-        out.println("exclude:                    " + exclude);
+        out.println("driver settings ...");
+        out.println("logRealTime:                    " + logRealTime);
+        out.println("logMemUsage:                    " + logMemUsage);
+        out.println("includeFullGC:                  " + includeFullGC);
+        out.println("renewConnection:                " + renewConnection);
+        out.println("warmupRuns:                     " + warmupRuns);
+        out.println("hotRuns:                        " + hotRuns);
     }
 
-    /**
-     * Opens the benchmark's data log file.
-     */
+    // opens the benchmark's data log file
     private void openLogFile() throws IOException {
         out.println();
-        out.println("writing results to file:    " + logFileName);
+        out.println("writing results to file:        " + logFileName);
         log = new PrintWriter(new FileWriter(logFileName, false));
     }
 
-    /**
-     * Closes the benchmark's data log file.
-     */
+    // closes the benchmark's data log file
     private void closeLogFile() throws IOException {
-        out.print("closing files ...    ");
+        out.print("closing files ...");
         out.flush();
         if (log != null) {
             log.close();
             log = null;
         }
-        out.println("       [ok]");
+        out.println("               [ok]");
     }
 
     // ----------------------------------------------------------------------
+    // benchmark operations
+    // ----------------------------------------------------------------------
 
-    /**
-     * Runs a series of benchmark operations on scaled-up data.
-     */
-    protected void runTests() throws Exception {
-        initConnection();
-        initOperations();
-
-        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) {
-                    // already in rollback for database/orm exceptions
-                    //rollbackTransaction();
-                    throw ex;
-                }
-            }
-        }
-
-        out.println();
-        out.println("------------------------------------------------------------");
-        out.println();
-
-        clearData();
-        closeOperations();
-        closeConnection();
-    }
-
-    /**
-     * Runs a series of benchmark operations.
-     */
-    protected void runOperations(int countA, int countB) throws Exception {
-        out.println();
-        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) {
-            rtimes.append("A=" + countA + ", B=" + countB);
-            ta = 0;
-        }
-        if (logMemUsage) {
-            musage.append("A=" + countA + ", B=" + countB);
-            ma = 0;
-        }
-        
-        // pre-run cleanup
-        if (renewConnection) {
-            closeOperations();
-            closeConnection();
-            initConnection();
-            initOperations();
-        } else if (renewOperations) {
-            closeOperations();
-            initOperations();
-        }
-        clearData();
-
-        // run operations
-        for (Op op : ops) {
-            // pre-tx cleanup
-            if (!allowExtendedPC) {
-                // effectively prevent caching beyond Tx scope by clearing
-                // any data/result caches before the next transaction
-                clearPersistenceContext();
-            }
-            runOp(op, countA, countB);
-        }
-        if (logHeader) {
-            if (logSumOfOps)
-                header.append("\ttotal");
-        }
-
-        // log buffers
-        logHeader = false;
-        if (logRealTime) {
-            if (logSumOfOps) {
-                rtimes.append("\t" + ta);
-                out.println();
-                out.println("total");
-                out.println("tx real time\t\t= " + ta
-                            + "\tms [begin..commit]");
-            }
-            rtimes.append(endl);
-        }
-        if (logMemUsage) {
-            if (logSumOfOps) {
-                musage.append("\t" + ma);
-                out.println();
-                out.println("total");
-                out.println("net mem usage\t\t= " + (ma >= 0 ? "+" : "") + ma
-                            + "\tKiB");
-            }
-            musage.append(endl);
-        }               
-    }
-
-    /**
-     * Runs a benchmark operation.
-     */
-    protected void runOp(Op op, int countA, int countB) throws Exception {
-        final String name = op.getName();
-        if (!exclude.contains(name)) {
-            begin(name);
-            op.run(countA, countB);
-            commit(name);
-        }
-    }
+    abstract protected void runTests() throws Exception;
 
-    /**
-     * Begins a benchmarked transaction.
-     */
     protected void begin(String name) throws Exception {
         out.println();
         out.println(name);
@@ -644,16 +385,9 @@ abstract public class Driver {
             //t0 = System.currentTimeMillis();
             t0 = System.nanoTime() / 1000000;
         }
-
-        beginTransaction();
     }
 
-    /**
-     * Closes a benchmarked transaction.
-     */
     protected void commit(String name) throws Exception {
-        commitTransaction();
-
         // attempt one full GC, before timing tx end
         if (includeFullGC) {
             rt.gc();
@@ -663,8 +397,8 @@ abstract public class Driver {
             //t1 = System.currentTimeMillis();
             t1 = System.nanoTime() / 1000000;
             final long t = t1 - t0;
-            out.println("tx real time\t\t= " + t
-                        + "\tms [begin..commit]");
+            out.println("tx real time                    " + t
+                        + "\tms");
             //rtimes.append("\t" + (Math.round(t / 100.0) / 10.0));
             rtimes.append("\t" + t);
             ta += t;
@@ -677,7 +411,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\t\t= " + (mK >= 0 ? "+" : "") + mK
+            out.println("net mem usage                   "
+                        + (mK >= 0 ? "+" : "") + mK
                         + "\tKiB [" + m0K + "K->" + m1K + "K]");
             musage.append("\t" + mK);
             ma += mK;
@@ -687,65 +422,12 @@ abstract public class Driver {
             header.append("\t" + name);
     }
 
-    /**
-     * Attempts to run the JVM's Garbage Collector.
-     */
-    static private void gc() {
-        // empirically determined limit after which no further
-        // reduction in memory usage has been observed
-        //final int nFullGCs = 5;
-        final int nFullGCs = 10;
-        for (int i = 0; i < nFullGCs; i++) {
-            //out.print("gc: ");
-            long oldfree;
-            long newfree = rt.freeMemory();
-            do {
-                oldfree = newfree;
-                rt.runFinalization();
-                rt.gc();
-                newfree = rt.freeMemory();
-                //out.print('.');
-            } while (newfree > oldfree);
-            //out.println();
-        }
-    }
-
+    // ----------------------------------------------------------------------
+    // datastore operations
     // ----------------------------------------------------------------------
 
-    /**
-     * Prints a command-line usage message and exits.
-     */
-    static private void exitUsage() {
-        out.println("usage: [options]");
-        out.println("    [-p <file name>]...    a properties file name");
-        out.println("    [-l <file name>]       log file name for data output");
-        out.println("    [-h|--help]            print usage message and exit");
-        out.println();
-        System.exit(1); // return an error code
-    }
-
-    /**
-     * Parses the benchmark's command-line arguments.
-     */
-    static public void parseArguments(String[] args) {
-        for (int i = 0; i < args.length; i++) {
-            final String arg = args[i];
-            if (arg.equals("-p")) {
-                if (i >= args.length) {
-                    exitUsage();
-                }
-                propFileNames.add(args[++i]);
-            } else if (arg.equals("-l")) {
-                if (i >= args.length) {
-                    exitUsage();
-                }
-                logFileName = args[++i];
-            } else if (arg.equals("-h") || arg.equals("--help")) {
-                exitUsage();
-            } else {
-                out.println("unknown option: " + arg);
-                exitUsage();
-            }
-        }
-    }
+    abstract protected void initConnection() throws Exception;
+    abstract protected void closeConnection() throws Exception;
+    abstract protected void clearPersistenceContext() throws Exception;
+    abstract protected void clearData() throws Exception;
 }

=== modified file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/JdbcLoad.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/JdbcLoad.java	2010-09-04 01:20:28 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/JdbcLoad.java	2010-10-05 08:48:30 +0000
@@ -33,39 +33,33 @@ import java.sql.ResultSet;
 /**
  * A benchmark implementation against a JDBC/SQL database.
  */
-public class JdbcLoad extends Driver {
+public class JdbcLoad extends CrundDriver {
+
+    // ----------------------------------------------------------------------
+    // JDBC resources
+    // ----------------------------------------------------------------------
 
-    // JDBC connection
     protected String driver;
     protected String url;
+    protected String user;
+    protected String password;
+    protected boolean autoCommit;
     protected Connection conn;
     protected PreparedStatement delAllA;
     protected PreparedStatement delAllB0;
 
-    protected abstract class JdbcOp extends Op {
-        final protected String sql;
-        protected PreparedStatement stmt;
-
-        public JdbcOp(String name, String sql) {
-            super(name);
-            this.sql = sql;
-        }
-
-        public void init() throws SQLException {
-            if (stmt == null)
-                stmt = conn.prepareStatement(sql);
-        }
-
-        public void close() throws SQLException {
-            if (stmt != null)
-                stmt.close();
-            stmt = null;
-        }
-    };
+    // ----------------------------------------------------------------------
+    // JDBC intializers/finalizers
+    // ----------------------------------------------------------------------
 
     protected void initProperties() {
         super.initProperties();
 
+        out.print("setting jdbc properties ...");
+
+        final StringBuilder msg = new StringBuilder();
+        final String eol = System.getProperty("line.separator");
+
         // load the JDBC driver class
         driver = props.getProperty("jdbc.driver");
         if (driver == null) {
@@ -85,42 +79,63 @@ public class JdbcLoad extends Driver {
             throw new RuntimeException("Missing property: jdbc.url");
         }
 
+        user = props.getProperty("jdbc.user");
+        password = props.getProperty("jdbc.password");
+
+        // single ops not supported yet
+        autoCommit = parseBoolean("jdbc.autoCommit", false);
+        if (autoCommit) {
+            msg.append("[ignored] autoCommit:           " + autoCommit + eol);
+            autoCommit = false;
+        }
+
+        if (msg.length() == 0) {
+            out.println("     [ok]");
+        } else {
+            out.println();
+            out.print(msg.toString());
+        }
+
+        // have url initialized first
         descr = "->" + url;
-    }
+     }
 
     protected void printProperties() {
         super.printProperties();
-        out.println("jdbc.driver:                " + driver);
-        out.println("jdbc.url:                   " + url);
-    }
 
-    protected void initConnection() throws SQLException {
-        out.print("initializing connection ...");
-        out.flush();
-        final String user = props.getProperty("jdbc.user");
-        final String password = props.getProperty("jdbc.password");
-        final String autoCommit = props.getProperty("jdbc.autoCommit");
-        conn = DriverManager.getConnection(url, user, password);
-        conn.setAutoCommit(Boolean.getBoolean(autoCommit));
-        delAllA = conn.prepareStatement("DELETE FROM a");
-        delAllB0 = conn.prepareStatement("DELETE FROM b0");
-        out.println(" [Conn: 1]");
+        out.println();
+        out.println("jdbc settings ...");
+        out.println("jdbc.driver:                    " + driver);
+        out.println("jdbc.url:                       " + url);
+        out.println("jdbc.user:                      \"" + user + "\"");
+        out.println("jdbc.password:                  \"" + password + "\"");
+        out.println("jdbc.autoCommit:                " + autoCommit);
     }
 
-    protected void closeConnection() throws SQLException {
-        out.print("closing connection ...");
-        out.flush();
-        if (delAllB0 != null)
-            delAllB0.close();
-        delAllB0 = null;
-        if (delAllA != null)
-            delAllA.close();
-        delAllA = null;
-        if (conn != null)
-            conn.close();
-        conn = null;
-        out.println("      [ok]");
-    }
+    // ----------------------------------------------------------------------
+    // JDBC operations
+    // ----------------------------------------------------------------------
+
+    protected abstract class JdbcOp extends Op {
+        final protected String sql;
+        protected PreparedStatement stmt;
+
+        public JdbcOp(String name, String sql) {
+            super(name);
+            this.sql = sql;
+        }
+
+        public void init() throws SQLException {
+            if (stmt == null)
+                stmt = conn.prepareStatement(sql);
+        }
+
+        public void close() throws SQLException {
+            if (stmt != null)
+                stmt.close();
+            stmt = null;
+        }
+    };
 
     static protected void setCommonAttributes(PreparedStatement stmt, int i)
         throws SQLException {
@@ -171,6 +186,7 @@ public class JdbcLoad extends Driver {
                                 verify(cnts[i] == 1);
                             }
                         }
+                        conn.commit();
                     }
                 });
 
@@ -193,6 +209,7 @@ public class JdbcLoad extends Driver {
                                 verify(cnts[i] == 1);
                             }
                         }
+                        conn.commit();
                     }
                 });
 
@@ -220,6 +237,7 @@ public class JdbcLoad extends Driver {
                                 verify(cnts[i] == 1);
                             }
                         }
+                        conn.commit();
                     }
                 });
 
@@ -247,6 +265,7 @@ public class JdbcLoad extends Driver {
                                 verify(cnts[i] == 1);
                             }
                         }
+                        conn.commit();
                     }
                 });
 
@@ -279,6 +298,7 @@ public class JdbcLoad extends Driver {
                                 rs.close();
                             }
                         }
+                        conn.commit();
                     }
                 });
 
@@ -311,6 +331,7 @@ public class JdbcLoad extends Driver {
                                 rs.close();
                             }
                         }
+                        conn.commit();
                     }
                 });
 
@@ -339,6 +360,7 @@ public class JdbcLoad extends Driver {
                                     verify(cnts[i] == 1);
                                 }
                             }
+                            conn.commit();
                         }
                     });
 
@@ -356,6 +378,7 @@ public class JdbcLoad extends Driver {
                                 verify(!rs.next());
                                 rs.close();
                             }
+                            conn.commit();
                         }
                     });
 
@@ -379,10 +402,11 @@ public class JdbcLoad extends Driver {
                                     verify(cnts[i] == 1);
                                 }
                             }
+                            conn.commit();
                         }
                     });
             }
-        
+
             for (int i = 0, l = 1; l <= maxVarcharChars; l *= 10, i++) {
                 final String s = strings[i];
                 assert l == s.length();
@@ -408,6 +432,7 @@ public class JdbcLoad extends Driver {
                                     verify(cnts[i] == 1);
                                 }
                             }
+                            conn.commit();
                         }
                     });
 
@@ -425,6 +450,7 @@ public class JdbcLoad extends Driver {
                                 verify(!rs.next());
                                 rs.close();
                             }
+                            conn.commit();
                         }
                     });
 
@@ -448,6 +474,7 @@ public class JdbcLoad extends Driver {
                                     verify(cnts[i] == 1);
                                 }
                             }
+                            conn.commit();
                         }
                     });
             }
@@ -477,6 +504,7 @@ public class JdbcLoad extends Driver {
                                     verify(cnts[i] == 1);
                                 }
                             }
+                            conn.commit();
                         }
                     });
 
@@ -494,6 +522,7 @@ public class JdbcLoad extends Driver {
                                 verify(!rs.next());
                                 rs.close();
                             }
+                            conn.commit();
                         }
                     });
             }
@@ -523,6 +552,7 @@ public class JdbcLoad extends Driver {
                                     verify(cnts[i] == 1);
                                 }
                             }
+                            conn.commit();
                         }
                     });
 
@@ -540,6 +570,7 @@ public class JdbcLoad extends Driver {
                                 verify(!rs.next());
                                 rs.close();
                             }
+                            conn.commit();
                         }
                     });
             }
@@ -565,6 +596,7 @@ public class JdbcLoad extends Driver {
                                 verify(cnts[i] == 1);
                             }
                         }
+                        conn.commit();
                     }
                 });
 
@@ -583,6 +615,7 @@ public class JdbcLoad extends Driver {
                             verify(!rs.next());
                             rs.close();
                         }
+                        conn.commit();
                     }
                 });
 
@@ -601,6 +634,7 @@ public class JdbcLoad extends Driver {
                             verify(!rs.next());
                             rs.close();
                         }
+                        conn.commit();
                     }
                 });
 
@@ -642,6 +676,7 @@ public class JdbcLoad extends Driver {
                             verify(!rs.next());
                             rs.close();
                         }
+                        conn.commit();
                     }
                 });
 
@@ -663,6 +698,7 @@ public class JdbcLoad extends Driver {
                             rs.close();
                         }
                         verify(cnt == countB);
+                        conn.commit();
                     }
                 });
 
@@ -685,6 +721,7 @@ public class JdbcLoad extends Driver {
                                 verify(cnts[i] == 1);
                             }
                         }
+                        conn.commit();
                     }
                 });
 
@@ -708,6 +745,7 @@ public class JdbcLoad extends Driver {
                                 verify(cnts[i] == 1);
                             }
                         }
+                        conn.commit();
                     }
                 });
 
@@ -731,6 +769,7 @@ public class JdbcLoad extends Driver {
                                 verify(cnts[i] == 1);
                             }
                         }
+                        conn.commit();
                     }
                 });
 
@@ -754,6 +793,7 @@ public class JdbcLoad extends Driver {
                                 verify(cnts[i] == 1);
                             }
                         }
+                        conn.commit();
                     }
                 });
 
@@ -777,6 +817,7 @@ public class JdbcLoad extends Driver {
                                 verify(cnts[i] == 1);
                             }
                         }
+                        conn.commit();
                     }
                 });
 
@@ -786,6 +827,7 @@ public class JdbcLoad extends Driver {
                     public void run(int countA, int countB) throws SQLException {
                         int cnt = stmt.executeUpdate();
                         verify(cnt == countB);
+                        conn.commit();
                     }
                 });
 
@@ -795,38 +837,56 @@ public class JdbcLoad extends Driver {
                     public void run(int countA, int countB) throws SQLException {
                         int cnt = stmt.executeUpdate();
                         verify(cnt == countA);
+                        conn.commit();
                     }
                 });
         }
-        
+
         // prepare all statements
-        for (Iterator<Driver.Op> i = ops.iterator(); i.hasNext();) {
+        for (Iterator<CrundDriver.Op> i = ops.iterator(); i.hasNext();) {
             ((JdbcOp)i.next()).init();
         }
-        out.println(" [JdbcOp: " + ops.size() + "]");
+        out.println("     [JdbcOp: " + ops.size() + "]");
     }
 
     protected void closeOperations() throws SQLException {
         out.print("closing statements ...");
         out.flush();
         // close all statements
-        for (Iterator<Driver.Op> i = ops.iterator(); i.hasNext();) {
+        for (Iterator<CrundDriver.Op> i = ops.iterator(); i.hasNext();) {
             ((JdbcOp)i.next()).close();
         }
         ops.clear();
-        out.println("      [ok]");
+        out.println("          [ok]");
     }
 
-    protected void beginTransaction() {
-        // nothing to do for JDBC
-    }
+    // ----------------------------------------------------------------------
+    // JDBC datastore operations
+    // ----------------------------------------------------------------------
 
-    protected void commitTransaction() throws SQLException {
-        conn.commit();
+    protected void initConnection() throws SQLException {
+        out.print("initializing connection ...");
+        out.flush();
+        conn = DriverManager.getConnection(url, user, password);
+        conn.setAutoCommit(autoCommit);
+        delAllA = conn.prepareStatement("DELETE FROM a");
+        delAllB0 = conn.prepareStatement("DELETE FROM b0");
+        out.println("     [Conn: 1]");
     }
 
-    protected void rollbackTransaction() throws SQLException {
-        conn.rollback();
+    protected void closeConnection() throws SQLException {
+        out.print("closing connection ...");
+        out.flush();
+        if (delAllB0 != null)
+            delAllB0.close();
+        delAllB0 = null;
+        if (delAllA != null)
+            delAllA.close();
+        delAllA = null;
+        if (conn != null)
+            conn.close();
+        conn = null;
+        out.println("          [ok]");
     }
 
     protected void clearPersistenceContext() {
@@ -837,7 +897,7 @@ public class JdbcLoad extends Driver {
         out.print("deleting all rows ...");
         out.flush();
         int delB0 = delAllB0.executeUpdate();
-        out.print("       [B0: " + delB0);
+        out.print("           [B0: " + delB0);
         out.flush();
         int delA = delAllA.executeUpdate();
         out.print(", A: " + delA);

=== removed file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/JdoLoad.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/JdoLoad.java	2010-02-14 05:05:31 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/JdoLoad.java	1970-01-01 00:00:00 +0000
@@ -1,487 +0,0 @@
-/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
- *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
- *
- *  Copyright (C) 2008 MySQL
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-package com.mysql.cluster.crund;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-import javax.jdo.*;
-
-/**
- * A benchmark implementation against a JDO-mapped datastore.
- */
-public class JdoLoad extends Driver {
-
-    // non-static fields
-    protected PersistenceManagerFactory pmf;
-    protected PersistenceManager pm;
-    protected Query getAllA;
-    protected Query getAllB0;
-    protected Query getAByB0;
-    protected Query getB0ByA;
-
-    protected void init() {
-        // init PersistenceManagerFactory
-        final String driver = props.getProperty("jdo.driver");
-        final String url = props.getProperty("jdo.url");
-        final String user = props.getProperty("jdo.user");
-        final String password = props.getProperty("jdo.password");
-        try {
-            pmf = JDOHelper.getPersistenceManagerFactory();
-            pmf.setConnectionDriverName(driver);
-            pmf.setConnectionURL(url);
-            pmf.setConnectionUserName(user);
-            pmf.setConnectionPassword(password);
-            //pmf.setConnectionMinPool(1);
-            //pmf.setConnectionMaxPool(1);
-            //pmf.setOptimistic(false);
-            //pmf.setRetainValues(false);
-        } catch (Exception e) {
-            out.println("caught " + e);
-            e.printStackTrace();
-            throw new RuntimeException("Cannot get PersistenceManagerFactory");
-        }
-    }
-
-    protected void close() {
-        if (pmf == null)
-            pmf.close();
-        pmf = null;
-    }
-
-    protected void initConnection() {
-        if (pm != null)
-            pm.close();
-        pm = pmf.getPersistenceManager();
-    }
-
-    protected void closeConnection() {
-        if (pm != null)
-            pm.close();
-        pm = null;
-    }
-
-    protected void initOperations() {
-/*
-        Extent<A> extentA = pm.getExtent(A.class, false);
-        Extent<B0> extentB0 = pm.getExtent(B0.class, false);
-
-        getAllA = pm.newQuery(extentA);
-
-        getAllB0 = pm.newQuery(extentB0);
-
-        getAByB0 = pm.newQuery(extentA, "b0s.contains(b0) & b0.id==id");
-        getAByB0.declareParameters("int id");
-        getAByB0.declareVariables("scalability.B0 b0");
-
-        getB0ByA = pm.newQuery(extentB0, "a.id == id");
-        getB0ByA.declareParameters("int id");
-*/
-    }
-
-    protected void closeOperations() {
-    }
-
-    protected void beginTransaction() {
-        pm.currentTransaction().begin();
-    }
-
-    protected void commitTransaction() {
-        pm.currentTransaction().commit();
-    }
-
-    protected void rollbackTransaction() {
-        pm.currentTransaction().rollback();
-    }
-
-    protected void clearPersistenceContext() {
-        // XXX adapt to JDO (retain values...)
-        // as long as we haven't created the EM with a Tx PC scope
-        // (i.e. emf.createEntityManager(PersistenceContextType.TRANSACTION))
-        // we effectively prevent caching beyond Tx scope by clearing
-        // the EM's PC
-        //pm.clear();
-    }
-
-    protected void clearData() {
-        out.println();
-        out.println("delete all objects");
-
-        beginTransaction();
-        pm.deletePersistentAll((Collection)getAllA.execute());
-        commitTransaction();
-
-        beginTransaction();
-        pm.deletePersistentAll((Collection)getAllB0.execute());
-        commitTransaction();
-    }
-
-/*
-    protected void create0(int countA, int countB0) {
-        Object o[] = new Object[countA];
-        for (int i = 0; i < countA; i++) {
-            o[i] = createA(i);
-        }
-    }
-
-    protected void create1(int countA, int countB0) {
-        Object o[] = new Object[countB0];
-        for (int i = 0; i < countB0; i++) {
-            o[i] = createB0(countA + i);
-        }
-    }
-
-    protected void delete0(int countA, int countB0) {
-        //TODO: iterate extent <-> JDBC
-        //Collection result = (Collection)getAllA.execute();
-        //pm.deletePersistentAll(result);
-    }
-
-    protected void delete1(int countA, int countB0) {
-        //TODO: iterate extent <-> JDBC
-        //Collection result = (Collection)getAllB0.execute();
-        //pm.deletePersistentAll(result);
-    }
-
-    protected void query0(int countA, int countB0) {
-        Collection result = (Collection)getAllA.execute();
-        for (Iterator i = result.iterator(); i.hasNext();) {
-            A o = (A) i.next();
-        }
-    }
-
-    protected void query1(int countA, int countB0) {
-        Collection result = (Collection)getAllB0.execute();
-        for (Iterator i = result.iterator(); i.hasNext();) {
-            B0 o = (B0) i.next();
-        }
-    }
-
-    protected void setRel0(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        Collection b0Result = (Collection)getAllB0.execute();
-        final int rAB0 = countA / countB0;
-        final int rB0A = countB0 / countA;
-        if (rAB0 <= 1) {
-            Iterator j = b0Result.iterator();
-            Iterator i = aResult.iterator();
-            while (i.hasNext()) {
-                A a = (A) i.next();
-                for (int r = 0; r < rB0A; r++) {
-                    B0 b0 = (B0) j.next();
-                    a.getB0s().add(b0);
-                    b0 = null;
-                }
-                a = null;
-            }
-            i = null;
-            j = null;
-        } else {
-            Iterator j = b0Result.iterator();
-            Iterator i = aResult.iterator();
-            while (i.hasNext()) {
-                A a = null;
-                for (int r = 0; r < rAB0; r++)
-                    a = (A) i.next();
-                B0 b0 = (B0) j.next();
-                a.getB0s().add(b0);
-                b0 = null;
-                a = null;
-            }
-            i = null;
-            j = null;
-        }
-        aResult = null;
-        b0Result = null;
-    }
-
-    protected void setRel1(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        Collection b0Result = (Collection)getAllB0.execute();
-        final int rAB0 = countA / countB0;
-        final int rB0A = countB0 / countA;
-        if (rAB0 <= 1) {
-            Iterator j = b0Result.iterator();
-            for (Iterator i = aResult.iterator(); i.hasNext();) {
-                A a = (A) i.next();
-                for (int r = 0; r < rB0A; r++) {
-                    B0 b0 = (B0) j.next();
-                    b0.setA(a);
-                }
-            }
-        } else {
-            Iterator j = b0Result.iterator();
-            for (Iterator i = aResult.iterator(); i.hasNext();) {
-                A a = null;
-                for (int r = 0; r < rAB0; r++)
-                    a = (A) i.next();
-                B0 b0 = (B0) j.next();
-                b0.setA(a);
-            }
-        }
-    }
-
-    protected void delRel0(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        for (Iterator i = aResult.iterator(); i.hasNext();) {
-            A a = (A) i.next();
-            a.getB0s().clear();
-        }
-    }
-
-    protected void delRel1(int countA, int countB0) {
-        Collection b0Result = (Collection)getAllB0.execute();
-        for (Iterator i = b0Result.iterator(); i.hasNext();) {
-            B0 b0 = (B0) i.next();
-            b0.setA(null);
-        }
-    }
-
-    protected void delRel2(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        for (Iterator i = aResult.iterator(); i.hasNext();) {
-            A a = (A) i.next();
-            for (Iterator j = a.getB0s().iterator(); j.hasNext();) {
-                B0 b0 = (B0) j.next();
-                a.getB0s().remove(b0);
-            }
-        }
-    }
-
-    protected void queryRel0(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        for (Iterator i = aResult.iterator(); i.hasNext();) {
-            A a = (A) i.next();
-            Collection b0Result
-                = (Collection)getB0ByA.execute(new java.lang.Integer(a.getId()));
-            for (Iterator j = b0Result.iterator(); j.hasNext();) {
-                B0 b0 = (B0) j.next();
-            }
-        }
-    }
-
-    protected void queryRel1(int countA, int countB0) {
-        Collection b0Result = (Collection)getAllB0.execute();
-        for (Iterator i = b0Result.iterator(); i.hasNext();) {
-            B0 b0 = (B0) i.next();
-            Collection aResult
-                = (Collection)getAByB0.execute(new java.lang.Integer(b0.getId()));
-            for (Iterator j = aResult.iterator(); j.hasNext();) {
-                A a = (A) j.next();
-            }
-        }
-    }
-
-    protected void fetchInt0(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        for (Iterator i = aResult.iterator(); i.hasNext();) {
-            A a = (A) i.next();
-            a.getCint();
-        }
-    }
-
-    protected void fetchInt1(int countA, int countB0) {
-        Collection b0Result = (Collection)getAllB0.execute();
-        for (Iterator i = b0Result.iterator(); i.hasNext();) {
-            B0 b0 = (B0) i.next();
-            b0.getCint();
-        }
-    }
-
-    protected void fetchLong0(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        for (Iterator i = aResult.iterator(); i.hasNext();) {
-            A a = (A) i.next();
-            a.getClong();
-        }
-    }
-
-    protected void fetchLong1(int countA, int countB0) {
-        Collection b0Result = (Collection)getAllB0.execute();
-        for (Iterator i = b0Result.iterator(); i.hasNext();) {
-            B0 b0 = (B0) i.next();
-            b0.getClong();
-        }
-    }
-
-    protected void fetchFloat0(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        for (Iterator i = aResult.iterator(); i.hasNext();) {
-            A a = (A) i.next();
-            a.getCfloat();
-        }
-    }
-
-    protected void fetchFloat1(int countA, int countB0) {
-        Collection b0Result = (Collection)getAllB0.execute();
-        for (Iterator i = b0Result.iterator(); i.hasNext();) {
-            B0 b0 = (B0) i.next();
-            b0.getCfloat();
-        }
-    }
-
-    protected void fetchDouble0(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        for (Iterator i = aResult.iterator(); i.hasNext();) {
-            A a = (A) i.next();
-            a.getCdouble();
-        }
-    }
-
-    protected void fetchDouble1(int countA, int countB0) {
-        Collection b0Result = (Collection)getAllB0.execute();
-        for (Iterator i = b0Result.iterator(); i.hasNext();) {
-            B0 b0 = (B0) i.next();
-            b0.getCdouble();
-        }
-    }
-
-    protected void fetchString0(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        for (Iterator i = aResult.iterator(); i.hasNext();) {
-            A a = (A) i.next();
-            a.getCstring();
-        }
-    }
-
-    protected void fetchString1(int countA, int countB0) {
-        Collection b0Result = (Collection)getAllB0.execute();
-        for (Iterator i = b0Result.iterator(); i.hasNext();) {
-            B0 b0 = (B0) i.next();
-            b0.getCstring();
-        }
-    }
-
-    protected void updateInt0(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        for (Iterator i = aResult.iterator(); i.hasNext();) {
-            A a = (A) i.next();
-            a.setCint(0);
-        }
-    }
-
-    protected void updateInt1(int countA, int countB0) {
-        Collection b0Result = (Collection)getAllB0.execute();
-        for (Iterator i = b0Result.iterator(); i.hasNext();) {
-            B0 b0 = (B0) i.next();
-            b0.setCint(0);
-        }
-    }
-
-    protected void updateLong0(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        for (Iterator i = aResult.iterator(); i.hasNext();) {
-            A a = (A) i.next();
-            a.setClong(0);
-        }
-    }
-
-    protected void updateLong1(int countA, int countB0) {
-        Collection b0Result = (Collection)getAllB0.execute();
-        for (Iterator i = b0Result.iterator(); i.hasNext();) {
-            B0 b0 = (B0) i.next();
-            b0.setClong(0);
-        }
-    }
-
-    protected void updateFloat0(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        for (Iterator i = aResult.iterator(); i.hasNext();) {
-            A a = (A) i.next();
-            a.setCfloat(0);
-        }
-    }
-
-    protected void updateFloat1(int countA, int countB0) {
-        Collection b0Result = (Collection)getAllB0.execute();
-        for (Iterator i = b0Result.iterator(); i.hasNext();) {
-            B0 b0 = (B0) i.next();
-            b0.setCfloat(0);
-        }
-    }
-
-    protected void updateDouble0(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        for (Iterator i = aResult.iterator(); i.hasNext();) {
-            A a = (A) i.next();
-            a.setCdouble(0);
-        }
-    }
-
-    protected void updateDouble1(int countA, int countB0) {
-        Collection b0Result = (Collection)getAllB0.execute();
-        for (Iterator i = b0Result.iterator(); i.hasNext();) {
-            B0 b0 = (B0) i.next();
-            b0.setCdouble(0);
-        }
-    }
-
-    protected void updateString0(int countA, int countB0) {
-        Collection aResult = (Collection)getAllA.execute();
-        for (Iterator i = aResult.iterator(); i.hasNext();) {
-            A a = (A) i.next();
-            a.setCstring("newAString");
-        }
-    }
-
-    protected void updateString1(int countA, int countB0) {
-        Collection b0Result = (Collection)getAllB0.execute();
-        for (Iterator i = b0Result.iterator(); i.hasNext();) {
-            B0 b0 = (B0) i.next();
-            b0.setCstring("newB0String");
-        }
-    }
-
-    protected A createA(int id) {
-        A o = new A();
-        o.setId(id);
-        o.setCint(id);
-        o.setClong((long)id);
-        o.setCfloat((float)id);
-        o.setCdouble((double)id);
-        o.setCstring("aString");
-        pm.makePersistent(o);
-        return o;
-    }
-
-    protected B0 createB0(int id) {
-        B0 o = new B0();
-        o.setId(id);
-        o.setCint(id);
-        o.setClong((long)id);
-        o.setCfloat((float)id);
-        o.setCdouble((double)id);
-        o.setCstring("b0String");
-        pm.makePersistent(o);
-        return o;
-    }
-*/
-
-    // ----------------------------------------------------------------------
-
-    static public void main(String[] args) {
-        System.out.println("JdoLoad.main()");
-        parseArguments(args);
-        new JdoLoad().run();
-        System.out.println();
-        System.out.println("JdoLoad.main(): done.");
-    }
-}

=== modified file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/JpaLoad.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/JpaLoad.java	2010-09-04 01:20:28 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/JpaLoad.java	2010-10-05 08:48:30 +0000
@@ -35,32 +35,37 @@ import javax.persistence.PersistenceCont
 /**
  * A benchmark implementation against a JPA-mapped database.
  */
-public class JpaLoad extends Driver {
+public class JpaLoad extends CrundDriver {
+
+    // ----------------------------------------------------------------------
+    // JPA resources
+    // ----------------------------------------------------------------------
 
-    // JPA database connection
     protected String driver;
     protected String url;
+    protected String user;
+    protected String password;
     protected String connectionRetainMode;
-    protected String ndbConnectString;
     protected String brokerFactory;
+    protected String ndbConnectString;
+    protected String ndbDatabase;
     protected EntityManagerFactory emf;
     protected EntityManager em;
     protected Query delAllA;
     protected Query delAllB0;
 
-    protected abstract class JpaOp extends Op {
-        public JpaOp(String name) {
-            super(name);
-        }
-
-        public void init() {}
-
-        public void close() {}
-    };
+    // ----------------------------------------------------------------------
+    // JPA intializers/finalizers
+    // ----------------------------------------------------------------------
 
     protected void initProperties() {
         super.initProperties();
 
+        out.print("setting jpa properties ...");
+
+        final StringBuilder msg = new StringBuilder();
+        final String eol = System.getProperty("line.separator");
+
         // load the JDBC driver class
         driver = props.getProperty("openjpa.ConnectionDriverName");
         if (driver == null) {
@@ -81,45 +86,68 @@ public class JpaLoad extends Driver {
             throw new RuntimeException("Missing property: "
                                        + "openjpa.ConnectionURL");
         }
-        
+
+        user = props.getProperty("openjpa.ConnectionUserName");
+        password = props.getProperty("openjpa.ConnectionPassword");
+
         connectionRetainMode = props.getProperty("openjpa.ConnectionRetainMode");
         if (connectionRetainMode == null) {
             throw new RuntimeException("Missing property: "
                                        + "openjpa.ConnectionRetainMode");
         }
 
-        ndbConnectString = props.getProperty("openjpa.ndb.connectString");
-        if (url == null) {
-            throw new RuntimeException("Missing property: "
-                                       + "openjpa.ndb.connectString");
-        }
-
         brokerFactory = props.getProperty("openjpa.BrokerFactory");
-        if (url == null) {
-            throw new RuntimeException("Missing property: "
-                                       + "openjpa.BrokerFactory");
-        }
-
-        descr = "->JPA->" + url;
+        ndbConnectString = props.getProperty("openjpa.ndb.connectString");
+        ndbDatabase = props.getProperty("openjpa.ndb.database");
+        if ("ndb".equals(brokerFactory)) {
+            if (ndbConnectString == null) {
+                throw new RuntimeException("Missing property: "
+                                           + "openjpa.ndb.connectString");
+            }
+            if (ndbDatabase == null) {
+                throw new RuntimeException("Missing property: "
+                                           + "openjpa.ndb.database");
+            }
+        }
+
+        if (msg.length() == 0) {
+            out.println("      [ok]");
+        } else {
+            out.println();
+            out.print(msg.toString());
+        }
+
+        // have brokerFactory... initialized first
+        final String c =  ("ndb".equals(brokerFactory)
+                           ? ("clusterj(" + ndbConnectString + ")")
+                           : url);
+        descr = "->jpa->" + c;
     }
 
     protected void printProperties() {
         super.printProperties();
-        out.println("openjpa.ConnectionDriverName: " + driver);
-        out.println("openjpa.ConnectionURL:        " + url);
-        out.println("openjpa.ConnectionRetainMode: " + connectionRetainMode);
-        out.println("openjpa.ndb.connectString:    " + ndbConnectString);
-        out.println("openjpa.BrokerFactory:        " + brokerFactory);
+
+        out.println();
+        out.println("jpa settings ...");
+        out.println("openjpa.ConnectionDriverName:   " + driver);
+        out.println("openjpa.ConnectionURL:          " + url);
+        out.println("openjpa.ConnectionUserName:     \"" + user + "\"");
+        out.println("openjpa.ConnectionPassword:     \"" + password + "\"");
+        out.println("openjpa.ConnectionRetainMode:   " + connectionRetainMode);
+        out.println("openjpa.BrokerFactory:          " + brokerFactory);
+        out.println("openjpa.ndb.connectString:      " + ndbConnectString);
+        out.println("openjpa.ndb.database:           " + ndbDatabase);
     }
 
     protected void init() throws Exception {
         super.init();
+
         out.println();
         out.print("creating EMFactory ...");
         out.flush();
         // create EMF by standard API, which allows vendors to pool factories
         emf = Persistence.createEntityManagerFactory("crundjpa", props);
-        out.println("      [EMF: 1]");
+        out.println("          [EMF: 1]");
     }
 
     protected void close() throws Exception {
@@ -128,41 +156,24 @@ public class JpaLoad extends Driver {
         if (emf != null)
             emf.close();
         emf = null;
-        out.println("       [ok]");
+        out.println("           [ok]");
+
         super.close();
     }
 
-    protected void initConnection() {
-        out.print("creating EntityManager ...");
-        out.flush();
-        // See: clearPersistenceContext() for !allowExtendedPC
-        // Tx-scope EM supported by JPA only by container injection:
-        //   em = emf.createEntityManager(PersistenceContextType.TRANSACTION);
-        em = emf.createEntityManager();
-        // XXX check query.setHint(...) for standardized optimizations, e.g.:
-        //import org.eclipse.persistence.config.QueryHints;
-        //import org.eclipse.persistence.config.QueryType;        
-        //import org.eclipse.persistence.config.PessimisticLock;        
-        //import org.eclipse.persistence.config.HintValues;
-        //query.setHint(QueryHints.QUERY_TYPE, QueryType.ReadObject);
-        //query.setHint(QueryHints.PESSIMISTIC_LOCK, PessimisticLock.LockNoWait);
-        //query.setHint("eclipselink.batch", "e.address");
-        //query.setHint("eclipselink.join-fetch", "e.address");
-        delAllA = em.createQuery("DELETE FROM A");
-        delAllB0 = em.createQuery("DELETE FROM B0");
-        out.println("  [EM: 1]");
-    }
+    // ----------------------------------------------------------------------
+    // JPA operations
+    // ----------------------------------------------------------------------
 
-    protected void closeConnection() {
-        out.print("closing EntityManager ...");
-        out.flush();
-        delAllB0 = null;
-        delAllA = null;
-        if (em != null)
-            em.close();
-        em = null;
-        out.println("   [ok]");
-    }
+    protected abstract class JpaOp extends Op {
+        public JpaOp(String name) {
+            super(name);
+        }
+
+        public void init() {}
+
+        public void close() {}
+    };
 
     protected void setCommonFields(A o, int i) {
         assert o != null;
@@ -171,7 +182,7 @@ public class JpaLoad extends Driver {
         o.setCfloat((float)i);
         o.setCdouble((double)i);
     }
-    
+
     protected void setCommonFields(B0 o, int i) {
         assert o != null;
         o.setCint(i);
@@ -179,7 +190,7 @@ public class JpaLoad extends Driver {
         o.setCfloat((float)i);
         o.setCdouble((double)i);
     }
-    
+
     protected void verifyCommonFields(A o, int i) {
         assert o != null;
         final int id = o.getId();
@@ -215,80 +226,96 @@ public class JpaLoad extends Driver {
         ops.add(
             new JpaOp("insA") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countA; i++) {
                         final A o = new A();
                         o.setId(i);
                         em.persist(o);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("insB0") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         final B0 o = new B0();
                         o.setId(i);
                         em.persist(o);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("setAByPK_bulk") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     // OpenJPA 1.2.1 fails to parse a unary '-' operator
                     final int upd = em.createQuery("UPDATE A o SET o.cint = 0-(o.id), o.clong = 0-(o.id), o.cfloat = 0-(o.id), o.cdouble = 0-(o.id)").executeUpdate();
                     assert upd == countA;
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("setB0ByPK_bulk") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     // OpenJPA 1.2.1 fails to parse a unary '-' operator
                     final int upd = em.createQuery("UPDATE B0 o SET o.cint = 0-(o.id), o.clong = 0-(o.id), o.cfloat = 0-(o.id), o.cdouble = 0-(o.id)").executeUpdate();
                     assert upd == countB;
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("setAByPK") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countA; i++) {
                         final A o = em.find(A.class, i);
                         setCommonFields(o, i);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("setB0ByPK") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         final B0 o = em.find(B0.class, i);
                         setCommonFields(o, i);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("getAByPK") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countA; i++) {
                         final A o = em.find(A.class, i);
                         verifyCommonFields(o, i);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("getB0ByPK") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         final B0 o = em.find(B0.class, i);
                         verifyCommonFields(o, i);
                     }
+                    commitTransaction();
                 }
             });
 
@@ -299,39 +326,45 @@ public class JpaLoad extends Driver {
             ops.add(
                 new JpaOp("setVarbinary" + l) {
                     public void run(int countA, int countB) {
+                        beginTransaction();
                         for (int i = 0; i < countB; i++) {
                             final B0 o = em.find(B0.class, i);
                             assert o != null;
                             //o.cvarbinary_def = b; // not detected by OpenJPA
                             o.setCvarbinary_def(b);
                         }
+                        commitTransaction();
                     }
                 });
 
             ops.add(
                 new JpaOp("getVarbinary" + l) {
                     public void run(int countA, int countB) {
+                        beginTransaction();
                         for (int i = 0; i < countB; i++) {
                             final B0 o = em.find(B0.class, i);
                             assert o != null;
                             verify(Arrays.equals(b, o.getCvarbinary_def()));
                         }
+                        commitTransaction();
                     }
                 });
 
             ops.add(
                 new JpaOp("clearVarbinary" + l) {
                     public void run(int countA, int countB) {
+                        beginTransaction();
                         for (int i = 0; i < countB; i++) {
                             final B0 o = em.find(B0.class, i);
                             assert o != null;
                             //o.cvarbinary_def = null; // not detected by OpenJPA
                             o.setCvarbinary_def(null);
                         }
+                        commitTransaction();
                     }
                 });
         }
-        
+
         for (int i = 0, l = 1; l <= maxVarcharChars; l *= 10, i++) {
             final String s = strings[i];
             assert l == s.length();
@@ -339,42 +372,49 @@ public class JpaLoad extends Driver {
             ops.add(
                 new JpaOp("setVarchar" + l) {
                     public void run(int countA, int countB) {
+                        beginTransaction();
                         for (int i = 0; i < countB; i++) {
                             final B0 o = em.find(B0.class, i);
                             assert o != null;
                             //o.cvarchar_def = s; // not detected by OpenJPA
                             o.setCvarchar_def(s);
                         }
+                        commitTransaction();
                     }
                 });
 
             ops.add(
                 new JpaOp("getVarchar" + l) {
                     public void run(int countA, int countB) {
+                        beginTransaction();
                         for (int i = 0; i < countB; i++) {
                             final B0 o = em.find(B0.class, i);
                             assert o != null;
                             verify(s.equals(o.getCvarchar_def()));
                         }
+                        commitTransaction();
                     }
                 });
 
             ops.add(
                 new JpaOp("clearVarchar" + l) {
                     public void run(int countA, int countB) {
+                        beginTransaction();
                         for (int i = 0; i < countB; i++) {
                             final B0 o = em.find(B0.class, i);
                             assert o != null;
                             //o.cvarchar_def = null; // not detected by OpenJPA
                             o.setCvarchar_def(null);
                         }
+                        commitTransaction();
                     }
                 });
         }
-        
+
         ops.add(
             new JpaOp("setB0->A") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         final B0 b0 = em.find(B0.class, i);
                         assert b0 != null;
@@ -383,24 +423,28 @@ public class JpaLoad extends Driver {
                         assert a != null;
                         b0.setA(a);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("navB0->A") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         final B0 b0 = em.find(B0.class, i);
                         assert b0 != null;
                         final A a = b0.getA();
                         verifyCommonFields(a, i % countA);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("navA->B0") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countA; i++) {
                         final A a = em.find(A.class, i);
                         assert a != null;
@@ -411,17 +455,20 @@ public class JpaLoad extends Driver {
                             verifyCommonFields(b0, i % countA);
                         }
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("nullB0->A") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         final B0 b0 = em.find(B0.class, i);
                         assert b0 != null;
                         b0.setA(null);
                     }
+                    commitTransaction();
                 }
             });
 
@@ -442,79 +489,93 @@ public class JpaLoad extends Driver {
         ops.add(
             new JpaOp("nullB0->A_bulk") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     // OpenJPA 1.2.1 fails to parse a unary '-' operator
                     final int upd = em.createQuery("UPDATE B0 o SET o.a = NULL").executeUpdate();
                     assert upd == countB;
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("delB0ByPK") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         final B0 o = em.find(B0.class, i);
                         assert o != null;
                         em.remove(o);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("delAByPK") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countA; i++) {
                         final A o = em.find(A.class, i);
                         assert o != null;
                         em.remove(o);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("insA_attr") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countA; i++) {
                         final A o = new A();
                         o.setId(i);
                         setCommonFields(o, -i);
                         em.persist(o);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("insB0_attr") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     for (int i = 0; i < countB; i++) {
                         final B0 o = new B0();
                         o.setId(i);
                         setCommonFields(o, -i);
                         em.persist(o);
                     }
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("delAllB0") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     int del = em.createQuery("DELETE FROM B0").executeUpdate();
                     assert del == countB;
+                    commitTransaction();
                 }
             });
 
         ops.add(
             new JpaOp("delAllA") {
                 public void run(int countA, int countB) {
+                    beginTransaction();
                     int del = em.createQuery("DELETE FROM A").executeUpdate();
                     assert del == countA;
+                    commitTransaction();
                 }
             });
 
         // prepare queries
-        for (Iterator<Driver.Op> i = ops.iterator(); i.hasNext();) {
+        for (Iterator<CrundDriver.Op> i = ops.iterator(); i.hasNext();) {
             ((JpaOp)i.next()).init();
         }
-        out.println(" [JpaOp: " + ops.size() + "]");
+        out.println("     [JpaOp: " + ops.size() + "]");
     }
 
     protected void closeOperations() {
@@ -522,12 +583,12 @@ public class JpaLoad extends Driver {
         out.flush();
 
         // close all queries
-        for (Iterator<Driver.Op> i = ops.iterator(); i.hasNext();) {
+        for (Iterator<CrundDriver.Op> i = ops.iterator(); i.hasNext();) {
             ((JpaOp)i.next()).close();
         }
         ops.clear();
 
-        out.println("      [ok]");
+        out.println("          [ok]");
     }
 
     protected void beginTransaction() {
@@ -538,8 +599,40 @@ public class JpaLoad extends Driver {
         em.getTransaction().commit();
     }
 
-    protected void rollbackTransaction() {
-        em.getTransaction().rollback();
+    // ----------------------------------------------------------------------
+    // JPA datastore operations
+    // ----------------------------------------------------------------------
+
+    protected void initConnection() {
+        out.print("creating EntityManager ...");
+        out.flush();
+        // See: clearPersistenceContext() for !allowExtendedPC
+        // Tx-scope EM supported by JPA only by container injection:
+        //   em = emf.createEntityManager(PersistenceContextType.TRANSACTION);
+        em = emf.createEntityManager();
+        // XXX check query.setHint(...) for standardized optimizations, e.g.:
+        //import org.eclipse.persistence.config.QueryHints;
+        //import org.eclipse.persistence.config.QueryType;
+        //import org.eclipse.persistence.config.PessimisticLock;
+        //import org.eclipse.persistence.config.HintValues;
+        //query.setHint(QueryHints.QUERY_TYPE, QueryType.ReadObject);
+        //query.setHint(QueryHints.PESSIMISTIC_LOCK, PessimisticLock.LockNoWait);
+        //query.setHint("eclipselink.batch", "e.address");
+        //query.setHint("eclipselink.join-fetch", "e.address");
+        delAllA = em.createQuery("DELETE FROM A");
+        delAllB0 = em.createQuery("DELETE FROM B0");
+        out.println("      [EM: 1]");
+    }
+
+    protected void closeConnection() {
+        out.print("closing EntityManager ...");
+        out.flush();
+        delAllB0 = null;
+        delAllA = null;
+        if (em != null)
+            em.close();
+        em = null;
+        out.println("       [ok]");
     }
 
     protected void clearPersistenceContext() {
@@ -557,7 +650,7 @@ public class JpaLoad extends Driver {
 
         em.getTransaction().begin();
         int delB0 = delAllB0.executeUpdate();
-        out.print("    [B0: " + delB0);
+        out.print("        [B0: " + delB0);
         out.flush();
         int delA = delAllA.executeUpdate();
         out.print(", A: " + delA);

=== 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-01 04:10:21 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbApiLoad.java	2010-10-05 08:48:30 +0000
@@ -22,24 +22,19 @@ package com.mysql.cluster.crund;
 
 public class NdbApiLoad extends NdbBase {
 
+    // ----------------------------------------------------------------------
+    // NDB API intializers/finalizers
+    // ----------------------------------------------------------------------
+
     protected void initProperties() {
         super.initProperties();
-        descr = "->NDBAPI(" + mgmdConnect + ")";
+        descr = "->ndbapi(" + mgmdConnect + ")";
     }
 
-    /**
-     * Initializes the NDB benchmark class.
-     *
-     * @return a non-zero value in case of an error, and zero otherwise.
-     */
-    static public native int ndbinit(String mgmd_host_portno);
-
-    /**
-     * Finalizes the NDB benchmark class.
-     *
-     * @return a non-zero value in case of an error, and zero otherwise.
-     */
-    static public native int ndbclose();
+    // initializes/finalizes the NDB benchmark class
+    // a non-zero value in case of an error, and zero otherwise
+    static protected native int ndbinit(String mgmd_host_portno);
+    static protected native int ndbclose();
 
     protected void init() throws Exception {
         super.init();
@@ -72,16 +67,9 @@ public class NdbApiLoad extends NdbBase 
     }
 
     // ----------------------------------------------------------------------
+    // NDB API operations
+    // ----------------------------------------------------------------------
 
-    // native connection handling methods
-    protected native void initConnection(String catalog, String schema);
-    protected void initConnection() {
-        initConnection(catalog, schema);
-    }
-    protected native void closeConnection();
-
-    // native benchmark operations
-    protected native void clearData();
     protected native void delAllA(int countA, int countB,
                                   boolean batch);
     protected native void delAllB0(int countA, int countB,
@@ -217,7 +205,7 @@ public class NdbApiLoad extends NdbBase 
                         }
                     });
             }
-            
+
             for (int i = 1; i <= maxVarcharChars; i *= 10) {
                 final int length = i;
 
@@ -330,17 +318,28 @@ public class NdbApiLoad extends NdbBase 
 
         }
 
-        out.println(" [Op: " + ops.size() + "]");
+        out.println("     [Op: " + ops.size() + "]");
     }
 
     protected void closeOperations() {
         out.print("closing operations ...");
         out.flush();
         ops.clear();
-        out.println("      [ok]");
+        out.println("          [ok]");
     }
 
     // ----------------------------------------------------------------------
+    // NDB API datastore operations
+    // ----------------------------------------------------------------------
+
+    protected native void initConnection(String catalog, String schema);
+    protected void initConnection() {
+        initConnection(catalog, schema);
+    }
+    protected native void closeConnection();
+    protected native void clearData();
+
+    // ----------------------------------------------------------------------
 
     static public void main(String[] args) {
         System.out.println("NdbApiLoad.main()");

=== 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-01 04:10:21 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbBase.java	2010-10-05 08:48:30 +0000
@@ -20,9 +20,9 @@
 
 package com.mysql.cluster.crund;
 
-abstract public class NdbBase extends Driver {
+abstract public class NdbBase extends CrundDriver {
 
-    // the NDB database connection
+    // NDB resources
     protected String mgmdConnect;
     protected String catalog;
     protected String schema;
@@ -30,14 +30,18 @@ abstract public class NdbBase extends Dr
     // so far, there's no NDB support for caching data beyond Tx scope
     protected void clearPersistenceContext() throws Exception {}
 
-    // NDB operations must demarcate transactions themselves
-    final protected void beginTransaction() throws Exception {}
-    final protected void commitTransaction() throws Exception {}
-    final protected void rollbackTransaction() throws Exception {}
+     // ----------------------------------------------------------------------
+    // JDBC intializers/finalizers
+    // ----------------------------------------------------------------------
 
-    protected void initProperties() {
+   protected void initProperties() {
         super.initProperties();
 
+        out.print("setting ndb properties ...");
+
+        final StringBuilder msg = new StringBuilder();
+        final String eol = System.getProperty("line.separator");
+
         // the hostname and port number of NDB mgmd
         mgmdConnect = props.getProperty("ndb.mgmdConnect", "localhost");
         assert mgmdConnect != null;
@@ -49,12 +53,22 @@ abstract public class NdbBase extends Dr
         // the schema
         schema = props.getProperty("ndb.schema", "");
         assert schema != null;
+
+        if (msg.length() == 0) {
+            out.println("      [ok]");
+        } else {
+            out.println();
+            out.print(msg.toString());
+        }
     }
 
     protected void printProperties() {
         super.printProperties();
-        out.println("ndb.mgmdConnect             \"" + mgmdConnect + "\"");
-        out.println("ndb.catalog                 \"" + catalog + "\"");
-        out.println("ndb.schema                  \"" + schema + "\"");
+
+        out.println();
+        out.println("ndb settings ...");
+        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-10-01 04:10:21 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbJTieLoad.java	2010-10-05 08:48:30 +0000
@@ -54,6 +54,10 @@ import com.mysql.ndbjtie.ndbapi.NdbIndex
  */
 public class NdbJTieLoad extends NdbBase {
 
+    // ----------------------------------------------------------------------
+    // NDB JTie resources
+    // ----------------------------------------------------------------------
+
     // singleton object representing the NDB cluster (one per process)
     protected Ndb_cluster_connection mgmd;
 
@@ -61,22 +65,73 @@ public class NdbJTieLoad extends NdbBase
     protected Ndb ndb;
 
     // the benchmark's metadata shortcuts
-    protected Meta meta;
+    protected Model model;
 
     // object representing an NDB database transaction
     protected NdbTransaction tx;
 
-    /**
-     * Returns a string representation of an NdbError.
-     */
-    static public String toStr(NdbErrorConst e) {
+    // ----------------------------------------------------------------------
+    // NDB JTie intializers/finalizers
+    // ----------------------------------------------------------------------
+
+    protected void initProperties() {
+        super.initProperties();
+        descr = "->ndbjtie(" + mgmdConnect + ")";
+    }
+
+    protected void init() throws Exception {
+        super.init();
+
+        // load native library (better diagnostics doing it explicitely)
+        out.println();
+        loadSystemLibrary("ndbclient");
+
+        // instantiate NDB cluster singleton
+        out.println();
+        out.print("creating cluster conn ...");
+        out.flush();
+        mgmd = Ndb_cluster_connection.create(mgmdConnect);
+        assert mgmd != null;
+        out.println("       [ok, mgmd=" + mgmd + "]");
+
+        // connect to cluster management node (ndb_mgmd)
+        out.print("connecting to mgmd ...");
+        out.flush();
+        final int retries = 0;        // retries (< 0 = indefinitely)
+        final int delay = 0;          // seconds to wait after retry
+        final int verbose = 1;        // print report of progess
+        // 0 = success, 1 = recoverable error, -1 = non-recoverable error
+        if (mgmd.connect(retries, delay, verbose) != 0) {
+            final String msg = ("mgmd@" + mgmdConnect
+                                + " was not ready within "
+                                + (retries * delay) + "s.");
+            out.println(msg);
+            throw new RuntimeException("!!! " + msg);
+        }
+        out.println("          [ok: " + mgmdConnect + "]");
+    }
+
+    protected void close() throws Exception {
+        out.print("closing mgmd conn ...");
+        out.flush();
+        if (mgmd != null)
+            Ndb_cluster_connection.delete(mgmd);
+        mgmd = null;
+        out.println("           [ok]");
+        super.close();
+    }
+
+    // ----------------------------------------------------------------------
+    // NDB JTie operations
+    // ----------------------------------------------------------------------
+
+    // returns a string representation of an NdbError
+    static protected String toStr(NdbErrorConst e) {
         return "NdbError[" + e.code() + "]: " + e.message();
     }
 
-    /**
-     * Holds shortcuts to the benchmark's schema information.
-     */
-    static protected class Meta {
+    // holds shortcuts to the benchmark's schema information
+    static protected class Model {
         public final TableConst table_A;
         public final TableConst table_B0;
         public final ColumnConst column_A_id;
@@ -103,7 +158,7 @@ public class NdbJTieLoad extends NdbBase
         public final int attr_B0_cvarchar_def;
 
         // initialize this instance from the dictionary
-        public Meta(Ndb ndb) {
+        public Model(Ndb ndb) {
             final Dictionary dict = ndb.getDictionary();
 
             // get columns of table A
@@ -168,93 +223,6 @@ public class NdbJTieLoad extends NdbBase
         }
     };
 
-    protected void initProperties() {
-        super.initProperties();
-        descr = "->NDBJTIE->NDBAPI(" + mgmdConnect + ")";
-    }
-
-    protected void init() throws Exception {
-        super.init();
-
-        // load native library (better diagnostics doing it explicitely)
-        out.println();
-        loadSystemLibrary("ndbclient");
-
-        // instantiate NDB cluster singleton
-        out.println();
-        out.print("creating cluster conn ...");
-        out.flush();
-        mgmd = Ndb_cluster_connection.create(mgmdConnect);
-        assert mgmd != null;
-        out.println("   [ok, mgmd=" + mgmd + "]");
-
-        // connect to cluster management node (ndb_mgmd)
-        out.print("connecting to mgmd ...");
-        out.flush();
-        final int retries = 0;        // retries (< 0 = indefinitely)
-        final int delay = 0;          // seconds to wait after retry
-        final int verbose = 1;        // print report of progess
-        // 0 = success, 1 = recoverable error, -1 = non-recoverable error
-        if (mgmd.connect(retries, delay, verbose) != 0) {
-            final String msg = ("mgmd@" + mgmdConnect
-                                + " was not ready within "
-                                + (retries * delay) + "s.");
-            out.println(msg);
-            throw new RuntimeException("!!! " + msg);
-        }
-        out.println("      [ok: " + mgmdConnect + "]");
-    }
-
-    protected void close() throws Exception {
-        out.print("closing mgmd conn ...");
-        out.flush();
-        if (mgmd != null)
-            Ndb_cluster_connection.delete(mgmd);
-        mgmd = null;
-        out.println("       [ok]");
-        super.close();
-    }
-
-    protected void initConnection() {
-        // optionally, connect and wait for reaching the data nodes (ndbds)
-        out.print("waiting for data nodes...");
-        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 "
-                                + (initial_wait + final_wait) + "s.");
-            out.println(msg);
-            throw new RuntimeException(msg);
-        }
-        out.println("   [ok]");
-
-        // connect 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
-        if (ndb.init(max_no_tx) != 0) {
-            String msg = "Error caught: " + ndb.getNdbError().message();
-            throw new RuntimeException(msg);
-        }
-        out.println("   [ok]");
-
-        // initialize the schema shortcuts
-        meta = new Meta(ndb);
-    }
-
-    protected void closeConnection() {
-        out.print("closing database conn ...");
-        out.flush();
-        meta = null;
-        Ndb.delete(ndb);
-        ndb = null;
-        out.println("   [ok]");
-    }
-
     protected void initOperations() {
         out.print("initializing operations ...");
         out.flush();
@@ -271,56 +239,56 @@ public class NdbJTieLoad extends NdbBase
             ops.add(
                 new Op("insA" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        ins(meta.table_A, 1, countA, !setAttrs, batch);
+                        ins(model.table_A, 1, countA, !setAttrs, batch);
                     }
                 });
 
             ops.add(
                 new Op("insB0" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        ins(meta.table_B0, 1, countB, !setAttrs, batch);
+                        ins(model.table_B0, 1, countB, !setAttrs, batch);
                     }
                 });
 
             ops.add(
                 new Op("setAByPK" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        setByPK(meta.table_A, 1, countA, batch);
+                        setByPK(model.table_A, 1, countA, batch);
                     }
                 });
 
             ops.add(
                 new Op("setB0ByPK" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        setByPK(meta.table_B0, 1, countB, batch);
+                        setByPK(model.table_B0, 1, countB, batch);
                     }
                 });
 
             ops.add(
                 new Op("getAByPK_bb" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        getByPK_bb(meta.table_A, 1, countA, batch);
+                        getByPK_bb(model.table_A, 1, countA, batch);
                     }
                 });
 
             ops.add(
                 new Op("getAByPK_ar" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        getByPK_ar(meta.table_A, 1, countA, batch);
+                        getByPK_ar(model.table_A, 1, countA, batch);
                     }
                 });
 
             ops.add(
                 new Op("getB0ByPK_bb" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        getByPK_bb(meta.table_B0, 1, countB, batch);
+                        getByPK_bb(model.table_B0, 1, countB, batch);
                     }
                 });
 
             ops.add(
                 new Op("getB0ByPK_ar" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        getByPK_ar(meta.table_B0, 1, countB, batch);
+                        getByPK_ar(model.table_B0, 1, countB, batch);
                     }
                 });
 
@@ -331,21 +299,21 @@ public class NdbJTieLoad extends NdbBase
                 ops.add(
                     new Op("setVarbinary" + l + (batch ? "_batch" : "")) {
                         public void run(int countA, int countB) {
-                            setVarbinary(meta.table_B0, 1, countB, batch, b);
+                            setVarbinary(model.table_B0, 1, countB, batch, b);
                         }
                     });
 
                 ops.add(
                     new Op("getVarbinary" + l + (batch ? "_batch" : "")) {
                         public void run(int countA, int countB) {
-                            getVarbinary(meta.table_B0, 1, countB, batch, b);
+                            getVarbinary(model.table_B0, 1, countB, batch, b);
                         }
                     });
 
                 ops.add(
                     new Op("clearVarbinary" + l + (batch ? "_batch" : "")) {
                         public void run(int countA, int countB) {
-                            setVarbinary(meta.table_B0, 1, countB, batch, null);
+                            setVarbinary(model.table_B0, 1, countB, batch, null);
                         }
                     });
             }
@@ -357,21 +325,21 @@ public class NdbJTieLoad extends NdbBase
                 ops.add(
                     new Op("setVarchar" + l + (batch ? "_batch" : "")) {
                         public void run(int countA, int countB) {
-                            setVarchar(meta.table_B0, 1, countB, batch, s);
+                            setVarchar(model.table_B0, 1, countB, batch, s);
                         }
                     });
 
                 ops.add(
                     new Op("getVarchar" + l + (batch ? "_batch" : "")) {
                         public void run(int countA, int countB) {
-                            getVarchar(meta.table_B0, 1, countB, batch, s);
+                            getVarchar(model.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);
+                            setVarchar(model.table_B0, 1, countB, batch, null);
                         }
                     });
             }
@@ -421,35 +389,35 @@ public class NdbJTieLoad extends NdbBase
             ops.add(
                 new Op("delB0ByPK" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        delByPK(meta.table_B0, 1, countB, batch);
+                        delByPK(model.table_B0, 1, countB, batch);
                     }
                 });
 
             ops.add(
                 new Op("delAByPK" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        delByPK(meta.table_A, 1, countA, batch);
+                        delByPK(model.table_A, 1, countA, batch);
                     }
                 });
 
             ops.add(
                 new Op("insA_attr" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        ins(meta.table_A, 1, countA, setAttrs, batch);
+                        ins(model.table_A, 1, countA, setAttrs, batch);
                     }
                 });
 
             ops.add(
                 new Op("insB0_attr" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        ins(meta.table_B0, 1, countB, setAttrs, batch);
+                        ins(model.table_B0, 1, countB, setAttrs, batch);
                     }
                 });
 
             ops.add(
                 new Op("delAllB0" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        final int count = delByScan(meta.table_B0, batch);
+                        final int count = delByScan(model.table_B0, batch);
                         assert count == countB;
                     }
                 });
@@ -457,23 +425,23 @@ public class NdbJTieLoad extends NdbBase
             ops.add(
                 new Op("delAllA" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB) {
-                        final int count = delByScan(meta.table_A, batch);
+                        final int count = delByScan(model.table_A, batch);
                         assert count == countA;
                     }
                 });
         }
 
-        out.println(" [Op: " + ops.size() + "]");
+        out.println("     [Op: " + ops.size() + "]");
     }
 
     protected void closeOperations() {
         out.print("closing operations ...");
         out.flush();
         ops.clear();
-        out.println("      [ok]");
+        out.println("          [ok]");
     }
 
-    protected void beginTransaction1() {
+    protected void beginTransaction() {
         // start a transaction
         // must be closed with NdbTransaction.close
         final TableConst table  = null;
@@ -483,7 +451,7 @@ public class NdbJTieLoad extends NdbBase
             throw new RuntimeException(toStr(ndb.getNdbError()));
     }
 
-    protected void executeOperations1() {
+    protected void executeOperations() {
         // execute but don't commit the current transaction
         final int execType = NdbTransaction.ExecType.NoCommit;
         final int abortOption = NdbOperation.AbortOption.AbortOnError;
@@ -493,7 +461,7 @@ public class NdbJTieLoad extends NdbBase
             throw new RuntimeException(toStr(tx.getNdbError()));
     }
 
-    protected void commitTransaction1() {
+    protected void commitTransaction() {
         // commit the current transaction
         final int execType = NdbTransaction.ExecType.Commit;
         final int abortOption = NdbOperation.AbortOption.AbortOnError;
@@ -503,7 +471,7 @@ public class NdbJTieLoad extends NdbBase
             throw new RuntimeException(toStr(tx.getNdbError()));
     }
 
-    protected void rollbackTransaction1() {
+    protected void rollbackTransaction() {
         // abort the current transaction
         final int execType = NdbTransaction.ExecType.Rollback;
         final int abortOption = NdbOperation.AbortOption.DefaultAbortOption;
@@ -513,7 +481,7 @@ public class NdbJTieLoad extends NdbBase
             throw new RuntimeException(toStr(tx.getNdbError()));
     }
 
-    protected void closeTransaction1() {
+    protected void closeTransaction() {
         // close the current transaction
         // to be called irrespectively of success or failure
         // equivalent to tx.close()
@@ -521,18 +489,6 @@ public class NdbJTieLoad extends NdbBase
         tx = null;
     }
 
-    protected void clearData() {
-        out.print("deleting all rows ...");
-        out.flush();
-        final int delB0 = delByScan(meta.table_B0, true);
-        out.print("       [B0: " + delB0);
-        out.flush();
-        final int delA = delByScan(meta.table_A, true);
-        out.print(", A: " + delA);
-        out.flush();
-        out.println("]");
-    }
-
     // ----------------------------------------------------------------------
 
     static protected class CommonAB_RA {
@@ -545,15 +501,15 @@ public class NdbJTieLoad extends NdbBase
 
     protected void fetchCommonAttributes(CommonAB_RA cab, NdbOperation op) {
         final ByteBuffer val = null;
-        if ((cab.id = op.getValue(meta.attr_id, val)) == null)
+        if ((cab.id = op.getValue(model.attr_id, val)) == null)
             throw new RuntimeException(toStr(tx.getNdbError()));
-        if ((cab.cint = op.getValue(meta.attr_cint, val)) == null)
+        if ((cab.cint = op.getValue(model.attr_cint, val)) == null)
             throw new RuntimeException(toStr(tx.getNdbError()));
-        if ((cab.clong = op.getValue(meta.attr_clong, val)) == null)
+        if ((cab.clong = op.getValue(model.attr_clong, val)) == null)
             throw new RuntimeException(toStr(tx.getNdbError()));
-        if ((cab.cfloat = op.getValue(meta.attr_cfloat, val)) == null)
+        if ((cab.cfloat = op.getValue(model.attr_cfloat, val)) == null)
             throw new RuntimeException(toStr(tx.getNdbError()));
-        if ((cab.cdouble = op.getValue(meta.attr_cdouble, val)) == null)
+        if ((cab.cdouble = op.getValue(model.attr_cdouble, val)) == null)
             throw new RuntimeException(toStr(tx.getNdbError()));
     }
 
@@ -572,7 +528,7 @@ public class NdbJTieLoad extends NdbBase
 
     protected void ins(TableConst table, int from, int to,
                        boolean setAttrs, boolean batch) {
-        beginTransaction1();
+        beginTransaction();
         for (int i = from; i <= to; i++) {
             // get an insert operation for the table
             NdbOperation op = tx.getNdbOperation(table);
@@ -582,30 +538,30 @@ public class NdbJTieLoad extends NdbBase
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // set values; key attribute needs to be set first
-            if (op.equal(meta.attr_id, i) != 0)
+            if (op.equal(model.attr_id, i) != 0)
                 throw new RuntimeException(toStr(tx.getNdbError()));
             if (setAttrs) {
-                if (op.setValue(meta.attr_cint, -i) != 0)
+                if (op.setValue(model.attr_cint, -i) != 0)
                     throw new RuntimeException(toStr(tx.getNdbError()));
-                if (op.setValue(meta.attr_clong, (long)-i) != 0)
+                if (op.setValue(model.attr_clong, (long)-i) != 0)
                     throw new RuntimeException(toStr(tx.getNdbError()));
-                if (op.setValue(meta.attr_cfloat, (float)-i) != 0)
+                if (op.setValue(model.attr_cfloat, (float)-i) != 0)
                     throw new RuntimeException(toStr(tx.getNdbError()));
-                if (op.setValue(meta.attr_cdouble, (double)-i) != 0)
+                if (op.setValue(model.attr_cdouble, (double)-i) != 0)
                     throw new RuntimeException(toStr(tx.getNdbError()));
             }
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
     }
 
     protected void delByPK(TableConst table, int from, int to,
                            boolean batch) {
-        beginTransaction1();
+        beginTransaction();
         for (int i = from; i <= to; i++) {
             // get a delete operation for the table
             NdbOperation op = tx.getNdbOperation(table);
@@ -615,25 +571,25 @@ public class NdbJTieLoad extends NdbBase
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // set key attribute
-            if (op.equal(meta.attr_id, i) != 0)
+            if (op.equal(model.attr_id, i) != 0)
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
     }
 
     protected int delByScan(TableConst table, boolean batch) {
-        beginTransaction1();
+        beginTransaction();
 
         // get a full table scan operation (no scan filter defined)
         final NdbScanOperation op = tx.getNdbScanOperation(table);
         if (op == null)
             throw new RuntimeException(toStr(tx.getNdbError()));
-        
+
         // define a read scan with exclusive locks
         final int lock_mode = NdbOperation.LockMode.LM_Exclusive;
         final int scan_flags = 0;
@@ -643,7 +599,7 @@ public class NdbJTieLoad extends NdbBase
             throw new RuntimeException(toStr(tx.getNdbError()));
 
         // start the scan; don't commit yet
-        executeOperations1();
+        executeOperations();
 
         // delete all rows in a given scan
         int count = 0;
@@ -656,10 +612,10 @@ public class NdbJTieLoad extends NdbBase
                 if (op.deleteCurrentTuple() != 0)
                     throw new RuntimeException(toStr(tx.getNdbError()));
                 count++;
-                
+
                 // execute the operation now if in non-batching mode
                 if (!batch)
-                    executeOperations1();
+                    executeOperations();
             } while ((stat = op.nextResult(!allowFetch, forceSend)) == 0);
 
             if (stat == 1) {
@@ -686,14 +642,14 @@ public class NdbJTieLoad extends NdbBase
         final boolean releaseOp = false;
         op.close(forceSend_, releaseOp);
 
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
         return count;
     }
 
     protected void setByPK(TableConst table, int from, int to,
                            boolean batch) {
-        beginTransaction1();
+        beginTransaction();
         for (int i = from; i <= to; i++) {
             // get an update operation for the table
             NdbOperation op = tx.getNdbOperation(table);
@@ -703,43 +659,43 @@ public class NdbJTieLoad extends NdbBase
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // set key attribute
-            if (op.equal(meta.attr_id, i) != 0)
+            if (op.equal(model.attr_id, i) != 0)
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // set values
-            if (op.setValue(meta.attr_cint, i) != 0)
+            if (op.setValue(model.attr_cint, i) != 0)
                 throw new RuntimeException(toStr(tx.getNdbError()));
-            if (op.setValue(meta.attr_clong, (long)i) != 0)
+            if (op.setValue(model.attr_clong, (long)i) != 0)
                 throw new RuntimeException(toStr(tx.getNdbError()));
-            if (op.setValue(meta.attr_cfloat, (float)i) != 0)
+            if (op.setValue(model.attr_cfloat, (float)i) != 0)
                 throw new RuntimeException(toStr(tx.getNdbError()));
-            if (op.setValue(meta.attr_cdouble, (double)i) != 0)
+            if (op.setValue(model.attr_cdouble, (double)i) != 0)
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
     }
 
     protected void fetchCommonAttributes(ByteBuffer cab, NdbOperation op) {
-        if (op.getValue(meta.attr_id, cab) == null)
+        if (op.getValue(model.attr_id, cab) == null)
             throw new RuntimeException(toStr(tx.getNdbError()));
         int p = cab.position();
         //out.println("cab.position() == " + p);
         cab.position(p += 4);
-        if (op.getValue(meta.attr_cint, cab) == null)
+        if (op.getValue(model.attr_cint, cab) == null)
             throw new RuntimeException(toStr(tx.getNdbError()));
         cab.position(p += 4);
-        if (op.getValue(meta.attr_clong, cab) == null)
+        if (op.getValue(model.attr_clong, cab) == null)
             throw new RuntimeException(toStr(tx.getNdbError()));
         cab.position(p += 8);
-        if (op.getValue(meta.attr_cfloat, cab) == null)
+        if (op.getValue(model.attr_cfloat, cab) == null)
             throw new RuntimeException(toStr(tx.getNdbError()));
         cab.position(p += 4);
-        if (op.getValue(meta.attr_cdouble, cab) == null)
+        if (op.getValue(model.attr_cdouble, cab) == null)
             throw new RuntimeException(toStr(tx.getNdbError()));
         cab.position(p += 8);
     }
@@ -774,7 +730,7 @@ public class NdbJTieLoad extends NdbBase
         final ByteBuffer cab = ByteBuffer.allocateDirect(count * 28);
         cab.order(ByteOrder.nativeOrder());
 
-        beginTransaction1();
+        beginTransaction();
         for (int i = 0, j = from; i < count; i++, j++) {
             // get a read operation for the table
             NdbOperation op = tx.getNdbOperation(table);
@@ -784,17 +740,17 @@ public class NdbJTieLoad extends NdbBase
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // set key attribute
-            if (op.equal(meta.attr_id, j) != 0)
+            if (op.equal(model.attr_id, j) != 0)
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // get attributes (not readable until after commit)
             fetchCommonAttributes(cab, op);
-            
+
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
+        commitTransaction();
 
         // check fetched values
         cab.rewind();
@@ -804,7 +760,7 @@ public class NdbJTieLoad extends NdbBase
             final int id1 = verifyCommonAttributes(cab);
             verify(id1 == j);
         }
-        closeTransaction1();
+        closeTransaction();
     }
 
     protected void getByPK_ar(TableConst table, int from, int to,
@@ -813,7 +769,7 @@ public class NdbJTieLoad extends NdbBase
         final int count = (to - from) + 1;
         final CommonAB_RA[] cab_ra = new CommonAB_RA[count];
 
-        beginTransaction1();
+        beginTransaction();
         for (int i = 0, j = from; i < count; i++, j++) {
             // get a read operation for the table
             NdbOperation op = tx.getNdbOperation(table);
@@ -823,32 +779,32 @@ public class NdbJTieLoad extends NdbBase
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // set key attribute
-            if (op.equal(meta.attr_id, j) != 0)
+            if (op.equal(model.attr_id, j) != 0)
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // get attributes (not readable until after commit)
             final CommonAB_RA c = new CommonAB_RA();
-            //if ((c.id = op.getValue(meta.attr_id, null)) == null)
+            //if ((c.id = op.getValue(model.attr_id, null)) == null)
             //    throw new RuntimeException(toStr(tx.getNdbError()));
             fetchCommonAttributes(c, op);
             cab_ra[i] = c;
-            
+
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
+        commitTransaction();
 
         // check fetched values
         for (int i = 0, j = from; i < count; i++, j++) {
             //check key attribute
             verify(cab_ra[i].id.int32_value() == j);
-            
+
             // check other attributes
             final int id1 = verifyCommonAttributes(cab_ra[i]);
             verify(id1 == j);
         }
-        closeTransaction1();
+        closeTransaction();
     }
 
     protected void setVarbinary(TableConst table, int from, int to,
@@ -871,7 +827,7 @@ public class NdbJTieLoad extends NdbBase
             buf.flip();
         }
 
-        beginTransaction1();
+        beginTransaction();
         for (int i = from; i <= to; i++) {
             // get an insert operation for the table
             NdbOperation op = tx.getNdbOperation(table);
@@ -881,19 +837,19 @@ public class NdbJTieLoad extends NdbBase
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // set key attribute
-            if (op.equal(meta.attr_id, i) != 0)
+            if (op.equal(model.attr_id, i) != 0)
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // set values
-            if (op.setValue(meta.attr_B0_cvarbinary_def, buf) != 0)
+            if (op.setValue(model.attr_B0_cvarbinary_def, buf) != 0)
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
 */
     }
 
@@ -901,24 +857,24 @@ public class NdbJTieLoad extends NdbBase
                               boolean batch, String string) {
 // XXX not implemented yet
 /*
-        beginTransaction1();
+        beginTransaction();
         for (int i = from; i <= to; i++) {
             // get an update operation for the table
             final NdbOperation op = tx.getUpdateOperation(table);
             assert op != null;
 
             // set key attribute
-            op.equalInt(meta.attr_id, i);
+            op.equalInt(model.attr_id, i);
 
             // set varchar
-            op.setString(meta.attr_B0_cvarchar_def, string);
+            op.setString(model.attr_B0_cvarchar_def, string);
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
 */
     }
 
@@ -932,8 +888,8 @@ public class NdbJTieLoad extends NdbBase
         final int sbuf = count * sline;
         final ByteBuffer buf = ByteBuffer.allocateDirect(sbuf);
         //buf.order(ByteOrder.nativeOrder());
-        
-        beginTransaction1();
+
+        beginTransaction();
         for (int i = 0, j = from; i < count; i++, j++) {
             // get a read operation for the table
             NdbOperation op = tx.getNdbOperation(table);
@@ -943,7 +899,7 @@ public class NdbJTieLoad extends NdbBase
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // set key attribute
-            if (op.equal(meta.attr_id, j) != 0)
+            if (op.equal(model.attr_id, j) != 0)
                 throw new RuntimeException(toStr(tx.getNdbError()));
 
             // get attributes (not readable until after commit)
@@ -952,12 +908,12 @@ public class NdbJTieLoad extends NdbBase
                 throw new RuntimeException(toStr(tx.getNdbError()));
             //out.println("buf.position() == " + p);
             buf.position(p += sline);
-            
+
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
+        commitTransaction();
 
         // check fetched values
         buf.rewind();
@@ -970,16 +926,16 @@ public class NdbJTieLoad extends NdbBase
 
             const size_t n = s[0];
             VERIFY(n < sline);
-            
+
             // move and 0-terminated string
             memmove(s, s + 1, n);
             s[n] = 0;
-            
+
             // check fetched values
             //CDBG << "!!! s=" << (void*)s << ", '" << s << "'" << endl;
             VERIFY(strcmp(s, str) == 0);
         }
-        closeTransaction1();
+        closeTransaction();
 */
     }
 
@@ -991,27 +947,27 @@ public class NdbJTieLoad extends NdbBase
         final int count = (to - from) + 1;
         final NdbResultSet[] rss = new NdbResultSet[count];
 
-        beginTransaction1();
+        beginTransaction();
         for (int i = 0, j = from; i < count; i++, j++) {
             // get a read operation for the table
             NdbOperation op = tx.getSelectOperation(table);
             assert op != null;
 
             // set key attribute
-            op.equalInt(meta.attr_id, j);
+            op.equalInt(model.attr_id, j);
 
             // define fetched attributes
-            op.getValue(meta.attr_B0_cvarchar_def);
+            op.getValue(model.attr_B0_cvarchar_def);
 
             // get attributes (not readable until after commit)
             rss[i] = op.resultData();
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        //executeOperations1();
-        commitTransaction1();
+        //executeOperations();
+        commitTransaction();
 
         // check fetched values
         for (int i = 0, j = from; i < count; i++, j++) {
@@ -1022,18 +978,18 @@ public class NdbJTieLoad extends NdbBase
             // check varchar
             if (true) {
                 final String cvarchar_def
-                    = rs.getString(meta.attr_B0_cvarchar_def);
+                    = rs.getString(model.attr_B0_cvarchar_def);
                 verify(string.equals(cvarchar_def));
             } else {
                 // verification imposes a string->bytes conversion penalty
                 final byte[] cvarchar_def
-                    = rs.getStringBytes(meta.attr_B0_cvarchar_def);
+                    = rs.getStringBytes(model.attr_B0_cvarchar_def);
                 verify(Arrays.equals(string.getBytes(), cvarchar_def));
             }
 
             assert !rs.next();
         }
-        closeTransaction1();
+        closeTransaction();
 */
     }
 
@@ -1041,25 +997,25 @@ public class NdbJTieLoad extends NdbBase
                             boolean batch) {
 // XXX not implemented yet
 /*
-        beginTransaction1();
+        beginTransaction();
         for (int i = 1; i <= count_B; i++) {
             // get an update operation for the table
-            final NdbOperation op = tx.getUpdateOperation(meta.table_B0);
+            final NdbOperation op = tx.getUpdateOperation(model.table_B0);
             assert op != null;
 
             // set key attribute
-            op.equalInt(meta.attr_id, i);
+            op.equalInt(model.attr_id, i);
 
             // set a_id attribute
             int a_id = ((i - 1) % count_A) + 1;
-            op.setInt(meta.attr_B0_a_id, a_id);
+            op.setInt(model.attr_B0_a_id, a_id);
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
 */
     }
 
@@ -1067,25 +1023,25 @@ public class NdbJTieLoad extends NdbBase
                              boolean batch) {
 // XXX not implemented yet
 /*
-        beginTransaction1();
+        beginTransaction();
         for (int i = 1; i <= count_B; i++) {
             // get an update operation for the table
-            final NdbOperation op = tx.getUpdateOperation(meta.table_B0);
+            final NdbOperation op = tx.getUpdateOperation(model.table_B0);
             assert op != null;
 
             // set key attribute
-            op.equalInt(meta.attr_id, i);
+            op.equalInt(model.attr_id, i);
 
             // set a_id attribute
             int a_id = ((i - 1) % count_A) + 1;
-            op.setNull(meta.attr_B0_a_id);
+            op.setNull(model.attr_B0_a_id);
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
 */
     }
 
@@ -1093,7 +1049,7 @@ public class NdbJTieLoad extends NdbBase
                             boolean batch) {
 // XXX not implemented yet
 /*
-        beginTransaction1();
+        beginTransaction();
 
         // fetch the foreign keys from B0 and read attributes from A
         final NdbResultSet[] abs = new NdbResultSet[count_B];
@@ -1102,33 +1058,33 @@ public class NdbJTieLoad extends NdbBase
             NdbResultSet rs;
             {
                 // get a read operation for the table
-                NdbOperation op = tx.getSelectOperation(meta.table_B0);
+                NdbOperation op = tx.getSelectOperation(model.table_B0);
                 assert op != null;
 
                 // set key attribute
-                op.equalInt(meta.attr_id, i);
+                op.equalInt(model.attr_id, i);
 
                 // define fetched attributes
-                op.getValue(meta.attr_B0_a_id);
+                op.getValue(model.attr_B0_a_id);
 
                 // get attributes (not readable until after commit)
                 rs = op.resultData();
             }
-            executeOperations1(); // start the scan; don't commit yet
+            executeOperations(); // start the scan; don't commit yet
 
             // fetch the attributes from A
             {
                 // get a read operation for the table
-                NdbOperation op = tx.getSelectOperation(meta.table_A);
+                NdbOperation op = tx.getSelectOperation(model.table_A);
                 assert op != null;
 
                 // set key attribute
-                final int a_id = rs.getInt(meta.attr_B0_a_id);
+                final int a_id = rs.getInt(model.attr_B0_a_id);
                 assert a_id == ((i - 1) % count_A) + 1;
-                op.equalInt(meta.attr_id, a_id);
+                op.equalInt(model.attr_id, a_id);
 
                 // define fetched attributes
-                op.getValue(meta.attr_id);
+                op.getValue(model.attr_id);
                 fetchCommonAttributes(op);
 
                 // get attributes (not readable until after commit)
@@ -1137,9 +1093,9 @@ public class NdbJTieLoad extends NdbBase
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
+        commitTransaction();
 
         // check fetched values
         for (int i = 1, j = 0; i <= count_B; i++, j++) {
@@ -1148,7 +1104,7 @@ public class NdbJTieLoad extends NdbBase
             assert hasNext;
 
             // check key attribute
-            final int id = ab.getInt(meta.attr_id);
+            final int id = ab.getInt(model.attr_id);
             //out.println("id = " + id + ", i = " + i);
             verify(id == ((i - 1) % count_A) + 1);
 
@@ -1158,7 +1114,7 @@ public class NdbJTieLoad extends NdbBase
 
             assert !ab.next();
         }
-        closeTransaction1();
+        closeTransaction();
 */
     }
 
@@ -1166,40 +1122,40 @@ public class NdbJTieLoad extends NdbBase
                                boolean batch) {
 // XXX not implemented yet
 /*
-        beginTransaction1();
+        beginTransaction();
 
         // fetch the foreign key value from B0
         final NdbResultSet[] a_ids = new NdbResultSet[count_B];
         for (int i = 1, j = 0; i <= count_B; i++, j++) {
                 // get a read operation for the table
-                NdbOperation op = tx.getSelectOperation(meta.table_B0);
+                NdbOperation op = tx.getSelectOperation(model.table_B0);
                 assert op != null;
 
                 // set key attribute
-                op.equalInt(meta.attr_id, i);
+                op.equalInt(model.attr_id, i);
 
                 // define fetched attributes
-                op.getValue(meta.attr_B0_a_id);
+                op.getValue(model.attr_B0_a_id);
 
                 // get attributes (not readable until after commit)
                 a_ids[j] = op.resultData();
         }
-        executeOperations1(); // start the scan; don't commit yet
+        executeOperations(); // start the scan; don't commit yet
 
         // fetch the attributes from A
         final NdbResultSet[] abs = new NdbResultSet[count_B];
         for (int i = 1, j = 0; i <= count_B; i++, j++) {
             // get a read operation for the table
-            NdbOperation op = tx.getSelectOperation(meta.table_A);
+            NdbOperation op = tx.getSelectOperation(model.table_A);
             assert op != null;
 
             // set key attribute
-            final int a_id = a_ids[j].getInt(meta.attr_B0_a_id);
+            final int a_id = a_ids[j].getInt(model.attr_B0_a_id);
             assert a_id == ((i - 1) % count_A) + 1;
-            op.equalInt(meta.attr_id, a_id);
+            op.equalInt(model.attr_id, a_id);
 
             // define fetched attributes
-            op.getValue(meta.attr_id);
+            op.getValue(model.attr_id);
             fetchCommonAttributes(op);
 
             // get attributes (not readable until after commit)
@@ -1207,9 +1163,9 @@ public class NdbJTieLoad extends NdbBase
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
+        commitTransaction();
 
         // check fetched values
         for (int i = 1, j = 0; i <= count_B; i++, j++) {
@@ -1218,7 +1174,7 @@ public class NdbJTieLoad extends NdbBase
             assert hasNext;
 
             // check key attribute
-            final int id = ab.getInt(meta.attr_id);
+            final int id = ab.getInt(model.attr_id);
             //out.println("id = " + id + ", i = " + i);
             verify(id == ((i - 1) % count_A) + 1);
 
@@ -1228,7 +1184,7 @@ public class NdbJTieLoad extends NdbBase
 
             assert !ab.next();
         }
-        closeTransaction1();
+        closeTransaction();
 */
     }
 
@@ -1236,7 +1192,7 @@ public class NdbJTieLoad extends NdbBase
                             boolean forceSend) {
 // XXX not implemented yet
 /*
-        beginTransaction1();
+        beginTransaction();
 
         // fetch attributes from B0 by foreign key scan
         final NdbResultSet[] abs = new NdbResultSet[count_B];
@@ -1245,8 +1201,8 @@ public class NdbJTieLoad extends NdbBase
             // get an index scan operation for the table
             // XXX ? no locks (LM_CommittedRead) or shared locks (LM_Read)
             final NdbIndexScanOperation op
-                = tx.getSelectIndexScanOperation(meta.idx_B0_a_id,
-                                                 meta.table_B0,
+                = tx.getSelectIndexScanOperation(model.idx_B0_a_id,
+                                                 model.table_B0,
                                                  LockMode.LM_CommittedRead);
             assert op != null;
 
@@ -1258,10 +1214,10 @@ public class NdbJTieLoad extends NdbBase
             //
             // which translates into
             //out.println("idx_B0_a_id.getNoOfColumns() = "
-            //            + meta.idx_B0_a_id.getNoOfColumns());
+            //            + model.idx_B0_a_id.getNoOfColumns());
             //out.println("idx_B0_a_id.getColumn(0).getColumnNo() = "
-            //            + meta.idx_B0_a_id.getColumn(0).getColumnNo());
-            //op.setBoundInt(meta.idx_B0_a_id.getColumn(0).getColumnNo(),
+            //            + model.idx_B0_a_id.getColumn(0).getColumnNo());
+            //op.setBoundInt(model.idx_B0_a_id.getColumn(0).getColumnNo(),
             //               BoundType.BoundEQ, i);
             // except that we get the usual error with NDBJ:
             //[java] idx_B0_a_id.getColumn(0).getColumnNo() = 0
@@ -1270,18 +1226,18 @@ public class NdbJTieLoad extends NdbBase
             //
             // so we go by column name
             //out.println("idx_B0_a_id.getColumn(0).getName() = "
-            //            + meta.idx_B0_a_id.getColumn(0).getName());
-            //op.setBoundInt(meta.idx_B0_a_id.getColumn(0).getName(),
+            //            + model.idx_B0_a_id.getColumn(0).getName());
+            //op.setBoundInt(model.idx_B0_a_id.getColumn(0).getName(),
             //               BoundType.BoundEQ, i);
             // which is actually "a_id", so, for now, we call
             op.setBoundInt("a_id", BoundType.BoundEQ, i);
 
             // define fetched attributes
-            op.getValue(meta.attr_id);
+            op.getValue(model.attr_id);
             fetchCommonAttributes(op);
 
             // start the scan; don't commit yet
-            executeOperations1();
+            executeOperations();
 
             int stat;
             final boolean allowFetch = true; // request new batches when exhausted
@@ -1292,7 +1248,7 @@ public class NdbJTieLoad extends NdbBase
             if (stat != 1)
                 throw new RuntimeException("stat == " + stat);
         }
-        commitTransaction1();
+        commitTransaction();
         assert (j++ == count_B);
 
         // check fetched values
@@ -1305,13 +1261,13 @@ public class NdbJTieLoad extends NdbBase
             //[java] j = 1, ab = com.mysql.ndbjtie.ndbapi.NdbResultSetImpl@6f144c
             //    [java] caught com.mysql.ndbjtie.ndbapi.NdbApiException: Unknown error code
             //    [java] com.mysql.ndbjtie.ndbapi.NdbApiException: Unknown error code
-            //    [java] at com.mysql.ndbjtie.ndbapi.NdbJTieJNI.NdbScanOperationImpl_nextResult__SWIG_1(Native Method)
+            //    [java] at com.mysql.ndbjtie.ndbapi.NdbJTieJNI.NdbScanOperationImpl_nextResult__SWIG_(Native Method)
             //    [java] at com.mysql.ndbjtie.ndbapi.NdbScanOperationImpl.nextResult(NdbScanOperationImpl.java:93)
             //    [java] at com.mysql.ndbjtie.ndbapi.NdbResultSetImpl.next(NdbResultSetImpl.java:362)
             //    [java] at com.mysql.cluster.crund.NdbJTieLoad.navAToB0(NdbJTieLoad.java:1205)
             //
             // YYY Frazer: check tx object for error (could be node failure)
-            // Martin: doesn't help much; after ab.next(): 
+            // Martin: doesn't help much; after ab.next():
             //out.println("tx.getNdbError() = " + tx.getNdbError().getCode());
             // returns -1 and
             //out.println("tx.getNdbError() = " + tx.getNdbError().getMessage());
@@ -1328,7 +1284,7 @@ public class NdbJTieLoad extends NdbBase
             assert hasNext;
 
             // check key attribute
-            final int id = ab.getInt(meta.attr_id);
+            final int id = ab.getInt(model.attr_id);
             verify(id == i);
 
             // check other attributes
@@ -1337,7 +1293,7 @@ public class NdbJTieLoad extends NdbBase
 
             assert !ab.next();
         }
-        closeTransaction1();
+        closeTransaction();
 */
     }
 
@@ -1349,6 +1305,63 @@ public class NdbJTieLoad extends NdbBase
 */
     }
 
+
+    // ----------------------------------------------------------------------
+    // NDB JTie datastore operations
+    // ----------------------------------------------------------------------
+
+    protected void initConnection() {
+        // optionally, connect and wait for reaching the data nodes (ndbds)
+        out.print("waiting for data nodes...");
+        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 "
+                                + (initial_wait + final_wait) + "s.");
+            out.println(msg);
+            throw new RuntimeException(msg);
+        }
+        out.println("       [ok]");
+
+        // connect 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
+        if (ndb.init(max_no_tx) != 0) {
+            String msg = "Error caught: " + ndb.getNdbError().message();
+            throw new RuntimeException(msg);
+        }
+        out.println("       [ok]");
+
+        // initialize the schema shortcuts
+        model = new Model(ndb);
+    }
+
+    protected void closeConnection() {
+        out.print("closing database conn ...");
+        out.flush();
+        model = null;
+        Ndb.delete(ndb);
+        ndb = null;
+        out.println("       [ok]");
+    }
+
+    protected void clearData() {
+        out.print("deleting all rows ...");
+        out.flush();
+        final int delB0 = delByScan(model.table_B0, true);
+        out.print("           [B0: " + delB0);
+        out.flush();
+        final int delA = delByScan(model.table_A, true);
+        out.print(", A: " + delA);
+        out.flush();
+        out.println("]");
+    }
+
     // ----------------------------------------------------------------------
 
     static public void main(String[] args) {

=== modified file 'storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbjLoad.java'
--- a/storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbjLoad.java	2010-02-14 05:05:31 +0000
+++ b/storage/ndb/test/crund/src/com/mysql/cluster/crund/NdbjLoad.java	2010-10-05 08:48:30 +0000
@@ -49,6 +49,10 @@ import com.mysql.cluster.ndbj.NdbResultS
  */
 public class NdbjLoad extends NdbBase {
 
+    // ----------------------------------------------------------------------
+    // NDBJ resources
+    // ----------------------------------------------------------------------
+
     // singleton object representing the NDB cluster (one per process)
     protected NdbClusterConnection mgmd;
 
@@ -61,17 +65,68 @@ public class NdbjLoad extends NdbBase {
     // object representing an NDB database transaction
     protected NdbTransaction tx;
 
-    /**
-     * Returns a string representation of an NdbError.
-     */
-    static public String toStr(NdbError e) {
+    // ----------------------------------------------------------------------
+    // NDBJ intializers/finalizers
+    // ----------------------------------------------------------------------
+
+    protected void initProperties() {
+        super.initProperties();
+        descr = "->ndbj->ndbapi(" + mgmdConnect + ")";
+    }
+
+    protected void init() throws Exception {
+        super.init();
+
+        // load native library (better diagnostics doing it explicitely)
+        out.println();
+        loadSystemLibrary("ndbj");
+
+        // instantiate NDB cluster singleton
+        out.println();
+        out.print("creating cluster conn...");
+        out.flush();
+        mgmd = NdbClusterConnection.create(mgmdConnect);
+        assert mgmd != null;
+        out.println("    [ok]");
+
+        // connect to cluster management node (ndb_mgmd)
+        out.print("connecting to mgmd ...");
+        out.flush();
+        final int retries = 0;        // retries (< 0 = indefinitely)
+        final int delay = 0;          // seconds to wait after retry
+        final boolean verbose = true; // print report of progess
+        // 0 = success, 1 = recoverable error, -1 = non-recoverable error
+        if (mgmd.connect(retries, delay, verbose) != 0) {
+            final String msg = ("mgmd@" + mgmdConnect
+                                + " was not ready within "
+                                + (retries * delay) + "s.");
+            out.println(msg);
+            throw new RuntimeException("!!! " + msg);
+        }
+        out.println("      [ok: " + mgmdConnect + "]");
+    }
+
+    protected void close() throws Exception {
+        out.print("closing mgmd conn ...");
+        out.flush();
+        if (mgmd != null)
+            mgmd.close();
+        mgmd = null;
+        out.println("       [ok]");
+        super.close();
+    }
+
+    // ----------------------------------------------------------------------
+    // NDBJ operations
+    // ----------------------------------------------------------------------
+
+    // returns a string representation of an NdbError
+    static protected String toStr(NdbError e) {
         return "NdbError[" + e.getCode() + "]: " + e.getMessage();
     }
 
-    /**
-     * Holds shortcuts to the benchmark's schema information.
-     */
-    static protected class Meta {
+    // holds shortcuts to the benchmark's schema information
+    static protected class Model {
         public final NdbTable table_A;
         public final NdbTable table_B0;
         public final NdbColumn column_A_id;
@@ -109,7 +164,7 @@ public class NdbjLoad extends NdbBase {
         public final String name_B0_cvarchar_def;
 
         // initialize this instance from the dictionary
-        public Meta(Ndb ndb) throws NdbApiException {
+        public Model(Ndb ndb) throws NdbApiException {
             final NdbDictionary dict = ndb.getDictionary();
 
             // get columns of table A
@@ -207,103 +262,6 @@ public class NdbjLoad extends NdbBase {
     final String[] strings = { string1, string10, string100 };
     final byte[][] bytes = { bytes1, bytes10, bytes100 };
 
-    protected void initProperties() {
-        super.initProperties();
-        descr = "->NDBJ->NDBAPI(" + mgmdConnect + ")";
-    }
-
-    protected void init() throws Exception {
-        super.init();
-
-        // load native library (better diagnostics doing it explicitely)
-        out.println();
-        loadSystemLibrary("ndbj");
-
-        // instantiate NDB cluster singleton
-        out.println();
-        out.print("creating cluster conn...");
-        out.flush();
-        mgmd = NdbClusterConnection.create(mgmdConnect);
-        assert mgmd != null;
-        out.println("    [ok]");
-
-        // connect to cluster management node (ndb_mgmd)
-        out.print("connecting to mgmd ...");
-        out.flush();
-        final int retries = 0;        // retries (< 0 = indefinitely)
-        final int delay = 0;          // seconds to wait after retry
-        final boolean verbose = true; // print report of progess
-        // 0 = success, 1 = recoverable error, -1 = non-recoverable error
-        if (mgmd.connect(retries, delay, verbose) != 0) {
-            final String msg = ("mgmd@" + mgmdConnect
-                                + " was not ready within "
-                                + (retries * delay) + "s.");
-            out.println(msg);
-            throw new RuntimeException("!!! " + msg);
-        }
-        out.println("      [ok: " + mgmdConnect + "]");
-    }
-
-    protected void close() throws Exception {
-        out.print("closing mgmd conn ...");
-        out.flush();
-        if (mgmd != null)
-            mgmd.close();
-        mgmd = null;
-        out.println("       [ok]");
-        super.close();
-    }
-
-    protected void initConnection() throws NdbApiException {
-        // optionally, connect and wait for reaching the data nodes (ndbds)
-        out.print("waiting for data nodes...");
-        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
-
-        // XXX return: 0 all nodes live, > 0 at least one node live, < 0 error
-        try {
-            mgmd.waitUntilReady(initial_wait, final_wait);
-        } catch (NdbApiException e) {
-            out.println();
-            out.println("!!! data nodes were not ready within "
-                        + (initial_wait + final_wait) + "s.");
-            throw e;
-        }
-        out.println("   [ok]");
-
-        // connect to database
-        out.print("connecting to database...");
-        out.flush();
-        try {
-            // XXX where to set schema?
-            // YYY Frazer: schema not too useful in NDB at the moment
-            // XXX unclear if maxThreads ^= maxNumberOfTransactions
-            //     since ndb.init(maxNumberOfTransactions) is deprecated
-            //final int maxThreads = 4;
-            //ndb = mgmd.createNdb(catalog, maxThreads);
-            // YYY Frazer: yes, maxThreads == maxNumber(concurrent)OfTransactions
-            ndb = mgmd.createNdb(catalog);
-        } catch (NdbApiException e) {
-            out.println();
-            out.println("!!! failed to connect: " + e);
-            throw e;
-        }
-        out.println("   [ok]");
-
-        // initialize the schema shortcuts
-        meta = new Meta(ndb);
-    }
-
-    protected void closeConnection() {
-        out.print("closing database conn ...");
-        out.flush();
-        meta = null;
-        ndb.close();
-        ndb = null;
-        out.println("   [ok]");
-    }
-
     protected void initOperations() throws NdbApiException {
         out.print("initializing operations ...");
         out.flush();
@@ -321,7 +279,7 @@ public class NdbjLoad extends NdbBase {
                 new Op("insA" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB)
                         throws NdbApiException {
-                        ins(meta.table_A, 1, countA, !setAttrs, batch);
+                        ins(model.table_A, 1, countA, !setAttrs, batch);
                     }
                 });
 
@@ -329,7 +287,7 @@ public class NdbjLoad extends NdbBase {
                 new Op("insB0" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB)
                         throws NdbApiException {
-                        ins(meta.table_B0, 1, countB, !setAttrs, batch);
+                        ins(model.table_B0, 1, countB, !setAttrs, batch);
                     }
                 });
 
@@ -337,7 +295,7 @@ public class NdbjLoad extends NdbBase {
                 new Op("setAByPK" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB)
                         throws NdbApiException {
-                        setByPK(meta.table_A, 1, countA, batch);
+                        setByPK(model.table_A, 1, countA, batch);
                     }
                 });
 
@@ -345,7 +303,7 @@ public class NdbjLoad extends NdbBase {
                 new Op("setB0ByPK" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB)
                         throws NdbApiException {
-                        setByPK(meta.table_B0, 1, countB, batch);
+                        setByPK(model.table_B0, 1, countB, batch);
                     }
                 });
 
@@ -353,7 +311,7 @@ public class NdbjLoad extends NdbBase {
                 new Op("getAByPK" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB)
                         throws NdbApiException {
-                        getByPK(meta.table_A, 1, countA, batch);
+                        getByPK(model.table_A, 1, countA, batch);
                     }
                 });
 
@@ -361,7 +319,7 @@ public class NdbjLoad extends NdbBase {
                 new Op("getB0ByPK" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB)
                         throws NdbApiException {
-                        getByPK(meta.table_B0, 1, countB, batch);
+                        getByPK(model.table_B0, 1, countB, batch);
                     }
                 });
 
@@ -373,7 +331,7 @@ public class NdbjLoad extends NdbBase {
                     new Op("setVarbinary" + l + (batch ? "_batch" : "")) {
                         public void run(int countA, int countB)
                             throws NdbApiException {
-                            setVarbinary(meta.table_B0, 1, countB, batch, b);
+                            setVarbinary(model.table_B0, 1, countB, batch, b);
                         }
                     });
 
@@ -381,11 +339,11 @@ public class NdbjLoad extends NdbBase {
                     new Op("getVarbinary" + l + (batch ? "_batch" : "")) {
                         public void run(int countA, int countB)
                             throws NdbApiException {
-                            getVarbinary(meta.table_B0, 1, countB, batch, b);
+                            getVarbinary(model.table_B0, 1, countB, batch, b);
                         }
                     });
             }
-            
+
             for (int i = 0, l = 1; l <= maxVarcharChars; l *= 10, i++) {
                 final String s = strings[i];
                 assert l == s.length();
@@ -394,7 +352,7 @@ public class NdbjLoad extends NdbBase {
                     new Op("setVarchar" + l + (batch ? "_batch" : "")) {
                         public void run(int countA, int countB)
                             throws NdbApiException {
-                            setVarchar(meta.table_B0, 1, countB, batch, s);
+                            setVarchar(model.table_B0, 1, countB, batch, s);
                         }
                     });
 
@@ -402,7 +360,7 @@ public class NdbjLoad extends NdbBase {
                     new Op("getVarchar" + l + (batch ? "_batch" : "")) {
                         public void run(int countA, int countB)
                             throws NdbApiException {
-                            getVarchar(meta.table_B0, 1, countB, batch, s);
+                            getVarchar(model.table_B0, 1, countB, batch, s);
                         }
                     });
             }
@@ -461,7 +419,7 @@ public class NdbjLoad extends NdbBase {
                 new Op("delB0ByPK" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB)
                         throws NdbApiException {
-                        delByPK(meta.table_B0, 1, countB, batch);
+                        delByPK(model.table_B0, 1, countB, batch);
                     }
                 });
 
@@ -469,7 +427,7 @@ public class NdbjLoad extends NdbBase {
                 new Op("delAByPK" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB)
                         throws NdbApiException {
-                        delByPK(meta.table_A, 1, countA, batch);
+                        delByPK(model.table_A, 1, countA, batch);
                     }
                 });
 
@@ -477,7 +435,7 @@ public class NdbjLoad extends NdbBase {
                 new Op("insA_attr" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB)
                         throws NdbApiException {
-                        ins(meta.table_A, 1, countA, setAttrs, batch);
+                        ins(model.table_A, 1, countA, setAttrs, batch);
                     }
                 });
 
@@ -485,7 +443,7 @@ public class NdbjLoad extends NdbBase {
                 new Op("insB0_attr" + (batch ? "_batch" : "")) {
                     public void run(int countA, int countB)
                         throws NdbApiException {
-                        ins(meta.table_B0, 1, countB, setAttrs, batch);
+                        ins(model.table_B0, 1, countB, setAttrs, batch);
                     }
                 });
 
@@ -493,7 +451,7 @@ public class NdbjLoad extends NdbBase {
                 new Op("delAllB0") {
                     public void run(int countA, int countB)
                         throws NdbApiException {
-                        final int count = delByScan(meta.table_B0);
+                        final int count = delByScan(model.table_B0);
                         assert count == countB;
                     }
                 });
@@ -502,7 +460,7 @@ public class NdbjLoad extends NdbBase {
                 new Op("delAllA") {
                     public void run(int countA, int countB)
                         throws NdbApiException {
-                        final int count = delByScan(meta.table_A);
+                        final int count = delByScan(model.table_A);
                         assert count == countA;
                     }
                 });
@@ -518,14 +476,14 @@ public class NdbjLoad extends NdbBase {
         out.println("      [ok]");
     }
 
-    protected void beginTransaction1() throws NdbApiException {
+    protected void beginTransaction() throws NdbApiException {
         // start a transaction
         // must be closed with NdbTransaction.close
         tx = ndb.startTransaction();
         assert tx != null;
     }
 
-    protected void executeOperations1() throws NdbApiException {
+    protected void executeOperations() throws NdbApiException {
         // execute but don't commit the current transaction
         // XXX not documented: return value != 0 v throwing exception
         // YYY Monty: should always throw exception -> void method
@@ -534,7 +492,7 @@ public class NdbjLoad extends NdbBase {
             throw new RuntimeException("stat == " + stat);
     }
 
-    protected void commitTransaction1() throws NdbApiException {
+    protected void commitTransaction() throws NdbApiException {
         // commit the current transaction
         // XXX not documented: return value != 0 v throwing exception
         // YYY Monty: should always throw exception -> void method
@@ -544,7 +502,7 @@ public class NdbjLoad extends NdbBase {
             throw new RuntimeException("stat == " + stat);
     }
 
-    protected void rollbackTransaction1() throws NdbApiException {
+    protected void rollbackTransaction() throws NdbApiException {
         // abort the current transaction
         // XXX not documented: return value != 0 v throwing exception
         // YYY Monty: should always throw exception -> void method
@@ -553,43 +511,31 @@ public class NdbjLoad extends NdbBase {
             throw new RuntimeException("stat == " + stat);
     }
 
-    protected void closeTransaction1() {
+    protected void closeTransaction() {
         // close the current transaction
         // to be called irrespectively of success or failure
         tx.close();
         tx = null;
     }
 
-    protected void clearData() throws NdbApiException {
-        out.print("deleting all rows ...");
-        out.flush();
-        final int delB0 = delByScan(meta.table_B0);
-        out.print("       [B0: " + delB0);
-        out.flush();
-        final int delA = delByScan(meta.table_A);
-        out.print(", A: " + delA);
-        out.flush();
-        out.println("]");
-    }
-
     // ----------------------------------------------------------------------
 
     protected void fetchCommonAttributes(NdbOperation op)
         throws NdbApiException {
-        op.getValue(meta.name_cint);
-        op.getValue(meta.name_clong);
-        op.getValue(meta.name_cfloat);
-        op.getValue(meta.name_cdouble);
+        op.getValue(model.name_cint);
+        op.getValue(model.name_clong);
+        op.getValue(model.name_cfloat);
+        op.getValue(model.name_cdouble);
     }
 
     protected int getCommonAttributes(NdbResultSet rs)
         throws NdbApiException {
-        final int cint = rs.getInt(meta.name_cint);
-        final long clong = rs.getLong(meta.name_clong);
+        final int cint = rs.getInt(model.name_cint);
+        final long clong = rs.getLong(model.name_clong);
         verify(clong == cint);
-        final float cfloat = rs.getFloat(meta.name_cfloat);
+        final float cfloat = rs.getFloat(model.name_cfloat);
         verify(cfloat == cint);
-        final double cdouble = rs.getDouble(meta.name_cdouble);
+        final double cdouble = rs.getDouble(model.name_cdouble);
         verify(cdouble == cint);
         return cint;
     }
@@ -597,53 +543,53 @@ public class NdbjLoad extends NdbBase {
     protected void ins(NdbTable table, int from, int to,
                        boolean setAttrs, boolean batch)
         throws NdbApiException {
-        beginTransaction1();
+        beginTransaction();
         for (int i = from; i <= to; i++) {
             // get an insert operation for the table
             final NdbOperation op = tx.getInsertOperation(table);
             assert op != null;
 
             // set key attribute
-            op.equalInt(meta.name_id, i);
+            op.equalInt(model.name_id, i);
 
             // set other attributes
             if (setAttrs) {
-                op.setInt(meta.name_cint, -i);
-                op.setLong(meta.name_clong, -i);
-                op.setFloat(meta.name_cfloat, -i);
-                op.setDouble(meta.name_cdouble, -i);
+                op.setInt(model.name_cint, -i);
+                op.setLong(model.name_clong, -i);
+                op.setFloat(model.name_cfloat, -i);
+                op.setDouble(model.name_cdouble, -i);
             }
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
     }
 
     protected void delByPK(NdbTable table, int from, int to,
                            boolean batch)
         throws NdbApiException {
-        beginTransaction1();
+        beginTransaction();
         for (int i = from; i <= to; i++) {
             // get a delete operation for the table
             final NdbOperation op = tx.getDeleteOperation(table);
             assert op != null;
 
             // set key attribute
-            op.equalInt(meta.name_id, i);
+            op.equalInt(model.name_id, i);
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
     }
 
     protected int delByScan(NdbTable table) throws NdbApiException {
-        beginTransaction1();
+        beginTransaction();
 
         // get a full table scan operation with exclusive locks
         final NdbScanOperation op
@@ -651,7 +597,7 @@ public class NdbjLoad extends NdbBase {
         assert op != null;
 
         // start the scan; don't commit yet
-        executeOperations1();
+        executeOperations();
 
         // delete all rows in a given scan
         int count = 0;
@@ -689,35 +635,35 @@ public class NdbjLoad extends NdbBase {
         // close the scan
         op.close();
 
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
         return count;
     }
 
     protected void setByPK(NdbTable table, int from, int to,
                            boolean batch)
         throws NdbApiException {
-        beginTransaction1();
+        beginTransaction();
         for (int i = from; i <= to; i++) {
             // get an insert operation for the table
             final NdbOperation op = tx.getUpdateOperation(table);
             assert op != null;
 
             // set key attribute
-            op.equalInt(meta.name_id, i);
+            op.equalInt(model.name_id, i);
 
             // set other attributes
-            op.setInt(meta.name_cint, i);
-            op.setLong(meta.name_clong, i);
-            op.setFloat(meta.name_cfloat, i);
-            op.setDouble(meta.name_cdouble, i);
+            op.setInt(model.name_cint, i);
+            op.setLong(model.name_clong, i);
+            op.setFloat(model.name_cfloat, i);
+            op.setDouble(model.name_cdouble, i);
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
     }
 
     // XXX need to use names instead of ids due to broken
@@ -727,7 +673,7 @@ public class NdbjLoad extends NdbBase {
         assert tx == null;
         tx = ndb.startTransaction();
         assert tx != null;
-        NdbOperation op = tx.getSelectOperation(meta.table_A);
+        NdbOperation op = tx.getSelectOperation(model.table_A);
         assert op != null;
         final int int_val = 1;
         op.equalInt("id", int_val);
@@ -749,17 +695,17 @@ public class NdbjLoad extends NdbBase {
         final int count = (to - from) + 1;
         final NdbResultSet[] rss = new NdbResultSet[count];
 
-        beginTransaction1();
+        beginTransaction();
         for (int i = 0, j = from; i < count; i++, j++) {
             // get a read operation for the table
             NdbOperation op = tx.getSelectOperation(table);
             assert op != null;
 
             // set key attribute
-            op.equalInt(meta.name_id, j);
+            op.equalInt(model.name_id, j);
 
             // define fetched attributes
-            op.getValue(meta.name_id);
+            op.getValue(model.name_id);
             fetchCommonAttributes(op);
 
             // get attributes (not readable until after commit)
@@ -767,9 +713,9 @@ public class NdbjLoad extends NdbBase {
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
+        commitTransaction();
 
         // check fetched values
         for (int i = 0, j = from; i < count; i++, j++) {
@@ -778,7 +724,7 @@ public class NdbjLoad extends NdbBase {
             assert hasNext;
 
             // check key attribute
-            final int id = rs.getInt(meta.name_id);
+            final int id = rs.getInt(model.name_id);
             verify(id == j);
 
             // check other attributes
@@ -787,53 +733,53 @@ public class NdbjLoad extends NdbBase {
 
             assert !rs.next();
         }
-        closeTransaction1();
+        closeTransaction();
     }
 
     protected void setVarbinary(NdbTable table, int from, int to,
                                 boolean batch, byte[] bytes)
         throws NdbApiException {
-        beginTransaction1();
+        beginTransaction();
         for (int i = from; i <= to; i++) {
             // get an update operation for the table
             final NdbOperation op = tx.getUpdateOperation(table);
             assert op != null;
 
             // set key attribute
-            op.equalInt(meta.name_id, i);
+            op.equalInt(model.name_id, i);
 
             // set varbinary
-            op.setBytes(meta.name_B0_cvarbinary_def, bytes);
+            op.setBytes(model.name_B0_cvarbinary_def, bytes);
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
     }
 
     protected void setVarchar(NdbTable table, int from, int to,
                               boolean batch, String string)
         throws NdbApiException {
-        beginTransaction1();
+        beginTransaction();
         for (int i = from; i <= to; i++) {
             // get an update operation for the table
             final NdbOperation op = tx.getUpdateOperation(table);
             assert op != null;
 
             // set key attribute
-            op.equalInt(meta.name_id, i);
+            op.equalInt(model.name_id, i);
 
             // set varchar
-            op.setString(meta.name_B0_cvarchar_def, string);
+            op.setString(model.name_B0_cvarchar_def, string);
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
     }
 
     protected void getVarbinary(NdbTable table, int from, int to,
@@ -843,27 +789,27 @@ public class NdbjLoad extends NdbBase {
         final int count = (to - from) + 1;
         final NdbResultSet[] rss = new NdbResultSet[count];
 
-        beginTransaction1();
+        beginTransaction();
         for (int i = 0, j = from; i < count; i++, j++) {
             // get a read operation for the table
             NdbOperation op = tx.getSelectOperation(table);
             assert op != null;
 
             // set key attribute
-            op.equalInt(meta.name_id, j);
+            op.equalInt(model.name_id, j);
 
             // define fetched attributes
-            op.getValue(meta.name_B0_cvarbinary_def);
+            op.getValue(model.name_B0_cvarbinary_def);
 
             // get attributes (not readable until after commit)
             rss[i] = op.resultData();
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        //executeOperations1();
-        commitTransaction1();
+        //executeOperations();
+        commitTransaction();
 
         // check fetched values
         for (int i = 0, j = from; i < count; i++, j++) {
@@ -873,12 +819,12 @@ public class NdbjLoad extends NdbBase {
 
             // check varbinary
             final byte[] cvarbinary_def
-                = rs.getBytes(meta.name_B0_cvarbinary_def);
+                = rs.getBytes(model.name_B0_cvarbinary_def);
             verify(Arrays.equals(bytes, cvarbinary_def));
 
             assert !rs.next();
         }
-        closeTransaction1();
+        closeTransaction();
     }
 
     protected void getVarchar(NdbTable table, int from, int to,
@@ -888,27 +834,27 @@ public class NdbjLoad extends NdbBase {
         final int count = (to - from) + 1;
         final NdbResultSet[] rss = new NdbResultSet[count];
 
-        beginTransaction1();
+        beginTransaction();
         for (int i = 0, j = from; i < count; i++, j++) {
             // get a read operation for the table
             NdbOperation op = tx.getSelectOperation(table);
             assert op != null;
 
             // set key attribute
-            op.equalInt(meta.name_id, j);
+            op.equalInt(model.name_id, j);
 
             // define fetched attributes
-            op.getValue(meta.name_B0_cvarchar_def);
+            op.getValue(model.name_B0_cvarchar_def);
 
             // get attributes (not readable until after commit)
             rss[i] = op.resultData();
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        //executeOperations1();
-        commitTransaction1();
+        //executeOperations();
+        commitTransaction();
 
         // check fetched values
         for (int i = 0, j = from; i < count; i++, j++) {
@@ -919,72 +865,72 @@ public class NdbjLoad extends NdbBase {
             // check varchar
             if (true) {
                 final String cvarchar_def
-                    = rs.getString(meta.name_B0_cvarchar_def);
+                    = rs.getString(model.name_B0_cvarchar_def);
                 verify(string.equals(cvarchar_def));
             } else {
                 // verification imposes a string->bytes conversion penalty
                 final byte[] cvarchar_def
-                    = rs.getStringBytes(meta.name_B0_cvarchar_def);
+                    = rs.getStringBytes(model.name_B0_cvarchar_def);
                 verify(Arrays.equals(string.getBytes(), cvarchar_def));
             }
 
             assert !rs.next();
         }
-        closeTransaction1();
+        closeTransaction();
     }
 
     protected void setB0ToA(int count_A, int count_B,
                             boolean batch)
         throws NdbApiException {
-        beginTransaction1();
+        beginTransaction();
         for (int i = 1; i <= count_B; i++) {
             // get an update operation for the table
-            final NdbOperation op = tx.getUpdateOperation(meta.table_B0);
+            final NdbOperation op = tx.getUpdateOperation(model.table_B0);
             assert op != null;
 
             // set key attribute
-            op.equalInt(meta.name_id, i);
+            op.equalInt(model.name_id, i);
 
             // set a_id attribute
             int a_id = ((i - 1) % count_A) + 1;
-            op.setInt(meta.name_B0_a_id, a_id);
+            op.setInt(model.name_B0_a_id, a_id);
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
     }
 
     protected void nullB0ToA(int count_A, int count_B,
                              boolean batch)
         throws NdbApiException {
-        beginTransaction1();
+        beginTransaction();
         for (int i = 1; i <= count_B; i++) {
             // get an update operation for the table
-            final NdbOperation op = tx.getUpdateOperation(meta.table_B0);
+            final NdbOperation op = tx.getUpdateOperation(model.table_B0);
             assert op != null;
 
             // set key attribute
-            op.equalInt(meta.name_id, i);
+            op.equalInt(model.name_id, i);
 
             // set a_id attribute
             int a_id = ((i - 1) % count_A) + 1;
-            op.setNull(meta.name_B0_a_id);
+            op.setNull(model.name_B0_a_id);
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
-        closeTransaction1();
+        commitTransaction();
+        closeTransaction();
     }
 
     protected void navB0ToA(int count_A, int count_B,
                             boolean batch)
         throws NdbApiException {
-        beginTransaction1();
+        beginTransaction();
 
         // fetch the foreign keys from B0 and read attributes from A
         final NdbResultSet[] abs = new NdbResultSet[count_B];
@@ -993,33 +939,33 @@ public class NdbjLoad extends NdbBase {
             NdbResultSet rs;
             {
                 // get a read operation for the table
-                NdbOperation op = tx.getSelectOperation(meta.table_B0);
+                NdbOperation op = tx.getSelectOperation(model.table_B0);
                 assert op != null;
 
                 // set key attribute
-                op.equalInt(meta.name_id, i);
+                op.equalInt(model.name_id, i);
 
                 // define fetched attributes
-                op.getValue(meta.name_B0_a_id);
+                op.getValue(model.name_B0_a_id);
 
                 // get attributes (not readable until after commit)
                 rs = op.resultData();
             }
-            executeOperations1(); // start the scan; don't commit yet
+            executeOperations(); // start the scan; don't commit yet
 
             // fetch the attributes from A
             {
                 // get a read operation for the table
-                NdbOperation op = tx.getSelectOperation(meta.table_A);
+                NdbOperation op = tx.getSelectOperation(model.table_A);
                 assert op != null;
 
                 // set key attribute
-                final int a_id = rs.getInt(meta.name_B0_a_id);
+                final int a_id = rs.getInt(model.name_B0_a_id);
                 assert a_id == ((i - 1) % count_A) + 1;
-                op.equalInt(meta.name_id, a_id);
+                op.equalInt(model.name_id, a_id);
 
                 // define fetched attributes
-                op.getValue(meta.name_id);
+                op.getValue(model.name_id);
                 fetchCommonAttributes(op);
 
                 // get attributes (not readable until after commit)
@@ -1028,9 +974,9 @@ public class NdbjLoad extends NdbBase {
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
+        commitTransaction();
 
         // check fetched values
         for (int i = 1, j = 0; i <= count_B; i++, j++) {
@@ -1039,7 +985,7 @@ public class NdbjLoad extends NdbBase {
             assert hasNext;
 
             // check key attribute
-            final int id = ab.getInt(meta.name_id);
+            final int id = ab.getInt(model.name_id);
             //out.println("id = " + id + ", i = " + i);
             verify(id == ((i - 1) % count_A) + 1);
 
@@ -1049,46 +995,46 @@ public class NdbjLoad extends NdbBase {
 
             assert !ab.next();
         }
-        closeTransaction1();
+        closeTransaction();
     }
 
     protected void navB0ToAalt(int count_A, int count_B,
                                boolean batch)
         throws NdbApiException {
-        beginTransaction1();
+        beginTransaction();
 
         // fetch the foreign key value from B0
         final NdbResultSet[] a_ids = new NdbResultSet[count_B];
         for (int i = 1, j = 0; i <= count_B; i++, j++) {
                 // get a read operation for the table
-                NdbOperation op = tx.getSelectOperation(meta.table_B0);
+                NdbOperation op = tx.getSelectOperation(model.table_B0);
                 assert op != null;
 
                 // set key attribute
-                op.equalInt(meta.name_id, i);
+                op.equalInt(model.name_id, i);
 
                 // define fetched attributes
-                op.getValue(meta.name_B0_a_id);
+                op.getValue(model.name_B0_a_id);
 
                 // get attributes (not readable until after commit)
                 a_ids[j] = op.resultData();
         }
-        executeOperations1(); // start the scan; don't commit yet
+        executeOperations(); // start the scan; don't commit yet
 
         // fetch the attributes from A
         final NdbResultSet[] abs = new NdbResultSet[count_B];
         for (int i = 1, j = 0; i <= count_B; i++, j++) {
             // get a read operation for the table
-            NdbOperation op = tx.getSelectOperation(meta.table_A);
+            NdbOperation op = tx.getSelectOperation(model.table_A);
             assert op != null;
 
             // set key attribute
-            final int a_id = a_ids[j].getInt(meta.name_B0_a_id);
+            final int a_id = a_ids[j].getInt(model.name_B0_a_id);
             assert a_id == ((i - 1) % count_A) + 1;
-            op.equalInt(meta.name_id, a_id);
+            op.equalInt(model.name_id, a_id);
 
             // define fetched attributes
-            op.getValue(meta.name_id);
+            op.getValue(model.name_id);
             fetchCommonAttributes(op);
 
             // get attributes (not readable until after commit)
@@ -1096,9 +1042,9 @@ public class NdbjLoad extends NdbBase {
 
             // execute the operation now if in non-batching mode
             if (!batch)
-                executeOperations1();
+                executeOperations();
         }
-        commitTransaction1();
+        commitTransaction();
 
         // check fetched values
         for (int i = 1, j = 0; i <= count_B; i++, j++) {
@@ -1107,7 +1053,7 @@ public class NdbjLoad extends NdbBase {
             assert hasNext;
 
             // check key attribute
-            final int id = ab.getInt(meta.name_id);
+            final int id = ab.getInt(model.name_id);
             //out.println("id = " + id + ", i = " + i);
             verify(id == ((i - 1) % count_A) + 1);
 
@@ -1117,7 +1063,7 @@ public class NdbjLoad extends NdbBase {
 
             assert !ab.next();
         }
-        closeTransaction1();
+        closeTransaction();
     }
 
     protected void navAToB0(int count_A, int count_B,
@@ -1125,7 +1071,7 @@ public class NdbjLoad extends NdbBase {
         throws NdbApiException {
 // throws exceptions, see below:
 /*
-        beginTransaction1();
+        beginTransaction();
 
         // fetch attributes from B0 by foreign key scan
         final NdbResultSet[] abs = new NdbResultSet[count_B];
@@ -1134,8 +1080,8 @@ public class NdbjLoad extends NdbBase {
             // get an index scan operation for the table
             // XXX ? no locks (LM_CommittedRead) or shared locks (LM_Read)
             final NdbIndexScanOperation op
-                = tx.getSelectIndexScanOperation(meta.idx_B0_a_id,
-                                                 meta.table_B0,
+                = tx.getSelectIndexScanOperation(model.idx_B0_a_id,
+                                                 model.table_B0,
                                                  LockMode.LM_CommittedRead);
             assert op != null;
 
@@ -1147,10 +1093,10 @@ public class NdbjLoad extends NdbBase {
             //
             // which translates into
             //out.println("idx_B0_a_id.getNoOfColumns() = "
-            //            + meta.idx_B0_a_id.getNoOfColumns());
+            //            + model.idx_B0_a_id.getNoOfColumns());
             //out.println("idx_B0_a_id.getColumn(0).getColumnNo() = "
-            //            + meta.idx_B0_a_id.getColumn(0).getColumnNo());
-            //op.setBoundInt(meta.idx_B0_a_id.getColumn(0).getColumnNo(),
+            //            + model.idx_B0_a_id.getColumn(0).getColumnNo());
+            //op.setBoundInt(model.idx_B0_a_id.getColumn(0).getColumnNo(),
             //               BoundType.BoundEQ, i);
             // except that we get the usual error with NDBJ:
             //[java] idx_B0_a_id.getColumn(0).getColumnNo() = 0
@@ -1159,18 +1105,18 @@ public class NdbjLoad extends NdbBase {
             //
             // so we go by column name
             //out.println("idx_B0_a_id.getColumn(0).getName() = "
-            //            + meta.idx_B0_a_id.getColumn(0).getName());
-            //op.setBoundInt(meta.idx_B0_a_id.getColumn(0).getName(),
+            //            + model.idx_B0_a_id.getColumn(0).getName());
+            //op.setBoundInt(model.idx_B0_a_id.getColumn(0).getName(),
             //               BoundType.BoundEQ, i);
             // which is actually "a_id", so, for now, we call
             op.setBoundInt("a_id", BoundType.BoundEQ, i);
 
             // define fetched attributes
-            op.getValue(meta.name_id);
+            op.getValue(model.name_id);
             fetchCommonAttributes(op);
 
             // start the scan; don't commit yet
-            executeOperations1();
+            executeOperations();
 
             int stat;
             final boolean allowFetch = true; // request new batches when exhausted
@@ -1181,7 +1127,7 @@ public class NdbjLoad extends NdbBase {
             if (stat != 1)
                 throw new RuntimeException("stat == " + stat);
         }
-        commitTransaction1();
+        commitTransaction();
         assert (j++ == count_B);
 
         // check fetched values
@@ -1194,13 +1140,13 @@ public class NdbjLoad extends NdbBase {
             //[java] j = 1, ab = com.mysql.cluster.ndbj.NdbResultSetImpl@6f144c
             //    [java] caught com.mysql.cluster.ndbj.NdbApiException: Unknown error code
             //    [java] com.mysql.cluster.ndbj.NdbApiException: Unknown error code
-            //    [java] at com.mysql.cluster.ndbj.NdbjJNI.NdbScanOperationImpl_nextResult__SWIG_1(Native Method)
+            //    [java] at com.mysql.cluster.ndbj.NdbjJNI.NdbScanOperationImpl_nextResult__SWIG_(Native Method)
             //    [java] at com.mysql.cluster.ndbj.NdbScanOperationImpl.nextResult(NdbScanOperationImpl.java:93)
             //    [java] at com.mysql.cluster.ndbj.NdbResultSetImpl.next(NdbResultSetImpl.java:362)
             //    [java] at com.mysql.cluster.crund.NdbjLoad.navAToB0(NdbjLoad.java:1205)
             //
             // YYY Frazer: check tx object for error (could be node failure)
-            // Martin: doesn't help much; after ab.next(): 
+            // Martin: doesn't help much; after ab.next():
             //out.println("tx.getNdbError() = " + tx.getNdbError().getCode());
             // returns -1 and
             //out.println("tx.getNdbError() = " + tx.getNdbError().getMessage());
@@ -1217,7 +1163,7 @@ public class NdbjLoad extends NdbBase {
             assert hasNext;
 
             // check key attribute
-            final int id = ab.getInt(meta.name_id);
+            final int id = ab.getInt(model.name_id);
             verify(id == i);
 
             // check other attributes
@@ -1226,7 +1172,7 @@ public class NdbjLoad extends NdbBase {
 
             assert !ab.next();
         }
-        closeTransaction1();
+        closeTransaction();
 */
     }
 
@@ -1240,6 +1186,72 @@ public class NdbjLoad extends NdbBase {
     }
 
     // ----------------------------------------------------------------------
+    // NDBJ datastore operations
+    // ----------------------------------------------------------------------
+
+    protected void initConnection() throws NdbApiException {
+        // optionally, connect and wait for reaching the data nodes (ndbds)
+        out.print("waiting for data nodes...");
+        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
+
+        // XXX return: 0 all nodes live, > 0 at least one node live, < 0 error
+        try {
+            mgmd.waitUntilReady(initial_wait, final_wait);
+        } catch (NdbApiException e) {
+            out.println();
+            out.println("!!! data nodes were not ready within "
+                        + (initial_wait + final_wait) + "s.");
+            throw e;
+        }
+        out.println("   [ok]");
+
+        // connect to database
+        out.print("connecting to database...");
+        out.flush();
+        try {
+            // XXX where to set schema?
+            // YYY Frazer: schema not too useful in NDB at the moment
+            // XXX unclear if maxThreads ^= maxNumberOfTransactions
+            //     since ndb.init(maxNumberOfTransactions) is deprecated
+            //final int maxThreads = 4;
+            //ndb = mgmd.createNdb(catalog, maxThreads);
+            // YYY Frazer: yes, maxThreads == maxNumber(concurrent)OfTransactions
+            ndb = mgmd.createNdb(catalog);
+        } catch (NdbApiException e) {
+            out.println();
+            out.println("!!! failed to connect: " + e);
+            throw e;
+        }
+        out.println("   [ok]");
+
+        // initialize the schema shortcuts
+        model = new Model(ndb);
+    }
+
+    protected void closeConnection() {
+        out.print("closing database conn ...");
+        out.flush();
+        model = null;
+        ndb.close();
+        ndb = null;
+        out.println("   [ok]");
+    }
+
+    protected void clearData() throws NdbApiException {
+        out.print("deleting all rows ...");
+        out.flush();
+        final int delB0 = delByScan(model.table_B0);
+        out.print("       [B0: " + delB0);
+        out.flush();
+        final int delA = delByScan(model.table_A);
+        out.print(", A: " + delA);
+        out.flush();
+        out.println("]");
+    }
+
+    // ----------------------------------------------------------------------
 
     static public void main(String[] args) {
         System.out.println("NdbjLoad.main()");

=== added file 'storage/ndb/test/crund/src/crundndb/CrundDriver.cpp'
--- a/storage/ndb/test/crund/src/crundndb/CrundDriver.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/crund/src/crundndb/CrundDriver.cpp	2010-10-05 08:48:30 +0000
@@ -0,0 +1,292 @@
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
+ *
+ *  Copyright (C) 2009 MySQL
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <cassert>
+
+#include "helpers.hpp"
+#include "string_helpers.hpp"
+
+#include "CrundDriver.hpp"
+
+using std::cout;
+using std::flush;
+using std::endl;
+using std::ios_base;
+using std::ostringstream;
+using std::string;
+using std::wstring;
+
+using utils::toBool;
+using utils::toInt;
+using utils::toString;
+
+// ----------------------------------------------------------------------
+
+void
+CrundDriver::initProperties() {
+    Driver::initProperties();
+    
+    cout << "setting crund properties ..." << flush;
+
+    ostringstream msg;
+
+    renewOperations = toBool(props[L"renewOperations"], false);
+    logSumOfOps = toBool(props[L"logSumOfOps"], true);
+    //logSumOfOps = toBool(props[L"allowExtendedPC"], false); // not used
+
+    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;
+    }
+
+    // initialize exclude set
+    const wstring& estr = props[L"exclude"];
+    //cout << "estr='" << toString(estr) << "'" << endl;
+    const size_t len = estr.length();
+    size_t beg = 0, next;
+    while (beg < len
+           && ((next = estr.find_first_of(L",", beg)) != wstring::npos)) {
+        // add substring if not empty
+        if (beg < next) {
+            const wstring& s = estr.substr(beg, next - beg);
+            exclude.insert(toString(s));
+        }
+        beg = next + 1;
+    }
+    // add last substring if any
+    if (beg < len) {
+        const wstring& s = estr.substr(beg, len - beg);
+        exclude.insert(toString(s));
+    }
+
+    if (msg.tellp() == 0) {
+        cout << "    [ok: "
+             << "A=" << aStart << ".." << aEnd
+             << ", B=" << bStart << ".." << bEnd << "]" << endl;
+    } else {
+        cout << endl << msg.str() << endl;
+    }
+}
+
+void
+CrundDriver::printProperties() {
+    Driver::printProperties();
+    
+    const ios_base::fmtflags f = cout.flags();
+    // no effect calling manipulator function, not sure why
+    //cout << ios_base::boolalpha;
+    cout.flags(ios_base::boolalpha);
+
+    cout << endl << "crund settings ..." << endl;
+    cout << "renewOperations:                " << renewOperations << endl;
+    cout << "logSumOfOps:                    " << logSumOfOps << endl;
+    //cout << "allowExtendedPC:                " << allowExtendedPC << endl;
+    cout << "aStart:                         " << aStart << endl;
+    cout << "bStart:                         " << bStart << endl;
+    cout << "aEnd:                           " << aEnd << endl;
+    cout << "bEnd:                           " << bEnd << 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 << "exclude:                        " << toString(exclude) << endl;
+
+    cout.flags(f);
+}
+
+// ----------------------------------------------------------------------
+
+void
+CrundDriver::runTests() {
+    initConnection();
+    initOperations();
+
+    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);
+        }
+    }
+
+    cout << endl
+         << "------------------------------------------------------------" << endl
+         << endl;
+
+    clearData();
+    closeOperations();
+    closeConnection();
+}
+
+void
+CrundDriver::runOperations(int countA, int countB) {
+    cout << 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) {
+        rtimes << "A=" << countA << ", B=" << countB;
+        rta = 0L;
+    }
+    if (logCpuTime) {
+        ctimes << "A=" << countA << ", B=" << countB;
+        cta = 0L;
+    }
+
+    // pre-run cleanup
+    if (renewConnection) {
+        closeOperations();
+        closeConnection();
+        initConnection();
+        initOperations();
+    } else if (renewOperations) {
+        closeOperations();
+        initOperations();
+    }
+    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";
+    }
+
+    if (logSumOfOps) {
+        cout << endl
+             << "total" << endl;
+        if (logRealTime) {
+            cout << "tx real time                    " << rta
+                 << "\tms" << endl;
+        }
+        if (logSumOfOps) {
+            cout << "tx cpu time                     " << cta
+                 << "\tms" << endl;
+        }
+    }
+
+    // log buffers
+    logHeader = false;
+    if (logRealTime) {
+        if (logSumOfOps) {
+            rtimes << "\t" << rta;
+        }
+        rtimes << endl;
+    }
+    if (logCpuTime) {
+        if (logSumOfOps) {
+            ctimes << "\t" << cta;
+        }
+        ctimes << endl;
+    }
+}
+
+void
+CrundDriver::runOp(const Op& op, int countA, int countB) {
+    const string& name = op.name;
+    if (exclude.find(name) == exclude.end()) {
+        begin(name);
+        op.run(countA, countB);
+        commit(name);
+    }
+}
+
+//---------------------------------------------------------------------------

=== added file 'storage/ndb/test/crund/src/crundndb/CrundDriver.hpp'
--- a/storage/ndb/test/crund/src/crundndb/CrundDriver.hpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/crund/src/crundndb/CrundDriver.hpp	2010-10-05 08:48:30 +0000
@@ -0,0 +1,85 @@
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
+ *
+ *  Copyright (C) 2009 MySQL
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef CrundDriver_hpp
+#define CrundDriver_hpp
+
+#include <string>
+#include <vector>
+#include <set>
+
+#include "hrt_utils.h"
+
+#include "Driver.hpp"
+
+using std::string;
+using std::vector;
+using std::set;
+
+class CrundDriver : public Driver {
+protected:
+
+    // benchmark settings
+    bool renewOperations;
+    bool logSumOfOps;
+    //bool allowExtendedPC; // not used
+    int aStart;
+    int bStart;
+    int aEnd;
+    int bEnd;
+    int aScale;
+    int bScale;
+    int maxVarbinaryBytes;
+    int maxVarcharChars;
+    int maxBlobBytes;
+    int maxTextChars;
+    set< string > exclude;
+
+    // benchmark intializers/finalizers
+    virtual void initProperties();
+    virtual void printProperties();
+
+    // a database operation to be benchmarked
+    struct Op {
+        const string name;
+
+        virtual void run(int countA, int countB) const = 0;
+
+        Op(const string& name) : name(name) {}
+
+        virtual ~Op() {}
+    };
+
+    // the list of database operations to be benchmarked
+    typedef vector< const Op* > Operations;
+    Operations operations;
+
+    // benchmark operations
+    virtual void initOperations() = 0;
+    virtual void closeOperations() = 0;
+    virtual void runTests();
+    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

=== renamed file 'storage/ndb/test/crund/src/crundndb/Operations.cpp' => 'storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.cpp'
--- a/storage/ndb/test/crund/src/crundndb/Operations.cpp	2010-10-01 08:58:08 +0000
+++ b/storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.cpp	2010-10-05 08:48:30 +0000
@@ -1,31 +1,42 @@
-/*
- * com_mysql_cluster_crund_NdbApiLoad.cpp
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
+ *
+ *  Copyright (C) 2009 MySQL
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
  *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <iostream>
-#include <sstream>
-#include <cassert>
 #include <vector>
 #include <algorithm>
 #include <cstring>
-#include <cstdio>
+#include <cassert>
 
 #include <NdbApi.hpp>
 #include <NdbError.hpp>
 
 #include "helpers.hpp"
 #include "string_helpers.hpp"
-#include "Operations.hpp"
+
+#include "CrundNdbApiOperations.hpp"
 
 //using namespace std;
-using std::vector;
 using std::cout;
+using std::flush;
 using std::endl;
-
-//using namespace crund_ndb;
-using crund_ndb::Meta;
-using crund_ndb::Operations;
+using std::vector;
 
 // JNI crashes with gcc & operator<<(ostream &, long/int)
 using utils::toString;
@@ -64,11 +75,11 @@ using utils::toString;
     if (cond); else ABORT_ERROR("wrong data; verification failed")
 
 /************************************************************
- * Member Functions of Class Meta
+ * Member Functions of Class CrundModel
  ************************************************************/
 
 void
-Meta::init(Ndb* ndb)
+CrundModel::init(Ndb* ndb)
 {
     const NdbDictionary::Dictionary* dict = ndb->getDictionary();
 
@@ -159,7 +170,7 @@ Meta::init(Ndb* ndb)
 */
 
 void
-Operations::init(const char* mgmd_conn_str)
+CrundNdbApiOperations::init(const char* mgmd_conn_str)
 {
     assert (mgmd_conn_str);
 
@@ -169,12 +180,12 @@ Operations::init(const char* mgmd_conn_s
     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
+    cout << "       [ok]" << endl; // no useful mgmd->string conversion
 
     // connect to cluster management node (ndb_mgmd)
     cout << "connecting to mgmd ..." << flush;
@@ -185,25 +196,25 @@ Operations::init(const char* mgmd_conn_s
     if (mgmd->connect(retries, delay, verbose) != 0)
         ABORT_ERROR("mgmd@" << mgmd_conn_str << " was not ready within "
                      << (retries * delay) << "s.");
-    cout << "      [ok: " << mgmd_conn_str << "]" << endl;
+    cout << "          [ok: " << mgmd_conn_str << "]" << endl;
 }
 
 void
-Operations::close()
+CrundNdbApiOperations::close()
 {
     cout << "closing mgmd conn ..." << flush;
     delete mgmd;
     mgmd = NULL;
-    cout << "       [ok]" << endl;
+    cout << "           [ok]" << endl;
 
     // ndb_close must be called last
     cout << "closing NDBAPI ...   " << flush;
     ndb_end(0);
-    cout << "       [ok]" << endl;
+    cout << "           [ok]" << endl;
 }
 
 void
-Operations::initConnection(const char* catalog, const char* schema)
+CrundNdbApiOperations::initConnection(const char* catalog, const char* schema)
 {
     // optionally, connect and wait for reaching the data nodes (ndbds)
     cout << "waiting for data nodes..." << flush;
@@ -213,7 +224,7 @@ Operations::initConnection(const char* c
     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;
@@ -223,28 +234,28 @@ Operations::initConnection(const char* c
     //if (ndb->init() != 0)
     if (ndb->init(max_no_tx) != 0)
         ABORT_NDB_ERROR(ndb->getNdbError());
-    cout << "   [ok]" << endl;
+    cout << "       [ok]" << endl;
 
     // initialize the schema shortcuts
-    Meta* m = new Meta();
+    CrundModel* m = new CrundModel();
     m->init(ndb);
-    meta = m;
+    model = m;
 }
 
 void
-Operations::closeConnection()
+CrundNdbApiOperations::closeConnection()
 {
     cout << "closing database conn ..." << flush;
-    delete meta;
-    meta = NULL;
+    delete model;
+    model = NULL;
     // no ndb->close();
     delete ndb;
     ndb = NULL;
-    cout << "   [ok]" << endl;
+    cout << "       [ok]" << endl;
 }
 
 void
-Operations::beginTransaction()
+CrundNdbApiOperations::beginTransaction()
 {
     // start a transaction
     // must be closed with Ndb::closeTransaction or NdbTransaction::close
@@ -253,7 +264,7 @@ Operations::beginTransaction()
 }
 
 void
-Operations::executeOperations()
+CrundNdbApiOperations::executeOperations()
 {
     // execute but don't commit the current transaction
     if (tx->execute(NdbTransaction::NoCommit) != 0
@@ -262,7 +273,7 @@ Operations::executeOperations()
 }
 
 void
-Operations::commitTransaction()
+CrundNdbApiOperations::commitTransaction()
 {
     // commit the current transaction
     if (tx->execute(NdbTransaction::Commit) != 0
@@ -271,7 +282,7 @@ Operations::commitTransaction()
 }
 
 void
-Operations::rollbackTransaction()
+CrundNdbApiOperations::rollbackTransaction()
 {
     // abort the current transaction
     if (tx->execute(NdbTransaction::Rollback) != 0
@@ -280,7 +291,7 @@ Operations::rollbackTransaction()
 }
 
 void
-Operations::closeTransaction()
+CrundNdbApiOperations::closeTransaction()
 {
     // close the current transaction
     // to be called irrespectively of success or failure
@@ -291,15 +302,15 @@ Operations::closeTransaction()
 // ----------------------------------------------------------------------
 
 void
-Operations::clearData()
+CrundNdbApiOperations::clearData()
 {
     cout << "deleting all rows ..." << flush;
     const bool batch = true;
     int delB0 = -1;
-    delByScan(meta->table_B0, delB0, batch);
-    cout << "       [B0: " << toString(delB0) << flush;
+    delByScan(model->table_B0, delB0, batch);
+    cout << "           [B0: " << toString(delB0) << flush;
     int delA = -1;
-    delByScan(meta->table_A, delA, batch);
+    delByScan(model->table_A, delA, batch);
     cout << ", A: " << toString(delA) << "]" << endl;
 }
 
@@ -352,9 +363,9 @@ selectString(int length)
 }
 
 void
-Operations::ins(const NdbDictionary::Table* table,
-                int from, int to,
-                bool setAttrs, bool batch)
+CrundNdbApiOperations::ins(const NdbDictionary::Table* table,
+                           int from, int to,
+                           bool setAttrs, bool batch)
 {
     beginTransaction();
     for (int i = from; i <= to; i++) {
@@ -366,16 +377,16 @@ Operations::ins(const NdbDictionary::Tab
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // set values; key attribute needs to be set first
-        if (op->equal(meta->attr_id, (Int32)i) != 0)
+        if (op->equal(model->attr_id, (Int32)i) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
         if (setAttrs) {
-            if (op->setValue(meta->attr_cint, (Int32)-i) != 0)
+            if (op->setValue(model->attr_cint, (Int32)-i) != 0)
                 ABORT_NDB_ERROR(tx->getNdbError());
-            if (op->setValue(meta->attr_clong, (Int64)-i) != 0)
+            if (op->setValue(model->attr_clong, (Int64)-i) != 0)
                 ABORT_NDB_ERROR(tx->getNdbError());
-            if (op->setValue(meta->attr_cfloat, (float)-i) != 0)
+            if (op->setValue(model->attr_cfloat, (float)-i) != 0)
                 ABORT_NDB_ERROR(tx->getNdbError());
-            if (op->setValue(meta->attr_cdouble, (double)-i) != 0)
+            if (op->setValue(model->attr_cdouble, (double)-i) != 0)
                 ABORT_NDB_ERROR(tx->getNdbError());
         }
 
@@ -388,8 +399,8 @@ Operations::ins(const NdbDictionary::Tab
 }
 
 void
-Operations::delByScan(const NdbDictionary::Table* table, int& count,
-                      bool batch)
+CrundNdbApiOperations::delByScan(const NdbDictionary::Table* table, int& count,
+                                 bool batch)
 {
     beginTransaction();
 
@@ -458,9 +469,9 @@ Operations::delByScan(const NdbDictionar
 }
 
 void
-Operations::delByPK(const NdbDictionary::Table* table,
-                    int from, int to,
-                    bool batch)
+CrundNdbApiOperations::delByPK(const NdbDictionary::Table* table,
+                               int from, int to,
+                               bool batch)
 {
     beginTransaction();
     for (int i = from; i <= to; i++) {
@@ -472,7 +483,7 @@ Operations::delByPK(const NdbDictionary:
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // set key attribute
-        if (op->equal(meta->attr_id, (Int32)i) != 0)
+        if (op->equal(model->attr_id, (Int32)i) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // execute the operation now if in non-batching mode
@@ -484,7 +495,7 @@ Operations::delByPK(const NdbDictionary:
 }
 
 void
-Operations::setByPK(const NdbDictionary::Table* table,
+CrundNdbApiOperations::setByPK(const NdbDictionary::Table* table,
                     int from, int to,
                     bool batch)
 {
@@ -498,15 +509,15 @@ Operations::setByPK(const NdbDictionary:
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // set values; key attribute needs to be set first
-        if (op->equal(meta->attr_id, (Int32)i) != 0)
+        if (op->equal(model->attr_id, (Int32)i) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->setValue(meta->attr_cint, (Int32)i) != 0)
+        if (op->setValue(model->attr_cint, (Int32)i) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->setValue(meta->attr_clong, (Int64)i) != 0)
+        if (op->setValue(model->attr_clong, (Int64)i) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->setValue(meta->attr_cfloat, (float)i) != 0)
+        if (op->setValue(model->attr_cfloat, (float)i) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->setValue(meta->attr_cdouble, (double)i) != 0)
+        if (op->setValue(model->attr_cdouble, (double)i) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // execute the operation now if in non-batching mode
@@ -518,7 +529,7 @@ Operations::setByPK(const NdbDictionary:
 }
 
 void
-Operations::getByPK_bb(const NdbDictionary::Table* table,
+CrundNdbApiOperations::getByPK_bb(const NdbDictionary::Table* table,
                        int from, int to,
                        bool batch)
 {
@@ -538,19 +549,19 @@ Operations::getByPK_bb(const NdbDictiona
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // set key attribute
-        if (op->equal(meta->attr_id, (Int32)i) != 0)
+        if (op->equal(model->attr_id, (Int32)i) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // get attributes (not readable until after commit)
-        if (op->getValue(meta->attr_id, (char*)&pab->id) == NULL)
+        if (op->getValue(model->attr_id, (char*)&pab->id) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->getValue(meta->attr_cint, (char*)&pab->cint) == NULL)
+        if (op->getValue(model->attr_cint, (char*)&pab->cint) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->getValue(meta->attr_clong, (char*)&pab->clong) == NULL)
+        if (op->getValue(model->attr_clong, (char*)&pab->clong) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->getValue(meta->attr_cfloat, (char*)&pab->cfloat) == NULL)
+        if (op->getValue(model->attr_cfloat, (char*)&pab->cfloat) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->getValue(meta->attr_cdouble, (char*)&pab->cdouble) == NULL)
+        if (op->getValue(model->attr_cdouble, (char*)&pab->cdouble) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // execute the operation now if in non-batching mode
@@ -598,7 +609,7 @@ getCommonAB(const CommonAB_AR* const ab)
 }
 
 void
-Operations::getByPK_ar(const NdbDictionary::Table* table,
+CrundNdbApiOperations::getByPK_ar(const NdbDictionary::Table* table,
                        int from, int to,
                        bool batch)
 {
@@ -618,19 +629,19 @@ Operations::getByPK_ar(const NdbDictiona
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // set key attribute
-        if (op->equal(meta->attr_id, (Int32)i) != 0)
+        if (op->equal(model->attr_id, (Int32)i) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // get attributes (not readable until after commit)
-        if ((pab->id = op->getValue(meta->attr_id, NULL)) == NULL)
+        if ((pab->id = op->getValue(model->attr_id, NULL)) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if ((pab->cint = op->getValue(meta->attr_cint, NULL)) == NULL)
+        if ((pab->cint = op->getValue(model->attr_cint, NULL)) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if ((pab->clong = op->getValue(meta->attr_clong, NULL)) == NULL)
+        if ((pab->clong = op->getValue(model->attr_clong, NULL)) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if ((pab->cfloat = op->getValue(meta->attr_cfloat, NULL)) == NULL)
+        if ((pab->cfloat = op->getValue(model->attr_cfloat, NULL)) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if ((pab->cdouble = op->getValue(meta->attr_cdouble, NULL)) == NULL)
+        if ((pab->cdouble = op->getValue(model->attr_cdouble, NULL)) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // execute the operation now if in non-batching mode
@@ -657,39 +668,39 @@ Operations::getByPK_ar(const NdbDictiona
 }
 
 void
-Operations::setVarbinary(const NdbDictionary::Table* table,
+CrundNdbApiOperations::setVarbinary(const NdbDictionary::Table* table,
                          int from, int to, bool batch, int length)
 {
-    setVar(table, meta->attr_B0_cvarbinary_def,
+    setVar(table, model->attr_B0_cvarbinary_def,
            from, to, batch, selectString(length));
 }
 
 void
-Operations::setVarchar(const NdbDictionary::Table* table,
+CrundNdbApiOperations::setVarchar(const NdbDictionary::Table* table,
                        int from, int to, bool batch, int length)
 {
-    setVar(table, meta->attr_B0_cvarchar_def,
+    setVar(table, model->attr_B0_cvarchar_def,
            from, to, batch, selectString(length));
 }
 
 void
-Operations::getVarbinary(const NdbDictionary::Table* table,
+CrundNdbApiOperations::getVarbinary(const NdbDictionary::Table* table,
                          int from, int to, bool batch, int length)
 {
-    getVar(table, meta->attr_B0_cvarbinary_def,
+    getVar(table, model->attr_B0_cvarbinary_def,
            from, to, batch, selectString(length));
 }
 
 void
-Operations::getVarchar(const NdbDictionary::Table* table,
+CrundNdbApiOperations::getVarchar(const NdbDictionary::Table* table,
                        int from, int to, bool batch, int length)
 {
-    getVar(table, meta->attr_B0_cvarchar_def,
+    getVar(table, model->attr_B0_cvarchar_def,
            from, to, batch, selectString(length));
 }
 
 void
-Operations::setVar(const NdbDictionary::Table* table, int attr_cvar,
+CrundNdbApiOperations::setVar(const NdbDictionary::Table* table, int attr_cvar,
                    int from, int to,
                    bool batch, const char* str)
 {
@@ -719,7 +730,7 @@ Operations::setVar(const NdbDictionary::
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // set values; key attribute needs to be set first
-        if (op->equal(meta->attr_id, (Int32)i) != 0)
+        if (op->equal(model->attr_id, (Int32)i) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
         if (op->setValue(attr_cvar, buf) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
@@ -738,7 +749,7 @@ Operations::setVar(const NdbDictionary::
 }
 
 void
-Operations::getVar(const NdbDictionary::Table* table, int attr_cvar,
+CrundNdbApiOperations::getVar(const NdbDictionary::Table* table, int attr_cvar,
                    int from, int to,
                    bool batch, const char* str)
 {
@@ -768,7 +779,7 @@ Operations::getVar(const NdbDictionary::
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // set key attribute
-        if (op->equal(meta->attr_id, (Int32)1) != 0)
+        if (op->equal(model->attr_id, (Int32)1) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // get attributes (not readable until after commit)
@@ -808,25 +819,25 @@ Operations::getVar(const NdbDictionary::
 }
 
 void
-Operations::setB0ToA(int count_A, int count_B,
+CrundNdbApiOperations::setB0ToA(int count_A, int count_B,
                      bool batch)
 {
     beginTransaction();
     for (int i = 1; i <= count_B; i++) {
         // get an update operation for the table
-        NdbOperation* op = tx->getNdbOperation(meta->table_B0);
+        NdbOperation* op = tx->getNdbOperation(model->table_B0);
         if (op == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
         if (op->updateTuple() != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // set key attribute
-        if (op->equal(meta->attr_id, (Int32)i) != 0)
+        if (op->equal(model->attr_id, (Int32)i) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // set a_id attribute
         int a_id = ((i - 1) % count_A) + 1;
-        if (op->setValue(meta->attr_B0_a_id, (Int32)a_id) != 0)
+        if (op->setValue(model->attr_B0_a_id, (Int32)a_id) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // execute the operation now if in non-batching mode
@@ -838,24 +849,24 @@ Operations::setB0ToA(int count_A, int co
 }
 
 void
-Operations::nullB0ToA(int count_A, int count_B,
+CrundNdbApiOperations::nullB0ToA(int count_A, int count_B,
                       bool batch)
 {
     beginTransaction();
     for (int i = 1; i <= count_B; i++) {
         // get an update operation for the table
-        NdbOperation* op = tx->getNdbOperation(meta->table_B0);
+        NdbOperation* op = tx->getNdbOperation(model->table_B0);
         if (op == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
         if (op->updateTuple() != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // set key attribute
-        if (op->equal(meta->attr_id, (Int32)i) != 0)
+        if (op->equal(model->attr_id, (Int32)i) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // clear a_id attribute
-        if (op->setValue(meta->attr_B0_a_id, (char*)NULL) != 0)
+        if (op->setValue(model->attr_B0_a_id, (char*)NULL) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // execute the operation now if in non-batching mode
@@ -867,7 +878,7 @@ Operations::nullB0ToA(int count_A, int c
 }
 
 void
-Operations::navB0ToA(int count_A, int count_B,
+CrundNdbApiOperations::navB0ToA(int count_A, int count_B,
                      bool batch)
 {
     // allocate attributes holder
@@ -881,18 +892,18 @@ Operations::navB0ToA(int count_A, int co
         Int32 a_id;
         {
             // get a read operation for the table
-            NdbOperation* op = tx->getNdbOperation(meta->table_B0);
+            NdbOperation* op = tx->getNdbOperation(model->table_B0);
             if (op == NULL)
                 ABORT_NDB_ERROR(tx->getNdbError());
             if (op->readTuple(NdbOperation::LM_CommittedRead) != 0)
                 ABORT_NDB_ERROR(tx->getNdbError());
 
             // set key attribute
-            if (op->equal(meta->attr_id, (Int32)i) != 0)
+            if (op->equal(model->attr_id, (Int32)i) != 0)
                 ABORT_NDB_ERROR(tx->getNdbError());
 
             // get attribute (not readable until after commit)
-            if (op->getValue(meta->attr_B0_a_id, (char*)&a_id) == NULL)
+            if (op->getValue(model->attr_B0_a_id, (char*)&a_id) == NULL)
                 ABORT_NDB_ERROR(tx->getNdbError());
         }
         executeOperations(); // start the scan; don't commit yet
@@ -900,7 +911,7 @@ Operations::navB0ToA(int count_A, int co
         // fetch the attributes from A
         {
             // get a read operation for the table
-            NdbOperation* op = tx->getNdbOperation(meta->table_A);
+            NdbOperation* op = tx->getNdbOperation(model->table_A);
             if (op == NULL)
                 ABORT_NDB_ERROR(tx->getNdbError());
             if (op->readTuple(NdbOperation::LM_CommittedRead) != 0)
@@ -908,19 +919,19 @@ Operations::navB0ToA(int count_A, int co
 
             // set key attribute
             assert (a_id == ((i - 1) % count_A) + 1);
-            if (op->equal(meta->attr_id, a_id) != 0)
+            if (op->equal(model->attr_id, a_id) != 0)
                 ABORT_NDB_ERROR(tx->getNdbError());
 
             // get attributes (not readable until after commit)
-            if (op->getValue(meta->attr_id, (char*)&pab->id) == NULL)
+            if (op->getValue(model->attr_id, (char*)&pab->id) == NULL)
                 ABORT_NDB_ERROR(tx->getNdbError());
-            if (op->getValue(meta->attr_cint, (char*)&pab->cint) == NULL)
+            if (op->getValue(model->attr_cint, (char*)&pab->cint) == NULL)
                 ABORT_NDB_ERROR(tx->getNdbError());
-            if (op->getValue(meta->attr_clong, (char*)&pab->clong) == NULL)
+            if (op->getValue(model->attr_clong, (char*)&pab->clong) == NULL)
                 ABORT_NDB_ERROR(tx->getNdbError());
-            if (op->getValue(meta->attr_cfloat, (char*)&pab->cfloat) == NULL)
+            if (op->getValue(model->attr_cfloat, (char*)&pab->cfloat) == NULL)
                 ABORT_NDB_ERROR(tx->getNdbError());
-            if (op->getValue(meta->attr_cdouble, (char*)&pab->cdouble) == NULL)
+            if (op->getValue(model->attr_cdouble, (char*)&pab->cdouble) == NULL)
                 ABORT_NDB_ERROR(tx->getNdbError());
         }
 
@@ -948,7 +959,7 @@ Operations::navB0ToA(int count_A, int co
 }
 
 void
-Operations::navB0ToAalt(int count_A, int count_B,
+CrundNdbApiOperations::navB0ToAalt(int count_A, int count_B,
                         bool batch)
 {
     // allocate foreign key values holder
@@ -959,18 +970,18 @@ Operations::navB0ToAalt(int count_A, int
     Int32* pa_id = a_id;
     for (int i = 1; i <= count_B; i++) {
         // get a read operation for the table
-        NdbOperation* op = tx->getNdbOperation(meta->table_B0);
+        NdbOperation* op = tx->getNdbOperation(model->table_B0);
         if (op == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
         if (op->readTuple(NdbOperation::LM_CommittedRead) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // set key attribute
-        if (op->equal(meta->attr_id, (Int32)i) != 0)
+        if (op->equal(model->attr_id, (Int32)i) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // get attribute (not readable until after commit)
-        if (op->getValue(meta->attr_B0_a_id, (char*)pa_id++) == NULL)
+        if (op->getValue(model->attr_B0_a_id, (char*)pa_id++) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // execute the operation now if in non-batching mode
@@ -987,7 +998,7 @@ Operations::navB0ToAalt(int count_A, int
     CommonAB* pab = ab;
     for (int i = 1; i <= count_B; i++, pa_id++, pab++) {
         // get a read operation for the table
-        NdbOperation* op = tx->getNdbOperation(meta->table_A);
+        NdbOperation* op = tx->getNdbOperation(model->table_A);
         if (op == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
         if (op->readTuple(NdbOperation::LM_CommittedRead) != 0)
@@ -995,19 +1006,19 @@ Operations::navB0ToAalt(int count_A, int
 
         // set key attribute
         assert (*pa_id == ((i - 1) % count_A) + 1);
-        if (op->equal(meta->attr_id, (Int32)*pa_id) != 0)
+        if (op->equal(model->attr_id, (Int32)*pa_id) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // get attributes (not readable until after commit)
-        if (op->getValue(meta->attr_id, (char*)&pab->id) == NULL)
+        if (op->getValue(model->attr_id, (char*)&pab->id) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->getValue(meta->attr_cint, (char*)&pab->cint) == NULL)
+        if (op->getValue(model->attr_cint, (char*)&pab->cint) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->getValue(meta->attr_clong, (char*)&pab->clong) == NULL)
+        if (op->getValue(model->attr_clong, (char*)&pab->clong) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->getValue(meta->attr_cfloat, (char*)&pab->cfloat) == NULL)
+        if (op->getValue(model->attr_cfloat, (char*)&pab->cfloat) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->getValue(meta->attr_cdouble, (char*)&pab->cdouble) == NULL)
+        if (op->getValue(model->attr_cdouble, (char*)&pab->cdouble) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // execute the operation now if in non-batching mode
@@ -1037,7 +1048,7 @@ Operations::navB0ToAalt(int count_A, int
 }
 
 void
-Operations::navAToB0(int count_A, int count_B,
+CrundNdbApiOperations::navAToB0(int count_A, int count_B,
                      bool forceSend)
 {
     // attributes holder
@@ -1052,7 +1063,7 @@ Operations::navAToB0(int count_A, int co
     for (int i = 1; i <= count_A; i++) {
         // get an index scan operation for the table
         NdbIndexScanOperation* op
-            = tx->getNdbIndexScanOperation(meta->idx_B0_a_id);
+            = tx->getNdbIndexScanOperation(model->idx_B0_a_id);
         if (op == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
 
@@ -1062,26 +1073,26 @@ Operations::navAToB0(int count_A, int co
 
         // define the scan's bounds (more efficient than using a scan filter)
         // the argument to setBound() is not the column's attribute id
-        //    if (op->setBound(meta->attr_B0_a_id, ...
+        //    if (op->setBound(model->attr_B0_a_id, ...
         // or column name
         //    if (op->setBound("a_id", ...
         // but the attribute id of the column *in the index*.
         //    if (op->setBound(idx_B0_a_id->getColumn(0)->getAttrId()...
         // for which we introduced a shortcut.
-        if (op->setBound(meta->attr_idx_B0_a_id,
+        if (op->setBound(model->attr_idx_B0_a_id,
                          NdbIndexScanOperation::BoundEQ, &i) != 0)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // get attributes (not readable until after commit)
-        if (op->getValue(meta->attr_id, (char*)&h.id) == NULL)
+        if (op->getValue(model->attr_id, (char*)&h.id) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->getValue(meta->attr_cint, (char*)&h.cint) == NULL)
+        if (op->getValue(model->attr_cint, (char*)&h.cint) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->getValue(meta->attr_clong, (char*)&h.clong) == NULL)
+        if (op->getValue(model->attr_clong, (char*)&h.clong) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->getValue(meta->attr_cfloat, (char*)&h.cfloat) == NULL)
+        if (op->getValue(model->attr_cfloat, (char*)&h.cfloat) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
-        if (op->getValue(meta->attr_cdouble, (char*)&h.cdouble) == NULL)
+        if (op->getValue(model->attr_cdouble, (char*)&h.cdouble) == NULL)
             ABORT_NDB_ERROR(tx->getNdbError());
 
         // start the scan; don't commit yet
@@ -1120,7 +1131,7 @@ Operations::navAToB0(int count_A, int co
 }
 
 void
-Operations::navAToB0alt(int count_A, int count_B,
+CrundNdbApiOperations::navAToB0alt(int count_A, int count_B,
                         bool forceSend)
 {
     // number of operations in a multi-scan batch
@@ -1142,7 +1153,7 @@ Operations::navAToB0alt(int count_A, int
 
         for (int i = 0; i < nmscans; i++) {
             // get an index scan operation for the table
-            op[i] = tx->getNdbIndexScanOperation(meta->idx_B0_a_id);
+            op[i] = tx->getNdbIndexScanOperation(model->idx_B0_a_id);
             if (op[i] == NULL)
                 ABORT_NDB_ERROR(tx->getNdbError());
 
@@ -1153,26 +1164,26 @@ Operations::navAToB0alt(int count_A, int
 
             // define the scan's bounds (more efficient than using a scan filter)
             // the argument to setBound() is not the column's attribute id
-            //    if (op[i]->setBound(meta->attr_B0_a_id, ...
+            //    if (op[i]->setBound(model->attr_B0_a_id, ...
             // or column name
             //    if (op[i]->setBound("a_id", ...
             // but the attribute id of the column *in the index*.
             //    if (op[i]->setBound(idx_B0_a_id->getColumn(0)->getAttrId()...
             // for which we introduced a shortcut.
-            if (op[i]->setBound(meta->attr_idx_B0_a_id,
+            if (op[i]->setBound(model->attr_idx_B0_a_id,
                                 NdbIndexScanOperation::BoundEQ, &a_id) != 0)
                 ABORT_NDB_ERROR(tx->getNdbError());
 
             // get attributes (not readable until after commit)
-            if (op[i]->getValue(meta->attr_id, (char*)&h.id) == NULL)
+            if (op[i]->getValue(model->attr_id, (char*)&h.id) == NULL)
                 ABORT_NDB_ERROR(tx->getNdbError());
-            if (op[i]->getValue(meta->attr_cint, (char*)&h.cint) == NULL)
+            if (op[i]->getValue(model->attr_cint, (char*)&h.cint) == NULL)
                 ABORT_NDB_ERROR(tx->getNdbError());
-            if (op[i]->getValue(meta->attr_clong, (char*)&h.clong) == NULL)
+            if (op[i]->getValue(model->attr_clong, (char*)&h.clong) == NULL)
                 ABORT_NDB_ERROR(tx->getNdbError());
-            if (op[i]->getValue(meta->attr_cfloat, (char*)&h.cfloat) == NULL)
+            if (op[i]->getValue(model->attr_cfloat, (char*)&h.cfloat) == NULL)
                 ABORT_NDB_ERROR(tx->getNdbError());
-            if (op[i]->getValue(meta->attr_cdouble, (char*)&h.cdouble) == NULL)
+            if (op[i]->getValue(model->attr_cdouble, (char*)&h.cdouble) == NULL)
                 ABORT_NDB_ERROR(tx->getNdbError());
 
             // next a

=== renamed file 'storage/ndb/test/crund/src/crundndb/Operations.hpp' => 'storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.hpp'
--- a/storage/ndb/test/crund/src/crundndb/Operations.hpp	2010-10-01 08:58:08 +0000
+++ b/storage/ndb/test/crund/src/crundndb/CrundNdbApiOperations.hpp	2010-10-05 08:48:30 +0000
@@ -1,20 +1,33 @@
-/*
- * Operations.hpp
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
  *
+ *  Copyright (C) 2009 MySQL
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifndef crundndb_Operations_hpp
-#define crundndb_Operations_hpp
+#ifndef CrundNdbApiOperations_hpp
+#define CrundNdbApiOperations_hpp
 
 #include <NdbApi.hpp>
 #include <NdbError.hpp>
 
-namespace crund_ndb {
-
 /**
  * Holds shortcuts to the benchmark's schema information.
  */
-struct Meta
+struct CrundModel
 {
     const NdbDictionary::Table* table_A;
     const NdbDictionary::Table* table_B0;
@@ -50,7 +63,7 @@ struct Meta
 /**
  * Implements the benchmark's basic database operations.
  */
-class Operations
+class CrundNdbApiOperations
 {
 // For a better locality of information, consider refactorizing this
 // class into separate classes: Cluster, Db, Tx, and Operations by
@@ -61,7 +74,7 @@ class Operations
 
 public:
     // the benchmark's metadata shortcuts
-    const Meta* meta;
+    const CrundModel* model;
 
 //protected:
     // singleton object representing the NDB cluster (one per process)
@@ -152,6 +165,4 @@ protected:
                 int from, int to, bool batch, const char* str);
 };
 
-} // crund_ndb
-
-#endif // crundndb_Operations_hpp
+#endif // CrundNdbApiOperations_hpp

=== modified file 'storage/ndb/test/crund/src/crundndb/Driver.cpp'
--- a/storage/ndb/test/crund/src/crundndb/Driver.cpp	2010-10-01 08:58:08 +0000
+++ b/storage/ndb/test/crund/src/crundndb/Driver.cpp	2010-10-05 08:48:30 +0000
@@ -1,6 +1,21 @@
-/*
- * Driver.cpp
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
  *
+ *  Copyright (C) 2009 MySQL
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <iostream>
@@ -10,261 +25,92 @@
 #include <vector>
 #include <cassert>
 #include <ctime>
-#include <set>
 
 #include "helpers.hpp"
 #include "string_helpers.hpp"
-#include "Properties.hpp"
-#include "hrt_utils.h"
-#include "Operations.hpp"
 
-// global type aliases
-typedef const NdbDictionary::Table* NdbTable;
+#include "Driver.hpp"
 
-namespace crund_ndb {
-
-//using namespace std;
+using std::cout;
+using std::flush;
+using std::endl;
+using std::ios_base;
+using std::ofstream;
+using std::ostringstream;
 using std::string;
 using std::wstring;
 using std::vector;
-using std::ofstream;
-using std::ostringstream;
-using std::set;
 
 using utils::Properties;
+using utils::toBool;
+using utils::toInt;
+using utils::toString;
 
-class Driver {
-
-public:
-    /**
-     * Creates a Driver instance.
-     */
-    Driver();
-
-    /**
-     * Parses the benchmark's command-line arguments.
-     */
-    void parseArguments(int argc, const char* argv[]);
-
-    /**
-     * Runs the entire benchmark.
-     */
-    void run();
-
-protected:
-    // command-line arguments
-    vector< string > propFileNames;
-    string logFileName;
-
-    // the data output stream
-    ofstream log;
-
-    // benchmark settings
-    Properties props;
-    string descr;
-    bool logRealTime;
-    bool logCpuTime;
-    bool logSumOfOps;
-    bool renewConnection;
-    bool renewOperations;
-    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
-    string mgmdConnect;
-    string catalog;
-    string schema;
-
-    // the benchmark's basic database operations.
-    static crund_ndb::Operations* ops;
-
-    /**
-     * A database operation to be benchmarked.
-     */
-    struct Op {
-        const string name;
+//---------------------------------------------------------------------------
 
-        virtual void run(int countA, int countB) const = 0;
-        //void (*run)(int countA, int countB);
+vector< string > Driver::propFileNames;
+string Driver::logFileName;
 
-        Op(const string& name)
-            : name(name) {
-        }
+void
+Driver::exitUsage()
+{
+    cout << "usage: [options]" << endl
+         << "    [-p <file name>]...    properties file name" << endl
+         << "    [-l <file name>]       log file name for data output" << endl
+         << "    [-h|--help]            print usage message and exit" << endl
+         << endl;
+    exit(1); // return an error code
+}
 
-        virtual ~Op() {
+void
+Driver::parseArguments(int argc, const char* argv[])
+{
+    for (int i = 1; i < argc; i++) {
+        const string arg = argv[i];
+        if (arg.compare("-p") == 0) {
+            if (i >= argc) {
+                exitUsage();
+            }
+            propFileNames.push_back(argv[++i]);
+        } else if (arg.compare("-l") == 0) {
+            if (i >= argc) {
+                exitUsage();
+            }
+            logFileName = argv[++i];
+        } else if (arg.compare("-h") == 0 || arg.compare("--help") == 0) {
+            exitUsage();
+        } else {
+            cout << "unknown option: " << arg << endl;
+            exitUsage();
         }
-    };
-
-    /**
-     * The list of database operations to be benchmarked.
-     * Managed by methods initOperations() and closeOperations().
-     */
-    typedef vector< const Op* > Operations;
-    Operations operations;
-
-private:
-    // buffers collecting the header and data lines written to log
-    bool logHeader;
-    ostringstream header;
-    ostringstream rtimes;
-    ostringstream ctimes;
-
-    // benchmark data fields
-    int s0, s1;
-    hrt_tstamp t0, t1;
-    long rta, cta;
-
-protected:
-
-    /**
-     * Loads the benchmark's properties from properties files.
-     */
-    void loadProperties();
-
-    /**
-     * Reads and initializes the benchmark's properties from a file.
-     */
-    void initProperties();
-
-    /**
-     * Prints the benchmark's properties.
-     */
-    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();
-
-    /**
-     * Releases the benchmark's resources.
-     */
-    void close();
-
-    /**
-     * Prints a command-line usage message and exits.
-     */
-    void exitUsage();
-
-    /**
-     * Runs a series of benchmark operations on scaled-up data.
-     */
-    void runTests();
-
-    /**
-     * Runs a series of benchmark operations.
-     */
-    void runOperations(int countA, int countB);
-
-    /**
-     * Runs a benchmark operation.
-     */
-    void runOp(const Op& op, int countA, int countB);
-
-    /**
-     * Begins a benchmarked transaction.
-     */
-    void begin(const string& name);
-
-    /**
-     * Closes a benchmarked transaction.
-     */
-    void commit(const string& name);
-
-    // ----------------------------------------------------------------------
-
-    void initConnection();
-
-    void closeConnection();
-
-    void initOperations();
-
-    template< bool feat > void initOperationsFeat();
-
-    void closeOperations();
-
-    void clearData();
-
-    // operation invocation templates
-    template< bool > struct ADelAllOp;
-
-    template< bool > struct B0DelAllOp;
-
-    template< bool, bool > struct AInsOp;
-
-    template< bool, bool > struct B0InsOp;
-
-    template< const char**,
-              void (crund_ndb::Operations::*)(NdbTable,int,int,bool),
-              bool >
-    struct AByPKOp;
-
-    template< const char**,
-              void (crund_ndb::Operations::*)(NdbTable,int,int,bool),
-              bool >
-    struct B0ByPKOp;
-
-    template< const char**,
-              void (crund_ndb::Operations::*)(NdbTable,int,int,bool,int),
-              bool >
-    struct LengthOp;
-
-    template< const char**,
-              void (crund_ndb::Operations::*)(NdbTable,int,int,bool,int),
-              bool >
-    struct ZeroLengthOp;
-
-    template< const char**,
-              void (crund_ndb::Operations::*)(int,int,bool),
-              bool >
-    struct RelOp;
-};
+    }
 
-} // crund_ndb
+    if (propFileNames.size() == 0) {
+        propFileNames.push_back("run.properties");
+    }
 
-// ----------------------------------------------------------------------
+    if (logFileName.empty()) {
+        logFileName = "log_";
 
-//using namespace std;
-using std::wistringstream;
-using std::ios_base;
-using std::cout;
-using std::flush;
-using std::endl;
-using std::string;
-using std::wstring;
+        // format, destination strings (static size)
+        const char format[] = "%Y%m%d_%H%M%S";
+        const int size = sizeof("yyyymmdd_HHMMSS");
+        char dest[size];
 
-using utils::toBool;
-using utils::toInt;
-using utils::toString;
-using crund_ndb::Driver;
+        // 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);
+        (void)nchars;
 
-Driver::Driver() {
+        logFileName += dest;
+        logFileName += ".txt";
+        //cout << "logFileName='" << logFileName << "'" << endl;
+    }
 }
 
-#include <algorithm>
-#include <cctype>
-
 // ----------------------------------------------------------------------
 
-crund_ndb::Operations* Driver::ops = NULL;
-
 void
 Driver::run() {
     init();
@@ -318,11 +164,6 @@ Driver::init() {
     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
@@ -331,25 +172,15 @@ Driver::close() {
     header.rdbuf()->str("");
     rtimes.rdbuf()->str("");
 
-    // release the benchmark's resources
-    assert (!mgmdConnect.empty());
-    ops->close();
-    delete ops;
-    ops = NULL;
-
     closeLogFile();
 }
 
 void
 Driver::loadProperties() {
-    if (propFileNames.size() == 0) {
-        propFileNames.push_back("crund.properties");
-    }
-
     cout << endl;
     for (vector<string>::const_iterator i = propFileNames.begin();
          i != propFileNames.end(); ++i) {
-        cout << "reading properties file:    " << *i << endl;
+        cout << "reading properties file:        " << *i << endl;
         props.load(i->c_str());
         props.load(i->c_str());
         //wcout << props << endl;
@@ -358,81 +189,13 @@ Driver::loadProperties() {
 
 void
 Driver::initProperties() {
-    cout << "initializing properties ... " << flush;
+    cout << "setting driver properties ..." << flush;
 
     ostringstream msg;
 
-    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"]);
-
-    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;
-    }
+    logRealTime = toBool(props[L"logRealTime"], true);
+    logCpuTime = toBool(props[L"logCpuTime"], false);
+    renewConnection = toBool(props[L"renewConnection"], false);
 
     warmupRuns = toInt(props[L"warmupRuns"], 0, -1);
     if (warmupRuns < 0) {
@@ -448,42 +211,11 @@ Driver::initProperties() {
         hotRuns = 1;
     }
 
-    // initialize exclude set
-    const wstring& estr = props[L"exclude"];
-    //cout << "estr='" << toString(estr) << "'" << endl;
-    const size_t len = estr.length();
-    size_t beg = 0, next;
-    while (beg < len
-           && ((next = estr.find_first_of(L",", beg)) != wstring::npos)) {
-        // add substring if not empty
-        if (beg < next) {
-            const wstring& s = estr.substr(beg, next - beg);
-            exclude.insert(toString(s));
-        }
-        beg = next + 1;
-    }
-    // add last substring if any
-    if (beg < len) {
-        const wstring& s = estr.substr(beg, len - beg);
-        exclude.insert(toString(s));
-    }
-
-    // string properties
-    mgmdConnect = toString(props[L"ndb.mgmdConnect"]);
-    catalog = toString(props[L"ndb.catalog"]);
-    schema = toString(props[L"ndb.schema"]);
-
-    descr = "C++->NDBAPI(" + mgmdConnect + ")";
-
     if (msg.tellp() == 0) {
-        cout << "[ok]" << endl;
+        cout << "   [ok]" << endl;
     } else {
         cout << endl << msg.str() << endl;
     }
-
-    cout << "data set:                   "
-         << "[A=" << aStart << ".." << aEnd
-         << ", B=" << bStart << ".." << bEnd << "]" << endl;
 }
 
 void
@@ -493,28 +225,12 @@ Driver::printProperties() {
     //cout << ios_base::boolalpha;
     cout.flags(ios_base::boolalpha);
 
-    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 << "bStart:                     " << bStart << endl;
-    cout << "aEnd:                       " << aEnd << endl;
-    cout << "bEnd:                       " << bEnd << 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;
-    cout << "ndb.mgmdConnect             \"" << mgmdConnect << "\"" << endl;
-    cout << "ndb.catalog                 \"" << catalog << "\"" << endl;
-    cout << "ndb.schema                  \"" << schema << "\"" << endl;
+    cout << endl << "driver settings ..." << endl;
+    cout << "logRealTime:                    " << logRealTime << endl;
+    cout << "logCpuTime:                     " << logCpuTime << endl;
+    cout << "renewConnection:                " << renewConnection << endl;
+    cout << "warmupRuns:                     " << warmupRuns << endl;
+    cout << "hotRuns:                        " << hotRuns << endl;
 
     cout.flags(f);
 }
@@ -522,7 +238,7 @@ Driver::printProperties() {
 void
 Driver::openLogFile() {
     cout << endl
-         << "writing results to file:    " << logFileName << 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());
@@ -530,121 +246,14 @@ Driver::openLogFile() {
 
 void
 Driver::closeLogFile() {
-    cout << "closing files ...    " << flush;
+    cout << "closing files ..." << flush;
     log.close();
-    cout << "       [ok]" << endl;
+    cout << "               [ok]" << endl;
 }
 
 // ----------------------------------------------------------------------
 
 void
-Driver::runTests() {
-    initConnection();
-    initOperations();
-
-    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);
-        }
-    }
-
-    cout << endl
-         << "------------------------------------------------------------" << endl
-         << endl;
-
-    clearData();
-    closeOperations();
-    closeConnection();
-}
-
-void
-Driver::runOperations(int countA, int countB) {
-    cout << 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) {
-        rtimes << "A=" << countA << ", B=" << countB;
-        rta = 0L;
-    }
-    if (logCpuTime) {
-        ctimes << "A=" << countA << ", B=" << countB;
-        cta = 0L;
-    }
-
-    // pre-run cleanup
-    if (renewConnection) {
-        closeOperations();
-        closeConnection();
-        initConnection();
-        initOperations();
-    } else if (renewOperations) {
-        closeOperations();
-        initOperations();
-    }
-    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";
-    }
-
-    // log buffers
-    logHeader = false;
-    if (logRealTime) {
-        if (logSumOfOps) {
-            rtimes << "\t" << rta;
-            cout << endl
-                 << "total" << endl
-                 << "tx real time\t\t= " << rta
-                 << "\tms [begin..commit]" << endl;
-        }
-        rtimes << endl;
-    }
-    if (logCpuTime) {
-        if (logSumOfOps) {
-            ctimes << "\t" << cta;
-            cout << endl
-                 << "total" << endl
-                 << "tx cpu time\t\t= " << cta
-                 << "\tms [begin..commit]" << endl;
-        }
-        ctimes << endl;
-    }
-}
-
-void
-Driver::runOp(const Op& op, int countA, int countB) {
-    const string& name = op.name;
-    if (exclude.find(name) == exclude.end()) {
-        begin(name);
-        op.run(countA, countB);
-        commit(name);
-    }
-}
-
-void
 Driver::begin(const string& name) {
     cout << endl;
     cout << name << endl;
@@ -656,16 +265,10 @@ Driver::begin(const string& name) {
     } else if (logCpuTime) {
         s0 = hrt_ctnow(&t0.ctstamp);
     }
-
-    // NDB Operations manages transactions boundaries itself
-    //beginTransaction();
 }
 
 void
 Driver::commit(const string& name) {
-    // NDB Operations manages transactions boundaries itself
-    //commitTransaction();
-
     if (logRealTime && logCpuTime) {
         s1 = hrt_tnow(&t1);
     } else if (logRealTime) {
@@ -680,8 +283,8 @@ Driver::commit(const string& name) {
             rtimes << "\tERROR";
         } else {
             long t = long(hrt_rtmicros(&t1.rtstamp, &t0.rtstamp)/1000);
-            cout << "tx real time\t\t= " << t
-                 << "\tms [begin..commit]" << endl;
+            cout << "tx real time:                   " << t
+                 << "\tms" << endl;
             rtimes << "\t" << t;
             rta += t;
         }
@@ -693,8 +296,8 @@ Driver::commit(const string& name) {
             ctimes << "\tERROR";
         } else {
             long t = long(hrt_ctmicros(&t1.ctstamp, &t0.ctstamp)/1000);
-            cout << "tx cpu time\t\t= " << t
-                 << "\tms [begin..commit]" << endl;
+            cout << "tx cpu time:                    " << t
+                 << "\tms" << endl;
             ctimes << "\t" << t;
             cta += t;
         }
@@ -705,350 +308,3 @@ Driver::commit(const string& name) {
 }
 
 //---------------------------------------------------------------------------
-
-void
-Driver::initConnection() {
-    ops->initConnection(catalog.c_str(), schema.c_str());
-}
-
-void
-Driver::closeConnection() {
-    ops->closeConnection();
-}
-
-void
-Driver::initOperations() {
-    cout << "initializing operations ..." << flush;
-
-    const bool feat = true;
-    initOperationsFeat< !feat >();
-    initOperationsFeat< feat >();
-
-    cout << " [Op: " << operations.size() << "]" << endl;
-}
-
-// the operation invocation templates look a bit complex, but they help
-// a lot to factorize code over the operations' parameter signatures
-
-template< bool OB >
-struct Driver::ADelAllOp : Op {
-    ADelAllOp() : Op(string("delAllA")
-                     + (OB ? "_batch" : "")) {
-    }
-
-    virtual void run(int countA, int countB) const {
-        int count;
-        ops->delByScan(ops->meta->table_A, count, OB);
-        assert (count == countA);
-    }
-};
-
-template< bool OB >
-struct Driver::B0DelAllOp : Op {
-    B0DelAllOp() : Op(string("delAllB0")
-                      + (OB ? "_batch" : "")) {
-    }
-
-    virtual void run(int countA, int countB) const {
-        int count;
-        ops->delByScan(ops->meta->table_B0, count, OB);
-        assert (count == countB);
-    }
-};
-
-template< bool OSA, bool OB >
-struct Driver::AInsOp : Op {
-    AInsOp() : Op(string("insA")
-                  + (OSA ? "_attr" : "")
-                  + (OB ? "_batch" : "")) {
-    }
-
-    virtual void run(int countA, int countB) const {
-        ops->ins(ops->meta->table_A, 1, countA, OSA, OB);
-    }
-};
-
-template< bool OSA, bool OB >
-struct Driver::B0InsOp : Op {
-    B0InsOp() : Op(string("insB0")
-                   + (OSA ? "_attr" : "")
-                   + (OB ? "_batch" : "")) {
-    }
-
-    virtual void run(int countA, int countB) const {
-        ops->ins(ops->meta->table_B0, 1, countB, OSA, OB);
-    }
-};
-
-template< const char** ON,
-          void (crund_ndb::Operations::*OF)(NdbTable,int,int,bool),
-          bool OB >
-struct Driver::AByPKOp : Op {
-    AByPKOp() : Op(string(*ON)
-                   + (OB ? "_batch" : "")) {
-    }
-
-    virtual void run(int countA, int countB) const {
-        (ops->*OF)(ops->meta->table_A, 1, countA, OB);
-    }
-};
-
-template< const char** ON,
-          void (crund_ndb::Operations::*OF)(NdbTable,int,int,bool),
-          bool OB >
-struct Driver::B0ByPKOp : Op {
-    B0ByPKOp() : Op(string(*ON)
-                    + (OB ? "_batch" : "")) {
-    }
-
-    virtual void run(int countA, int countB) const {
-        (ops->*OF)(ops->meta->table_B0, 1, countB, OB);
-    }
-};
-
-template< const char** ON,
-          void (crund_ndb::Operations::*OF)(NdbTable,int,int,bool,int),
-          bool OB >
-struct Driver::LengthOp : Op {
-    const int length;
-
-    LengthOp(int length) : Op(string(*ON)
-                              + toString(length)
-                              + (OB ? "_batch" : "")),
-                           length(length) {
-    }
-
-    virtual void run(int countA, int countB) const {
-        (ops->*OF)(ops->meta->table_B0, 1, countB, OB, length);
-    }
-};
-
-template< const char** ON,
-          void (crund_ndb::Operations::*OF)(NdbTable,int,int,bool,int),
-          bool OB >
-struct Driver::ZeroLengthOp : LengthOp< ON, OF, OB > {
-    ZeroLengthOp(int length) : LengthOp< ON, OF, OB >(length) {
-    }
-
-    virtual void run(int countA, int countB) const {
-        (ops->*OF)(ops->meta->table_B0, 1, countB, OB, 0);
-    }
-};
-
-template< const char** ON,
-          void (crund_ndb::Operations::*OF)(int,int,bool),
-          bool OFS >
-struct Driver::RelOp : Op {
-    RelOp() : Op(string(*ON)
-                 + (OFS ? "_forceSend" : "")) {
-    }
-
-    virtual void run(int countA, int countB) const {
-        (ops->*OF)(countA, countB, OFS);
-    }
-};
-
-// ISO C++ 98 does not allow for a string literal as a template argument
-// for a non-type template parameter, because string literals are objects
-// with internal linkage.  This restriction maybe lifted in C++0x.
-//
-// Until then, we have to allocate the operation names as variables
-// (which are external at file scope by default).
-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";
-const char* navAToB0_s = "navA->B0";
-const char* navAToB0alt_s = "navA->B0_alt";
-const char* nullB0ToA_s = "nullB0->A";
-
-template< bool feat > void
-Driver::initOperationsFeat() {
-
-    const bool setAttr = true;
-    operations.push_back(
-        new AInsOp< !setAttr, feat >());
-
-    operations.push_back(
-        new B0InsOp< !setAttr, feat >());
-
-    operations.push_back(
-        new AByPKOp< &setAByPK_s, &crund_ndb::Operations::setByPK, feat >());
-
-    operations.push_back(
-        new B0ByPKOp< &setB0ByPK_s, &crund_ndb::Operations::setByPK, feat >());
-
-    operations.push_back(
-        new AByPKOp< &getAByPK_bb_s, &crund_ndb::Operations::getByPK_bb, feat >());
-
-    operations.push_back(
-        new AByPKOp< &getAByPK_ar_s, &crund_ndb::Operations::getByPK_ar, feat >());
-
-    operations.push_back(
-        new B0ByPKOp< &getB0ByPK_bb_s, &crund_ndb::Operations::getByPK_bb, feat >());
-
-    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));
-
-        operations.push_back(
-            new LengthOp< &getVarbinary_s, &crund_ndb::Operations::getVarbinary, feat >(length));
-
-        operations.push_back(
-            new ZeroLengthOp< &clearVarbinary_s, &crund_ndb::Operations::setVarbinary, feat >(length));
-    }
-
-    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));
-
-        operations.push_back(
-            new LengthOp< &getVarchar_s, &crund_ndb::Operations::getVarchar, feat >(length));
-
-        operations.push_back(
-            new ZeroLengthOp< &clearVarchar_s, &crund_ndb::Operations::setVarchar, feat >(length));
-    }
-
-    operations.push_back(
-        new RelOp< &setB0ToA_s, &crund_ndb::Operations::setB0ToA, feat >());
-
-    operations.push_back(
-        new RelOp< &navB0ToA_s, &crund_ndb::Operations::navB0ToA, feat >());
-
-    operations.push_back(
-        new RelOp< &navB0ToAalt_s, &crund_ndb::Operations::navB0ToAalt, feat >());
-
-    operations.push_back(
-        new RelOp< &navAToB0_s, &crund_ndb::Operations::navAToB0, feat >());
-
-    operations.push_back(
-        new RelOp< &navAToB0alt_s, &crund_ndb::Operations::navAToB0alt, feat >());
-
-    operations.push_back(
-        new RelOp< &nullB0ToA_s, &crund_ndb::Operations::nullB0ToA, feat >());
-
-    operations.push_back(
-        new B0ByPKOp< &setAByPK_s, &crund_ndb::Operations::delByPK, feat >());
-
-    operations.push_back(
-        new AByPKOp< &setB0ByPK_s, &crund_ndb::Operations::delByPK, feat >());
-
-    operations.push_back(
-        new AInsOp< setAttr, feat >());
-
-    operations.push_back(
-        new B0InsOp< setAttr, feat >());
-
-    operations.push_back(
-        new ADelAllOp< feat >());
-
-    operations.push_back(
-        new B0DelAllOp< feat >());
-}
-
-void
-Driver::closeOperations() {
-    cout << "closing operations ..." << flush;
-    for (Operations::const_iterator i = operations.begin();
-         i != operations.end(); ++i) {
-        delete *i;
-    }
-    operations.clear();
-    cout << "      [ok]" << endl;
-}
-
-void
-Driver::clearData()
-{
-    ops->clearData();
-}
-
-//---------------------------------------------------------------------------
-
-void
-Driver::exitUsage()
-{
-    cout << "usage: [options]" << endl
-         << "    [-p <file name>]...    properties file name" << endl
-         << "    [-l <file name>]       log file name for data output" << endl
-         << "    [-h|--help]            print usage message and exit" << endl
-         << endl;
-    exit(1); // return an error code
-}
-
-void
-Driver::parseArguments(int argc, const char* argv[])
-{
-    for (int i = 1; i < argc; i++) {
-        const string arg = argv[i];
-        if (arg.compare("-p") == 0) {
-            if (i >= argc) {
-                exitUsage();
-            }
-            propFileNames.push_back(argv[++i]);
-        } else if (arg.compare("-l") == 0) {
-            if (i >= argc) {
-                exitUsage();
-            }
-            logFileName = argv[++i];
-        } else if (arg.compare("-h") == 0 || arg.compare("--help") == 0) {
-            exitUsage();
-        } else {
-            cout << "unknown option: " << arg << endl;
-            exitUsage();
-        }
-    }
-
-    if (logFileName.empty()) {
-        logFileName = "log_";
-
-        // format, destination strings (static size)
-        const char format[] = "%Y%m%d_%H%M%S";
-        const int size = sizeof("yyyymmdd_HHMMSS");
-        char dest[size];
-
-        // 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);
-        (void)nchars;
-
-        logFileName += dest;
-        logFileName += ".txt";
-        //cout << "logFileName='" << logFileName << "'" << endl;
-    }
-}
-
-int
-main(int argc, const char* argv[])
-{
-    TRACE("main()");
-
-    Driver d;
-    d.parseArguments(argc, argv);
-    d.run();
-
-    return 0;
-}

=== added file 'storage/ndb/test/crund/src/crundndb/Driver.hpp'
--- a/storage/ndb/test/crund/src/crundndb/Driver.hpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/crund/src/crundndb/Driver.hpp	2010-10-05 08:48:30 +0000
@@ -0,0 +1,106 @@
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
+ *
+ *  Copyright (C) 2009 MySQL
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef Driver_hpp
+#define Driver_hpp
+
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+#include "Properties.hpp"
+#include "hrt_utils.h"
+
+using std::ofstream;
+using std::ostringstream;
+using std::string;
+using std::vector;
+
+using utils::Properties;
+
+class Driver {
+public:
+
+    /**
+     * Parses the benchmark's command-line arguments.
+     */
+    static void parseArguments(int argc, const char* argv[]);
+
+    /**
+     * Creates an instance.
+     */
+    Driver() {}
+
+    /**
+     * Runs the benchmark.
+     */
+    void run();
+
+protected:
+
+    // driver command-line arguments
+    static vector< string > propFileNames;
+    static string logFileName;
+
+    static void exitUsage();
+
+    // driver settings
+    Properties props;
+    bool logRealTime;
+    bool logCpuTime;
+    bool renewConnection;
+    int warmupRuns;
+    int hotRuns;
+
+    // driver resources
+    ofstream log;
+    string descr;
+    bool logHeader;
+    ostringstream header;
+    ostringstream rtimes;
+    ostringstream ctimes;
+    int s0, s1;
+    hrt_tstamp t0, t1;
+    long rta, cta;
+
+    // driver intializers/finalizers
+    virtual void init();
+    virtual void close();
+    virtual void loadProperties();
+    virtual void initProperties();
+    virtual void printProperties();
+    virtual void openLogFile();
+    virtual void closeLogFile();
+
+    // benchmark operations
+    virtual void runTests() = 0;
+    virtual void begin(const string& name);
+    virtual void commit(const string& name);
+
+    // datastore operations
+    virtual void initConnection() = 0;
+    virtual void closeConnection() = 0;
+    //virtual void clearPersistenceContext() = 0; // not used
+    virtual void clearData() = 0;
+};
+
+#endif // Driver_hpp

=== modified file 'storage/ndb/test/crund/src/crundndb/Makefile'
--- a/storage/ndb/test/crund/src/crundndb/Makefile	2010-10-01 08:58:08 +0000
+++ b/storage/ndb/test/crund/src/crundndb/Makefile	2010-10-05 08:48:30 +0000
@@ -10,7 +10,7 @@ include	../../env.properties
 
   DDEFINES 	=
 
-  DELIVERABLES	= libcrundndb.a libcrundndb.$(DLL_SUFFIX) Driver 
+  DELIVERABLES	= libcrundndb.a libcrundndb.$(DLL_SUFFIX) NdbApiDriver 
 
   GENERATED_H	= com_mysql_cluster_crund_NdbApiLoad.h
 
@@ -54,43 +54,43 @@ com_mysql_cluster_crund_NdbApiLoad.h:
 #		$(API_PKG_PATH)/NdbApiLoad.java
 #	$(COMPILE.java) $<
 
-run.driver:	Driver
-	LD_LIBRARY_PATH=${NDB_LIBDIR} ./Driver \
+run.driver:	NdbApiDriver
+	LD_LIBRARY_PATH=${NDB_LIBDIR} ./NdbApiDriver \
 	-p ../../crundRun.properties -p ../../crundNdbapi.properties
 
 # for JVM processes, try running valgrind with
 # --smc-check=all --trace-children=yes --leak-check=full --show-reachable=yes
-valgrind.driver:	Driver
+valgrind.driver:	NdbApiDriver
 	LD_LIBRARY_PATH=${NDB_LIBDIR} valgrind \
 	--leak-check=full --show-reachable=yes --trace-children=yes \
-	./Driver \
+	./NdbApiDriver \
 	-p ../../crundRun.properties -p ../../crundNdbapi.properties
 
-Driver:	libcrundndb.a
+NdbApiDriver:	Driver.o CrundDriver.o libcrundndb.a
 
 # can list multiple archive members: lib.a(a.o b.o ...) lib.a(c.o)...
-libcrundndb.a:	libcrundndb.a(Operations.o)	\
+libcrundndb.a:	libcrundndb.a(CrundNdbApiOperations.o)	\
 		libcrundndb.a(com_mysql_cluster_crund_NdbApiLoad.o)
 
 # XXX cleanup & refactorize this rule!
 # LINK.o
-#libcrundndb.so:	Operations.o com_mysql_cluster_crund_NdbApiLoad.o
+#libcrundndb.so:	CrundNdbApiOperations.o com_mysql_cluster_crund_NdbApiLoad.o
 #libcrundndb.so:	libcrundndb.a
-libcrundndb.so:	Operations.cpp
+libcrundndb.so:	CrundNdbApiOperations.cpp
 	$(LINK.cpp) \
 	-fPIC -shared \
 	-L${NDB_LIBDIR} \
 	-lndbclient \
 	-o libcrundndb.so \
-	Operations.cpp com_mysql_cluster_crund_NdbApiLoad.cpp
+	CrundNdbApiOperations.cpp com_mysql_cluster_crund_NdbApiLoad.cpp
 
-libcrundndb.dylib:	Operations.cpp
+libcrundndb.dylib:	CrundNdbApiOperations.cpp
 	$(LINK.cpp) \
 	-fPIC -shared -dynamiclib \
 	-L${NDB_LIBDIR} \
 	-lndbclient \
 	-o libcrundndb.dylib \
-	Operations.cpp com_mysql_cluster_crund_NdbApiLoad.cpp
+	CrundNdbApiOperations.cpp com_mysql_cluster_crund_NdbApiLoad.cpp
 
 # Solaris cc?
 # -#          <!-- verbose mode -->

=== added file 'storage/ndb/test/crund/src/crundndb/NdbApiDriver.cpp'
--- a/storage/ndb/test/crund/src/crundndb/NdbApiDriver.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/crund/src/crundndb/NdbApiDriver.cpp	2010-10-05 08:48:30 +0000
@@ -0,0 +1,405 @@
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
+ *
+ *  Copyright (C) 2009 MySQL
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <cassert>
+
+#include "helpers.hpp"
+#include "string_helpers.hpp"
+
+#include "NdbApiDriver.hpp"
+#include "CrundNdbApiOperations.hpp"
+
+using std::cout;
+using std::flush;
+using std::endl;
+using std::ios_base;
+using std::ostringstream;
+using std::string;
+using std::wstring;
+
+using utils::toString;
+
+// ----------------------------------------------------------------------
+
+CrundNdbApiOperations* NdbApiDriver::ops = NULL;
+
+// ISO C++ 98 does not allow for a string literal as a template argument
+// for a non-type template parameter, because string literals are objects
+// with internal linkage.  This restriction maybe lifted in C++0x.
+//
+// Until then, we have to allocate the operation names as variables
+// (which are external at file scope by default).
+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";
+const char* navAToB0_s = "navA->B0";
+const char* navAToB0alt_s = "navA->B0_alt";
+const char* nullB0ToA_s = "nullB0->A";
+
+//---------------------------------------------------------------------------
+
+void
+NdbApiDriver::init() {
+    CrundDriver::init();
+
+    // initialize the benchmark's resources
+    ops = new CrundNdbApiOperations();
+    assert (!mgmdConnect.empty());
+    ops->init(mgmdConnect.c_str());
+}
+
+void
+NdbApiDriver::close() {
+    // release the benchmark's resources
+    assert (!mgmdConnect.empty());
+    ops->close();
+    delete ops;
+    ops = NULL;
+
+    CrundDriver::close();
+}
+
+void
+NdbApiDriver::initProperties() {
+    CrundDriver::initProperties();
+
+    cout << "setting ndb properties ..." << flush;
+
+    ostringstream msg;
+
+    mgmdConnect = toString(props[L"ndb.mgmdConnect"]);
+    catalog = toString(props[L"ndb.catalog"]);
+    schema = toString(props[L"ndb.schema"]);
+
+    if (msg.tellp() == 0) {
+        cout << "      [ok]" << endl;
+    } else {
+        cout << endl << msg.str() << endl;
+    }
+
+    descr = "ndbapi(" + mgmdConnect + ")";
+}
+
+void
+NdbApiDriver::printProperties() {
+    CrundDriver::printProperties();
+    
+    const ios_base::fmtflags f = cout.flags();
+    // no effect calling manipulator function, not sure why
+    //cout << ios_base::boolalpha;
+    cout.flags(ios_base::boolalpha);
+
+    cout << endl << "ndb settings ..." << endl;
+    cout << "ndb.mgmdConnect:                \"" << mgmdConnect << "\"" << endl;
+    cout << "ndb.catalog:                    \"" << catalog << "\"" << endl;
+    cout << "ndb.schema:                     \"" << schema << "\"" << endl;
+
+    cout.flags(f);
+}
+
+void
+NdbApiDriver::initConnection() {
+    ops->initConnection(catalog.c_str(), schema.c_str());
+}
+
+void
+NdbApiDriver::closeConnection() {
+    ops->closeConnection();
+}
+
+void
+NdbApiDriver::initOperations() {
+    cout << "initializing operations ..." << flush;
+
+    const bool feat = true;
+    initOperationsFeat< !feat >();
+    initOperationsFeat< feat >();
+
+    cout << "     [Op: " << operations.size() << "]" << endl;
+}
+
+// the operation invocation templates look a bit complex, but they help
+// a lot to factorize code over the operations' parameter signatures
+
+template< bool OB >
+struct NdbApiDriver::ADelAllOp : Op {
+    ADelAllOp() : Op(string("delAllA")
+                     + (OB ? "_batch" : "")) {
+    }
+
+    virtual void run(int countA, int countB) const {
+        int count;
+        ops->delByScan(ops->model->table_A, count, OB);
+        assert (count == countA);
+    }
+};
+
+template< bool OB >
+struct NdbApiDriver::B0DelAllOp : Op {
+    B0DelAllOp() : Op(string("delAllB0")
+                      + (OB ? "_batch" : "")) {
+    }
+
+    virtual void run(int countA, int countB) const {
+        int count;
+        ops->delByScan(ops->model->table_B0, count, OB);
+        assert (count == countB);
+    }
+};
+
+template< bool OSA, bool OB >
+struct NdbApiDriver::AInsOp : Op {
+    AInsOp() : Op(string("insA")
+                  + (OSA ? "_attr" : "")
+                  + (OB ? "_batch" : "")) {
+    }
+
+    virtual void run(int countA, int countB) const {
+        ops->ins(ops->model->table_A, 1, countA, OSA, OB);
+    }
+};
+
+template< bool OSA, bool OB >
+struct NdbApiDriver::B0InsOp : Op {
+    B0InsOp() : Op(string("insB0")
+                   + (OSA ? "_attr" : "")
+                   + (OB ? "_batch" : "")) {
+    }
+
+    virtual void run(int countA, int countB) const {
+        ops->ins(ops->model->table_B0, 1, countB, OSA, OB);
+    }
+};
+
+template< const char** ON,
+          void (CrundNdbApiOperations::*OF)(NdbTable,int,int,bool),
+          bool OB >
+struct NdbApiDriver::AByPKOp : Op {
+    AByPKOp() : Op(string(*ON)
+                   + (OB ? "_batch" : "")) {
+    }
+
+    virtual void run(int countA, int countB) const {
+        (ops->*OF)(ops->model->table_A, 1, countA, OB);
+    }
+};
+
+template< const char** ON,
+          void (CrundNdbApiOperations::*OF)(NdbTable,int,int,bool),
+          bool OB >
+struct NdbApiDriver::B0ByPKOp : Op {
+    B0ByPKOp() : Op(string(*ON)
+                    + (OB ? "_batch" : "")) {
+    }
+
+    virtual void run(int countA, int countB) const {
+        (ops->*OF)(ops->model->table_B0, 1, countB, OB);
+    }
+};
+
+template< const char** ON,
+          void (CrundNdbApiOperations::*OF)(NdbTable,int,int,bool,int),
+          bool OB >
+struct NdbApiDriver::LengthOp : Op {
+    const int length;
+
+    LengthOp(int length) : Op(string(*ON)
+                              + toString(length)
+                              + (OB ? "_batch" : "")),
+                           length(length) {
+    }
+
+    virtual void run(int countA, int countB) const {
+        (ops->*OF)(ops->model->table_B0, 1, countB, OB, length);
+    }
+};
+
+template< const char** ON,
+          void (CrundNdbApiOperations::*OF)(NdbTable,int,int,bool,int),
+          bool OB >
+struct NdbApiDriver::ZeroLengthOp : LengthOp< ON, OF, OB > {
+    ZeroLengthOp(int length) : LengthOp< ON, OF, OB >(length) {
+    }
+
+    virtual void run(int countA, int countB) const {
+        (ops->*OF)(ops->model->table_B0, 1, countB, OB, 0);
+    }
+};
+
+template< const char** ON,
+          void (CrundNdbApiOperations::*OF)(int,int,bool),
+          bool OFS >
+struct NdbApiDriver::RelOp : Op {
+    RelOp() : Op(string(*ON)
+                 + (OFS ? "_forceSend" : "")) {
+    }
+
+    virtual void run(int countA, int countB) const {
+        (ops->*OF)(countA, countB, OFS);
+    }
+};
+
+template< bool feat > void
+NdbApiDriver::initOperationsFeat() {
+
+    const bool setAttr = true;
+    operations.push_back(
+        new AInsOp< !setAttr, feat >());
+
+    operations.push_back(
+        new B0InsOp< !setAttr, feat >());
+
+    operations.push_back(
+        new AByPKOp< &setAByPK_s, &CrundNdbApiOperations::setByPK, feat >());
+
+    operations.push_back(
+        new B0ByPKOp< &setB0ByPK_s, &CrundNdbApiOperations::setByPK, feat >());
+
+    operations.push_back(
+        new AByPKOp< &getAByPK_bb_s, &CrundNdbApiOperations::getByPK_bb, feat >());
+
+    operations.push_back(
+        new AByPKOp< &getAByPK_ar_s, &CrundNdbApiOperations::getByPK_ar, feat >());
+
+    operations.push_back(
+        new B0ByPKOp< &getB0ByPK_bb_s, &CrundNdbApiOperations::getByPK_bb, feat >());
+
+    operations.push_back(
+        new B0ByPKOp< &getB0ByPK_ar_s, &CrundNdbApiOperations::getByPK_ar, feat >());
+
+    for (int i = 1; i <= maxVarbinaryBytes; i *= 10) {
+        const int length = i;
+
+        operations.push_back(
+            new LengthOp< &setVarbinary_s, &CrundNdbApiOperations::setVarbinary, feat >(length));
+
+        operations.push_back(
+            new LengthOp< &getVarbinary_s, &CrundNdbApiOperations::getVarbinary, feat >(length));
+
+        operations.push_back(
+            new ZeroLengthOp< &clearVarbinary_s, &CrundNdbApiOperations::setVarbinary, feat >(length));
+    }
+
+    for (int i = 1; i <= maxVarcharChars; i *= 10) {
+        const int length = i;
+
+        operations.push_back(
+            new LengthOp< &setVarchar_s, &CrundNdbApiOperations::setVarchar, feat >(length));
+
+        operations.push_back(
+            new LengthOp< &getVarchar_s, &CrundNdbApiOperations::getVarchar, feat >(length));
+
+        operations.push_back(
+            new ZeroLengthOp< &clearVarchar_s, &CrundNdbApiOperations::setVarchar, feat >(length));
+    }
+
+    operations.push_back(
+        new RelOp< &setB0ToA_s, &CrundNdbApiOperations::setB0ToA, feat >());
+
+    operations.push_back(
+        new RelOp< &navB0ToA_s, &CrundNdbApiOperations::navB0ToA, feat >());
+
+    operations.push_back(
+        new RelOp< &navB0ToAalt_s, &CrundNdbApiOperations::navB0ToAalt, feat >());
+
+    operations.push_back(
+        new RelOp< &navAToB0_s, &CrundNdbApiOperations::navAToB0, feat >());
+
+    operations.push_back(
+        new RelOp< &navAToB0alt_s, &CrundNdbApiOperations::navAToB0alt, feat >());
+
+    operations.push_back(
+        new RelOp< &nullB0ToA_s, &CrundNdbApiOperations::nullB0ToA, feat >());
+
+    operations.push_back(
+        new B0ByPKOp< &setAByPK_s, &CrundNdbApiOperations::delByPK, feat >());
+
+    operations.push_back(
+        new AByPKOp< &setB0ByPK_s, &CrundNdbApiOperations::delByPK, feat >());
+
+    operations.push_back(
+        new AInsOp< setAttr, feat >());
+
+    operations.push_back(
+        new B0InsOp< setAttr, feat >());
+
+    operations.push_back(
+        new ADelAllOp< feat >());
+
+    operations.push_back(
+        new B0DelAllOp< feat >());
+}
+
+void
+NdbApiDriver::closeOperations() {
+    cout << "closing operations ..." << flush;
+    for (Operations::const_iterator i = operations.begin();
+         i != operations.end(); ++i) {
+        delete *i;
+    }
+    operations.clear();
+    cout << "          [ok]" << endl;
+}
+
+void
+NdbApiDriver::clearPersistenceContext() {
+    // XXX not implemented yet
+}
+
+void
+NdbApiDriver::clearData()
+{
+    ops->clearData();
+}
+
+//---------------------------------------------------------------------------
+
+int
+main(int argc, const char* argv[])
+{
+    TRACE("main()");
+
+    NdbApiDriver::parseArguments(argc, argv);
+    NdbApiDriver d;
+    d.run();
+
+    return 0;
+}
+
+//---------------------------------------------------------------------------

=== added file 'storage/ndb/test/crund/src/crundndb/NdbApiDriver.hpp'
--- a/storage/ndb/test/crund/src/crundndb/NdbApiDriver.hpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/crund/src/crundndb/NdbApiDriver.hpp	2010-10-05 08:48:30 +0000
@@ -0,0 +1,85 @@
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
+ *
+ *  Copyright (C) 2009 MySQL
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef NdbApiDriver_hpp
+#define NdbApiDriver_hpp
+
+#include <string>
+
+#include "CrundDriver.hpp"
+#include "CrundNdbApiOperations.hpp"
+
+using std::string;
+
+// global type aliases
+typedef const NdbDictionary::Table* NdbTable;
+
+class NdbApiDriver : public CrundDriver {
+protected:
+
+    // NDB API resources
+    string mgmdConnect;
+    string catalog;
+    string schema;
+
+    // the benchmark's basic database operations
+    static CrundNdbApiOperations* ops;
+
+    // NDB API intializers/finalizers
+    virtual void initProperties();
+    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();
+    template< bool > struct ADelAllOp;
+    template< bool > struct B0DelAllOp;
+    template< bool, bool > struct AInsOp;
+    template< bool, bool > struct B0InsOp;
+    template< const char**,
+              void (CrundNdbApiOperations::*)(NdbTable,int,int,bool),
+              bool >
+    struct AByPKOp;
+    template< const char**,
+              void (CrundNdbApiOperations::*)(NdbTable,int,int,bool),
+              bool >
+    struct B0ByPKOp;
+    template< const char**,
+              void (CrundNdbApiOperations::*)(NdbTable,int,int,bool,int),
+              bool >
+    struct LengthOp;
+    template< const char**,
+              void (CrundNdbApiOperations::*)(NdbTable,int,int,bool,int),
+              bool >
+    struct ZeroLengthOp;
+    template< const char**,
+              void (CrundNdbApiOperations::*)(int,int,bool),
+              bool >
+    struct RelOp;
+};
+
+#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-01 08:58:08 +0000
+++ b/storage/ndb/test/crund/src/crundndb/com_mysql_cluster_crund_NdbApiLoad.cpp	2010-10-05 08:48:30 +0000
@@ -1,27 +1,38 @@
-/*
- * com_mysql_cluster_crund_NdbApiLoad.cpp
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
  *
+ *  Copyright (C) 2009 MySQL
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <jni.h>
 #include <cassert>
 
-#include "com_mysql_cluster_crund_NdbApiLoad.h"
 #include "helpers.hpp"
-#include "Operations.hpp"
 
-//using namespace crund_ndb;
-using crund_ndb::Meta;
-using crund_ndb::Operations;
-
-/************************************************************
- * Native JNI Functions
- ************************************************************/
+#include "com_mysql_cluster_crund_NdbApiLoad.h"
+
+#include "CrundNdbApiOperations.hpp"
 
-/**
- * Provides the benchmark's basic database operations.
- */
-static Operations* ops = NULL;
+// ----------------------------------------------------------------------
+
+// provides the benchmark's basic database operations
+static CrundNdbApiOperations* ops = NULL;
+
+// ----------------------------------------------------------------------
 
 JNIEXPORT jint JNICALL
 Java_com_mysql_cluster_crund_NdbApiLoad_ndbinit(JNIEnv* env,
@@ -36,7 +47,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
     const char* mgmd_cstr = env->GetStringUTFChars(mgmd_jstr, NULL);
 
     // initialize the benchmark's resources
-    ops = new Operations();
+    ops = new CrundNdbApiOperations();
     ops->init(mgmd_cstr);
 
     // release the native and Java strings
@@ -128,7 +139,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
 {
     TRACE("delAllA()");
     int count;
-    ops->delByScan(ops->meta->table_A, count, batch == JNI_TRUE);
+    ops->delByScan(ops->model->table_A, count, batch == JNI_TRUE);
     assert (count == count_A);
 }
 
@@ -141,7 +152,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
 {
     TRACE("delAllB0()");
     int count;
-    ops->delByScan(ops->meta->table_B0, count, batch == JNI_TRUE);
+    ops->delByScan(ops->model->table_B0, count, batch == JNI_TRUE);
     assert (count == count_B);
 }
 
@@ -154,7 +165,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                              jboolean batch)
 {
     TRACE("insA()");
-    ops->ins(ops->meta->table_A, 1, count_A,
+    ops->ins(ops->model->table_A, 1, count_A,
              setAttrs == JNI_TRUE, batch == JNI_TRUE);
 }
 
@@ -167,7 +178,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                               jboolean batch)
 {
     TRACE("insB0()");
-    ops->ins(ops->meta->table_B0, 1, count_B,
+    ops->ins(ops->model->table_B0, 1, count_B,
              setAttrs == JNI_TRUE, batch == JNI_TRUE);
 }
 
@@ -179,7 +190,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                                  jboolean batch)
 {
     TRACE("delAByPK()");
-    ops->delByPK(ops->meta->table_A, 1, count_A, batch == JNI_TRUE);
+    ops->delByPK(ops->model->table_A, 1, count_A, batch == JNI_TRUE);
 }
 
 JNIEXPORT void JNICALL
@@ -190,7 +201,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                                   jboolean batch)
 {
     TRACE("delB0ByPK()");
-    ops->delByPK(ops->meta->table_B0, 1, count_B, batch == JNI_TRUE);
+    ops->delByPK(ops->model->table_B0, 1, count_B, batch == JNI_TRUE);
 }
 
 JNIEXPORT void JNICALL
@@ -201,7 +212,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                                  jboolean batch)
 {
     TRACE("setAByPK()");
-    ops->setByPK(ops->meta->table_A, 1, count_A, batch == JNI_TRUE);
+    ops->setByPK(ops->model->table_A, 1, count_A, batch == JNI_TRUE);
 }
 
 JNIEXPORT void JNICALL
@@ -212,7 +223,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                                   jboolean batch)
 {
     TRACE("setB0ByPK()");
-    ops->setByPK(ops->meta->table_B0, 1, count_B, batch == JNI_TRUE);
+    ops->setByPK(ops->model->table_B0, 1, count_B, batch == JNI_TRUE);
 }
 
 JNIEXPORT void JNICALL
@@ -223,7 +234,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                                      jboolean batch)
 {
     TRACE("getAByPK_bb()");
-    ops->getByPK_bb(ops->meta->table_A, 1, count_A, batch == JNI_TRUE);
+    ops->getByPK_bb(ops->model->table_A, 1, count_A, batch == JNI_TRUE);
 }
 
 JNIEXPORT void JNICALL
@@ -234,7 +245,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                                       jboolean batch)
 {
     TRACE("getB0ByPK_bb()");
-    ops->getByPK_bb(ops->meta->table_B0, 1, count_B, batch == JNI_TRUE);
+    ops->getByPK_bb(ops->model->table_B0, 1, count_B, batch == JNI_TRUE);
 }
 
 JNIEXPORT void JNICALL
@@ -245,7 +256,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                                      jboolean batch)
 {
     TRACE("getAByPK_ar()");
-    ops->getByPK_ar(ops->meta->table_A, 1, count_A, batch == JNI_TRUE);
+    ops->getByPK_ar(ops->model->table_A, 1, count_A, batch == JNI_TRUE);
 }
 
 JNIEXPORT void JNICALL
@@ -256,7 +267,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                                       jboolean batch)
 {
     TRACE("getB0ByPK_ar()");
-    ops->getByPK_ar(ops->meta->table_B0, 1, count_B, batch == JNI_TRUE);
+    ops->getByPK_ar(ops->model->table_B0, 1, count_B, batch == JNI_TRUE);
 }
 
 JNIEXPORT void JNICALL
@@ -268,7 +279,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                                      jint length)
 {
     TRACE("setVarbinary()");
-    ops->setVarbinary(ops->meta->table_B0,
+    ops->setVarbinary(ops->model->table_B0,
                       1, count_B, batch == JNI_TRUE, length);
 }
 
@@ -281,7 +292,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                                      jint length)
 {
     TRACE("getVarbinary()");
-    ops->getVarbinary(ops->meta->table_B0,
+    ops->getVarbinary(ops->model->table_B0,
                       1, count_B, batch == JNI_TRUE, length);
 }
 
@@ -294,7 +305,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                                    jint length)
 {
     TRACE("setVarchar()");
-    ops->setVarchar(ops->meta->table_B0,
+    ops->setVarchar(ops->model->table_B0,
                     1, count_B, batch == JNI_TRUE, length);
 }
 
@@ -307,7 +318,7 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
                                                    jint length)
 {
     TRACE("getVarchar()");
-    ops->getVarchar(ops->meta->table_B0,
+    ops->getVarchar(ops->model->table_B0,
                     1, count_B, batch == JNI_TRUE, length);
 }
 
@@ -376,3 +387,5 @@ Java_com_mysql_cluster_crund_NdbApiLoad_
     TRACE("nullB0ToA()");
     ops->nullB0ToA(count_A, count_B, batch == JNI_TRUE);
 }
+
+// ----------------------------------------------------------------------

=== modified file 'storage/ndb/test/crund/tws_benchmark/src/Main.java'
--- a/storage/ndb/test/crund/tws_benchmark/src/Main.java	2010-10-03 04:52:07 +0000
+++ b/storage/ndb/test/crund/tws_benchmark/src/Main.java	2010-10-05 08:48:30 +0000
@@ -72,22 +72,25 @@ public class Main
     static protected final PrintWriter out = new PrintWriter(System.out, true);
     static protected final PrintWriter err = new PrintWriter(System.err, true);
 
+    // command-line arguments
+    static protected String propsFileName;
+    static protected String logFileName;
+
     // benchmark settings
-    static protected final String propsFileName  = "run.properties";
-    static protected final Properties props = new Properties();
-    static protected boolean doJdbc;
-    static protected boolean doClusterj;
-    static protected boolean doNdbjtie;
-    static protected boolean doInsert;
-    static protected boolean doLookup;
-    static protected boolean doUpdate;
-    static protected boolean doDelete;
-    static protected boolean doSingle;
-    static protected boolean doBulk;
-    static protected boolean doBatch;
-    static protected LockMode lockMode;
-    static protected int nRows;
-    static protected int nRuns;
+    protected final Properties props = new Properties();
+    protected boolean doJdbc;
+    protected boolean doClusterj;
+    protected boolean doNdbjtie;
+    protected boolean doInsert;
+    protected boolean doLookup;
+    protected boolean doUpdate;
+    protected boolean doDelete;
+    protected boolean doSingle;
+    protected boolean doBulk;
+    protected boolean doBatch;
+    protected LockMode lockMode;
+    protected int nRows;
+    protected int nRuns;
 
     // JDBC resources
     protected Connection connection;
@@ -178,18 +181,88 @@ public class Main
     }
 
     static public void main(String[] args) throws SQLException, IOException {
-        parseProperties();
-
+        parseArguments(args);
         Main main = new Main();
-        main.init();
         main.run();
-        main.close();
+    }
+
+    static private void exitUsage() {
+        out.println("usage: [options]");
+        out.println("    [-p <file name>]...    a properties file name");
+        out.println("    [-l <file name>]       log file name for data output");
+        out.println("    [-h|--help]            print usage message and exit");
+        out.println();
+        System.exit(1); // return an error code
+    }
+
+    static public void parseArguments(String[] args) {
+        for (int i = 0; i < args.length; i++) {
+            final String arg = args[i];
+            if (arg.equals("-p")) {
+                if (i >= args.length) {
+                    exitUsage();
+                }
+                propFileNames.add(args[++i]);
+            } else if (arg.equals("-l")) {
+                if (i >= args.length) {
+                    exitUsage();
+                }
+                logFileName = args[++i];
+            } else if (arg.equals("-h") || arg.equals("--help")) {
+                exitUsage();
+            } else {
+                out.println("unknown option: " + arg);
+                exitUsage();
+            }
+        }
+    }
+    
+    public void run() throws IOException, SQLException {
+        init();
+        runTests();
+        close();
     }
 
     // ----------------------------------------------------------------------
 
-    static public void parseProperties() throws IOException {
-        out.println("reading properties file " + propsFileName + " ...");
+    protected void init() throws IOException, SQLException {
+        loadProperties();
+        // XXX openLogFile();
+
+        // XXX init log buffers
+        //logHeader = true;
+        //header = new StringBuilder();
+        //rtimes = new StringBuilder();
+        //musage = new StringBuilder();
+
+        if (doJdbc)
+            initJdbcConnection();
+        if (doClusterj)
+            initClusterjConnection();
+        if (doNdbjtie)
+            initNdbjtieConnection();
+    }
+
+    protected void close() throws IOException, SQLException {
+        if (doJdbc)
+            closeJdbcConnection();
+        if (doClusterj)
+            closeClusterjConnection();
+        if (doNdbjtie)
+            closeNdbjtieConnection();
+
+        // XXX close log buffers
+        //header = null;
+        //rtimes = null;
+        //musage = null;
+
+        // XXX closeLogFile();
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected void loadProperties() throws IOException {
+        out.println("reading properties file:        " + propsFileName);
         InputStream is = null;
         try {
             is = new FileInputStream(propsFileName);
@@ -198,6 +271,11 @@ public class Main
             if (is != null)
                 is.close();
         }
+        //props.list(out);
+
+        out.print("initializing properties ...");
+        final StringBuilder msg = new StringBuilder();        
+        final String eol = System.getProperty("line.separator");
 
         doJdbc = parseBoolean("doJdbc", false);
         doClusterj = parseBoolean("doClusterj", false);
@@ -213,27 +291,36 @@ public class Main
         nRows = parseInt("nRows", 50000);
         nRuns = parseInt("nRuns", 5);
 
-        out.println("doJdbc     : " + doJdbc);
-        out.println("doClusterj : " + doClusterj);
-        out.println("doNdbjtie  : " + doNdbjtie);
-        out.println("doInsert   : " + doInsert);
-        out.println("doLookup   : " + doLookup);
-        out.println("doUpdate   : " + doUpdate);
-        out.println("doDelete   : " + doDelete);
-        out.println("doSingle   : " + doSingle);
-        out.println("doBulk     : " + doBulk);
-        out.println("doBatch    : " + doBatch);
-        out.println("lockMode   : " + lockMode);
-        out.println("nRows      : " + nRows);
-        out.println("nRuns      : " + nRuns);
+        if (msg.length() == 0) {
+            out.println("     [ok]");
+        } else {
+            out.println();
+            out.print(msg.toString());
+        }
+
+        out.println();
+        out.println("main settings ...");
+        out.println("doJdbc:                         " + doJdbc);
+        out.println("doClusterj:                     " + doClusterj);
+        out.println("doNdbjtie:                      " + doNdbjtie);
+        out.println("doInsert:                       " + doInsert);
+        out.println("doLookup:                       " + doLookup);
+        out.println("doUpdate:                       " + doUpdate);
+        out.println("doDelete:                       " + doDelete);
+        out.println("doSingle:                       " + doSingle);
+        out.println("doBulk:                         " + doBulk);
+        out.println("doBatch:                        " + doBatch);
+        out.println("lockMode:                       " + lockMode);
+        out.println("nRows:                          " + nRows);
+        out.println("nRuns:                          " + nRuns);
     }
 
-    static protected boolean parseBoolean(String k, boolean vdefault) {
+    protected boolean parseBoolean(String k, boolean vdefault) {
         final String v = props.getProperty(k);
         return (v == null ? vdefault : Boolean.parseBoolean(v));
     }
 
-    static protected int parseInt(String k, int vdefault) {
+    protected int parseInt(String k, int vdefault) {
         final String v = props.getProperty(k);
         try {
             return (v == null ? vdefault : Integer.parseInt(v));
@@ -246,7 +333,7 @@ public class Main
         }
     }
 
-    static protected LockMode parseLockMode(String k, LockMode vdefault) {
+    protected LockMode parseLockMode(String k, LockMode vdefault) {
         final String v = props.getProperty(k);
         try {
             return (v == null ? vdefault : LockMode.valueOf(v));
@@ -261,26 +348,6 @@ public class Main
 
     // ----------------------------------------------------------------------
 
-    public void init() throws SQLException {
-        if (doJdbc)
-            initJdbcConnection();
-        if (doClusterj)
-            initClusterjConnection();
-        if (doNdbjtie)
-            initNdbjtieConnection();
-    }
-
-    public void close() throws SQLException {
-        if (doJdbc)
-            closeJdbcConnection();
-        if (doClusterj)
-            closeClusterjConnection();
-        if (doNdbjtie)
-            closeNdbjtieConnection();
-    }
-
-    // ----------------------------------------------------------------------
-
     protected void initJdbcConnection() throws SQLException {
         assert (connection == null);
 
@@ -301,7 +368,7 @@ public class Main
                         + System.getProperty("java.class.path") + "'");
             throw new RuntimeException(e);
         }
-        out.println("          [ok: " + cls.getName() + "]");
+        out.println("         [ok: " + cls.getName() + "]");
 
         // create a connection to the database
         out.print("starting jdbc connection ...");
@@ -319,14 +386,14 @@ public class Main
             out.println("Cannot connect to database '" + url + "'");
             throw new RuntimeException(e);
         }
-        out.println("     [ok: " + url + "]");
+        out.println("    [ok: " + url + "]");
 
         out.print("setting isolation level ...");
         out.flush();
         // ndb storage engine only supports READ_COMMITTED
         final int il = Connection.TRANSACTION_READ_COMMITTED;
         connection.setTransactionIsolation(il);
-        out.print("      [ok: ");
+        out.print("     [ok: ");
         switch (connection.getTransactionIsolation()) {
         case Connection.TRANSACTION_READ_UNCOMMITTED:
             out.print("READ_UNCOMMITTED");
@@ -360,7 +427,7 @@ public class Main
         out.flush();
         connection.close();
         connection = null;
-        out.println("      [ok]");
+        out.println("     [ok]");
     }
 
     protected void initJdbcPreparedStatements() throws SQLException {
@@ -370,7 +437,8 @@ public class Main
         assert (upd0 == null);
         assert (del0 == null);
 
-        out.print("using lock mode for reads ...    [ok: ");
+        out.print("using lock mode for reads ...");
+        out.flush;
         final String lm;
         switch (lockMode) {
         case READ_COMMITTED:
@@ -386,7 +454,7 @@ public class Main
             lm = "";
             assert false;
         }
-        out.println("SELECT" + lm + ";]");
+        out.println("   [ok: " + "SELECT" + lm + ";]");
 
         out.print("compiling jdbc statements ...");
         out.flush();
@@ -403,7 +471,7 @@ public class Main
         final String sqlDel0 = "DELETE FROM mytable WHERE c0=?";
         del0 = connection.prepareStatement(sqlDel0);
 
-        out.println("    [ok]");
+        out.println("   [ok]");
     }
 
     protected void closeJdbcPreparedStatements() throws SQLException {
@@ -427,7 +495,7 @@ public class Main
         del0.close();
         del0 = null;
 
-        out.println("      [ok]");
+        out.println("     [ok]");
     }
 
     // ----------------------------------------------------------------------
@@ -443,11 +511,11 @@ public class Main
         out.flush();
         sessionFactory = ClusterJHelper.getSessionFactory(props);
         session = sessionFactory.getSession();
-        out.println("    [ok]");
+        out.println("   [ok]");
 
         out.print("setting session lock mode ...");
         session.setLockMode(lockMode);
-        out.println("    [ok: " + lockMode + "]");
+        out.println("   [ok: " + lockMode + "]");
     }
 
     protected void closeClusterjConnection() {
@@ -463,7 +531,7 @@ public class Main
         session = null;
         sessionFactory.close();
         sessionFactory = null;
-        out.println("     [ok]");
+        out.println("    [ok]");
     }
 
     // ----------------------------------------------------------------------
@@ -496,7 +564,7 @@ public class Main
         out.flush();
         mgmd = Ndb_cluster_connection.create(mgmdConnect);
         assert mgmd != null;
-        out.println("  [ok]");
+        out.println(" [ok]");
 
         // connect to cluster management node (ndb_mgmd)
         out.print("connecting to cluster ...");
@@ -512,7 +580,7 @@ public class Main
             out.println(msg);
             throw new RuntimeException("!!! " + msg);
         }
-        out.println("        [ok: " + mgmdConnect + "]");
+        out.println("       [ok: " + mgmdConnect + "]");
 
         // connect to data nodes (ndbds)
         out.print("waiting for data nodes ...");
@@ -526,7 +594,7 @@ public class Main
             out.println(msg);
             throw new RuntimeException(msg);
         }
-        out.println("       [ok]");
+        out.println("      [ok]");
 
         // connect to database
         out.print("connecting to database ...");
@@ -537,31 +605,34 @@ public class Main
             String msg = "Error caught: " + ndb.getNdbError().message();
             throw new RuntimeException(msg);
         }
-        out.println("       [ok: " + catalog + "." + schema + "]");
+        out.println("      [ok: " + catalog + "." + schema + "]");
 
         initNdbjtieMeta();
 
         initNdbjtieBuffers();
 
-        out.print("using lock mode for reads ...    [ok: ");
+        out.print("using lock mode for reads ...");
+        out.flush;
+        final String lm;
         switch (lockMode) {
         case READ_COMMITTED:
             ndbOpLockMode = NdbOperation.LockMode.LM_CommittedRead;
-            out.print("LM_CommittedRead");
+            lm = "LM_CommittedRead";
             break;
         case SHARED:
             ndbOpLockMode = NdbOperation.LockMode.LM_Read;
-            out.print("LM_Read");
+            lm = "LM_Read";
             break;
         case EXCLUSIVE:
             ndbOpLockMode = NdbOperation.LockMode.LM_Exclusive;
-            out.print("LM_Exclusive");
+            lm = "LM_Exclusive";
             break;
         default:
             ndbOpLockMode = NdbOperation.LockMode.LM_CommittedRead;
+            lm = "LM_CommittedRead";
             assert false;
         }
-        out.println("]");
+        out.println("   [ok: " + lm + "]");
     }
 
     protected void closeNdbjtieConnection() {
@@ -579,14 +650,14 @@ public class Main
         out.flush();
         Ndb.delete(ndb);
         ndb = null;
-        out.println("  [ok]");
+        out.println(" [ok]");
 
         out.print("closing cluster connection ...");
         out.flush();
         if (mgmd != null)
             Ndb_cluster_connection.delete(mgmd);
         mgmd = null;
-        out.println("   [ok]");
+        out.println("  [ok]");
     }
 
     protected void initNdbjtieMeta() {
@@ -665,7 +736,7 @@ public class Main
         width_c13 = ndbjtieColumnWidth(column_c13);
         width_c14 = ndbjtieColumnWidth(column_c14);
 
-        out.println("             [ok]");
+        out.println("            [ok]");
     }
 
     protected void closeNdbjtieMeta() {
@@ -710,7 +781,7 @@ public class Main
 
         table_t0 = null;
 
-        out.println("       [ok]");
+        out.println("      [ok]");
     }
 
     protected void initNdbjtieBuffers() {
@@ -743,7 +814,7 @@ public class Main
         // initial order of a byte buffer is always BIG_ENDIAN
         bb_r.order(bo);
 
-        out.println("            [ok]");
+        out.println("           [ok]");
     }
 
     protected void closeNdbjtieBuffers() {
@@ -755,7 +826,7 @@ public class Main
 
         bb_r = null;
 
-        out.println("             [ok]");
+        out.println("            [ok]");
     }
 
     static protected void loadSystemLibrary(String name) {
@@ -778,7 +849,7 @@ public class Main
                         + name + "'; caught exception: " + e);
             throw e;
         }
-        out.println("        [ok: " + name + "]");
+        out.println("       [ok: " + name + "]");
     }
 
     static protected String toStr(NdbErrorConst e) {
@@ -796,82 +867,104 @@ public class Main
 
     enum XMode { SINGLE, BULK, BATCH }
 
-    public void run() throws SQLException {
+    protected void runTests() throws SQLException {
         for (int i = 0; i < nRuns; i++) {
-            if (doJdbc) {
-                out.println();
-                out.println("handle " + nRows + " rows by JDBC ...");
-                if (doSingle) {
-                    out.println();
-                    if (doInsert) runJdbcInsert(XMode.SINGLE);
-                    if (doLookup) runJdbcLookup(XMode.SINGLE);
-                    if (doUpdate) runJdbcUpdate(XMode.SINGLE);
-                    if (doDelete) runJdbcDelete(XMode.SINGLE);
-                }
-                if (doBulk) {
-                    out.println();
-                    if (doInsert) runJdbcInsert(XMode.BULK);
-                    if (doLookup) runJdbcLookup(XMode.BULK);
-                    if (doUpdate) runJdbcUpdate(XMode.BULK);
-                    if (doDelete) runJdbcDelete(XMode.BULK);
-                }
-                if (doBatch) {
-                    out.println();
-                    if (doInsert) runJdbcInsert(XMode.BATCH);
-                    if (doLookup) runJdbcLookup(XMode.BATCH);
-                    if (doUpdate) runJdbcUpdate(XMode.BATCH);
-                    if (doDelete) runJdbcDelete(XMode.BATCH);
-                }
-            }
-            if (doClusterj) {
-                out.println();
-                out.println("handle " + nRows + " rows by ClusterJ ...");
-                if (doSingle) {
-                    out.println();
-                    if (doInsert) runClusterjInsert(XMode.SINGLE);
-                    if (doLookup) runClusterjLookup(XMode.SINGLE);
-                    if (doUpdate) runClusterjUpdate(XMode.SINGLE);
-                    if (doDelete) runClusterjDelete(XMode.SINGLE);
-                }
-                if (doBulk) {
-                    out.println();
-                    if (doInsert) runClusterjInsert(XMode.BULK);
-                    if (doLookup) runClusterjLookup(XMode.BULK);
-                    if (doUpdate) runClusterjUpdate(XMode.BULK);
-                    if (doDelete) runClusterjDelete(XMode.BULK);
-                }
-            }
-            if (doNdbjtie) {
-                out.println();
-                out.println("handle " + nRows + " rows by NDB JTie ...");
-                if (doSingle) {
-                    out.println();
-                    if (doInsert) runNdbjtieInsert(XMode.SINGLE);
-                    if (doLookup) runNdbjtieLookup(XMode.SINGLE);
-                    if (doUpdate) runNdbjtieUpdate(XMode.SINGLE);
-                    if (doDelete) runNdbjtieDelete(XMode.SINGLE);
-                }
-                if (doBulk) {
-                    out.println();
-                    if (doInsert) runNdbjtieInsert(XMode.BULK);
-                    if (doLookup) runNdbjtieLookup(XMode.BULK);
-                    if (doUpdate) runNdbjtieUpdate(XMode.BULK);
-                    if (doDelete) runNdbjtieDelete(XMode.BULK);
-                }
-                if (doBatch) {
-                    out.println();
-                    if (doInsert) runNdbjtieInsert(XMode.BATCH);
-                    if (doLookup) runNdbjtieLookup(XMode.BATCH);
-                    if (doUpdate) runNdbjtieUpdate(XMode.BATCH);
-                    if (doDelete) runNdbjtieDelete(XMode.BATCH);
-                }
-            }
+            out.println();
+            out.println("------------------------------------------------------------");
+
+            // XXX log buffers
+
+            if (doJdbc) runJdbcOperations();
+            if (doClusterj) runClusterjOperations();
+            if (doNdbjtie) runNdbjtieOperations();
+
+            // XXX log buffers
+        }
+
+        out.println();
+        out.println("------------------------------------------------------------");
+    }
+
+    protected void runJdbcOperations() throws SQLException {
+        out.println();
+        out.println("running JDBC operations ..."
+                    + "     [nRows=" + nRows + "]");
+
+        if (doSingle) {
+            out.println();
+            if (doInsert) runJdbcInsert(XMode.SINGLE);
+            if (doLookup) runJdbcLookup(XMode.SINGLE);
+            if (doUpdate) runJdbcUpdate(XMode.SINGLE);
+            if (doDelete) runJdbcDelete(XMode.SINGLE);
+        }
+        if (doBulk) {
+            out.println();
+            if (doInsert) runJdbcInsert(XMode.BULK);
+            if (doLookup) runJdbcLookup(XMode.BULK);
+            if (doUpdate) runJdbcUpdate(XMode.BULK);
+            if (doDelete) runJdbcDelete(XMode.BULK);
+        }
+        if (doBatch) {
+            out.println();
+            if (doInsert) runJdbcInsert(XMode.BATCH);
+            if (doLookup) runJdbcLookup(XMode.BATCH);
+            if (doUpdate) runJdbcUpdate(XMode.BATCH);
+            if (doDelete) runJdbcDelete(XMode.BATCH);
+        }
+    }
+
+    protected void runClusterjOperations() {
+        out.println();
+        out.println("running ClusterJ operations ..."
+                    + " [nRows=" + nRows + "]");
+
+        if (doSingle) {
+            out.println();
+            if (doInsert) runClusterjInsert(XMode.SINGLE);
+            if (doLookup) runClusterjLookup(XMode.SINGLE);
+            if (doUpdate) runClusterjUpdate(XMode.SINGLE);
+            if (doDelete) runClusterjDelete(XMode.SINGLE);
+        }
+        if (doBulk) {
+            out.println();
+            if (doInsert) runClusterjInsert(XMode.BULK);
+            if (doLookup) runClusterjLookup(XMode.BULK);
+            if (doUpdate) runClusterjUpdate(XMode.BULK);
+            if (doDelete) runClusterjDelete(XMode.BULK);
+        }
+    }
+
+    protected void runNdbjtieOperations() {
+        out.println();
+        out.println("running NDB JTie operations ..."
+                    + " [nRows=" + nRows + "]");
+
+        if (doSingle) {
+            out.println();
+            if (doInsert) runNdbjtieInsert(XMode.SINGLE);
+            if (doLookup) runNdbjtieLookup(XMode.SINGLE);
+            if (doUpdate) runNdbjtieUpdate(XMode.SINGLE);
+            if (doDelete) runNdbjtieDelete(XMode.SINGLE);
+        }
+        if (doBulk) {
+            out.println();
+            if (doInsert) runNdbjtieInsert(XMode.BULK);
+            if (doLookup) runNdbjtieLookup(XMode.BULK);
+            if (doUpdate) runNdbjtieUpdate(XMode.BULK);
+            if (doDelete) runNdbjtieDelete(XMode.BULK);
+        }
+        if (doBatch) {
+            out.println();
+            if (doInsert) runNdbjtieInsert(XMode.BATCH);
+            if (doLookup) runNdbjtieLookup(XMode.BATCH);
+            if (doUpdate) runNdbjtieUpdate(XMode.BATCH);
+            if (doDelete) runNdbjtieDelete(XMode.BATCH);
         }
     }
 
     // ----------------------------------------------------------------------
 
-    public void runJdbcInsert(XMode mode) throws SQLException {
+    protected void runJdbcInsert(XMode mode) throws SQLException {
         final String m = mode.toString().toLowerCase();
         //out.println("insert " + nRows + " rows by JDBC " + m + " tx ...");
 
@@ -886,10 +979,10 @@ public class Main
             connection.commit();
         time += System.currentTimeMillis();
 
-        out.println("jdbc_insert_" + m + "    \t: " + time + " ms");
+        out.println("jdbc_insert_" + m + "    \t: " + time + "\tms");
     }
 
-    public void runClusterjInsert(XMode mode) {
+    protected void runClusterjInsert(XMode mode) {
         final String m = mode.toString().toLowerCase();
         //out.println("insert " + nRows + " rows by ClusterJ " + m + " tx ...");
 
@@ -903,10 +996,10 @@ public class Main
             session.currentTransaction().commit();
         time += System.currentTimeMillis();
 
-        out.println("clusterj_insert_" + m + "  \t: " + time + " ms");
+        out.println("clusterj_insert_" + m + "  \t: " + time + "\tms");
     }
 
-    public void runNdbjtieInsert(XMode mode) {
+    protected void runNdbjtieInsert(XMode mode) {
         final String m = mode.toString().toLowerCase();
         //out.println("insert " + nRows + " rows by NDB JTie " + m + " tx ...");
 
@@ -931,10 +1024,10 @@ public class Main
         }
         time += System.currentTimeMillis();
 
-        out.println("ndbjtie_insert_" + m + "  \t: " + time + " ms");
+        out.println("ndbjtie_insert_" + m + "  \t: " + time + "\tms");
     }
 
-    public void jdbcInsert(int c0, XMode mode) {
+    protected void jdbcInsert(int c0, XMode mode) {
         // include exception handling as part of jdbc pattern
         try {
             final int i = c0;
@@ -958,7 +1051,7 @@ public class Main
         }
     }
 
-    public void clusterjInsert(int c0) {
+    protected void clusterjInsert(int c0) {
         final CJSubscriber o = session.newInstance(CJSubscriber.class);
         final int i = c0;
         final String str = Integer.toString(i);
@@ -1042,7 +1135,7 @@ public class Main
 
     // ----------------------------------------------------------------------
 
-    public void runJdbcLookup(XMode mode) throws SQLException {
+    protected void runJdbcLookup(XMode mode) throws SQLException {
         final String m = mode.toString().toLowerCase();
         //out.println("lookup " + nRows + " rows by JDBC " + m + " tx ...");
 
@@ -1060,10 +1153,10 @@ public class Main
             connection.commit();
         time += System.currentTimeMillis();
 
-        out.println("jdbc_lookup_" + m + "    \t: " + time + " ms");
+        out.println("jdbc_lookup_" + m + "    \t: " + time + "\tms");
     }
 
-    public void runClusterjLookup(XMode mode) {
+    protected void runClusterjLookup(XMode mode) {
         final String m = mode.toString().toLowerCase();
         //out.println("lookup " + nRows + " rows by ClusterJ " + m + " tx ...");
 
@@ -1077,10 +1170,10 @@ public class Main
             session.currentTransaction().commit();
         time += System.currentTimeMillis();
 
-        out.println("clusterj_lookup_" + m + "  \t: " + time + " ms");
+        out.println("clusterj_lookup_" + m + "  \t: " + time + "\tms");
     }
 
-    public void runNdbjtieLookup(XMode mode) {
+    protected void runNdbjtieLookup(XMode mode) {
         final String m = mode.toString().toLowerCase();
         //out.println("lookup " + nRows + " rows by NDB JTie " + m + " tx ...");
 
@@ -1109,10 +1202,10 @@ public class Main
         }
         time += System.currentTimeMillis();
 
-        out.println("ndbjtie_lookup_" + m + "  \t: " + time + " ms");
+        out.println("ndbjtie_lookup_" + m + "  \t: " + time + "\tms");
     }
 
-    public void jdbcLookup(int c0) {
+    protected void jdbcLookup(int c0) {
         // include exception handling as part of jdbc pattern
         try {
             sel0.setString(1, Integer.toString(c0)); // key
@@ -1144,7 +1237,7 @@ public class Main
         }
     }
 
-    public void clusterjLookup(int c0) {
+    protected void clusterjLookup(int c0) {
         final CJSubscriber o
             = session.find(CJSubscriber.class, Integer.toString(c0));
         if (o != null) {
@@ -1285,7 +1378,7 @@ public class Main
 
     // ----------------------------------------------------------------------
 
-    public void runJdbcUpdate(XMode mode) throws SQLException {
+    protected void runJdbcUpdate(XMode mode) throws SQLException {
         final String m = mode.toString().toLowerCase();
         //out.println("update " + nRows + " rows by JDBC " + m + " tx ...");
 
@@ -1300,10 +1393,10 @@ public class Main
             connection.commit();
         time += System.currentTimeMillis();
 
-        out.println("jdbc_update_" + m + "    \t: " + time + " ms");
+        out.println("jdbc_update_" + m + "    \t: " + time + "\tms");
     }
 
-    public void runClusterjUpdate(XMode mode) {
+    protected void runClusterjUpdate(XMode mode) {
         final String m = mode.toString().toLowerCase();
         //out.println("update " + nRows + " rows by ClusterJ " + m + " tx ...");
 
@@ -1317,10 +1410,10 @@ public class Main
             session.currentTransaction().commit();
         time += System.currentTimeMillis();
 
-        out.println("clusterj_update_" + m + "  \t: " + time + " ms");
+        out.println("clusterj_update_" + m + "  \t: " + time + "\tms");
     }
 
-    public void runNdbjtieUpdate(XMode mode) {
+    protected void runNdbjtieUpdate(XMode mode) {
         final String m = mode.toString().toLowerCase();
         //out.println("update " + nRows + " rows by NDB JTie " + m + " tx ...");
 
@@ -1345,10 +1438,10 @@ public class Main
         }
         time += System.currentTimeMillis();
 
-        out.println("ndbjtie_update_" + m + "  \t: " + time + " ms");
+        out.println("ndbjtie_update_" + m + "  \t: " + time + "\tms");
     }
 
-    public void jdbcUpdate(int c0, XMode mode) {
+    protected void jdbcUpdate(int c0, XMode mode) {
         final String str0 = Integer.toString(c0);
         final int r = -c0;
         final String str1 = Integer.toString(r);
@@ -1374,7 +1467,7 @@ public class Main
         }
     }
 
-    public void clusterjUpdate(int c0) {
+    protected void clusterjUpdate(int c0) {
         final String str0 = Integer.toString(c0);
         final int r = -c0;
         final String str1 = Integer.toString(r);
@@ -1464,7 +1557,7 @@ public class Main
 
     // ----------------------------------------------------------------------
 
-    public void runJdbcDelete(XMode mode) throws SQLException {
+    protected void runJdbcDelete(XMode mode) throws SQLException {
         final String m = mode.toString().toLowerCase();
         //out.println("delete " + nRows + " rows by JDBC " + m + " tx ...");
 
@@ -1479,10 +1572,10 @@ public class Main
             connection.commit();
         time += System.currentTimeMillis();
 
-        out.println("jdbc_delete_" + m + "    \t: " + time + " ms");
+        out.println("jdbc_delete_" + m + "    \t: " + time + "\tms");
     }
 
-    public void runClusterjDelete(XMode mode) {
+    protected void runClusterjDelete(XMode mode) {
         final String m = mode.toString().toLowerCase();
         //out.println("delete " + nRows + " rows by ClusterJ " + m + " tx ...");
 
@@ -1496,10 +1589,10 @@ public class Main
             session.currentTransaction().commit();
         time += System.currentTimeMillis();
 
-        out.println("clusterj_delete_" + m + "  \t: " + time + " ms");
+        out.println("clusterj_delete_" + m + "  \t: " + time + "\tms");
     }
 
-    public void runNdbjtieDelete(XMode mode) {
+    protected void runNdbjtieDelete(XMode mode) {
         final String m = mode.toString().toLowerCase();
         //out.println("delete " + nRows + " rows by NDB JTie " + m + " tx ...");
 
@@ -1524,10 +1617,10 @@ public class Main
         }
         time += System.currentTimeMillis();
 
-        out.println("ndbjtie_delete_" + m + "  \t: " + time + " ms");
+        out.println("ndbjtie_delete_" + m + "  \t: " + time + "\tms");
     }
 
-    public void jdbcDelete(int c0, XMode mode) {
+    protected void jdbcDelete(int c0, XMode mode) {
         // include exception handling as part of jdbc pattern
         try {
             final String str = Integer.toString(c0);
@@ -1543,7 +1636,7 @@ public class Main
         }
     }
 
-    public void clusterjDelete(int c0) {
+    protected void clusterjDelete(int c0) {
         // can do a blind delete
         final CJSubscriber o = session.newInstance(CJSubscriber.class);
         o.setC0(Integer.toString(c0));
@@ -1695,7 +1788,7 @@ public class Main
 
     @PersistenceCapable(table="mytable")
     //@Index(name="c0_UNIQUE")
-    static public interface CJSubscriber
+    static protected interface CJSubscriber
     {
         @PrimaryKey
         String getC0();


Attachment: [text/bzr-bundle] bzr/martin.zaun@oracle.com-20101005084830-431upumcvshncq1u.bundle
Thread
bzr commit into mysql-5.1-telco-7.1 branch (martin.zaun:3860) Martin Zaun5 Oct