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

 3865 Martin Zaun	2010-10-19
      crund - aligned java design and log+console output with c++ version.

    added:
      storage/ndb/test/crund/tws/tws_java/nbproject/private_sample/configs/
      storage/ndb/test/crund/tws/tws_java/nbproject/private_sample/configs/server-dbg.properties
      storage/ndb/test/crund/tws/tws_java/nbproject/private_sample/configs/server-opt.properties
      storage/ndb/test/crund/tws/tws_java/src/com/
      storage/ndb/test/crund/tws/tws_java/src/com/mysql/
      storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/
      storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/
      storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/
      storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/ClusterjLoad.java
      storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/Driver.java
      storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/JdbcLoad.java
      storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/NdbjtieLoad.java
      storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/TwsLoad.java
    renamed:
      storage/ndb/test/crund/tws/tws_java/src/TwsDriver.java => storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/TwsDriver.java
    modified:
      storage/ndb/test/crund/tws/tws_java/nbproject/configs_sample/server-dbg.properties
      storage/ndb/test/crund/tws/tws_java/nbproject/configs_sample/server-opt.properties
      storage/ndb/test/crund/tws/tws_java/nbproject/private_sample/config.properties
      storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/TwsDriver.java
=== modified file 'storage/ndb/test/crund/tws/tws_java/nbproject/configs_sample/server-dbg.properties'
--- a/storage/ndb/test/crund/tws/tws_java/nbproject/configs_sample/server-dbg.properties	2010-10-03 04:32:37 +0000
+++ b/storage/ndb/test/crund/tws/tws_java/nbproject/configs_sample/server-dbg.properties	2010-10-19 22:50:53 +0000
@@ -1,2 +1,3 @@
-run.jvmargs=-server -Xms512m -Xmx512m -ea -Djava.library.path="/Users/mz/mysql/bin-7.1-dbg64/lib/mysql"
+main.class=com.mysql.cluster.benchmark.tws.TwsDriver
+run.jvmargs=-server -Xms512m -Xmx512m -da -Djava.library.path="/Users/mz/mysql/bin-7.1-dbg64/lib/mysql"
 #run.jvmargs=-server -Xms512m -Xmx512m -ea -Djava.library.path="/home/md/mysql/bin-7.1-dbg32/lib/mysql"

=== modified file 'storage/ndb/test/crund/tws/tws_java/nbproject/configs_sample/server-opt.properties'
--- a/storage/ndb/test/crund/tws/tws_java/nbproject/configs_sample/server-opt.properties	2010-09-29 09:09:26 +0000
+++ b/storage/ndb/test/crund/tws/tws_java/nbproject/configs_sample/server-opt.properties	2010-10-19 22:50:53 +0000
@@ -1,2 +1,3 @@
+main.class=com.mysql.cluster.benchmark.tws.TwsDriver
 run.jvmargs=-server -Xms512m -Xmx512m -da -Djava.library.path="/Users/mz/mysql/bin-7.1-opt64/lib/mysql"
 #run.jvmargs=-server -Xms512m -Xmx512m -da -Djava.library.path="/home/md/mysql/bin-7.1-opt32/lib/mysql"

=== modified file 'storage/ndb/test/crund/tws/tws_java/nbproject/private_sample/config.properties'
--- a/storage/ndb/test/crund/tws/tws_java/nbproject/private_sample/config.properties	2010-09-29 09:09:26 +0000
+++ b/storage/ndb/test/crund/tws/tws_java/nbproject/private_sample/config.properties	2010-10-19 22:50:53 +0000
@@ -1,2 +1,2 @@
-config=server-opt
+config=server-dbg
 #config=server-dbg

=== added directory 'storage/ndb/test/crund/tws/tws_java/nbproject/private_sample/configs'
=== added file 'storage/ndb/test/crund/tws/tws_java/nbproject/private_sample/configs/server-dbg.properties'
--- a/storage/ndb/test/crund/tws/tws_java/nbproject/private_sample/configs/server-dbg.properties	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/crund/tws/tws_java/nbproject/private_sample/configs/server-dbg.properties	2010-10-19 22:50:53 +0000
@@ -0,0 +1 @@
+application.args=-p ../run.properties

=== added file 'storage/ndb/test/crund/tws/tws_java/nbproject/private_sample/configs/server-opt.properties'
--- a/storage/ndb/test/crund/tws/tws_java/nbproject/private_sample/configs/server-opt.properties	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/crund/tws/tws_java/nbproject/private_sample/configs/server-opt.properties	2010-10-19 22:50:53 +0000
@@ -0,0 +1 @@
+application.args=-p ../run.properties

=== added directory 'storage/ndb/test/crund/tws/tws_java/src/com'
=== added directory 'storage/ndb/test/crund/tws/tws_java/src/com/mysql'
=== added directory 'storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster'
=== added directory 'storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark'
=== added directory 'storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws'
=== added file 'storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/ClusterjLoad.java'
--- a/storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/ClusterjLoad.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/ClusterjLoad.java	2010-10-19 22:50:53 +0000
@@ -0,0 +1,386 @@
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
+ *
+ *  Copyright (C) 2010 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.benchmark.tws;
+
+import com.mysql.clusterj.ClusterJHelper;
+import com.mysql.clusterj.SessionFactory;
+import com.mysql.clusterj.Session;
+import com.mysql.clusterj.LockMode;
+import com.mysql.clusterj.Constants;
+import com.mysql.clusterj.annotation.Index;
+import com.mysql.clusterj.annotation.PersistenceCapable;
+import com.mysql.clusterj.annotation.PrimaryKey;
+
+import java.util.Map;
+import java.util.Iterator;
+
+
+class ClusterjLoad extends TwsLoad {
+
+    // ClusterJ resources
+    protected SessionFactory sessionFactory;
+    protected Session session;
+
+    public ClusterjLoad(TwsDriver driver) {
+        super(driver);
+    }
+
+    // ----------------------------------------------------------------------
+    // ClusterJ intializers/finalizers
+    // ----------------------------------------------------------------------
+
+    protected void initProperties() {
+        out.println();
+        out.print("setting clusterj properties ...");
+
+        final StringBuilder msg = new StringBuilder();
+        final String eol = System.getProperty("line.separator");
+
+        // check required properties
+        String mgmdConnect
+            = driver.props.getProperty(Constants.PROPERTY_CLUSTER_CONNECTSTRING);
+
+        if (msg.length() == 0) {
+            out.println(" [ok]");
+        } else {
+            out.println();
+            out.print(msg.toString());
+        }
+
+        // have mgmdConnect initialized first
+        descr = "clusterj(" + mgmdConnect + ")";
+    }
+
+    protected void printProperties() {
+        for (Iterator<Map.Entry<Object,Object>> i
+                 = driver.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, 18, k.length());
+                while (s.length() < 31) s.append(' ');
+                out.println(s + " " + e.getValue());
+            }
+        }
+    }
+
+    public void init() throws Exception {
+        super.init();
+        assert (sessionFactory == null);
+
+        // load native library (better diagnostics doing it explicitely)
+        //loadSystemLibrary("ndbclient");
+
+        out.print("creating SessionFactory ...");
+        out.flush();
+        sessionFactory = ClusterJHelper.getSessionFactory(driver.props);
+        out.println("     [ok]");
+    }
+
+    public void close() throws Exception {
+        assert (sessionFactory != null);
+
+        out.println();
+        out.print("closing SessionFactory ...");
+        out.flush();
+        sessionFactory.close();
+        sessionFactory = null;
+        out.println("      [ok]");
+
+        super.close();
+    }
+
+    // ----------------------------------------------------------------------
+    // ClusterJ datastore operations
+    // ----------------------------------------------------------------------
+
+    public void initConnection() {
+        assert (sessionFactory != null);
+        assert (session == null);
+
+        out.println();
+        out.println("initializing clusterj resources ...");
+
+        out.print("starting clusterj session ...");
+        out.flush();
+        session = sessionFactory.getSession();
+        out.println("   [ok]");
+
+        out.print("setting session lock mode ...");
+        session.setLockMode(driver.lockMode);
+        out.println("   [ok: " + driver.lockMode + "]");
+    }
+
+    public void closeConnection() {
+        assert (session != null);
+
+        out.println();
+        out.println("releasing clusterj resources ...");
+
+        out.print("closing clusterj session ...");
+        out.flush();
+        session.close();
+        session = null;
+        out.println("    [ok]");
+    }
+
+    // ----------------------------------------------------------------------
+
+    public void runOperations() {
+        out.println();
+        out.println("running ClusterJ operations ..."
+                    + " [nRows=" + driver.nRows + "]");
+
+        if (driver.doSingle) {
+            if (driver.doInsert) runClusterjInsert(TwsDriver.XMode.SINGLE);
+            if (driver.doLookup) runClusterjLookup(TwsDriver.XMode.SINGLE);
+            if (driver.doUpdate) runClusterjUpdate(TwsDriver.XMode.SINGLE);
+            if (driver.doDelete) runClusterjDelete(TwsDriver.XMode.SINGLE);
+        }
+        if (driver.doBulk) {
+            if (driver.doInsert) runClusterjInsert(TwsDriver.XMode.BULK);
+            if (driver.doLookup) runClusterjLookup(TwsDriver.XMode.BULK);
+            if (driver.doUpdate) runClusterjUpdate(TwsDriver.XMode.BULK);
+            if (driver.doDelete) runClusterjDelete(TwsDriver.XMode.BULK);
+        }
+        if (driver.doBatch) {
+            if (driver.doInsert) runClusterjInsert(TwsDriver.XMode.BATCH);
+            //if (driver.doLookup) runClusterjLookup(TwsDriver.XMode.BATCH);
+            if (driver.doUpdate) runClusterjUpdate(TwsDriver.XMode.BATCH);
+            if (driver.doDelete) runClusterjDelete(TwsDriver.XMode.BATCH);
+        }
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected void runClusterjInsert(TwsDriver.XMode mode) {
+        final String name = "insert_" + mode.toString().toLowerCase();
+        driver.begin(name);
+
+        if (mode != TwsDriver.XMode.SINGLE)
+            session.currentTransaction().begin();
+        for(int i = 0; i < driver.nRows; i++) {
+            clusterjInsert(i);
+            if (mode == TwsDriver.XMode.BULK)
+                session.flush();
+        }
+        if (mode != TwsDriver.XMode.SINGLE)
+            session.currentTransaction().commit();
+
+        driver.finish(name);
+    }
+
+    protected void clusterjInsert(int c0) {
+        final CJSubscriber o = session.newInstance(CJSubscriber.class);
+        final int i = c0;
+        final String str = Integer.toString(i);
+        //final String oneChar = Integer.toString(1);
+        o.setC0(str);
+        o.setC1(str);
+        o.setC2(i);
+        o.setC3(i);
+        //o.setC4(i);
+        o.setC5(str);
+        o.setC6(str);
+        o.setC7(str);
+        o.setC8(str);
+        //o.setC9(oneChar);
+        //o.setC10(oneChar);
+        //o.setC11(str);
+        //o.setC12(str);
+        //o.setC13(oneChar);
+        //o.setC14(str);
+        session.persist(o);
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected void runClusterjLookup(TwsDriver.XMode mode) {
+        assert(mode != TwsDriver.XMode.BATCH);
+
+        final String name = "lookup_" + mode.toString().toLowerCase();
+        driver.begin(name);
+
+        if (mode != TwsDriver.XMode.SINGLE)
+            session.currentTransaction().begin();
+        for(int i = 0; i < driver.nRows; i++) {
+            clusterjLookup(i);
+        }
+        if (mode != TwsDriver.XMode.SINGLE)
+            session.currentTransaction().commit();
+
+        driver.finish(name);
+    }
+
+    protected void clusterjLookup(int c0) {
+        final CJSubscriber o
+            = session.find(CJSubscriber.class, Integer.toString(c0));
+        if (o != null) {
+            // not verifying at this time
+            String ac0 = o.getC0();
+            String c1 = o.getC1();
+            int c2 = o.getC2();
+            int c3 = o.getC3();
+            int c4 = o.getC4();
+            String c5 = o.getC5();
+            String c6 = o.getC6();
+            String c7 = o.getC7();
+            String c8 = o.getC8();
+            String c9 = o.getC9();
+            String c10 = o.getC10();
+            String c11 = o.getC11();
+            String c12 = o.getC12();
+            String c13 = o.getC13();
+            String c14 = o.getC14();
+        }
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected void runClusterjUpdate(TwsDriver.XMode mode) {
+        final String name = "update_" + mode.toString().toLowerCase();
+        driver.begin(name);
+
+        if (mode != TwsDriver.XMode.SINGLE)
+            session.currentTransaction().begin();
+        for(int i = 0; i < driver.nRows; i++) {
+            clusterjUpdate(i);
+            if (mode == TwsDriver.XMode.BULK)
+                session.flush();
+        }
+        if (mode != TwsDriver.XMode.SINGLE)
+            session.currentTransaction().commit();
+
+        driver.finish(name);
+    }
+
+    protected void clusterjUpdate(int c0) {
+        final String str0 = Integer.toString(c0);
+        final int r = -c0;
+        final String str1 = Integer.toString(r);
+
+        // blind update
+        final CJSubscriber o = session.newInstance(CJSubscriber.class);
+        o.setC0(str0);
+        //final CJSubscriber o = session.find(CJSubscriber.class, str0);
+        //String oneChar = Integer.toString(2);
+        o.setC1(str1);
+        o.setC2(r);
+        o.setC3(r);
+        //o.setC4(r);
+        o.setC5(str1);
+        o.setC6(str1);
+        o.setC7(str1);
+        o.setC8(str1);
+        //o.setC9(oneChar);
+        //o.setC10(oneChar);
+        //o.setC11(str);
+        //o.setC12(str);
+        //o.setC13(oneChar);
+        //o.setC14(str);
+        session.updatePersistent(o);
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected void runClusterjDelete(TwsDriver.XMode mode) {
+        final String name = "delete_" + mode.toString().toLowerCase();
+        driver.begin(name);
+
+        if (mode != TwsDriver.XMode.SINGLE)
+            session.currentTransaction().begin();
+        for(int i = 0; i < driver.nRows; i++) {
+            clusterjDelete(i);
+            if (mode == TwsDriver.XMode.BULK)
+                session.flush();
+        }
+        if (mode != TwsDriver.XMode.SINGLE)
+            session.currentTransaction().commit();
+
+        driver.finish(name);
+    }
+
+    protected void clusterjDelete(int c0) {
+        // XXX use new API for blind delete
+        final CJSubscriber o = session.newInstance(CJSubscriber.class);
+        o.setC0(Integer.toString(c0));
+        assert o != null;
+        session.remove(o);
+    }
+
+    // ----------------------------------------------------------------------
+
+    @PersistenceCapable(table="mytable")
+    //@Index(name="c0_UNIQUE")
+    static public interface CJSubscriber {
+        @PrimaryKey
+        String getC0();
+        void setC0(String c0);
+
+        @Index(name="c1_UNIQUE")
+        String getC1();
+        void setC1(String c1);
+
+        @Index(name="c2_UNIQUE")
+        int getC2();
+        void setC2(int c2);
+
+        int getC3();
+        void setC3(int c3);
+
+        int getC4();
+        void setC4(int c4);
+
+        String getC5();
+        void setC5(String c5);
+
+        String getC6();
+        void setC6(String c6);
+
+        @Index(name="c7_UNIQUE")
+        String getC7();
+        void setC7(String c7);
+
+        @Index(name="c8_UNIQUE")
+        String getC8();
+        void setC8(String c8);
+
+        String getC9();
+        void setC9(String c9);
+
+        String getC10();
+        void setC10(String c10);
+
+        String getC11();
+        void setC11(String c11);
+
+        String getC12();
+        void setC12(String c12);
+
+        String getC13();
+        void setC13(String c13);
+
+        String getC14();
+        void setC14(String c14);
+    }
+
+}

=== added file 'storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/Driver.java'
--- a/storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/Driver.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/Driver.java	2010-10-19 22:50:53 +0000
@@ -0,0 +1,405 @@
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
+ *
+ *  Copyright (C) 2010 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.benchmark.tws;
+
+import java.io.PrintWriter;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.FileWriter;
+
+import java.util.Properties;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+
+
+public abstract class Driver {
+
+    // console
+    static protected final PrintWriter out = new PrintWriter(System.out, true);
+    static protected final PrintWriter err = new PrintWriter(System.err, true);
+
+    // shortcuts
+    static protected final String endl = System.getProperty("line.separator");
+    static protected final Runtime rt = Runtime.getRuntime();
+
+    // driver command-line arguments
+    static private final List<String> propFileNames = new ArrayList<String>();
+    static private String logFileName;
+
+    // driver settings
+    protected final Properties props = new Properties();
+    protected boolean logRealTime;
+    protected boolean logMemUsage;
+    protected boolean includeFullGC;
+    protected int warmupRuns;
+
+    // driver resources
+    protected PrintWriter log;
+    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;
+
+    // ----------------------------------------------------------------------
+    // driver usage
+    // ----------------------------------------------------------------------
+
+    /**
+     * Prints a command-line usage message and exits.
+     */
+    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
+    }
+
+    /**
+     * 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();
+            }
+        }
+
+        if (propFileNames.size() == 0) {
+            propFileNames.add("run.properties");
+        }
+
+        if (logFileName == null) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHMMss");
+            logFileName = ("log_" + sdf.format(new Date()) + ".txt");
+        }
+    }
+
+    /**
+     * Creates an instance.
+     */
+    public Driver() {}
+
+    /**
+     * Runs the benchmark.
+     */
+    public void run() {
+        try {
+            init();
+
+            if (warmupRuns > 0) {
+                out.println();
+                out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
+                out.println("warmup runs ...");
+                out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
+
+                for (int i = 0; i < warmupRuns; i++) {
+                    runTests();
+                }
+
+                // truncate log file, reset log buffers
+                closeLogFile();
+                openLogFile();
+                clearLogBuffers();
+            }
+
+            out.println();
+            out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
+            out.println("hot runs ...");
+            out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
+            runTests();
+
+            out.println();
+            out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
+            close();
+        } catch (Exception ex) {
+            // end the program regardless of threads
+            out.println("caught " + ex);
+            ex.printStackTrace();
+            System.exit(2); // return an error code
+        }
+    }
+
+    // ----------------------------------------------------------------------
+    // 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();
+        clearLogBuffers();
+    }
+
+    // releases the driver's resources.
+    protected void close() throws Exception {
+        out.println();
+
+        // release log buffers
+        logHeader = false;
+        header = null;
+        rtimes = null;
+        musage = null;
+
+        closeLogFile();
+        props.clear();
+    }
+
+    // loads the benchmark's properties from properties files
+    private void loadProperties() throws IOException {
+        out.println();
+        for (String fn : propFileNames) {
+            out.println("reading properties file:        " + fn);
+            InputStream is = null;
+            try {
+                is = new FileInputStream(fn);
+                props.load(is);
+            } finally {
+                if (is != null)
+                    is.close();
+            }
+        }
+    }
+
+    // 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
+    protected int parseInt(String k, int vdefault) {
+        final String v = props.getProperty(k);
+        try {
+            return (v == null ? vdefault : Integer.parseInt(v));
+        } catch (NumberFormatException e) {
+            final NumberFormatException nfe = new NumberFormatException(
+                "invalid value of benchmark property ('" + k + "', '"
+                + v + "').");
+            nfe.initCause(e);
+            throw nfe;
+        }
+    }
+
+    // initializes the benchmark properties
+    protected void initProperties() {
+        //props.list(out);
+        out.print("setting driver properties ...");
+        out.flush();
+
+        final StringBuilder msg = new StringBuilder();
+        final String eol = System.getProperty("line.separator");
+
+        logRealTime = parseBoolean("logRealTime", true);
+        logMemUsage = parseBoolean("logMemUsage", false);
+        includeFullGC = parseBoolean("includeFullGC", false);
+
+        warmupRuns = parseInt("warmupRuns", 0);
+        if (warmupRuns < 0) {
+            msg.append("[ignored] warmupRuns:           " + warmupRuns + eol);
+            warmupRuns = 0;
+        }
+
+        if (msg.length() == 0) {
+            out.println("   [ok]");
+        } else {
+            out.println();
+            out.print(msg.toString());
+        }
+    }
+
+    // prints the benchmark's properties
+    protected void printProperties() {
+        out.println();
+        out.println("driver settings ...");
+        out.println("logRealTime:                    " + logRealTime);
+        out.println("logMemUsage:                    " + logMemUsage);
+        out.println("includeFullGC:                  " + includeFullGC);
+        out.println("warmupRuns:                     " + warmupRuns);
+    }
+
+    // opens the benchmark's data log file
+    private void openLogFile() throws IOException {
+        out.println();
+        out.println("writing results to file:        " + logFileName);
+        log = new PrintWriter(new FileWriter(logFileName, false));
+    }
+
+    // closes the benchmark's data log file
+    private void closeLogFile() throws IOException {
+        out.print("closing files ...");
+        out.flush();
+        if (log != null) {
+            log.close();
+            log = null;
+        }
+        out.println("               [ok]");
+    }
+
+    // ----------------------------------------------------------------------
+    // benchmark operations
+    // ----------------------------------------------------------------------
+
+    abstract protected void runTests() throws Exception;
+
+    protected void clearLogBuffers() {
+        logHeader = true;
+        header = new StringBuilder();
+        if (logRealTime) {
+            rtimes = new StringBuilder();
+        }
+        if (logMemUsage) {
+            musage = new StringBuilder();
+        }
+    }
+    
+    protected void writeLogBuffers(String descr) {
+        if (logRealTime) {
+            log.println(descr + ", rtime[ms]"
+                        + header.toString() + endl
+                        + rtimes.toString() + endl);
+        }
+        if (logMemUsage) {
+            log.println(descr + ", net musage[KiB]"
+                        + header.toString() + endl
+                        + musage.toString() + endl);
+        }
+    }
+    
+    protected void begin(String name) {
+        out.println();
+        out.println(name);
+
+        // attempt max GC, before tx
+        gc();
+
+        if (logMemUsage) {
+            m0 = rt.totalMemory() - rt.freeMemory();
+        }
+
+        if (logRealTime) {
+            //t0 = System.currentTimeMillis();
+            t0 = System.nanoTime() / 1000000;
+        }
+    }
+
+    protected void finish(String name) {
+        // attempt one full GC, before timing tx end
+        if (includeFullGC) {
+            rt.gc();
+        }
+
+        if (logRealTime) {
+            //t1 = System.currentTimeMillis();
+            t1 = System.nanoTime() / 1000000;
+            final long t = t1 - t0;
+            out.println("tx real time                    " + t
+                        + "\tms");
+            //rtimes.append("\t" + (Math.round(t / 100.0) / 10.0));
+            rtimes.append("\t" + t);
+            ta += t;
+        }
+
+        if (logMemUsage) {
+            // attempt max GC, after tx
+            gc();
+            m1 = rt.totalMemory() - rt.freeMemory();
+            final long m0K = (m0 / 1024);
+            final long m1K = (m1 / 1024);
+            final long mK = m1K - m0K;
+            out.println("net mem usage                   "
+                        + (mK >= 0 ? "+" : "") + mK
+                        + "\tKiB [" + m0K + "K->" + m1K + "K]");
+            musage.append("\t" + mK);
+            ma += mK;
+        }
+
+        if (logHeader)
+            header.append("\t" + name);
+    }
+}

=== added file 'storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/JdbcLoad.java'
--- a/storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/JdbcLoad.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/JdbcLoad.java	2010-10-19 22:50:53 +0000
@@ -0,0 +1,462 @@
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
+ *
+ *  Copyright (C) 2010 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.benchmark.tws;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+
+class JdbcLoad extends TwsLoad {
+
+    // JDBC settings
+    protected String jdbcDriver;
+    protected String url;
+    protected String username;
+    protected String password;
+
+    // JDBC resources
+    protected Class jdbcDriverClass;
+    protected Connection connection;
+    protected PreparedStatement ins0;
+    protected PreparedStatement sel0;
+    protected PreparedStatement upd0;
+    protected PreparedStatement del0;
+    protected PreparedStatement delAll;
+
+    public JdbcLoad(TwsDriver driver) {
+        super(driver);
+    }
+
+    // ----------------------------------------------------------------------
+    // JDBC intializers/finalizers
+    // ----------------------------------------------------------------------
+
+    protected void initProperties() {
+        out.println();
+        out.print("setting jdbc properties ...");
+
+        final StringBuilder msg = new StringBuilder();
+        final String eol = System.getProperty("line.separator");
+
+        // load the JDBC driver class
+        jdbcDriver = driver.props.getProperty("jdbc.driver");
+        if (jdbcDriver == null) {
+            throw new RuntimeException("Missing property: jdbc.driver");
+        }
+        try {
+            Class.forName(jdbcDriver);
+        } catch (ClassNotFoundException e) {
+            out.println("Cannot load JDBC driver '" + jdbcDriver
+                        + "' from classpath '"
+                        + System.getProperty("java.class.path") + "'");
+            throw new RuntimeException(e);
+        }
+
+        url = driver.props.getProperty("jdbc.url");
+        if (url == null) {
+            throw new RuntimeException("Missing property: jdbc.url");
+        }
+
+        username = driver.props.getProperty("jdbc.user");
+        password = driver.props.getProperty("jdbc.password");
+
+        if (msg.length() == 0) {
+            out.println("     [ok]");
+        } else {
+            out.println();
+            out.print(msg.toString());
+        }
+
+        // have url initialized first
+        descr = "jdbc(" + url + ")";
+     }
+
+    protected void printProperties() {
+        out.println("jdbc.driver:                    " + jdbcDriver);
+        out.println("jdbc.url:                       " + url);
+        out.println("jdbc.user:                      \"" + username + "\"");
+        out.println("jdbc.password:                  \"" + password + "\"");
+    }
+
+    public void init() throws Exception {
+        super.init();
+        assert (jdbcDriverClass == null);
+
+        // load the JDBC driver class
+        out.print("loading jdbc driver ...");
+        out.flush();
+        try {
+            jdbcDriverClass = Class.forName(jdbcDriver);
+        } catch (ClassNotFoundException e) {
+            out.println("Cannot load JDBC driver '" + jdbcDriver
+                        + "' from classpath '"
+                        + System.getProperty("java.class.path") + "'");
+            throw new RuntimeException(e);
+        }
+        out.println("         [ok: " + jdbcDriverClass.getName() + "]");
+    }
+
+    public void close() throws Exception {
+        assert (jdbcDriverClass != null);
+
+        //out.println();
+        jdbcDriverClass = null;
+
+        super.close();
+    }
+
+    // ----------------------------------------------------------------------
+    // JDBC datastore operations
+    // ----------------------------------------------------------------------
+
+    public void initConnection() throws SQLException {
+        assert (jdbcDriverClass != null);
+        assert (connection == null);
+
+        out.println();
+        out.println("initializing jdbc resources ...");
+
+        // create a connection to the database
+        out.print("starting jdbc connection ...");
+        out.flush();
+        try {
+            connection = DriverManager.getConnection(url, username, password);
+        } catch (SQLException e) {
+            out.println("Cannot connect to database '" + url + "'");
+            throw new RuntimeException(e);
+        }
+        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: ");
+        switch (connection.getTransactionIsolation()) {
+        case Connection.TRANSACTION_READ_UNCOMMITTED:
+            out.print("READ_UNCOMMITTED");
+            break;
+        case Connection.TRANSACTION_READ_COMMITTED:
+            out.print("READ_COMMITTED");
+            break;
+        case Connection.TRANSACTION_REPEATABLE_READ:
+            out.print("REPEATABLE_READ");
+            break;
+        case Connection.TRANSACTION_SERIALIZABLE:
+            out.print("SERIALIZABLE");
+            break;
+        default:
+            assert false;
+        }
+        out.println("]");
+
+        initPreparedStatements();
+    }
+
+    public void closeConnection() throws SQLException {
+        assert (connection != null);
+
+        out.println();
+        out.println("releasing jdbc resources ...");
+
+        closePreparedStatements();
+
+        out.print("closing jdbc connection ...");
+        out.flush();
+        connection.close();
+        connection = null;
+        out.println("     [ok]");
+    }
+
+    public void initPreparedStatements() throws SQLException {
+        assert (connection != null);
+        assert (ins0 == null);
+        assert (sel0 == null);
+        assert (upd0 == null);
+        assert (del0 == null);
+
+        out.print("using lock mode for reads ...");
+        out.flush();
+        final String lm;
+        switch (driver.lockMode) {
+        case READ_COMMITTED:
+            lm = "";
+            break;
+        case SHARED:
+            lm = " LOCK IN share mode";
+            break;
+        case EXCLUSIVE:
+            lm = " FOR UPDATE";
+            break;
+        default:
+            lm = "";
+            assert false;
+        }
+        out.println("   [ok: " + "SELECT" + lm + ";]");
+
+        out.print("compiling jdbc statements ...");
+        out.flush();
+
+        final String sqlIns0 = "INSERT INTO mytable (c0, c1, c2, c3, c5, c6, c7, c8) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
+        ins0 = connection.prepareStatement(sqlIns0);
+
+        final String sqlSel0 = ("SELECT * FROM mytable where c0=?" + lm);
+        sel0 = connection.prepareStatement(sqlSel0);
+
+        final String sqlUpd0 = "UPDATE mytable SET c1 = ?, c2 = ?, c3 = ?, c5 = ?, c6 = ?, c7 = ?, c8 = ? WHERE c0=?";
+        upd0 = connection.prepareStatement(sqlUpd0);
+
+        final String sqlDel0 = "DELETE FROM mytable WHERE c0=?";
+        del0 = connection.prepareStatement(sqlDel0);
+
+        delAll = connection.prepareStatement("DELETE FROM mytable");
+
+        out.println("   [ok]");
+    }
+
+    protected void closePreparedStatements() throws SQLException {
+        assert (ins0 != null);
+        assert (sel0 != null);
+        assert (upd0 != null);
+        assert (del0 != null);
+        assert (delAll != null);
+
+        out.print("closing jdbc statements ...");
+        out.flush();
+
+        ins0.close();
+        ins0 = null;
+
+        sel0.close();
+        sel0 = null;
+
+        upd0.close();
+        upd0 = null;
+
+        del0.close();
+        del0 = null;
+
+        delAll.close();
+        delAll = null;
+
+        out.println("     [ok]");
+    }
+
+    // ----------------------------------------------------------------------
+
+    public void runOperations() throws SQLException {
+        out.println();
+        out.println("running JDBC operations ..."
+                    + "     [nRows=" + driver.nRows + "]");
+
+        if (driver.doSingle) {
+            if (driver.doInsert) runJdbcInsert(TwsDriver.XMode.SINGLE);
+            if (driver.doLookup) runJdbcLookup(TwsDriver.XMode.SINGLE);
+            if (driver.doUpdate) runJdbcUpdate(TwsDriver.XMode.SINGLE);
+            if (driver.doDelete) runJdbcDelete(TwsDriver.XMode.SINGLE);
+        }
+        if (driver.doBulk) {
+            if (driver.doInsert) runJdbcInsert(TwsDriver.XMode.BULK);
+            if (driver.doLookup) runJdbcLookup(TwsDriver.XMode.BULK);
+            if (driver.doUpdate) runJdbcUpdate(TwsDriver.XMode.BULK);
+            if (driver.doDelete) runJdbcDelete(TwsDriver.XMode.BULK);
+        }
+        if (driver.doBatch) {
+            if (driver.doInsert) runJdbcInsert(TwsDriver.XMode.BATCH);
+            //if (driver.doLookup) runJdbcLookup(TwsDriver.XMode.BATCH);
+            if (driver.doUpdate) runJdbcUpdate(TwsDriver.XMode.BATCH);
+            if (driver.doDelete) runJdbcDelete(TwsDriver.XMode.BATCH);
+        }
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected void runJdbcInsert(TwsDriver.XMode mode) throws SQLException {
+        final String name = "insert_" + mode.toString().toLowerCase();
+        driver.begin(name);
+
+        connection.setAutoCommit(mode == TwsDriver.XMode.SINGLE);
+        for(int i = 0; i < driver.nRows; i++) {
+            jdbcInsert(i, mode);
+        }
+        if (mode == TwsDriver.XMode.BATCH)
+            ins0.executeBatch();
+        if (mode != TwsDriver.XMode.SINGLE)
+            connection.commit();
+
+        driver.finish(name);
+    }
+
+    protected void jdbcInsert(int c0, TwsDriver.XMode mode) {
+        // include exception handling as part of jdbc pattern
+        try {
+            final int i = c0;
+            final String str = Integer.toString(i);
+            ins0.setString(1, str); // key
+            ins0.setString(2, str);
+            ins0.setInt(3, i);
+            ins0.setInt(4, i);
+            ins0.setString(5, str);
+            ins0.setString(6, str);
+            ins0.setString(7, str);
+            ins0.setString(8, str);
+            if (mode == TwsDriver.XMode.BATCH) {
+                ins0.addBatch();
+            } else {
+                int cnt = ins0.executeUpdate();
+                assert (cnt == 1);
+            }
+        } catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected void runJdbcLookup(TwsDriver.XMode mode) throws SQLException {
+        assert(mode != TwsDriver.XMode.BATCH);
+
+        final String name = "lookup_" + mode.toString().toLowerCase();
+        driver.begin(name);
+
+        connection.setAutoCommit(mode == TwsDriver.XMode.SINGLE);
+        for(int i = 0; i < driver.nRows; i++) {
+            jdbcLookup(i);
+        }
+        if (mode != TwsDriver.XMode.SINGLE)
+            connection.commit();
+
+        driver.finish(name);
+    }
+
+    protected void jdbcLookup(int c0) {
+        // include exception handling as part of jdbc pattern
+        try {
+            sel0.setString(1, Integer.toString(c0)); // key
+            ResultSet resultSet = sel0.executeQuery();
+
+            if (resultSet.next()) {
+                // not verifying at this time
+                String ac0 = resultSet.getString(1);
+                String c1 = resultSet.getString(2);
+                int c2 = resultSet.getInt(3);
+                int c3 = resultSet.getInt(4);
+                int c4 = resultSet.getInt(5);
+                String c5 = resultSet.getString(6);
+                String c6 = resultSet.getString(7);
+                String c7 = resultSet.getString(8);
+                String c8 = resultSet.getString(9);
+                String c9 = resultSet.getString(10);
+                String c10 = resultSet.getString(11);
+                String c11 = resultSet.getString(12);
+                String c12 = resultSet.getString(13);
+                String c13 = resultSet.getString(14);
+                String c14 = resultSet.getString(15);
+            }
+            assert (!resultSet.next());
+
+            resultSet.close();
+        } catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected void runJdbcUpdate(TwsDriver.XMode mode) throws SQLException {
+        final String name = "update_" + mode.toString().toLowerCase();
+        driver.begin(name);
+
+        connection.setAutoCommit(mode == TwsDriver.XMode.SINGLE);
+        for(int i = 0; i < driver.nRows; i++) {
+            jdbcUpdate(i, mode);
+        }
+        if (mode == TwsDriver.XMode.BATCH)
+            upd0.executeBatch();
+        if (mode != TwsDriver.XMode.SINGLE)
+            connection.commit();
+
+        driver.finish(name);
+    }
+
+    protected void jdbcUpdate(int c0, TwsDriver.XMode mode) {
+        final String str0 = Integer.toString(c0);
+        final int r = -c0;
+        final String str1 = Integer.toString(r);
+
+        // include exception handling as part of jdbc pattern
+        try {
+            upd0.setString(1, str1);
+            upd0.setInt(2, r);
+            upd0.setInt(3, r);
+            upd0.setString(4, str1);
+            upd0.setString(5, str1);
+            upd0.setString(6, str1);
+            upd0.setString(7, str1);
+            upd0.setString(8, str0); // key
+            if (mode == TwsDriver.XMode.BATCH) {
+                upd0.addBatch();
+            } else {
+                int cnt = upd0.executeUpdate();
+                assert (cnt == 1);
+            }
+        } catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected void runJdbcDelete(TwsDriver.XMode mode) throws SQLException {
+        final String name = "delete_" + mode.toString().toLowerCase();
+        driver.begin(name);
+
+        connection.setAutoCommit(mode == TwsDriver.XMode.SINGLE);
+        for(int i = 0; i < driver.nRows; i++) {
+            jdbcDelete(i, mode);
+        }
+        if (mode == TwsDriver.XMode.BATCH)
+            del0.executeBatch();
+        if (mode != TwsDriver.XMode.SINGLE)
+            connection.commit();
+
+        driver.finish(name);
+    }
+
+    protected void jdbcDelete(int c0, TwsDriver.XMode mode) {
+        // include exception handling as part of jdbc pattern
+        try {
+            final String str = Integer.toString(c0);
+            del0.setString(1, str);
+            if (mode == TwsDriver.XMode.BATCH) {
+                del0.addBatch();
+            } else {
+                int cnt = del0.executeUpdate();
+                assert (cnt == 1);
+            }
+        } catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

=== added file 'storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/NdbjtieLoad.java'
--- a/storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/NdbjtieLoad.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/NdbjtieLoad.java	2010-10-19 22:50:53 +0000
@@ -0,0 +1,997 @@
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
+ *
+ *  Copyright (C) 2010 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.benchmark.tws;
+
+import com.mysql.ndbjtie.ndbapi.Ndb_cluster_connection;
+import com.mysql.ndbjtie.ndbapi.Ndb;
+import com.mysql.ndbjtie.ndbapi.NdbDictionary.Dictionary;
+import com.mysql.ndbjtie.ndbapi.NdbDictionary.TableConst;
+import com.mysql.ndbjtie.ndbapi.NdbDictionary.Table;
+import com.mysql.ndbjtie.ndbapi.NdbDictionary.ColumnConst;
+import com.mysql.ndbjtie.ndbapi.NdbDictionary.IndexConst;
+import com.mysql.ndbjtie.ndbapi.NdbErrorConst;
+import com.mysql.ndbjtie.ndbapi.NdbError;
+import com.mysql.ndbjtie.ndbapi.NdbTransaction;
+import com.mysql.ndbjtie.ndbapi.NdbOperation;
+import com.mysql.ndbjtie.ndbapi.NdbScanOperation;
+import com.mysql.ndbjtie.ndbapi.NdbRecAttr;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.IntBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CharacterCodingException;
+
+
+class NdbjtieLoad extends TwsLoad {
+
+    // NDB settings
+    protected String mgmdConnect;
+    protected String catalog;
+    protected String schema;
+
+    // NDB JTie resources
+    protected Ndb_cluster_connection mgmd;
+    protected Ndb ndb;
+    protected NdbTransaction tx;
+    protected int ndbOpLockMode;
+
+    // NDB JTie metadata resources
+    protected TableConst table_t0;
+    protected ColumnConst column_c0;
+    protected ColumnConst column_c1;
+    protected ColumnConst column_c2;
+    protected ColumnConst column_c3;
+    protected ColumnConst column_c4;
+    protected ColumnConst column_c5;
+    protected ColumnConst column_c6;
+    protected ColumnConst column_c7;
+    protected ColumnConst column_c8;
+    protected ColumnConst column_c9;
+    protected ColumnConst column_c10;
+    protected ColumnConst column_c11;
+    protected ColumnConst column_c12;
+    protected ColumnConst column_c13;
+    protected ColumnConst column_c14;
+    protected int attr_c0;
+    protected int attr_c1;
+    protected int attr_c2;
+    protected int attr_c3;
+    protected int attr_c4;
+    protected int attr_c5;
+    protected int attr_c6;
+    protected int attr_c7;
+    protected int attr_c8;
+    protected int attr_c9;
+    protected int attr_c10;
+    protected int attr_c11;
+    protected int attr_c12;
+    protected int attr_c13;
+    protected int attr_c14;
+    protected int width_c0;
+    protected int width_c1;
+    protected int width_c2;
+    protected int width_c3;
+    protected int width_c4;
+    protected int width_c5;
+    protected int width_c6;
+    protected int width_c7;
+    protected int width_c8;
+    protected int width_c9;
+    protected int width_c10;
+    protected int width_c11;
+    protected int width_c12;
+    protected int width_c13;
+    protected int width_c14;
+    protected int width_row; // sum of {width_c0 .. width_c14}
+
+    // NDB JTie data resources
+    protected ByteBuffer bb;
+
+    // NDB JTie static resources
+    static protected final ByteOrder bo = ByteOrder.nativeOrder();
+    static protected final Charset cs;
+    static protected final CharsetEncoder csEncoder;
+    static protected final CharsetDecoder csDecoder;
+    static {
+        // default charset for mysql is "ISO-8859-1" ("US-ASCII", "UTF-8")
+        cs = Charset.forName("ISO-8859-1");
+        csDecoder = cs.newDecoder();
+        csEncoder = cs.newEncoder();
+
+        // report any unclean transcodings
+        csEncoder
+            .onMalformedInput(CodingErrorAction.REPORT)
+            .onUnmappableCharacter(CodingErrorAction.REPORT);
+        csDecoder
+            .onMalformedInput(CodingErrorAction.REPORT)
+            .onUnmappableCharacter(CodingErrorAction.REPORT);
+    }
+
+    public NdbjtieLoad(TwsDriver driver) {
+        super(driver);
+    }
+
+    // ----------------------------------------------------------------------
+    // NDB Base intializers/finalizers
+    // ----------------------------------------------------------------------
+
+    protected void initProperties() {
+        out.println();
+        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 = driver.props.getProperty("ndb.mgmdConnect", "localhost");
+        assert mgmdConnect != null;
+
+        // the database
+        catalog = driver.props.getProperty("ndb.catalog", "crunddb");
+        assert catalog != null;
+
+        // the schema
+        schema = driver.props.getProperty("ndb.schema", "def");
+        assert schema != null;
+
+        if (msg.length() == 0) {
+            out.println("      [ok]");
+        } else {
+            out.println();
+            out.print(msg.toString());
+        }
+
+        // have mgmdConnect initialized first
+        descr = "ndbjtie(" + mgmdConnect + ")";
+    }
+
+    protected void printProperties() {
+        out.println("ndb.mgmdConnect:                \"" + mgmdConnect + "\"");
+        out.println("ndb.catalog:                    \"" + catalog + "\"");
+        out.println("ndb.schema:                     \"" + schema + "\"");
+    }
+
+    public void init() throws Exception {
+        super.init();
+        assert mgmd == null;
+
+        // load native library (better diagnostics doing it explicitely)
+        Driver.loadSystemLibrary("ndbclient");
+
+        // instantiate NDB cluster singleton
+        out.print("creating cluster connection ...");
+        out.flush();
+        mgmd = Ndb_cluster_connection.create(mgmdConnect);
+        assert mgmd != null;
+        out.println(" [ok: mgmd@" + mgmdConnect + "]");
+    }
+
+    public void close() throws Exception {
+        assert mgmd != null;
+
+        out.println();
+        out.print("closing cluster connection ...");
+        out.flush();
+        Ndb_cluster_connection.delete(mgmd);
+        mgmd = null;
+        out.println("  [ok]");
+
+        super.close();
+    }
+
+    // ----------------------------------------------------------------------
+    // NDB JTie datastore operations
+    // ----------------------------------------------------------------------
+
+    public void initConnection() {
+        assert (mgmd != null);
+        assert (ndb == null);
+
+        out.println();
+        out.println("initializing ndbjtie resources ...");
+
+        // connect to cluster management node (ndb_mgmd)
+        out.print("connecting to cluster ...");
+        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 + "]");
+
+        // connect to 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 ...");
+        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: " + catalog + "." + schema + "]");
+
+        initNdbjtieModel();
+
+        initNdbjtieBuffers();
+
+        out.print("using lock mode for reads ...");
+        out.flush();
+        final String lm;
+        switch (driver.lockMode) {
+        case READ_COMMITTED:
+            ndbOpLockMode = NdbOperation.LockMode.LM_CommittedRead;
+            lm = "LM_CommittedRead";
+            break;
+        case SHARED:
+            ndbOpLockMode = NdbOperation.LockMode.LM_Read;
+            lm = "LM_Read";
+            break;
+        case EXCLUSIVE:
+            ndbOpLockMode = NdbOperation.LockMode.LM_Exclusive;
+            lm = "LM_Exclusive";
+            break;
+        default:
+            ndbOpLockMode = NdbOperation.LockMode.LM_CommittedRead;
+            lm = "LM_CommittedRead";
+            assert false;
+        }
+        out.println("   [ok: " + lm + "]");
+    }
+
+    public void closeConnection() {
+        assert (ndb != null);
+
+        out.println();
+        out.println("releasing ndbjtie resources ...");
+
+        closeNdbjtieBuffers();
+
+        closeNdbjtieModel();
+
+        out.print("closing database connection ...");
+        out.flush();
+        Ndb.delete(ndb);
+        ndb = null;
+        out.println(" [ok]");
+    }
+
+    protected void initNdbjtieModel() {
+        assert (ndb != null);
+        assert (table_t0 == null);
+        assert (column_c0 == null);
+
+        out.print("caching metadata ...");
+        out.flush();
+
+        final Dictionary dict = ndb.getDictionary();
+
+        if ((table_t0 = dict.getTable("mytable")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+
+        if ((column_c0 = table_t0.getColumn("c0")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+        if ((column_c1 = table_t0.getColumn("c1")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+        if ((column_c2 = table_t0.getColumn("c2")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+        if ((column_c3 = table_t0.getColumn("c3")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+        if ((column_c4 = table_t0.getColumn("c4")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+        if ((column_c5 = table_t0.getColumn("c5")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+        if ((column_c6 = table_t0.getColumn("c6")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+        if ((column_c7 = table_t0.getColumn("c7")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+        if ((column_c8 = table_t0.getColumn("c8")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+        if ((column_c9 = table_t0.getColumn("c9")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+        if ((column_c10 = table_t0.getColumn("c10")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+        if ((column_c11 = table_t0.getColumn("c11")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+        if ((column_c12 = table_t0.getColumn("c12")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+        if ((column_c13 = table_t0.getColumn("c13")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+        if ((column_c14 = table_t0.getColumn("c14")) == null)
+            throw new RuntimeException(toStr(dict.getNdbError()));
+
+        attr_c0 = column_c0.getColumnNo();
+        attr_c1 = column_c1.getColumnNo();
+        attr_c2 = column_c2.getColumnNo();
+        attr_c3 = column_c3.getColumnNo();
+        attr_c4 = column_c4.getColumnNo();
+        attr_c5 = column_c5.getColumnNo();
+        attr_c6 = column_c6.getColumnNo();
+        attr_c7 = column_c7.getColumnNo();
+        attr_c8 = column_c8.getColumnNo();
+        attr_c9 = column_c9.getColumnNo();
+        attr_c10 = column_c10.getColumnNo();
+        attr_c11 = column_c11.getColumnNo();
+        attr_c12 = column_c12.getColumnNo();
+        attr_c13 = column_c13.getColumnNo();
+        attr_c14 = column_c14.getColumnNo();
+
+        width_c0 = ndbjtieColumnWidth(column_c0);
+        width_c1 = ndbjtieColumnWidth(column_c1);
+        width_c2 = ndbjtieColumnWidth(column_c2);
+        width_c3 = ndbjtieColumnWidth(column_c3);
+        width_c4 = ndbjtieColumnWidth(column_c4);
+        width_c5 = ndbjtieColumnWidth(column_c5);
+        width_c6 = ndbjtieColumnWidth(column_c6);
+        width_c7 = ndbjtieColumnWidth(column_c7);
+        width_c8 = ndbjtieColumnWidth(column_c8);
+        width_c9 = ndbjtieColumnWidth(column_c9);
+        width_c10 = ndbjtieColumnWidth(column_c10);
+        width_c11 = ndbjtieColumnWidth(column_c11);
+        width_c12 = ndbjtieColumnWidth(column_c12);
+        width_c13 = ndbjtieColumnWidth(column_c13);
+        width_c14 = ndbjtieColumnWidth(column_c14);
+
+        width_row = (
+            + width_c0
+            + width_c1
+            + width_c2
+            + width_c3
+            + width_c4
+            + width_c5
+            + width_c6
+            + width_c7
+            + width_c8
+            + width_c9
+            + width_c10
+            + width_c11
+            + width_c12
+            + width_c13
+            + width_c14);
+
+        out.println("            [ok]");
+    }
+
+    protected void closeNdbjtieModel() {
+        assert (ndb != null);
+        assert (table_t0 != null);
+        assert (column_c0 != null);
+
+        out.print("clearing metadata cache...");
+        out.flush();
+
+        column_c14 = null;
+        column_c13 = null;
+        column_c12 = null;
+        column_c11 = null;
+        column_c10 = null;
+        column_c9 = null;
+        column_c8 = null;
+        column_c7 = null;
+        column_c6 = null;
+        column_c5 = null;
+        column_c4 = null;
+        column_c3 = null;
+        column_c2 = null;
+        column_c1 = null;
+        column_c0 = null;
+
+        table_t0 = null;
+
+        out.println("      [ok]");
+    }
+
+    public void initNdbjtieBuffers() {
+        assert (column_c0 != null);
+        assert (bb == null);
+
+        out.print("allocating buffers...");
+        out.flush();
+
+        bb = ByteBuffer.allocateDirect(width_row * driver.nRows);
+
+        // initial order of a byte buffer is always BIG_ENDIAN
+        bb.order(bo);
+
+        out.println("           [ok]");
+    }
+
+    protected void closeNdbjtieBuffers() {
+        assert (column_c0 != null);
+        assert (bb != null);
+
+        out.print("releasing buffers...");
+        out.flush();
+
+        bb = null;
+
+        out.println("            [ok]");
+    }
+
+    static protected String toStr(NdbErrorConst e) {
+        return "NdbError[" + e.code() + "]: " + e.message();
+    }
+
+    static protected int ndbjtieColumnWidth(ColumnConst c) {
+        int s = c.getSize(); // size of type or of base type
+        int al = c.getLength(); // length or max length, 1 for scalars
+        int at = c.getArrayType(); // size of length prefix, practically
+        return (s * al) + at;
+    }
+
+    // ----------------------------------------------------------------------
+
+    public void runOperations() {
+        out.println();
+        out.println("running NDB JTie operations ..."
+                    + " [nRows=" + driver.nRows + "]");
+
+        if (driver.doSingle) {
+            if (driver.doInsert) runNdbjtieInsert(TwsDriver.XMode.SINGLE);
+            if (driver.doLookup) runNdbjtieLookup(TwsDriver.XMode.SINGLE);
+            if (driver.doUpdate) runNdbjtieUpdate(TwsDriver.XMode.SINGLE);
+            if (driver.doDelete) runNdbjtieDelete(TwsDriver.XMode.SINGLE);
+        }
+        if (driver.doBulk) {
+            if (driver.doInsert) runNdbjtieInsert(TwsDriver.XMode.BULK);
+            if (driver.doLookup) runNdbjtieLookup(TwsDriver.XMode.BULK);
+            if (driver.doUpdate) runNdbjtieUpdate(TwsDriver.XMode.BULK);
+            if (driver.doDelete) runNdbjtieDelete(TwsDriver.XMode.BULK);
+        }
+        if (driver.doBatch) {
+            if (driver.doInsert) runNdbjtieInsert(TwsDriver.XMode.BATCH);
+            if (driver.doLookup) runNdbjtieLookup(TwsDriver.XMode.BATCH);
+            if (driver.doUpdate) runNdbjtieUpdate(TwsDriver.XMode.BATCH);
+            if (driver.doDelete) runNdbjtieDelete(TwsDriver.XMode.BATCH);
+        }
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected void runNdbjtieInsert(TwsDriver.XMode mode) {
+        final String name = "insert_" + mode.toString().toLowerCase();
+        driver.begin(name);
+
+        if (mode == TwsDriver.XMode.SINGLE) {
+            for(int i = 0; i < driver.nRows; i++) {
+                ndbjtieBeginTransaction();
+                ndbjtieInsert(i);
+                ndbjtieCommitTransaction();
+                ndbjtieCloseTransaction();
+            }
+        } else {
+            ndbjtieBeginTransaction();
+            for(int i = 0; i < driver.nRows; i++) {
+                ndbjtieInsert(i);
+
+                if (mode == TwsDriver.XMode.BULK)
+                    ndbjtieExecuteTransaction();
+            }
+            ndbjtieCommitTransaction();
+            ndbjtieCloseTransaction();
+        }
+
+        driver.finish(name);
+    }
+
+    protected void ndbjtieInsert(int c0) {
+        // get an insert operation for the table
+        NdbOperation op = tx.getNdbOperation(table_t0);
+        if (op == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        if (op.insertTuple() != 0)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+
+        // include exception handling as part of transcoding pattern
+        final int i = c0;
+        final CharBuffer str = CharBuffer.wrap(Integer.toString(i));
+        try {
+            // set values; key attribute needs to be set first
+            //str.rewind();
+            ndbjtieTranscode(bb, str);
+            if (op.equal(attr_c0, bb) != 0) // key
+                throw new RuntimeException(toStr(tx.getNdbError()));
+            bb.position(bb.position() + width_c0);
+
+            str.rewind();
+            ndbjtieTranscode(bb, str);
+            if (op.setValue(attr_c1, bb) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+            bb.position(bb.position() + width_c1);
+
+            if (op.setValue(attr_c2, i) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+
+            if (op.setValue(attr_c3, i) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+
+            // XXX
+            if (op.setValue(attr_c4, null) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+
+            str.rewind();
+            ndbjtieTranscode(bb, str);
+            if (op.setValue(attr_c5, bb) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+            bb.position(bb.position() + width_c5);
+
+            str.rewind();
+            ndbjtieTranscode(bb, str);
+            if (op.setValue(attr_c6, bb) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+            bb.position(bb.position() + width_c6);
+
+            str.rewind();
+            ndbjtieTranscode(bb, str);
+            if (op.setValue(attr_c7, bb) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+            bb.position(bb.position() + width_c7);
+
+            str.rewind();
+            ndbjtieTranscode(bb, str);
+            if (op.setValue(attr_c8, bb) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+            bb.position(bb.position() + width_c8);
+
+            // XXX
+            if (op.setValue(attr_c9, null) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+
+            if (op.setValue(attr_c10, null) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+
+            if (op.setValue(attr_c11, null) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+
+            if (op.setValue(attr_c12, null) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+
+            if (op.setValue(attr_c13, null) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+
+            if (op.setValue(attr_c14, null) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+        } catch (CharacterCodingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected void runNdbjtieLookup(TwsDriver.XMode mode) {
+        final String name = "lookup_" + mode.toString().toLowerCase();
+        driver.begin(name);
+
+        if (mode == TwsDriver.XMode.SINGLE) {
+            for(int i = 0; i < driver.nRows; i++) {
+                ndbjtieBeginTransaction();
+                ndbjtieLookup(i);
+                ndbjtieCommitTransaction();
+                ndbjtieRead(i);
+                ndbjtieCloseTransaction();
+            }
+        } else {
+            ndbjtieBeginTransaction();
+            for(int i = 0; i < driver.nRows; i++) {
+                ndbjtieLookup(i);
+
+                if (mode == TwsDriver.XMode.BULK)
+                    ndbjtieExecuteTransaction();
+            }
+            ndbjtieCommitTransaction();
+            for(int i = 0; i < driver.nRows; i++) {
+                ndbjtieRead(i);
+            }
+            ndbjtieCloseTransaction();
+        }
+
+        driver.finish(name);
+    }
+
+    protected void ndbjtieLookup(int c0) {
+        // get a lookup operation for the table
+        NdbOperation op = tx.getNdbOperation(table_t0);
+        if (op == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        if (op.readTuple(ndbOpLockMode) != 0)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+
+        int p = bb.position();
+
+        // include exception handling as part of transcoding pattern
+        final CharBuffer str = CharBuffer.wrap(Integer.toString(c0));
+        try {
+            // set values; key attribute needs to be set first
+            //str.rewind();
+            ndbjtieTranscode(bb, str);
+            if (op.equal(attr_c0, bb) != 0) // key
+                throw new RuntimeException(toStr(tx.getNdbError()));
+            bb.position(p += width_c0);
+        } catch (CharacterCodingException e) {
+            throw new RuntimeException(e);
+        }
+
+        // get attributes (not readable until after commit)
+        if (op.getValue(attr_c1, bb) == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        bb.position(p += width_c1);
+        if (op.getValue(attr_c2, bb) == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        bb.position(p += width_c2);
+        if (op.getValue(attr_c3, bb) == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        bb.position(p += width_c3);
+        if (op.getValue(attr_c4, bb) == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        bb.position(p += width_c4);
+        if (op.getValue(attr_c5, bb) == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        bb.position(p += width_c5);
+        if (op.getValue(attr_c6, bb) == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        bb.position(p += width_c6);
+        if (op.getValue(attr_c7, bb) == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        bb.position(p += width_c7);
+        if (op.getValue(attr_c8, bb) == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        bb.position(p += width_c8);
+        if (op.getValue(attr_c9, bb) == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        bb.position(p += width_c9);
+        if (op.getValue(attr_c10, bb) == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        bb.position(p += width_c10);
+        if (op.getValue(attr_c11, bb) == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        bb.position(p += width_c11);
+        if (op.getValue(attr_c12, bb) == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        bb.position(p += width_c12);
+        if (op.getValue(attr_c13, bb) == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        bb.position(p += width_c13);
+        if (op.getValue(attr_c14, bb) == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        bb.position(p += width_c14);
+    }
+
+    protected void ndbjtieRead(int c0) {
+        // include exception handling as part of transcoding pattern
+        //final int i = c0;
+        //final CharBuffer str = CharBuffer.wrap(Integer.toString(i));
+        //assert (str.position() == 0);
+
+        try {
+            int p = bb.position();
+            bb.position(p += width_c0);
+
+            // not verifying at this time
+            // (str.equals(ndbjtieTranscode(bb_c1)));
+            // (i == bb_c2.asIntBuffer().get());
+            //CharBuffer y = ndbjtieTranscode(bb);
+
+            ndbjtieTranscode(bb);
+            bb.position(p += width_c1);
+
+            bb.asIntBuffer().get();
+            bb.position(p += width_c2);
+            bb.asIntBuffer().get();
+            bb.position(p += width_c3);
+            bb.asIntBuffer().get();
+            bb.position(p += width_c4);
+
+            ndbjtieTranscode(bb);
+            bb.position(p += width_c5);
+            ndbjtieTranscode(bb);
+            bb.position(p += width_c6);
+            ndbjtieTranscode(bb);
+            bb.position(p += width_c7);
+            ndbjtieTranscode(bb);
+            bb.position(p += width_c8);
+            ndbjtieTranscode(bb);
+            bb.position(p += width_c9);
+            ndbjtieTranscode(bb);
+            bb.position(p += width_c10);
+            ndbjtieTranscode(bb);
+            bb.position(p += width_c11);
+            ndbjtieTranscode(bb);
+            bb.position(p += width_c12);
+            ndbjtieTranscode(bb);
+            bb.position(p += width_c13);
+            ndbjtieTranscode(bb);
+            bb.position(p += width_c14);
+        } catch (CharacterCodingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected void runNdbjtieUpdate(TwsDriver.XMode mode) {
+        final String name = "update_" + mode.toString().toLowerCase();
+        driver.begin(name);
+
+        if (mode == TwsDriver.XMode.SINGLE) {
+            for(int i = 0; i < driver.nRows; i++) {
+                ndbjtieBeginTransaction();
+                ndbjtieUpdate(i);
+                ndbjtieCommitTransaction();
+                ndbjtieCloseTransaction();
+            }
+        } else {
+            ndbjtieBeginTransaction();
+            for(int i = 0; i < driver.nRows; i++) {
+                ndbjtieUpdate(i);
+
+                if (mode == TwsDriver.XMode.BULK)
+                    ndbjtieExecuteTransaction();
+            }
+            ndbjtieCommitTransaction();
+            ndbjtieCloseTransaction();
+        }
+
+        driver.finish(name);
+    }
+
+    protected void ndbjtieUpdate(int c0) {
+        final CharBuffer str0 = CharBuffer.wrap(Integer.toString(c0));
+        final int r = -c0;
+        final CharBuffer str1 = CharBuffer.wrap(Integer.toString(r));
+
+        // get an update operation for the table
+        NdbOperation op = tx.getNdbOperation(table_t0);
+        if (op == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        if (op.updateTuple() != 0)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+
+        // include exception handling as part of transcoding pattern
+        try {
+            // set values; key attribute needs to be set first
+            //str0.rewind();
+            ndbjtieTranscode(bb, str0);
+            if (op.equal(attr_c0, bb) != 0) // key
+                throw new RuntimeException(toStr(tx.getNdbError()));
+            bb.position(bb.position() + width_c0);
+
+            //str1.rewind();
+            ndbjtieTranscode(bb, str1);
+            if (op.setValue(attr_c1, bb) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+            bb.position(bb.position() + width_c1);
+
+            if (op.setValue(attr_c2, r) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+
+            if (op.setValue(attr_c3, r) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+
+            str1.rewind();
+            ndbjtieTranscode(bb, str1);
+            if (op.setValue(attr_c5, bb) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+            bb.position(bb.position() + width_c5);
+
+            str1.rewind();
+            ndbjtieTranscode(bb, str1);
+            if (op.setValue(attr_c6, bb) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+            bb.position(bb.position() + width_c6);
+
+            str1.rewind();
+            ndbjtieTranscode(bb, str1);
+            if (op.setValue(attr_c7, bb) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+            bb.position(bb.position() + width_c7);
+
+            str1.rewind();
+            ndbjtieTranscode(bb, str1);
+            if (op.setValue(attr_c8, bb) != 0)
+                throw new RuntimeException(toStr(tx.getNdbError()));
+            bb.position(bb.position() + width_c8);
+        } catch (CharacterCodingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected void runNdbjtieDelete(TwsDriver.XMode mode) {
+        final String name = "delete_" + mode.toString().toLowerCase();
+        driver.begin(name);
+
+        if (mode == TwsDriver.XMode.SINGLE) {
+            for(int i = 0; i < driver.nRows; i++) {
+                ndbjtieBeginTransaction();
+                ndbjtieDelete(i);
+                ndbjtieCommitTransaction();
+                ndbjtieCloseTransaction();
+            }
+        } else {
+            ndbjtieBeginTransaction();
+            for(int i = 0; i < driver.nRows; i++) {
+                ndbjtieDelete(i);
+
+                if (mode == TwsDriver.XMode.BULK)
+                    ndbjtieExecuteTransaction();
+            }
+            ndbjtieCommitTransaction();
+            ndbjtieCloseTransaction();
+        }
+
+        driver.finish(name);
+    }
+
+    protected void ndbjtieDelete(int c0) {
+        // get a delete operation for the table
+        NdbOperation op = tx.getNdbOperation(table_t0);
+        if (op == null)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+        if (op.deleteTuple() != 0)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+
+        int p = bb.position();
+
+        // include exception handling as part of transcoding pattern
+        final int i = c0;
+        final CharBuffer str = CharBuffer.wrap(Integer.toString(c0));
+        try {
+            // set values; key attribute needs to be set first
+            //str.rewind();
+            ndbjtieTranscode(bb, str);
+            if (op.equal(attr_c0, bb) != 0) // key
+                throw new RuntimeException(toStr(tx.getNdbError()));
+            bb.position(p += width_c0);
+        } catch (CharacterCodingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected void ndbjtieBeginTransaction() {
+        assert (tx == null);
+
+        // prepare buffer for writing
+        bb.clear();
+
+        // start a transaction
+        // must be closed with NdbTransaction.close
+        final TableConst table  = null;
+        final ByteBuffer keyData = null;
+        final int keyLen = 0;
+        if ((tx = ndb.startTransaction(table, keyData, keyLen)) == null)
+            throw new RuntimeException(toStr(ndb.getNdbError()));
+    }
+
+    protected void ndbjtieExecuteTransaction() {
+        assert (tx != null);
+
+        // execute but don't commit the current transaction
+        final int execType = NdbTransaction.ExecType.NoCommit;
+        final int abortOption = NdbOperation.AbortOption.AbortOnError;
+        final int force = 0;
+        if (tx.execute(execType, abortOption, force) != 0
+            || tx.getNdbError().status() != NdbError.Status.Success)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+    }
+
+    protected void ndbjtieCommitTransaction() {
+        assert (tx != null);
+
+        // commit the current transaction
+        final int execType = NdbTransaction.ExecType.Commit;
+        final int abortOption = NdbOperation.AbortOption.AbortOnError;
+        final int force = 0;
+        if (tx.execute(execType, abortOption, force) != 0
+            || tx.getNdbError().status() != NdbError.Status.Success)
+            throw new RuntimeException(toStr(tx.getNdbError()));
+
+        // prepare buffer for reading
+        bb.rewind();
+    }
+
+    protected void ndbjtieCloseTransaction() {
+        assert (tx != null);
+
+        // close the current transaction (required after commit, rollback)
+        ndb.closeTransaction(tx);
+        tx = null;
+    }
+
+    // ----------------------------------------------------------------------
+
+    protected CharBuffer ndbjtieTranscode(ByteBuffer from)
+        throws CharacterCodingException {
+        // mark position
+        final int p = from.position();
+
+        // read 1-byte length prefix
+        final int l = from.get();
+        assert ((0 <= l) && (l < 256)); // or (l <= 256)?
+
+        // prepare buffer for reading
+        from.limit(from.position() + l);
+
+        // decode
+        final CharBuffer to = csDecoder.decode(from);
+        assert (!from.hasRemaining());
+
+        // allow for repositioning
+        from.limit(from.capacity());
+
+        assert (to.position() == 0);
+        assert (to.limit() == to.capacity());
+        return to;
+    }
+
+    protected void ndbjtieTranscode(ByteBuffer to, CharBuffer from)
+        throws CharacterCodingException {
+        // mark position
+        final int p = to.position();
+
+        // advance 1-byte length prefix
+        to.position(p + 1);
+        //to.put((byte)0);
+
+        // encode
+        final boolean endOfInput = true;
+        final CoderResult cr = csEncoder.encode(from, to, endOfInput);
+        if (!cr.isUnderflow())
+            cr.throwException();
+        assert (!from.hasRemaining());
+
+        // write 1-byte length prefix
+        final int l = (to.position() - p) - 1;
+        assert (0 <= l && l < 256); // or (l <= 256)?
+        to.put(p, (byte)l);
+
+        // reset position
+        to.position(p);
+    }
+}
\ No newline at end of file

=== renamed file 'storage/ndb/test/crund/tws/tws_java/src/TwsDriver.java' => 'storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/TwsDriver.java'
--- a/storage/ndb/test/crund/tws/tws_java/src/TwsDriver.java	2010-10-08 11:14:56 +0000
+++ b/storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/TwsDriver.java	2010-10-19 22:50:53 +0000
@@ -18,68 +18,16 @@
  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-//package com.mysql.cluster.crund.tws;
+package com.mysql.cluster.benchmark.tws;
 
-import com.mysql.clusterj.ClusterJHelper;
-import com.mysql.clusterj.SessionFactory;
-import com.mysql.clusterj.Session;
+// reusing this enum from ClusterJ
 import com.mysql.clusterj.LockMode;
-import com.mysql.clusterj.annotation.Index;
-import com.mysql.clusterj.annotation.PersistenceCapable;
-import com.mysql.clusterj.annotation.PrimaryKey;
-
-import com.mysql.ndbjtie.ndbapi.Ndb_cluster_connection;
-import com.mysql.ndbjtie.ndbapi.Ndb;
-import com.mysql.ndbjtie.ndbapi.NdbDictionary.Dictionary;
-import com.mysql.ndbjtie.ndbapi.NdbDictionary.TableConst;
-import com.mysql.ndbjtie.ndbapi.NdbDictionary.Table;
-import com.mysql.ndbjtie.ndbapi.NdbDictionary.ColumnConst;
-import com.mysql.ndbjtie.ndbapi.NdbDictionary.IndexConst;
-import com.mysql.ndbjtie.ndbapi.NdbErrorConst;
-import com.mysql.ndbjtie.ndbapi.NdbError;
-import com.mysql.ndbjtie.ndbapi.NdbTransaction;
-import com.mysql.ndbjtie.ndbapi.NdbOperation;
-import com.mysql.ndbjtie.ndbapi.NdbScanOperation;
-import com.mysql.ndbjtie.ndbapi.NdbRecAttr;
-
-import java.io.PrintWriter;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.CharBuffer;
-import java.nio.IntBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.CodingErrorAction;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CharacterCodingException;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-
-import java.util.Properties;
-import java.util.List;
-import java.util.ArrayList;
-
-public class TwsDriver
-{
-    // console
-    static protected final PrintWriter out = new PrintWriter(System.out, true);
-    static protected final PrintWriter err = new PrintWriter(System.err, true);
-
-    // command-line arguments
-    static private final List<String> propFileNames = new ArrayList<String>();
-    static protected String logFileName;
+
+
+public class TwsDriver extends Driver {
 
     // benchmark settings
-    protected final Properties props = new Properties();
+    protected boolean renewConnection;
     protected boolean doJdbc;
     protected boolean doClusterj;
     protected boolean doNdbjtie;
@@ -94,204 +42,74 @@ public class TwsDriver
     protected int nRows;
     protected int nRuns;
 
-    // JDBC resources
-    protected Connection connection;
-    protected PreparedStatement ins0;
-    protected PreparedStatement sel0;
-    protected PreparedStatement upd0;
-    protected PreparedStatement del0;
-
-    // ClusterJ resources
-    protected SessionFactory sessionFactory;
-    protected Session session;
-
-    // NDB JTie resources
-    protected Ndb_cluster_connection mgmd;
-    protected Ndb ndb;
-    protected NdbTransaction tx;
-    protected int ndbOpLockMode;
-
-    // NDB JTie metadata resources
-    protected TableConst table_t0;
-    protected ColumnConst column_c0;
-    protected ColumnConst column_c1;
-    protected ColumnConst column_c2;
-    protected ColumnConst column_c3;
-    protected ColumnConst column_c4;
-    protected ColumnConst column_c5;
-    protected ColumnConst column_c6;
-    protected ColumnConst column_c7;
-    protected ColumnConst column_c8;
-    protected ColumnConst column_c9;
-    protected ColumnConst column_c10;
-    protected ColumnConst column_c11;
-    protected ColumnConst column_c12;
-    protected ColumnConst column_c13;
-    protected ColumnConst column_c14;
-    protected int attr_c0;
-    protected int attr_c1;
-    protected int attr_c2;
-    protected int attr_c3;
-    protected int attr_c4;
-    protected int attr_c5;
-    protected int attr_c6;
-    protected int attr_c7;
-    protected int attr_c8;
-    protected int attr_c9;
-    protected int attr_c10;
-    protected int attr_c11;
-    protected int attr_c12;
-    protected int attr_c13;
-    protected int attr_c14;
-    protected int width_c0;
-    protected int width_c1;
-    protected int width_c2;
-    protected int width_c3;
-    protected int width_c4;
-    protected int width_c5;
-    protected int width_c6;
-    protected int width_c7;
-    protected int width_c8;
-    protected int width_c9;
-    protected int width_c10;
-    protected int width_c11;
-    protected int width_c12;
-    protected int width_c13;
-    protected int width_c14;
-    protected int width_row; // sum of {width_c0 .. width_c14}
-
-    // NDB JTie data resources
-    protected ByteBuffer bb;
-
-    // NDB JTie static resources
-    static protected final ByteOrder bo = ByteOrder.nativeOrder();
-    static protected final Charset cs;
-    static protected final CharsetEncoder csEncoder;
-    static protected final CharsetDecoder csDecoder;
-    static {
-        // default charset for mysql is "ISO-8859-1" ("US-ASCII", "UTF-8")
-        cs = Charset.forName("ISO-8859-1");
-        csDecoder = cs.newDecoder();
-        csEncoder = cs.newEncoder();
-
-        // report any unclean transcodings
-        csEncoder
-            .onMalformedInput(CodingErrorAction.REPORT)
-            .onUnmappableCharacter(CodingErrorAction.REPORT);
-        csDecoder
-            .onMalformedInput(CodingErrorAction.REPORT)
-            .onUnmappableCharacter(CodingErrorAction.REPORT);
-    }
+    // benchmark resources
+    protected TwsLoad jdbcLoad;
+    protected TwsLoad clusterjLoad;
+    protected TwsLoad ndbjtieLoad;
 
-    static public void main(String[] args) throws SQLException, IOException {
+    static public void main(String[] args) throws Exception {
         parseArguments(args);
         TwsDriver main = new TwsDriver();
         main.run();
     }
 
-    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();
-    }
-
+    // ----------------------------------------------------------------------
+    // benchmark intializers/finalizers
     // ----------------------------------------------------------------------
 
-    protected void init() throws IOException, SQLException {
-        loadProperties();
-        initProperties();
-        printProperties();
-        // 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();
+    protected void init() throws Exception {
+        super.init();
 
-        // XXX close log buffers
-        //header = null;
-        //rtimes = null;
-        //musage = null;
+        if (doJdbc) {
+            assert (jdbcLoad == null);
+            jdbcLoad = new JdbcLoad(this);
+            jdbcLoad.init();
+        }
+        if (doClusterj) {
+            assert (clusterjLoad == null);
+            clusterjLoad = new ClusterjLoad(this);
+            clusterjLoad.init();
+        }
+        if (doNdbjtie) {
+            assert (ndbjtieLoad == null);
+            ndbjtieLoad = new NdbjtieLoad(this);
+            ndbjtieLoad.init();
+        }
 
-        // XXX closeLogFile();
+        initConnections();
     }
 
-    // ----------------------------------------------------------------------
+    protected void close() throws Exception {
+        closeConnections();
 
-    // loads the benchmark's properties from properties files
-    private void loadProperties() throws IOException {
-        out.println();
-        for (String fn : propFileNames) {
-            out.println("reading properties file:        " + fn);
-            InputStream is = null;
-            try {
-                is = new FileInputStream(fn);
-                props.load(is);
-            } finally {
-                if (is != null)
-                    is.close();
-            }
+        if (doJdbc) {
+            assert (jdbcLoad != null);
+            jdbcLoad.close();
+            jdbcLoad = null;
         }
+        if (doClusterj) {
+            assert (clusterjLoad != null);
+            clusterjLoad.close();
+            clusterjLoad = null;
+        }
+        if (doNdbjtie) {
+            assert (ndbjtieLoad != null);
+            ndbjtieLoad.close();
+            ndbjtieLoad = null;
+        }
+
+        super.close();
     }
 
-    // initializes the benchmark properties
     protected void initProperties() {
-        //props.list(out);
-        out.print("setting driver properties ...");
-        out.flush();
+        super.initProperties();
+
+        out.print("setting tws properties ...");
 
-        out.print("initializing properties ...");
-        final StringBuilder msg = new StringBuilder();        
+        final StringBuilder msg = new StringBuilder();
         final String eol = System.getProperty("line.separator");
 
+        renewConnection = parseBoolean("renewConnection", false);
         doJdbc = parseBoolean("doJdbc", false);
         doClusterj = parseBoolean("doClusterj", false);
         doNdbjtie = parseBoolean("doNdbjtie", false);
@@ -320,24 +138,24 @@ public class TwsDriver
         }
 
         nRuns = parseInt("nRuns", 1);
-        if (nRuns < 1) {
-            msg.append("[ignored] nRuns:            '"
-                       + props.getProperty("nRuns") + "'" + eol);
+        if (nRuns < 0) {
+            msg.append("[ignored] nRuns:                " + nRuns + eol);
             nRuns = 1;
         }
 
         if (msg.length() == 0) {
-            out.println("     [ok]");
+            out.println("      [ok]");
         } else {
             out.println();
             out.print(msg.toString());
         }
     }
-    
-    // prints the benchmark's properties
+
     protected void printProperties() {
+        super.printProperties();
         out.println();
-        out.println("driver settings ...");
+        out.println("tws settings ...");
+        out.println("renewConnection:                " + renewConnection);
         out.println("doJdbc:                         " + doJdbc);
         out.println("doClusterj:                     " + doClusterj);
         out.println("doNdbjtie:                      " + doNdbjtie);
@@ -353,1513 +171,134 @@ public class TwsDriver
         out.println("nRuns:                          " + nRuns);
     }
 
-    protected boolean parseBoolean(String k, boolean vdefault) {
-        final String v = props.getProperty(k);
-        return (v == null ? vdefault : Boolean.parseBoolean(v));
-    }
-
-    protected int parseInt(String k, int vdefault) {
-        final String v = props.getProperty(k);
-        try {
-            return (v == null ? vdefault : Integer.parseInt(v));
-        } catch (NumberFormatException e) {
-            final NumberFormatException nfe = new NumberFormatException(
-                "invalid value of benchmark property ('" + k + "', '"
-                + v + "').");
-            nfe.initCause(e);
-            throw nfe;
-        }
-    }
-
     // ----------------------------------------------------------------------
-
-    protected void initJdbcConnection() throws SQLException {
-        assert (connection == null);
-
-        out.println();
-        out.println("initializing jdbc resources ...");
-
-        // load the JDBC driver class
-        out.print("loading jdbc driver ...");
-        out.flush();
-        final String driver
-            = props.getProperty("jdbc.driver", "com.mysql.jdbc.Driver");
-        final Class cls;
-        try {
-            cls = Class.forName(driver);
-        } catch (ClassNotFoundException e) {
-            out.println("Cannot load JDBC driver '" + driver
-                        + "' from classpath '"
-                        + System.getProperty("java.class.path") + "'");
-            throw new RuntimeException(e);
-        }
-        out.println("         [ok: " + cls.getName() + "]");
-
-        // create a connection to the database
-        out.print("starting jdbc connection ...");
-        out.flush();
-        final String url
-            = props.getProperty("jdbc.url",
-                                "jdbc:mysql://localhost/testdb");
-        final String username
-            = props.getProperty("jdbc.user", "root");
-        final String password
-            = props.getProperty("jdbc.password", "");
-        try {
-            connection = DriverManager.getConnection(url, username, password);
-        } catch (SQLException e) {
-            out.println("Cannot connect to database '" + url + "'");
-            throw new RuntimeException(e);
-        }
-        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: ");
-        switch (connection.getTransactionIsolation()) {
-        case Connection.TRANSACTION_READ_UNCOMMITTED:
-            out.print("READ_UNCOMMITTED");
-            break;
-        case Connection.TRANSACTION_READ_COMMITTED:
-            out.print("READ_COMMITTED");
-            break;
-        case Connection.TRANSACTION_REPEATABLE_READ:
-            out.print("REPEATABLE_READ");
-            break;
-        case Connection.TRANSACTION_SERIALIZABLE:
-            out.print("SERIALIZABLE");
-            break;
-        default:
-            assert false;
-        }
-        out.println("]");
-        
-        initJdbcPreparedStatements();
-    }
-
-    protected void closeJdbcConnection() throws SQLException {
-        assert (connection != null);
-
-        out.println();
-        out.println("releasing jdbc resources ...");
-
-        closeJdbcPreparedStatements();
-
-        out.print("closing jdbc connection ...");
-        out.flush();
-        connection.close();
-        connection = null;
-        out.println("     [ok]");
-    }
-
-    protected void initJdbcPreparedStatements() throws SQLException {
-        assert (connection != null);
-        assert (ins0 == null);
-        assert (sel0 == null);
-        assert (upd0 == null);
-        assert (del0 == null);
-
-        out.print("using lock mode for reads ...");
-        out.flush();
-        final String lm;
-        switch (lockMode) {
-        case READ_COMMITTED:
-            lm = "";
-            break;
-        case SHARED:
-            lm = " LOCK IN share mode";
-            break;
-        case EXCLUSIVE:
-            lm = " FOR UPDATE";
-            break;
-        default:
-            lm = "";
-            assert false;
-        }
-        out.println("   [ok: " + "SELECT" + lm + ";]");
-
-        out.print("compiling jdbc statements ...");
-        out.flush();
-
-        final String sqlIns0 = "INSERT INTO mytable (c0, c1, c2, c3, c5, c6, c7, c8) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
-        ins0 = connection.prepareStatement(sqlIns0);
-
-        final String sqlSel0 = ("SELECT * FROM mytable where c0=?" + lm);
-        sel0 = connection.prepareStatement(sqlSel0);
-
-        final String sqlUpd0 = "UPDATE mytable SET c1 = ?, c2 = ?, c3 = ?, c5 = ?, c6 = ?, c7 = ?, c8 = ? WHERE c0=?";
-        upd0 = connection.prepareStatement(sqlUpd0);
-
-        final String sqlDel0 = "DELETE FROM mytable WHERE c0=?";
-        del0 = connection.prepareStatement(sqlDel0);
-
-        out.println("   [ok]");
-    }
-
-    protected void closeJdbcPreparedStatements() throws SQLException {
-        assert (ins0 != null);
-        assert (sel0 != null);
-        assert (upd0 != null);
-        assert (del0 != null);
-
-        out.print("closing jdbc statements ...");
-        out.flush();
-
-        ins0.close();
-        ins0 = null;
-
-        sel0.close();
-        sel0 = null;
-
-        upd0.close();
-        upd0 = null;
-
-        del0.close();
-        del0 = null;
-
-        out.println("     [ok]");
-    }
-
+    // benchmark operations
     // ----------------------------------------------------------------------
 
-    protected void initClusterjConnection() {
-        assert (sessionFactory == null);
-        assert (session == null);
+    protected void runTests() throws Exception {
+        //initConnection();
 
-        out.println();
-        out.println("initializing clusterj resources ...");
+        //assert(rStart <= rEnd && rScale > 1);
+        //for (int i = rStart; i <= rEnd; i *= rScale)
+        runLoads();
 
-        out.print("starting clusterj session ...");
-        out.flush();
-        sessionFactory = ClusterJHelper.getSessionFactory(props);
-        session = sessionFactory.getSession();
-        out.println("   [ok]");
-
-        out.print("setting session lock mode ...");
-        session.setLockMode(lockMode);
-        out.println("   [ok: " + lockMode + "]");
+        //closeConnection();
     }
 
-    protected void closeClusterjConnection() {
-        assert (session != null);
-        assert (sessionFactory != null);
-
-        out.println();
-        out.println("releasing clusterj resources ...");
-
-        out.print("closing clusterj session ...");
-        out.flush();
-        session.close();
-        session = null;
-        sessionFactory.close();
-        sessionFactory = null;
-        out.println("    [ok]");
-    }
-
-    // ----------------------------------------------------------------------
-
-    protected void initNdbjtieConnection() {
-        assert (mgmd == null);
-        assert (ndb == null);
-
-        out.println();
-        out.println("initializing ndbjtie resources ...");
-
-        // load native library (better diagnostics doing it explicitely)
-        loadSystemLibrary("ndbclient");
-
-        // read connection properties
-        final String mgmdConnect
-            = props.getProperty("com.mysql.clusterj.connectstring",
-                                "localhost:1186");
-        final String catalog
-            = props.getProperty("com.mysql.clusterj.database",
-                                "testdb");
-        final String schema
-            = "def";
-        assert (mgmdConnect != null);
-        assert (catalog != null);
-        assert (schema != null);
-
-        // instantiate NDB cluster singleton
-        out.print("creating cluster connection ...");
-        out.flush();
-        mgmd = Ndb_cluster_connection.create(mgmdConnect);
-        assert mgmd != null;
-        out.println(" [ok]");
-
-        // connect to cluster management node (ndb_mgmd)
-        out.print("connecting to cluster ...");
-        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 + "]");
-
-        // connect to 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 ...");
-        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: " + catalog + "." + schema + "]");
-
-        initNdbjtieModel();
-
-        initNdbjtieBuffers();
-
-        out.print("using lock mode for reads ...");
-        out.flush();
-        final String lm;
-        switch (lockMode) {
-        case READ_COMMITTED:
-            ndbOpLockMode = NdbOperation.LockMode.LM_CommittedRead;
-            lm = "LM_CommittedRead";
-            break;
-        case SHARED:
-            ndbOpLockMode = NdbOperation.LockMode.LM_Read;
-            lm = "LM_Read";
-            break;
-        case EXCLUSIVE:
-            ndbOpLockMode = NdbOperation.LockMode.LM_Exclusive;
-            lm = "LM_Exclusive";
-            break;
-        default:
-            ndbOpLockMode = NdbOperation.LockMode.LM_CommittedRead;
-            lm = "LM_CommittedRead";
-            assert false;
-        }
-        out.println("   [ok: " + lm + "]");
+    protected void runLoads() throws Exception {
+        if (doJdbc)
+            runSeries(jdbcLoad);
+        if (doClusterj)
+            runSeries(clusterjLoad);
+        if (doNdbjtie)
+            runSeries(ndbjtieLoad);
     }
 
-    protected void closeNdbjtieConnection() {
-        assert (mgmd != null);
-        assert (ndb != null);
+    protected void runSeries(TwsLoad load) throws Exception {
+        if (nRuns == 0)
+            return; // nothing to do
 
         out.println();
-        out.println("releasing ndbjtie resources ...");
-
-        closeNdbjtieBuffers();
-
-        closeNdbjtieModel();
-
-        out.print("closing database connection ...");
-        out.flush();
-        Ndb.delete(ndb);
-        ndb = null;
-        out.println(" [ok]");
-
-        out.print("closing cluster connection ...");
-        out.flush();
-        Ndb_cluster_connection.delete(mgmd);
-        mgmd = null;
-        out.println("  [ok]");
-    }
-
-    protected void initNdbjtieModel() {
-        assert (ndb != null);
-        assert (table_t0 == null);
-        assert (column_c0 == null);
-
-        out.print("caching metadata ...");
-        out.flush();
-
-        final Dictionary dict = ndb.getDictionary();
-
-        if ((table_t0 = dict.getTable("mytable")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-
-        if ((column_c0 = table_t0.getColumn("c0")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-        if ((column_c1 = table_t0.getColumn("c1")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-        if ((column_c2 = table_t0.getColumn("c2")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-        if ((column_c3 = table_t0.getColumn("c3")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-        if ((column_c4 = table_t0.getColumn("c4")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-        if ((column_c5 = table_t0.getColumn("c5")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-        if ((column_c6 = table_t0.getColumn("c6")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-        if ((column_c7 = table_t0.getColumn("c7")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-        if ((column_c8 = table_t0.getColumn("c8")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-        if ((column_c9 = table_t0.getColumn("c9")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-        if ((column_c10 = table_t0.getColumn("c10")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-        if ((column_c11 = table_t0.getColumn("c11")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-        if ((column_c12 = table_t0.getColumn("c12")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-        if ((column_c13 = table_t0.getColumn("c13")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-        if ((column_c14 = table_t0.getColumn("c14")) == null)
-            throw new RuntimeException(toStr(dict.getNdbError()));
-
-        attr_c0 = column_c0.getColumnNo();
-        attr_c1 = column_c1.getColumnNo();
-        attr_c2 = column_c2.getColumnNo();
-        attr_c3 = column_c3.getColumnNo();
-        attr_c4 = column_c4.getColumnNo();
-        attr_c5 = column_c5.getColumnNo();
-        attr_c6 = column_c6.getColumnNo();
-        attr_c7 = column_c7.getColumnNo();
-        attr_c8 = column_c8.getColumnNo();
-        attr_c9 = column_c9.getColumnNo();
-        attr_c10 = column_c10.getColumnNo();
-        attr_c11 = column_c11.getColumnNo();
-        attr_c12 = column_c12.getColumnNo();
-        attr_c13 = column_c13.getColumnNo();
-        attr_c14 = column_c14.getColumnNo();
-
-        width_c0 = ndbjtieColumnWidth(column_c0);
-        width_c1 = ndbjtieColumnWidth(column_c1);
-        width_c2 = ndbjtieColumnWidth(column_c2);
-        width_c3 = ndbjtieColumnWidth(column_c3);
-        width_c4 = ndbjtieColumnWidth(column_c4);
-        width_c5 = ndbjtieColumnWidth(column_c5);
-        width_c6 = ndbjtieColumnWidth(column_c6);
-        width_c7 = ndbjtieColumnWidth(column_c7);
-        width_c8 = ndbjtieColumnWidth(column_c8);
-        width_c9 = ndbjtieColumnWidth(column_c9);
-        width_c10 = ndbjtieColumnWidth(column_c10);
-        width_c11 = ndbjtieColumnWidth(column_c11);
-        width_c12 = ndbjtieColumnWidth(column_c12);
-        width_c13 = ndbjtieColumnWidth(column_c13);
-        width_c14 = ndbjtieColumnWidth(column_c14);
-
-        width_row = (
-            + width_c0
-            + width_c1
-            + width_c2
-            + width_c3
-            + width_c4
-            + width_c5
-            + width_c6
-            + width_c7
-            + width_c8
-            + width_c9
-            + width_c10
-            + width_c11
-            + width_c12
-            + width_c13
-            + width_c14);
-
-        out.println("            [ok]");
-    }
-
-    protected void closeNdbjtieModel() {
-        assert (ndb != null);
-        assert (table_t0 != null);
-        assert (column_c0 != null);
-
-        out.print("clearing metadata cache...");
-        out.flush();
-
-        column_c14 = null;
-        column_c13 = null;
-        column_c12 = null;
-        column_c11 = null;
-        column_c10 = null;
-        column_c9 = null;
-        column_c8 = null;
-        column_c7 = null;
-        column_c6 = null;
-        column_c5 = null;
-        column_c4 = null;
-        column_c3 = null;
-        column_c2 = null;
-        column_c1 = null;
-        column_c0 = null;
-
-        table_t0 = null;
-
-        out.println("      [ok]");
-    }
-
-    protected void initNdbjtieBuffers() {
-        assert (column_c0 != null);
-        assert (bb == null);
-
-        out.print("allocating buffers...");
-        out.flush();
-
-        bb = ByteBuffer.allocateDirect(width_row * nRows);
-
-        // initial order of a byte buffer is always BIG_ENDIAN
-        bb.order(bo);
-
-        out.println("           [ok]");
-    }
-
-    protected void closeNdbjtieBuffers() {
-        assert (column_c0 != null);
-        assert (bb != null);
-
-        out.print("releasing buffers...");
-        out.flush();
-
-        bb = null;
-
-        out.println("            [ok]");
-    }
-
-    static protected void loadSystemLibrary(String name) {
-        out.print("loading native 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("       [ok: " + name + "]");
-    }
-
-    static protected String toStr(NdbErrorConst e) {
-        return "NdbError[" + e.code() + "]: " + e.message();
-    }
-
-    static protected int ndbjtieColumnWidth(ColumnConst c) {
-        int s = c.getSize(); // size of type or of base type
-        int al = c.getLength(); // length or max length, 1 for scalars
-        int at = c.getArrayType(); // size of length prefix, practically
-        return (s * al) + at;
-    }
-
-    // ----------------------------------------------------------------------
-
-    enum XMode { SINGLE, BULK, BATCH }
+        out.println("------------------------------------------------------------");
+        out.print("running " + nRuns + " iterations on load: "
+                  + load.getDescriptor());
 
-    protected void runTests() throws SQLException {
         for (int i = 0; i < nRuns; i++) {
             out.println();
             out.println("------------------------------------------------------------");
-
-            // XXX log buffers
-
-            if (doJdbc) runJdbcOperations();
-            if (doClusterj) runClusterjOperations();
-            if (doNdbjtie) runNdbjtieOperations();
-
-            // XXX log buffers
+            runOperations(load);
         }
 
-        out.println();
-        out.println("------------------------------------------------------------");
+        writeLogBuffers(load.getDescriptor());
+        clearLogBuffers();
     }
+    
+    enum XMode { SINGLE, BULK, BATCH }
 
-    protected void runJdbcOperations() throws SQLException {
-        out.println();
-        out.println("running JDBC operations ..."
-                    + "     [nRows=" + nRows + "]");
+    protected void runOperations(TwsLoad load) throws Exception {
+        //out.println("running 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);
+        // log buffers
+        if (logRealTime) {
+            rtimes.append("nRows=" + nRows);
+            ta = 0;
         }
-        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 (logMemUsage) {
+            musage.append("nRows=" + nRows);
+            ma = 0;
         }
-    }
-
-    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);
+        // pre-run cleanup
+        if (renewConnection) {
+            load.closeConnection();
+            load.initConnection();
         }
-    }
+        //clearData(); // not used
 
-    protected void runNdbjtieOperations() {
-        out.println();
-        out.println("running NDB JTie operations ..."
-                    + " [nRows=" + nRows + "]");
+        load.runOperations();
 
-        if (doSingle) {
-            out.println();
-            if (doInsert) runNdbjtieInsert(XMode.SINGLE);
-            if (doLookup) runNdbjtieLookup(XMode.SINGLE);
-            if (doUpdate) runNdbjtieUpdate(XMode.SINGLE);
-            if (doDelete) runNdbjtieDelete(XMode.SINGLE);
+        out.println();
+        out.println("total");
+        if (logRealTime) {
+            out.println("tx real time                    " + ta
+                        + "\tms");
         }
-        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 (logMemUsage) {
+            out.println("net mem usage                   "
+                        + (ma >= 0 ? "+" : "") + ma
+                        + "\tKiB");
         }
-        if (doBatch) {
-            out.println();
-            if (doInsert) runNdbjtieInsert(XMode.BATCH);
-            if (doLookup) runNdbjtieLookup(XMode.BATCH);
-            if (doUpdate) runNdbjtieUpdate(XMode.BATCH);
-            if (doDelete) runNdbjtieDelete(XMode.BATCH);
-        }
-    }
-
-    // ----------------------------------------------------------------------
 
-    protected void runJdbcInsert(XMode mode) throws SQLException {
-        final String m = mode.toString().toLowerCase();
-        //out.println("insert " + nRows + " rows by JDBC " + m + " tx ...");
-
-        long time = -System.currentTimeMillis();
-        connection.setAutoCommit(mode == XMode.SINGLE);
-        for(int i = 0; i < nRows; i++) {
-            jdbcInsert(i, mode);
-        }
-        if (mode == XMode.BATCH)
-            ins0.executeBatch();
-        if (mode != XMode.SINGLE)
-            connection.commit();
-        time += System.currentTimeMillis();
-
-        out.println("jdbc_insert_" + m + "    \t: " + time + "\tms");
-    }
-
-    protected void runClusterjInsert(XMode mode) {
-        final String m = mode.toString().toLowerCase();
-        //out.println("insert " + nRows + " rows by ClusterJ " + m + " tx ...");
-
-        long time = -System.currentTimeMillis();
-        if (mode != XMode.SINGLE)
-            session.currentTransaction().begin();
-        for(int i = 0; i < nRows; i++) {
-            clusterjInsert(i);
-        }
-        if (mode != XMode.SINGLE)
-            session.currentTransaction().commit();
-        time += System.currentTimeMillis();
-
-        out.println("clusterj_insert_" + m + "  \t: " + time + "\tms");
-    }
-
-    protected void runNdbjtieInsert(XMode mode) {
-        final String m = mode.toString().toLowerCase();
-        //out.println("insert " + nRows + " rows by NDB JTie " + m + " tx ...");
-
-        long time = -System.currentTimeMillis();
-        if (mode == XMode.SINGLE) {
-            for(int i = 0; i < nRows; i++) {
-                ndbjtieBeginTransaction();
-                ndbjtieInsert(i);
-                ndbjtieCommitTransaction();
-                ndbjtieCloseTransaction();
-            }
-        } else {
-            ndbjtieBeginTransaction();
-            for(int i = 0; i < nRows; i++) {
-                ndbjtieInsert(i);
-
-                if (mode == XMode.BULK)
-                    ndbjtieExecuteTransaction();
-            }
-            ndbjtieCommitTransaction();
-            ndbjtieCloseTransaction();
+        // log buffers
+        if (logHeader) {
+            header.append("\ttotal");
+            logHeader = false;
         }
-        time += System.currentTimeMillis();
-
-        out.println("ndbjtie_insert_" + m + "  \t: " + time + "\tms");
-    }
-
-    protected void jdbcInsert(int c0, XMode mode) {
-        // include exception handling as part of jdbc pattern
-        try {
-            final int i = c0;
-            final String str = Integer.toString(i);
-            ins0.setString(1, str); // key
-            ins0.setString(2, str);
-            ins0.setInt(3, i);
-            ins0.setInt(4, i);
-            ins0.setString(5, str);
-            ins0.setString(6, str);
-            ins0.setString(7, str);
-            ins0.setString(8, str);
-            if (mode == XMode.BATCH) {
-                ins0.addBatch();
-            } else {
-                int cnt = ins0.executeUpdate();
-                assert (cnt == 1);
-            }
-        } catch (SQLException e) {
-            throw new RuntimeException(e);
+        if (logRealTime) {
+            rtimes.append("\t" + ta);
+            rtimes.append(endl);
         }
-    }
-
-    protected void clusterjInsert(int c0) {
-        final CJSubscriber o = session.newInstance(CJSubscriber.class);
-        final int i = c0;
-        final String str = Integer.toString(i);
-        //final String oneChar = Integer.toString(1);
-        o.setC0(str);
-        o.setC1(str);
-        o.setC2(i);
-        o.setC3(i);
-        //o.setC4(i);
-        o.setC5(str);
-        o.setC6(str);
-        o.setC7(str);
-        o.setC8(str);
-        //o.setC9(oneChar);
-        //o.setC10(oneChar);
-        //o.setC11(str);
-        //o.setC12(str);
-        //o.setC13(oneChar);
-        //o.setC14(str);
-        session.persist(o);
-    }
-
-    protected void ndbjtieInsert(int c0) {
-        // get an insert operation for the table
-        NdbOperation op = tx.getNdbOperation(table_t0);
-        if (op == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        if (op.insertTuple() != 0)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-
-        // include exception handling as part of transcoding pattern
-        final int i = c0;
-        final CharBuffer str = CharBuffer.wrap(Integer.toString(i));
-        try {
-            // set values; key attribute needs to be set first
-            //str.rewind();
-            ndbjtieTranscode(bb, str);
-            if (op.equal(attr_c0, bb) != 0) // key
-                throw new RuntimeException(toStr(tx.getNdbError()));
-            bb.position(bb.position() + width_c0);
-
-            str.rewind();
-            ndbjtieTranscode(bb, str);
-            if (op.setValue(attr_c1, bb) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-            bb.position(bb.position() + width_c1);
-
-            if (op.setValue(attr_c2, i) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-
-            if (op.setValue(attr_c3, i) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-
-            // XXX
-            if (op.setValue(attr_c4, null) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-
-            str.rewind();
-            ndbjtieTranscode(bb, str);
-            if (op.setValue(attr_c5, bb) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-            bb.position(bb.position() + width_c5);
-
-            str.rewind();
-            ndbjtieTranscode(bb, str);
-            if (op.setValue(attr_c6, bb) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-            bb.position(bb.position() + width_c6);
-
-            str.rewind();
-            ndbjtieTranscode(bb, str);
-            if (op.setValue(attr_c7, bb) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-            bb.position(bb.position() + width_c7);
-
-            str.rewind();
-            ndbjtieTranscode(bb, str);
-            if (op.setValue(attr_c8, bb) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-            bb.position(bb.position() + width_c8);
-
-            // XXX
-            if (op.setValue(attr_c9, null) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-
-            if (op.setValue(attr_c10, null) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-
-            if (op.setValue(attr_c11, null) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-
-            if (op.setValue(attr_c12, null) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-
-            if (op.setValue(attr_c13, null) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-
-            if (op.setValue(attr_c14, null) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-        } catch (CharacterCodingException e) {
-            throw new RuntimeException(e);
+        if (logMemUsage) {
+            musage.append("\t" + ma);
+            musage.append(endl);
         }
     }
 
     // ----------------------------------------------------------------------
-
-    protected void runJdbcLookup(XMode mode) throws SQLException {
-        final String m = mode.toString().toLowerCase();
-        //out.println("lookup " + nRows + " rows by JDBC " + m + " tx ...");
-
-        if(mode == XMode.BATCH) {
-            out.println("jdbc_lookup_" + m + "    \t: " + 0 + " n/a");
-            return;
-        }
-        
-        long time = -System.currentTimeMillis();
-        connection.setAutoCommit(mode == XMode.SINGLE);
-        for(int i = 0; i < nRows; i++) {
-            jdbcLookup(i);
-        }
-        if (mode != XMode.SINGLE)
-            connection.commit();
-        time += System.currentTimeMillis();
-
-        out.println("jdbc_lookup_" + m + "    \t: " + time + "\tms");
-    }
-
-    protected void runClusterjLookup(XMode mode) {
-        final String m = mode.toString().toLowerCase();
-        //out.println("lookup " + nRows + " rows by ClusterJ " + m + " tx ...");
-
-        long time = -System.currentTimeMillis();
-        if (mode != XMode.SINGLE)
-            session.currentTransaction().begin();
-        for(int i = 0; i < nRows; i++) {
-            clusterjLookup(i);
-        }
-        if (mode != XMode.SINGLE)
-            session.currentTransaction().commit();
-        time += System.currentTimeMillis();
-
-        out.println("clusterj_lookup_" + m + "  \t: " + time + "\tms");
-    }
-
-    protected void runNdbjtieLookup(XMode mode) {
-        final String m = mode.toString().toLowerCase();
-        //out.println("lookup " + nRows + " rows by NDB JTie " + m + " tx ...");
-
-        long time = -System.currentTimeMillis();
-        if (mode == XMode.SINGLE) {
-            for(int i = 0; i < nRows; i++) {
-                ndbjtieBeginTransaction();
-                ndbjtieLookup(i);
-                ndbjtieCommitTransaction();
-                ndbjtieRead(i);
-                ndbjtieCloseTransaction();
-            }
-        } else {
-            ndbjtieBeginTransaction();
-            for(int i = 0; i < nRows; i++) {
-                ndbjtieLookup(i);
-
-                if (mode == XMode.BULK)
-                    ndbjtieExecuteTransaction();
-            }
-            ndbjtieCommitTransaction();
-            for(int i = 0; i < nRows; i++) {
-                ndbjtieRead(i);
-            }
-            ndbjtieCloseTransaction();
-        }
-        time += System.currentTimeMillis();
-
-        out.println("ndbjtie_lookup_" + m + "  \t: " + time + "\tms");
-    }
-
-    protected void jdbcLookup(int c0) {
-        // include exception handling as part of jdbc pattern
-        try {
-            sel0.setString(1, Integer.toString(c0)); // key
-            ResultSet resultSet = sel0.executeQuery();
-
-            if (resultSet.next()) {
-                // not verifying at this time
-                String ac0 = resultSet.getString(1);
-                String c1 = resultSet.getString(2);
-                int c2 = resultSet.getInt(3);
-                int c3 = resultSet.getInt(4);
-                int c4 = resultSet.getInt(5);
-                String c5 = resultSet.getString(6);
-                String c6 = resultSet.getString(7);
-                String c7 = resultSet.getString(8);
-                String c8 = resultSet.getString(9);
-                String c9 = resultSet.getString(10);
-                String c10 = resultSet.getString(11);
-                String c11 = resultSet.getString(12);
-                String c12 = resultSet.getString(13);
-                String c13 = resultSet.getString(14);
-                String c14 = resultSet.getString(15);
-            }
-            assert (!resultSet.next());
-
-            resultSet.close();
-        } catch (SQLException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    protected void clusterjLookup(int c0) {
-        final CJSubscriber o
-            = session.find(CJSubscriber.class, Integer.toString(c0));
-        if (o != null) {
-            // not verifying at this time
-            String ac0 = o.getC0();
-            String c1 = o.getC1();
-            int c2 = o.getC2();
-            int c3 = o.getC3();
-            int c4 = o.getC4();
-            String c5 = o.getC5();
-            String c6 = o.getC6();
-            String c7 = o.getC7();
-            String c8 = o.getC8();
-            String c9 = o.getC9();
-            String c10 = o.getC10();
-            String c11 = o.getC11();
-            String c12 = o.getC12();
-            String c13 = o.getC13();
-            String c14 = o.getC14();
-        }
-    }
-
-    protected void ndbjtieLookup(int c0) {
-        // get a lookup operation for the table
-        NdbOperation op = tx.getNdbOperation(table_t0);
-        if (op == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        if (op.readTuple(ndbOpLockMode) != 0)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-
-        int p = bb.position();
-
-        // include exception handling as part of transcoding pattern
-        final CharBuffer str = CharBuffer.wrap(Integer.toString(c0));
-        try {
-            // set values; key attribute needs to be set first
-            //str.rewind();
-            ndbjtieTranscode(bb, str);
-            if (op.equal(attr_c0, bb) != 0) // key
-                throw new RuntimeException(toStr(tx.getNdbError()));
-            bb.position(p += width_c0);
-        } catch (CharacterCodingException e) {
-            throw new RuntimeException(e);
-        }
-
-        // get attributes (not readable until after commit)
-        if (op.getValue(attr_c1, bb) == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        bb.position(p += width_c1);
-        if (op.getValue(attr_c2, bb) == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        bb.position(p += width_c2);
-        if (op.getValue(attr_c3, bb) == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        bb.position(p += width_c3);
-        if (op.getValue(attr_c4, bb) == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        bb.position(p += width_c4);
-        if (op.getValue(attr_c5, bb) == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        bb.position(p += width_c5);
-        if (op.getValue(attr_c6, bb) == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        bb.position(p += width_c6);
-        if (op.getValue(attr_c7, bb) == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        bb.position(p += width_c7);
-        if (op.getValue(attr_c8, bb) == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        bb.position(p += width_c8);
-        if (op.getValue(attr_c9, bb) == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        bb.position(p += width_c9);
-        if (op.getValue(attr_c10, bb) == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        bb.position(p += width_c10);
-        if (op.getValue(attr_c11, bb) == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        bb.position(p += width_c11);
-        if (op.getValue(attr_c12, bb) == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        bb.position(p += width_c12);
-        if (op.getValue(attr_c13, bb) == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        bb.position(p += width_c13);
-        if (op.getValue(attr_c14, bb) == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        bb.position(p += width_c14);
-    }
-
-    protected void ndbjtieRead(int c0) {
-        // include exception handling as part of transcoding pattern
-        //final int i = c0;
-        //final CharBuffer str = CharBuffer.wrap(Integer.toString(i));
-        //assert (str.position() == 0);
-
-        try {
-            int p = bb.position();
-            bb.position(p += width_c0);
-
-            // not verifying at this time
-            // (str.equals(ndbjtieTranscode(bb_c1)));
-            // (i == bb_c2.asIntBuffer().get());
-            //CharBuffer y = ndbjtieTranscode(bb);
-
-            ndbjtieTranscode(bb);
-            bb.position(p += width_c1);
-
-            bb.asIntBuffer().get();
-            bb.position(p += width_c2);
-            bb.asIntBuffer().get();
-            bb.position(p += width_c3);
-            bb.asIntBuffer().get();
-            bb.position(p += width_c4);
-
-            ndbjtieTranscode(bb);
-            bb.position(p += width_c5);
-            ndbjtieTranscode(bb);
-            bb.position(p += width_c6);
-            ndbjtieTranscode(bb);
-            bb.position(p += width_c7);
-            ndbjtieTranscode(bb);
-            bb.position(p += width_c8);
-            ndbjtieTranscode(bb);
-            bb.position(p += width_c9);
-            ndbjtieTranscode(bb);
-            bb.position(p += width_c10);
-            ndbjtieTranscode(bb);
-            bb.position(p += width_c11);
-            ndbjtieTranscode(bb);
-            bb.position(p += width_c12);
-            ndbjtieTranscode(bb);
-            bb.position(p += width_c13);
-            ndbjtieTranscode(bb);
-            bb.position(p += width_c14);
-        } catch (CharacterCodingException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
+    // datastore operations
     // ----------------------------------------------------------------------
 
-    protected void runJdbcUpdate(XMode mode) throws SQLException {
-        final String m = mode.toString().toLowerCase();
-        //out.println("update " + nRows + " rows by JDBC " + m + " tx ...");
-
-        long time = -System.currentTimeMillis();
-        connection.setAutoCommit(mode == XMode.SINGLE);
-        for(int i = 0; i < nRows; i++) {
-            jdbcUpdate(i, mode);
-        }
-        if (mode == XMode.BATCH)
-            upd0.executeBatch();
-        if (mode != XMode.SINGLE)
-            connection.commit();
-        time += System.currentTimeMillis();
-
-        out.println("jdbc_update_" + m + "    \t: " + time + "\tms");
-    }
-
-    protected void runClusterjUpdate(XMode mode) {
-        final String m = mode.toString().toLowerCase();
-        //out.println("update " + nRows + " rows by ClusterJ " + m + " tx ...");
-
-        long time = -System.currentTimeMillis();
-        if (mode != XMode.SINGLE)
-            session.currentTransaction().begin();
-        for(int i = 0; i < nRows; i++) {
-            clusterjUpdate(i);
-        }
-        if (mode != XMode.SINGLE)
-            session.currentTransaction().commit();
-        time += System.currentTimeMillis();
-
-        out.println("clusterj_update_" + m + "  \t: " + time + "\tms");
-    }
-
-    protected void runNdbjtieUpdate(XMode mode) {
-        final String m = mode.toString().toLowerCase();
-        //out.println("update " + nRows + " rows by NDB JTie " + m + " tx ...");
-
-        long time = -System.currentTimeMillis();
-        if (mode == XMode.SINGLE) {
-            for(int i = 0; i < nRows; i++) {
-                ndbjtieBeginTransaction();
-                ndbjtieUpdate(i);
-                ndbjtieCommitTransaction();
-                ndbjtieCloseTransaction();
-            }
-        } else {
-            ndbjtieBeginTransaction();
-            for(int i = 0; i < nRows; i++) {
-                ndbjtieUpdate(i);
-
-                if (mode == XMode.BULK)
-                    ndbjtieExecuteTransaction();
-            }
-            ndbjtieCommitTransaction();
-            ndbjtieCloseTransaction();
+    protected void initConnections() throws Exception {
+        if (doJdbc) {
+            assert (jdbcLoad != null);
+            jdbcLoad.initConnection();
         }
-        time += System.currentTimeMillis();
-
-        out.println("ndbjtie_update_" + m + "  \t: " + time + "\tms");
-    }
-
-    protected void jdbcUpdate(int c0, XMode mode) {
-        final String str0 = Integer.toString(c0);
-        final int r = -c0;
-        final String str1 = Integer.toString(r);
-
-        // include exception handling as part of jdbc pattern
-        try {
-            upd0.setString(1, str1);
-            upd0.setInt(2, r);
-            upd0.setInt(3, r);
-            upd0.setString(4, str1);
-            upd0.setString(5, str1);
-            upd0.setString(6, str1);
-            upd0.setString(7, str1);
-            upd0.setString(8, str0); // key
-            if (mode == XMode.BATCH) {
-                upd0.addBatch();
-            } else {
-                int cnt = upd0.executeUpdate();
-                assert (cnt == 1);
-            }
-        } catch (SQLException e) {
-            throw new RuntimeException(e);
+        if (doClusterj) {
+            assert (clusterjLoad != null);
+            clusterjLoad.initConnection();
         }
-    }
-
-    protected void clusterjUpdate(int c0) {
-        final String str0 = Integer.toString(c0);
-        final int r = -c0;
-        final String str1 = Integer.toString(r);
-
-        // blind update
-        final CJSubscriber o = session.newInstance(CJSubscriber.class);
-        o.setC0(str0);
-        //final CJSubscriber o = session.find(CJSubscriber.class, str0);
-        //String oneChar = Integer.toString(2);
-        o.setC1(str1);
-        o.setC2(r);
-        o.setC3(r);
-        //o.setC4(r);
-        o.setC5(str1);
-        o.setC6(str1);
-        o.setC7(str1);
-        o.setC8(str1);
-        //o.setC9(oneChar);
-        //o.setC10(oneChar);
-        //o.setC11(str);
-        //o.setC12(str);
-        //o.setC13(oneChar);
-        //o.setC14(str);
-        session.updatePersistent(o);
-    }
-
-    protected void ndbjtieUpdate(int c0) {
-        final CharBuffer str0 = CharBuffer.wrap(Integer.toString(c0));
-        final int r = -c0;
-        final CharBuffer str1 = CharBuffer.wrap(Integer.toString(r));
-
-        // get an update operation for the table
-        NdbOperation op = tx.getNdbOperation(table_t0);
-        if (op == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        if (op.updateTuple() != 0)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-
-        // include exception handling as part of transcoding pattern
-        try {
-            // set values; key attribute needs to be set first
-            //str0.rewind();
-            ndbjtieTranscode(bb, str0);
-            if (op.equal(attr_c0, bb) != 0) // key
-                throw new RuntimeException(toStr(tx.getNdbError()));
-            bb.position(bb.position() + width_c0);
-
-            //str1.rewind();
-            ndbjtieTranscode(bb, str1);
-            if (op.setValue(attr_c1, bb) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-            bb.position(bb.position() + width_c1);
-
-            if (op.setValue(attr_c2, r) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-
-            if (op.setValue(attr_c3, r) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-
-            str1.rewind();
-            ndbjtieTranscode(bb, str1);
-            if (op.setValue(attr_c5, bb) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-            bb.position(bb.position() + width_c5);
-
-            str1.rewind();
-            ndbjtieTranscode(bb, str1);
-            if (op.setValue(attr_c6, bb) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-            bb.position(bb.position() + width_c6);
-
-            str1.rewind();
-            ndbjtieTranscode(bb, str1);
-            if (op.setValue(attr_c7, bb) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-            bb.position(bb.position() + width_c7);
-
-            str1.rewind();
-            ndbjtieTranscode(bb, str1);
-            if (op.setValue(attr_c8, bb) != 0)
-                throw new RuntimeException(toStr(tx.getNdbError()));
-            bb.position(bb.position() + width_c8);
-        } catch (CharacterCodingException e) {
-            throw new RuntimeException(e);
+        if (doNdbjtie) {
+            assert (ndbjtieLoad != null);
+            ndbjtieLoad.initConnection();
         }
     }
 
-    // ----------------------------------------------------------------------
-
-    protected void runJdbcDelete(XMode mode) throws SQLException {
-        final String m = mode.toString().toLowerCase();
-        //out.println("delete " + nRows + " rows by JDBC " + m + " tx ...");
-
-        long time = -System.currentTimeMillis();
-        connection.setAutoCommit(mode == XMode.SINGLE);
-        for(int i = 0; i < nRows; i++) {
-            jdbcDelete(i, mode);
-        }
-        if (mode == XMode.BATCH)
-            del0.executeBatch();
-        if (mode != XMode.SINGLE)
-            connection.commit();
-        time += System.currentTimeMillis();
-
-        out.println("jdbc_delete_" + m + "    \t: " + time + "\tms");
-    }
-
-    protected void runClusterjDelete(XMode mode) {
-        final String m = mode.toString().toLowerCase();
-        //out.println("delete " + nRows + " rows by ClusterJ " + m + " tx ...");
-
-        long time = -System.currentTimeMillis();
-        if (mode != XMode.SINGLE)
-            session.currentTransaction().begin();
-        for(int i = 0; i < nRows; i++) {
-            clusterjDelete(i);
-        }
-        if (mode != XMode.SINGLE)
-            session.currentTransaction().commit();
-        time += System.currentTimeMillis();
-
-        out.println("clusterj_delete_" + m + "  \t: " + time + "\tms");
-    }
-
-    protected void runNdbjtieDelete(XMode mode) {
-        final String m = mode.toString().toLowerCase();
-        //out.println("delete " + nRows + " rows by NDB JTie " + m + " tx ...");
-
-        long time = -System.currentTimeMillis();
-        if (mode == XMode.SINGLE) {
-            for(int i = 0; i < nRows; i++) {
-                ndbjtieBeginTransaction();
-                ndbjtieDelete(i);
-                ndbjtieCommitTransaction();
-                ndbjtieCloseTransaction();
-            }
-        } else {
-            ndbjtieBeginTransaction();
-            for(int i = 0; i < nRows; i++) {
-                ndbjtieDelete(i);
-
-                if (mode == XMode.BULK)
-                    ndbjtieExecuteTransaction();
-            }
-            ndbjtieCommitTransaction();
-            ndbjtieCloseTransaction();
+    protected void closeConnections() throws Exception {
+        if (doJdbc) {
+            assert (jdbcLoad != null);
+            jdbcLoad.closeConnection();
         }
-        time += System.currentTimeMillis();
-
-        out.println("ndbjtie_delete_" + m + "  \t: " + time + "\tms");
-    }
-
-    protected void jdbcDelete(int c0, XMode mode) {
-        // include exception handling as part of jdbc pattern
-        try {
-            final String str = Integer.toString(c0);
-            del0.setString(1, str);
-            if (mode == XMode.BATCH) {
-                del0.addBatch();
-            } else {
-                int cnt = del0.executeUpdate();
-                assert (cnt == 1);
-            }
-        } catch (SQLException e) {
-            throw new RuntimeException(e);
+        if (doClusterj) {
+            assert (clusterjLoad != null);
+            clusterjLoad.closeConnection();
         }
-    }
-
-    protected void clusterjDelete(int c0) {
-        // can do a blind delete
-        final CJSubscriber o = session.newInstance(CJSubscriber.class);
-        o.setC0(Integer.toString(c0));
-        assert o != null;
-        session.remove(o);
-    }
-
-    protected void ndbjtieDelete(int c0) {
-        // get a delete operation for the table
-        NdbOperation op = tx.getNdbOperation(table_t0);
-        if (op == null)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-        if (op.deleteTuple() != 0)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-
-        int p = bb.position();
-
-        // include exception handling as part of transcoding pattern
-        final int i = c0;
-        final CharBuffer str = CharBuffer.wrap(Integer.toString(c0));
-        try {
-            // set values; key attribute needs to be set first
-            //str.rewind();
-            ndbjtieTranscode(bb, str);
-            if (op.equal(attr_c0, bb) != 0) // key
-                throw new RuntimeException(toStr(tx.getNdbError()));
-            bb.position(p += width_c0);
-        } catch (CharacterCodingException e) {
-            throw new RuntimeException(e);
+        if (doNdbjtie) {
+            assert (ndbjtieLoad != null);
+            ndbjtieLoad.closeConnection();
         }
     }
 
-    // ----------------------------------------------------------------------
-
-    protected void ndbjtieBeginTransaction() {
-        assert (tx == null);
-
-        // prepare buffer for writing
-        bb.clear();
-
-        // start a transaction
-        // must be closed with NdbTransaction.close
-        final TableConst table  = null;
-        final ByteBuffer keyData = null;
-        final int keyLen = 0;
-        if ((tx = ndb.startTransaction(table, keyData, keyLen)) == null)
-            throw new RuntimeException(toStr(ndb.getNdbError()));
-    }
-
-    protected void ndbjtieExecuteTransaction() {
-        assert (tx != null);
-
-        // execute but don't commit the current transaction
-        final int execType = NdbTransaction.ExecType.NoCommit;
-        final int abortOption = NdbOperation.AbortOption.AbortOnError;
-        final int force = 0;
-        if (tx.execute(execType, abortOption, force) != 0
-            || tx.getNdbError().status() != NdbError.Status.Success)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-    }
-
-    protected void ndbjtieCommitTransaction() {
-        assert (tx != null);
-
-        // commit the current transaction
-        final int execType = NdbTransaction.ExecType.Commit;
-        final int abortOption = NdbOperation.AbortOption.AbortOnError;
-        final int force = 0;
-        if (tx.execute(execType, abortOption, force) != 0
-            || tx.getNdbError().status() != NdbError.Status.Success)
-            throw new RuntimeException(toStr(tx.getNdbError()));
-
-        // prepare buffer for reading
-        bb.rewind();
-    }
-
-    protected void ndbjtieCloseTransaction() {
-        assert (tx != null);
-
-        // close the current transaction (required after commit, rollback)
-        ndb.closeTransaction(tx);
-        tx = null;
-    }
-
-    // ----------------------------------------------------------------------
-
-    protected CharBuffer ndbjtieTranscode(ByteBuffer from)
-        throws CharacterCodingException {
-        // mark position
-        final int p = from.position();
-
-        // read 1-byte length prefix
-        final int l = from.get();
-        assert ((0 <= l) && (l < 256)); // or (l <= 256)?
-
-        // prepare buffer for reading
-        from.limit(from.position() + l);
-
-        // decode
-        final CharBuffer to = csDecoder.decode(from);
-        assert (!from.hasRemaining());
-
-        // allow for repositioning
-        from.limit(from.capacity());
-
-        assert (to.position() == 0);
-        assert (to.limit() == to.capacity());
-        return to;
-    }
-
-    protected void ndbjtieTranscode(ByteBuffer to, CharBuffer from)
-        throws CharacterCodingException {
-        // mark position
-        final int p = to.position();
-
-        // advance 1-byte length prefix
-        to.position(p + 1);
-        //to.put((byte)0);
-
-        // encode
-        final boolean endOfInput = true;
-        final CoderResult cr = csEncoder.encode(from, to, endOfInput);
-        if (!cr.isUnderflow())
-            cr.throwException();
-        assert (!from.hasRemaining());
-
-        // write 1-byte length prefix
-        final int l = (to.position() - p) - 1;
-        assert (0 <= l && l < 256); // or (l <= 256)?
-        to.put(p, (byte)l);
-
-        // reset position
-        to.position(p);
-    }
-
-    // ----------------------------------------------------------------------
-
-    @PersistenceCapable(table="mytable")
-    //@Index(name="c0_UNIQUE")
-    static protected interface CJSubscriber
-    {
-        @PrimaryKey
-        String getC0();
-        void setC0(String c0);
-
-        @Index(name="c1_UNIQUE")
-        String getC1();
-        void setC1(String c1);
-
-        @Index(name="c2_UNIQUE")
-        int getC2();
-        void setC2(int c2);
-
-        int getC3();
-        void setC3(int c3);
-
-        int getC4();
-        void setC4(int c4);
-
-        String getC5();
-        void setC5(String c5);
-
-        String getC6();
-        void setC6(String c6);
-
-        @Index(name="c7_UNIQUE")
-        String getC7();
-        void setC7(String c7);
-
-        @Index(name="c8_UNIQUE")
-        String getC8();
-        void setC8(String c8);
-
-        String getC9();
-        void setC9(String c9);
-
-        String getC10();
-        void setC10(String c10);
-
-        String getC11();
-        void setC11(String c11);
-
-        String getC12();
-        void setC12(String c12);
-
-        String getC13();
-        void setC13(String c13);
-
-        String getC14();
-        void setC14(String c14);
-    }
-
-    // ----------------------------------------------------------------------
-}
\ No newline at end of file
+    //abstract protected void clearPersistenceContext() throws Exception;
+    //abstract protected void clearData() throws Exception;
+}

=== added file 'storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/TwsLoad.java'
--- a/storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/TwsLoad.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/test/crund/tws/tws_java/src/com/mysql/cluster/benchmark/tws/TwsLoad.java	2010-10-19 22:50:53 +0000
@@ -0,0 +1,95 @@
+/* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
+ *
+ *  Copyright (C) 2010 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.benchmark.tws;
+
+import java.io.PrintWriter;
+
+
+abstract class TwsLoad {
+
+    // console
+    static protected final PrintWriter out = TwsDriver.out;
+    static protected final PrintWriter err = TwsDriver.err;
+
+    // resources
+    protected final TwsDriver driver;
+    protected String descr;
+
+    public TwsLoad(TwsDriver driver) {
+        this.driver = driver;
+    }
+
+    // ----------------------------------------------------------------------
+    // intializers/finalizers
+    // ----------------------------------------------------------------------
+
+    abstract protected void initProperties();
+    abstract protected void printProperties();
+
+    public String getDescriptor() {
+        return descr;
+    }
+
+    public void init() throws Exception {
+        initProperties();
+        printProperties();
+    }
+
+    public void close() throws Exception {
+    }
+
+    // ----------------------------------------------------------------------
+    // benchmark operations
+    // ----------------------------------------------------------------------
+
+    abstract public void runOperations() throws Exception;
+
+    // reports an error if a condition is not met
+    static protected final void verify(boolean cond) {
+        //assert (cond);
+        if (!cond)
+            throw new RuntimeException("data verification failed.");
+    }
+
+    static protected final void verify(int exp, int act) {
+        if (exp != act)
+            throw new RuntimeException("data verification failed:"
+                                       + " expected = " + exp
+                                       + ", actual = " + act);
+    }
+
+    static protected final void verify(String exp, String act) {
+        if ((exp == null && act != null)
+            || (exp != null && !exp.equals(act)))
+            throw new RuntimeException("data verification failed:"
+                                       + " expected = '" + exp + "'"
+                                       + ", actual = '" + act + "'");
+    }
+
+    // ----------------------------------------------------------------------
+    // datastore operations
+    // ----------------------------------------------------------------------
+
+    abstract public void initConnection() throws Exception;
+    abstract public void closeConnection() throws Exception;
+    //abstract public void clearPersistenceContext() throws Exception;
+    //abstract public void clearData() throws Exception;
+}


Attachment: [text/bzr-bundle] bzr/martin.zaun@oracle.com-20101019225053-zoxr2vvifqmylcbp.bundle
Thread
bzr commit into mysql-5.1-telco-7.1 branch (martin.zaun:3865) Martin Zaun20 Oct