MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbjtieLoad.java
1 /* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
3  *
4  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 package com.mysql.cluster.benchmark.tws;
21 
22 import com.mysql.ndbjtie.ndbapi.Ndb_cluster_connection;
23 import com.mysql.ndbjtie.ndbapi.Ndb;
24 import com.mysql.ndbjtie.ndbapi.NdbDictionary.Dictionary;
25 import com.mysql.ndbjtie.ndbapi.NdbDictionary.TableConst;
26 import com.mysql.ndbjtie.ndbapi.NdbError;
27 import com.mysql.ndbjtie.ndbapi.NdbTransaction;
28 import com.mysql.ndbjtie.ndbapi.NdbOperation;
29 
30 import java.nio.ByteBuffer;
31 import java.nio.ByteOrder;
32 import java.nio.CharBuffer;
33 import java.nio.charset.Charset;
34 import java.nio.charset.CodingErrorAction;
35 import java.nio.charset.CharsetEncoder;
36 import java.nio.charset.CharsetDecoder;
37 import java.nio.charset.CoderResult;
38 import java.nio.charset.CharacterCodingException;
39 
40 
41 class NdbjtieLoad extends TwsLoad {
42 
43  // NDB settings
44  protected String mgmdConnect;
45  protected String catalog;
46  protected String schema;
47 
48  // NDB JTie resources
49  protected Ndb_cluster_connection mgmd;
50  protected Ndb ndb;
51  protected NdbTransaction tx;
52  protected int ndbOpLockMode;
53 
54  // NDB JTie metadata resources
55  protected TableConst table_t0;
56 
57  // NDB JTie data resources
58  protected ByteBuffer bb;
59 
60  // NDB JTie static resources
61  static protected final ByteOrder bo = ByteOrder.nativeOrder();
62  static protected final Charset cs;
63  static protected final CharsetEncoder csEncoder;
64  static protected final CharsetDecoder csDecoder;
65  static {
66  // default charset for mysql is "ISO-8859-1" ("US-ASCII", "UTF-8")
67  cs = Charset.forName("ISO-8859-1");
68  csDecoder = cs.newDecoder();
69  csEncoder = cs.newEncoder();
70 
71  // report any unclean transcodings
72  csEncoder
73  .onMalformedInput(CodingErrorAction.REPORT)
74  .onUnmappableCharacter(CodingErrorAction.REPORT);
75  csDecoder
76  .onMalformedInput(CodingErrorAction.REPORT)
77  .onUnmappableCharacter(CodingErrorAction.REPORT);
78  }
79 
80  public NdbjtieLoad(TwsDriver driver) {
81  super(driver, null);
82  }
83 
84  // ----------------------------------------------------------------------
85  // NDB Base intializers/finalizers
86  // ----------------------------------------------------------------------
87 
88  protected void initProperties() {
89  out.println();
90  out.print("setting ndb properties ...");
91 
92  final StringBuilder msg = new StringBuilder();
93  final String eol = System.getProperty("line.separator");
94 
95  // the hostname and port number of NDB mgmd
96  mgmdConnect = driver.props.getProperty("ndb.mgmdConnect", "localhost");
97  assert mgmdConnect != null;
98 
99  // the database
100  catalog = driver.props.getProperty("ndb.catalog", "crunddb");
101  assert catalog != null;
102 
103  // the schema
104  schema = driver.props.getProperty("ndb.schema", "def");
105  assert schema != null;
106 
107  if (msg.length() == 0) {
108  out.println(" [ok]");
109  } else {
110  out.println();
111  out.print(msg.toString());
112  }
113 
114  // have mgmdConnect initialized first
115  descr = "ndbjtie(" + mgmdConnect + ")";
116  }
117 
118  protected void printProperties() {
119  out.println("ndb.mgmdConnect: \"" + mgmdConnect + "\"");
120  out.println("ndb.catalog: \"" + catalog + "\"");
121  out.println("ndb.schema: \"" + schema + "\"");
122  }
123 
124  public void init() throws Exception {
125  super.init();
126  assert mgmd == null;
127 
128  // load native library (better diagnostics doing it explicitely)
129  Driver.loadSystemLibrary("ndbclient");
130 
131  // instantiate NDB cluster singleton
132  out.print("creating cluster connection ...");
133  out.flush();
134  mgmd = Ndb_cluster_connection.create(mgmdConnect);
135  assert mgmd != null;
136  out.println(" [ok: mgmd@" + mgmdConnect + "]");
137  }
138 
139  public void close() throws Exception {
140  assert mgmd != null;
141 
142  out.println();
143  out.print("closing cluster connection ...");
144  out.flush();
145  Ndb_cluster_connection.delete(mgmd);
146  mgmd = null;
147  out.println(" [ok]");
148 
149  super.close();
150  }
151 
152  // ----------------------------------------------------------------------
153  // NDB JTie datastore operations
154  // ----------------------------------------------------------------------
155 
156  public void initConnection() {
157  assert (mgmd != null);
158  assert (ndb == null);
159 
160  out.println();
161  out.println("initializing ndbjtie resources ...");
162 
163  // connect to cluster management node (ndb_mgmd)
164  out.print("connecting to cluster ...");
165  out.flush();
166  final int retries = 0; // retries (< 0 = indefinitely)
167  final int delay = 0; // seconds to wait after retry
168  final int verbose = 1; // print report of progess
169  // 0 = success, 1 = recoverable error, -1 = non-recoverable error
170  if (mgmd.connect(retries, delay, verbose) != 0) {
171  final String msg = ("mgmd@" + mgmdConnect
172  + " was not ready within "
173  + (retries * delay) + "s.");
174  out.println(msg);
175  throw new RuntimeException("!!! " + msg);
176  }
177  out.println(" [ok: " + mgmdConnect + "]");
178 
179  // connect to data nodes (ndbds)
180  out.print("waiting for data nodes ...");
181  out.flush();
182  final int initial_wait = 10; // secs to wait until first node detected
183  final int final_wait = 0; // secs to wait after first node detected
184  // returns: 0 all nodes live, > 0 at least one node live, < 0 error
185  if (mgmd.wait_until_ready(initial_wait, final_wait) < 0) {
186  final String msg = ("data nodes were not ready within "
187  + (initial_wait + final_wait) + "s.");
188  out.println(msg);
189  throw new RuntimeException(msg);
190  }
191  out.println(" [ok]");
192 
193  // connect to database
194  out.print("connecting to database ...");
195  ndb = Ndb.create(mgmd, catalog, schema);
196  final int max_no_tx = 10; // maximum number of parallel tx (<=1024)
197  // note each scan or index scan operation uses one extra transaction
198  if (ndb.init(max_no_tx) != 0) {
199  String msg = "Error caught: " + ndb.getNdbError().message();
200  throw new RuntimeException(msg);
201  }
202  out.println(" [ok: " + catalog + "." + schema + "]");
203 
204  metaData = new MetaData(ndb);
205 
206  metaData.initNdbjtieModel();
207 
208  initNdbjtieBuffers();
209 
210  out.print("using lock mode for reads ...");
211  out.flush();
212  final String lm;
213  switch (driver.lockMode) {
214  case READ_COMMITTED:
215  ndbOpLockMode = NdbOperation.LockMode.LM_CommittedRead;
216  lm = "LM_CommittedRead";
217  break;
218  case SHARED:
219  ndbOpLockMode = NdbOperation.LockMode.LM_Read;
220  lm = "LM_Read";
221  break;
222  case EXCLUSIVE:
223  ndbOpLockMode = NdbOperation.LockMode.LM_Exclusive;
224  lm = "LM_Exclusive";
225  break;
226  default:
227  ndbOpLockMode = NdbOperation.LockMode.LM_CommittedRead;
228  lm = "LM_CommittedRead";
229  assert false;
230  }
231  out.println(" [ok: " + lm + "]");
232  }
233 
234  public void closeConnection() {
235  assert (ndb != null);
236 
237  out.println();
238  out.println("releasing ndbjtie resources ...");
239 
240  closeNdbjtieBuffers();
241 
242  closeNdbjtieModel();
243 
244  out.print("closing database connection ...");
245  out.flush();
246  Ndb.delete(ndb);
247  ndb = null;
248  out.println(" [ok]");
249  }
250 
251 
252  protected void closeNdbjtieModel() {
253  assert (ndb != null);
254  assert (table_t0 != null);
255  assert (metaData.getColumn(0) != null);
256 
257  out.print("clearing metadata cache...");
258  out.flush();
259 
260 
261  table_t0 = null;
262 
263  out.println(" [ok]");
264  }
265 
266  public void initNdbjtieBuffers() {
267  assert (metaData.getColumn(0) != null);
268  assert (bb == null);
269 
270  out.print("allocating buffers...");
271  out.flush();
272 
273  bb = ByteBuffer.allocateDirect(metaData.getRowWidth() * driver.nRows);
274 
275  // initial order of a byte buffer is always BIG_ENDIAN
276  bb.order(bo);
277 
278  out.println(" [ok]");
279  }
280 
281  protected void closeNdbjtieBuffers() {
282  assert (metaData.getColumn(0) != null);
283  assert (bb != null);
284 
285  out.print("releasing buffers...");
286  out.flush();
287 
288  bb = null;
289 
290  out.println(" [ok]");
291  }
292 
293 
294  // ----------------------------------------------------------------------
295 
296  public void runOperations() {
297  out.println();
298  out.println("running NDB JTie operations ..."
299  + " [nRows=" + driver.nRows + "]");
300 
301  if (driver.doSingle) {
302  if (driver.doInsert) runNdbjtieInsert(TwsDriver.XMode.SINGLE);
303  if (driver.doLookup) runNdbjtieLookup(TwsDriver.XMode.SINGLE);
304  if (driver.doUpdate) runNdbjtieUpdate(TwsDriver.XMode.SINGLE);
305  if (driver.doDelete) runNdbjtieDelete(TwsDriver.XMode.SINGLE);
306  }
307  if (driver.doBulk) {
308  if (driver.doInsert) runNdbjtieInsert(TwsDriver.XMode.BULK);
309  if (driver.doLookup) runNdbjtieLookup(TwsDriver.XMode.BULK);
310  if (driver.doUpdate) runNdbjtieUpdate(TwsDriver.XMode.BULK);
311  if (driver.doDelete) runNdbjtieDelete(TwsDriver.XMode.BULK);
312  }
313  if (driver.doBatch) {
314  if (driver.doInsert) runNdbjtieInsert(TwsDriver.XMode.BATCH);
315  if (driver.doLookup) runNdbjtieLookup(TwsDriver.XMode.BATCH);
316  if (driver.doUpdate) runNdbjtieUpdate(TwsDriver.XMode.BATCH);
317  if (driver.doDelete) runNdbjtieDelete(TwsDriver.XMode.BATCH);
318  }
319  }
320 
321  // ----------------------------------------------------------------------
322 
323  protected void runNdbjtieInsert(TwsDriver.XMode mode) {
324  final String name = "insert_" + mode.toString().toLowerCase();
325  driver.begin(name);
326 
327  initTable();
328 
329  if (mode == TwsDriver.XMode.SINGLE) {
330  for(int i = 0; i < driver.nRows; i++) {
331  ndbjtieBeginTransaction();
332  ndbjtieInsert(i);
333  ndbjtieCommitTransaction();
334  ndbjtieCloseTransaction();
335  }
336  } else {
337  ndbjtieBeginTransaction();
338  for(int i = 0; i < driver.nRows; i++) {
339  ndbjtieInsert(i);
340 
341  if (mode == TwsDriver.XMode.BULK)
342  ndbjtieExecuteTransaction();
343  }
344  ndbjtieCommitTransaction();
345  ndbjtieCloseTransaction();
346  }
347 
348  driver.finish(name);
349  }
350 
351  protected void initTable() {
352  if(table_t0 == null) {
353 
354  final Dictionary dict = ndb.getDictionary();
355 
356  if ((table_t0 = dict.getTable("mytable")) == null)
357  throw new RuntimeException(TwsUtils.toStr(dict.getNdbError()));
358  }
359  }
360 
361  protected void ndbjtieInsert(int c0) {
362 
363  // get an insert operation for the table
364  NdbOperation op = tx.getNdbOperation(table_t0);
365  if (op == null)
366  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
367  if (op.insertTuple() != 0)
368  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
369 
370  // include exception handling as part of transcoding pattern
371  final int i = c0;
372  final CharBuffer str = CharBuffer.wrap(Integer.toString(i));
373  try {
374  // set values; key attribute needs to be set first
375  //str.rewind();
376  ndbjtieTranscode(bb, str);
377  if (op.equal(metaData.getAttr(0), bb) != 0) // key
378  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
379  bb.position(bb.position() + metaData.getColumnWidth(0));
380 
381  str.rewind();
382  ndbjtieTranscode(bb, str);
383  if (op.setValue(metaData.getAttr(1), bb) != 0)
384  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
385  bb.position(bb.position() + metaData.getColumnWidth(1));
386 
387  if (op.setValue(metaData.getAttr(2), i) != 0)
388  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
389 
390  if (op.setValue(metaData.getAttr(3), i) != 0)
391  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
392 
393  // XXX
394  if (op.setValue(metaData.getAttr(4), null) != 0)
395  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
396 
397  str.rewind();
398  ndbjtieTranscode(bb, str);
399  if (op.setValue(metaData.getAttr(5), bb) != 0)
400  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
401  bb.position(bb.position() + metaData.getColumnWidth(5));
402 
403  str.rewind();
404  ndbjtieTranscode(bb, str);
405  if (op.setValue(metaData.getAttr(6), bb) != 0)
406  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
407  bb.position(bb.position() + metaData.getColumnWidth(6));
408 
409  str.rewind();
410  ndbjtieTranscode(bb, str);
411  if (op.setValue(metaData.getAttr(7), bb) != 0)
412  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
413  bb.position(bb.position() + metaData.getColumnWidth(7));
414 
415  str.rewind();
416  ndbjtieTranscode(bb, str);
417  if (op.setValue(metaData.getAttr(8), bb) != 0)
418  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
419  bb.position(bb.position() + metaData.getColumnWidth(8));
420 
421  // XXX
422  if (op.setValue(metaData.getAttr(9), null) != 0)
423  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
424 
425  if (op.setValue(metaData.getAttr(10), null) != 0)
426  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
427 
428  if (op.setValue(metaData.getAttr(11), null) != 0)
429  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
430 
431  if (op.setValue(metaData.getAttr(12), null) != 0)
432  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
433 
434  if (op.setValue(metaData.getAttr(13), null) != 0)
435  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
436 
437  if (op.setValue(metaData.getAttr(14), null) != 0)
438  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
439  } catch (CharacterCodingException e) {
440  throw new RuntimeException(e);
441  }
442  }
443 
444  // ----------------------------------------------------------------------
445 
446  protected void runNdbjtieLookup(TwsDriver.XMode mode) {
447  final String name = "lookup_" + mode.toString().toLowerCase();
448  driver.begin(name);
449 
450  if (mode == TwsDriver.XMode.SINGLE) {
451  for(int i = 0; i < driver.nRows; i++) {
452  ndbjtieBeginTransaction();
453  ndbjtieLookup(i);
454  ndbjtieCommitTransaction();
455  ndbjtieRead(i);
456  ndbjtieCloseTransaction();
457  }
458  } else {
459  ndbjtieBeginTransaction();
460  for(int i = 0; i < driver.nRows; i++) {
461  ndbjtieLookup(i);
462 
463  if (mode == TwsDriver.XMode.BULK)
464  ndbjtieExecuteTransaction();
465  }
466  ndbjtieCommitTransaction();
467  for(int i = 0; i < driver.nRows; i++) {
468  ndbjtieRead(i);
469  }
470  ndbjtieCloseTransaction();
471  }
472 
473  driver.finish(name);
474  }
475 
476  protected void ndbjtieLookup(int c0) {
477  // get a lookup operation for the table
478  NdbOperation op = tx.getNdbOperation(table_t0);
479  if (op == null)
480  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
481  if (op.readTuple(ndbOpLockMode) != 0)
482  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
483 
484  int p = bb.position();
485 
486  // include exception handling as part of transcoding pattern
487  final CharBuffer str = CharBuffer.wrap(Integer.toString(c0));
488  try {
489  // set values; key attribute needs to be set first
490  //str.rewind();
491  ndbjtieTranscode(bb, str);
492  if (op.equal(metaData.getAttr(0), bb) != 0) // key
493  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
494  bb.position(p += metaData.getColumnWidth(0));
495  } catch (CharacterCodingException e) {
496  throw new RuntimeException(e);
497  }
498 
499  // get attributes (not readable until after commit)
500  for(int i = 1; i < metaData.getColumnCount(); i++) {
501  if (op.getValue(metaData.getAttr(i), bb) == null)
502  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
503  bb.position(p += metaData.getColumnWidth(i));
504  }
505  }
506 
507  protected void ndbjtieRead(int c0) {
508  // include exception handling as part of transcoding pattern
509  //final int i = c0;
510  //final CharBuffer str = CharBuffer.wrap(Integer.toString(i));
511  //assert (str.position() == 0);
512 
513  try {
514  int p = bb.position();
515  bb.position(p += metaData.getColumnWidth(0));
516 
517  // not verifying at this time
518  // (str.equals(ndbjtieTranscode(bb_c1)));
519  // (i == bb_c2.asIntBuffer().get());
520  //CharBuffer y = ndbjtieTranscode(bb);
521 
522  ndbjtieTranscode(bb);
523  bb.position(p += metaData.getColumnWidth(1));
524 
525  bb.asIntBuffer().get();
526  bb.position(p += metaData.getColumnWidth(2));
527  bb.asIntBuffer().get();
528  bb.position(p += metaData.getColumnWidth(3));
529  bb.asIntBuffer().get();
530  bb.position(p += metaData.getColumnWidth(4));
531 
532 
533  for(int i = 5; i < metaData.getColumnCount(); i++) {
534  ndbjtieTranscode(bb);
535  bb.position(p += metaData.getColumnWidth(i));
536  }
537  } catch (CharacterCodingException e) {
538  throw new RuntimeException(e);
539  }
540  }
541 
542  // ----------------------------------------------------------------------
543 
544  protected void runNdbjtieUpdate(TwsDriver.XMode mode) {
545  final String name = "update_" + mode.toString().toLowerCase();
546  driver.begin(name);
547 
548  if (mode == TwsDriver.XMode.SINGLE) {
549  for(int i = 0; i < driver.nRows; i++) {
550  ndbjtieBeginTransaction();
551  ndbjtieUpdate(i);
552  ndbjtieCommitTransaction();
553  ndbjtieCloseTransaction();
554  }
555  } else {
556  ndbjtieBeginTransaction();
557  for(int i = 0; i < driver.nRows; i++) {
558  ndbjtieUpdate(i);
559 
560  if (mode == TwsDriver.XMode.BULK)
561  ndbjtieExecuteTransaction();
562  }
563  ndbjtieCommitTransaction();
564  ndbjtieCloseTransaction();
565  }
566 
567  driver.finish(name);
568  }
569 
570  protected void ndbjtieUpdate(int c0) {
571  final CharBuffer str0 = CharBuffer.wrap(Integer.toString(c0));
572  final int r = -c0;
573  final CharBuffer str1 = CharBuffer.wrap(Integer.toString(r));
574 
575  // get an update operation for the table
576  NdbOperation op = tx.getNdbOperation(table_t0);
577  if (op == null)
578  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
579  if (op.updateTuple() != 0)
580  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
581 
582  // include exception handling as part of transcoding pattern
583  try {
584  // set values; key attribute needs to be set first
585  //str0.rewind();
586  ndbjtieTranscode(bb, str0);
587  if (op.equal(metaData.getAttr(0), bb) != 0) // key
588  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
589  bb.position(bb.position() + metaData.getColumnWidth(0));
590 
591  //str1.rewind();
592  ndbjtieTranscode(bb, str1);
593  if (op.setValue(metaData.getAttr(1), bb) != 0)
594  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
595  bb.position(bb.position() + metaData.getColumnWidth(1));
596 
597  if (op.setValue(metaData.getAttr(2), r) != 0)
598  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
599 
600  if (op.setValue(metaData.getAttr(3), r) != 0)
601  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
602 
603  for(int i = 5; i < metaData.getColumnCount(); i++) {
604  str1.rewind();
605  ndbjtieTranscode(bb, str1);
606  if (op.setValue(metaData.getAttr(i), bb) != 0)
607  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
608  bb.position(bb.position() + metaData.getColumnWidth(i));
609  }
610 
611  } catch (CharacterCodingException e) {
612  throw new RuntimeException(e);
613  }
614  }
615 
616  // ----------------------------------------------------------------------
617 
618  protected void runNdbjtieDelete(TwsDriver.XMode mode) {
619  final String name = "delete_" + mode.toString().toLowerCase();
620  driver.begin(name);
621 
622  if (mode == TwsDriver.XMode.SINGLE) {
623  for(int i = 0; i < driver.nRows; i++) {
624  ndbjtieBeginTransaction();
625  ndbjtieDelete(i);
626  ndbjtieCommitTransaction();
627  ndbjtieCloseTransaction();
628  }
629  } else {
630  ndbjtieBeginTransaction();
631  for(int i = 0; i < driver.nRows; i++) {
632  ndbjtieDelete(i);
633 
634  if (mode == TwsDriver.XMode.BULK)
635  ndbjtieExecuteTransaction();
636  }
637  ndbjtieCommitTransaction();
638  ndbjtieCloseTransaction();
639  }
640 
641  driver.finish(name);
642  }
643 
644  protected void ndbjtieDelete(int c0) {
645  // get a delete operation for the table
646  NdbOperation op = tx.getNdbOperation(table_t0);
647  if (op == null)
648  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
649  if (op.deleteTuple() != 0)
650  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
651 
652  int p = bb.position();
653 
654  // include exception handling as part of transcoding pattern
655  final int i = c0;
656  final CharBuffer str = CharBuffer.wrap(Integer.toString(c0));
657  try {
658  // set values; key attribute needs to be set first
659  //str.rewind();
660  ndbjtieTranscode(bb, str);
661  if (op.equal(metaData.getAttr(0), bb) != 0) // key
662  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
663  bb.position(p += metaData.getColumnWidth(0));
664  } catch (CharacterCodingException e) {
665  throw new RuntimeException(e);
666  }
667  }
668 
669  // ----------------------------------------------------------------------
670 
671  protected void ndbjtieBeginTransaction() {
672  assert (tx == null);
673 
674  // prepare buffer for writing
675  bb.clear();
676 
677  // start a transaction
678  // must be closed with NdbTransaction.close
679  final TableConst table = null;
680  final ByteBuffer keyData = null;
681  final int keyLen = 0;
682  if ((tx = ndb.startTransaction(table, keyData, keyLen)) == null)
683  throw new RuntimeException(TwsUtils.toStr(ndb.getNdbError()));
684  }
685 
686  protected void ndbjtieExecuteTransaction() {
687  assert (tx != null);
688 
689  // execute but don't commit the current transaction
690  final int execType = NdbTransaction.ExecType.NoCommit;
691  final int abortOption = NdbOperation.AbortOption.AbortOnError;
692  final int force = 0;
693  if (tx.execute(execType, abortOption, force) != 0
694  || tx.getNdbError().status() != NdbError.Status.Success)
695  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
696  }
697 
698  protected void ndbjtieCommitTransaction() {
699  assert (tx != null);
700 
701  // commit the current transaction
702  final int execType = NdbTransaction.ExecType.Commit;
703  final int abortOption = NdbOperation.AbortOption.AbortOnError;
704  final int force = 0;
705  if (tx.execute(execType, abortOption, force) != 0
706  || tx.getNdbError().status() != NdbError.Status.Success)
707  throw new RuntimeException(TwsUtils.toStr(tx.getNdbError()));
708 
709  // prepare buffer for reading
710  bb.rewind();
711  }
712 
713  protected void ndbjtieCloseTransaction() {
714  assert (tx != null);
715 
716  // close the current transaction (required after commit, rollback)
717  ndb.closeTransaction(tx);
718  tx = null;
719  }
720 
721  // ----------------------------------------------------------------------
722 
723  protected CharBuffer ndbjtieTranscode(ByteBuffer from)
724  throws CharacterCodingException {
725  // mark position
726  final int p = from.position();
727 
728  // read 1-byte length prefix
729  final int l = from.get();
730  assert ((0 <= l) && (l < 256)); // or (l <= 256)?
731 
732  // prepare buffer for reading
733  from.limit(from.position() + l);
734 
735  // decode
736  final CharBuffer to = csDecoder.decode(from);
737  assert (!from.hasRemaining());
738 
739  // allow for repositioning
740  from.limit(from.capacity());
741 
742  assert (to.position() == 0);
743  assert (to.limit() == to.capacity());
744  return to;
745  }
746 
747  protected void ndbjtieTranscode(ByteBuffer to, CharBuffer from)
748  throws CharacterCodingException {
749  // mark position
750  final int p = to.position();
751 
752  // advance 1-byte length prefix
753  to.position(p + 1);
754  //to.put((byte)0);
755 
756  // encode
757  final boolean endOfInput = true;
758  final CoderResult cr = csEncoder.encode(from, to, endOfInput);
759  if (!cr.isUnderflow())
760  cr.throwException();
761  assert (!from.hasRemaining());
762 
763  // write 1-byte length prefix
764  final int l = (to.position() - p) - 1;
765  assert (0 <= l && l < 256); // or (l <= 256)?
766  to.put(p, (byte)l);
767 
768  // reset position
769  to.position(p);
770  }
771 }