List:Commits« Previous MessageNext Message »
From:Craig L Russell Date:September 3 2010 1:32am
Subject:bzr push into clusterj branch (Craig.Russell:313 to 314)
View as plain text  
  314 Craig L Russell	2010-09-02
      Eagerly compute the record layout to remove hot spot in ResultDataImpl constructor

    modified:
      clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterTransactionImpl.java
      clusterj-tie/src/main/java/com/mysql/clusterj/tie/IndexOperationImpl.java
      clusterj-tie/src/main/java/com/mysql/clusterj/tie/IndexScanOperationImpl.java
      clusterj-tie/src/main/java/com/mysql/clusterj/tie/OperationImpl.java
      clusterj-tie/src/main/java/com/mysql/clusterj/tie/PartitionKeyImpl.java
      clusterj-tie/src/main/java/com/mysql/clusterj/tie/ResultDataImpl.java
      clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanOperationImpl.java
      clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanResultDataImpl.java
      clusterj-tie/src/main/java/com/mysql/clusterj/tie/TableImpl.java
      clusterj-tie/src/main/resources/com/mysql/clusterj/tie/Bundle.properties
  313 Craig L Russell	2010-09-02
      Improve construction of new instances in test

    modified:
      clusterj-test/src/main/java/testsuite/clusterj/AbstractClusterJModelTest.java
=== modified file 'clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterTransactionImpl.java'
--- a/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterTransactionImpl.java	2010-09-02 20:12:52 +0000
+++ b/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterTransactionImpl.java	2010-09-03 00:36:26 +0000
@@ -224,7 +224,7 @@ class ClusterTransactionImpl implements 
         int returnCode = ndbOperation.readTuples(lockMode, scanFlags, parallel, batch);
         handleError(returnCode, ndbTransaction);
         if (logger.isTraceEnabled()) logger.trace("Table: " + storeTable.getName() + " index: " + storeIndex.getName());
-        return new IndexScanOperationImpl(ndbOperation, this);
+        return new IndexScanOperationImpl(storeTable, ndbOperation, this);
     }
 
     public Operation getSelectOperation(Table storeTable) {
@@ -237,7 +237,7 @@ class ClusterTransactionImpl implements 
         int returnCode = ndbOperation.readTuple(lockMode);
         handleError(returnCode, ndbTransaction);
         if (logger.isTraceEnabled()) logger.trace("Table: " + storeTable.getName());
-        return new OperationImpl(ndbOperation, this);
+        return new OperationImpl(storeTable, ndbOperation, this);
     }
 
     public ScanOperation getSelectScanOperation(Table storeTable) {
@@ -253,7 +253,7 @@ class ClusterTransactionImpl implements 
         int returnCode = ndbScanOperation.readTuples(lockMode, scanFlags, parallel, batch);
         handleError(returnCode, ndbTransaction);
         if (logger.isTraceEnabled()) logger.trace("Table: " + storeTable.getName());
-        return new ScanOperationImpl(ndbScanOperation, this);
+        return new ScanOperationImpl(storeTable, ndbScanOperation, this);
     }
 
     public ScanOperation getSelectScanOperationLockModeExclusiveScanFlagKeyInfo(Table storeTable) {
@@ -269,7 +269,7 @@ class ClusterTransactionImpl implements 
         int returnCode = ndbScanOperation.readTuples(lockMode, scanFlags, parallel, batch);
         handleError(returnCode, ndbTransaction);
         if (logger.isTraceEnabled()) logger.trace("Table: " + storeTable.getName());
-        return new ScanOperationImpl(ndbScanOperation, this);
+        return new ScanOperationImpl(storeTable, ndbScanOperation, this);
     }
 
     public IndexOperation getSelectUniqueOperation(Index storeIndex, Table storeTable) {
@@ -282,7 +282,7 @@ class ClusterTransactionImpl implements 
         int returnCode = ndbIndexOperation.readTuple(lockMode);
         handleError(returnCode, ndbTransaction);
         if (logger.isTraceEnabled()) logger.trace("Table: " + storeTable.getName() + " index: " + storeIndex.getName());
-        return new IndexOperationImpl(ndbIndexOperation, this);
+        return new IndexOperationImpl(storeTable, ndbIndexOperation, this);
     }
 
     public Operation getUpdateOperation(Table storeTable) {
@@ -294,7 +294,7 @@ class ClusterTransactionImpl implements 
         int returnCode = ndbOperation.updateTuple();
         handleError(returnCode, ndbTransaction);
         if (logger.isTraceEnabled()) logger.trace("Table: " + storeTable.getName());
-        return new OperationImpl(ndbOperation, this);
+        return new OperationImpl(storeTable, ndbOperation, this);
     }
 
     public Operation getWriteOperation(Table storeTable) {
@@ -306,7 +306,7 @@ class ClusterTransactionImpl implements 
         int returnCode = ndbOperation.writeTuple();
         handleError(returnCode, ndbTransaction);
         if (logger.isTraceEnabled()) logger.trace("Table: " + storeTable.getName());
-        return new OperationImpl(ndbOperation, this);
+        return new OperationImpl(storeTable, ndbOperation, this);
     }
 
     public void postExecuteCallback(Runnable callback) {

=== modified file 'clusterj-tie/src/main/java/com/mysql/clusterj/tie/IndexOperationImpl.java'
--- a/clusterj-tie/src/main/java/com/mysql/clusterj/tie/IndexOperationImpl.java	2009-09-28 22:21:02 +0000
+++ b/clusterj-tie/src/main/java/com/mysql/clusterj/tie/IndexOperationImpl.java	2010-09-03 00:36:26 +0000
@@ -20,14 +20,16 @@ package com.mysql.clusterj.tie;
 
 import com.mysql.ndbjtie.ndbapi.NdbIndexOperation;
 import com.mysql.clusterj.core.store.IndexOperation;
+import com.mysql.clusterj.core.store.Table;
 
 /**
  *
  */
 class IndexOperationImpl extends OperationImpl implements IndexOperation {
 
-    public IndexOperationImpl(NdbIndexOperation ndbIndexOperation, ClusterTransactionImpl transaction) {
-        super(ndbIndexOperation, transaction);
+    public IndexOperationImpl(Table storeTable, NdbIndexOperation ndbIndexOperation,
+            ClusterTransactionImpl transaction) {
+        super(storeTable, ndbIndexOperation, transaction);
     }
 
 }

=== modified file 'clusterj-tie/src/main/java/com/mysql/clusterj/tie/IndexScanOperationImpl.java'
--- a/clusterj-tie/src/main/java/com/mysql/clusterj/tie/IndexScanOperationImpl.java	2009-12-10 00:16:24 +0000
+++ b/clusterj-tie/src/main/java/com/mysql/clusterj/tie/IndexScanOperationImpl.java	2010-09-03 00:36:26 +0000
@@ -24,6 +24,7 @@ import com.mysql.clusterj.ClusterJFatalI
 
 import com.mysql.clusterj.core.store.Column;
 import com.mysql.clusterj.core.store.IndexScanOperation;
+import com.mysql.clusterj.core.store.Table;
 import com.mysql.clusterj.core.util.I18NHelper;
 import com.mysql.clusterj.core.util.Logger;
 import com.mysql.clusterj.core.util.LoggerFactoryService;
@@ -46,9 +47,9 @@ class IndexScanOperationImpl extends Sca
 
     private NdbIndexScanOperation ndbIndexScanOperation;
 
-    public IndexScanOperationImpl(NdbIndexScanOperation ndbIndexScanOperation,
+    public IndexScanOperationImpl(Table storeTable, NdbIndexScanOperation ndbIndexScanOperation,
             ClusterTransactionImpl transaction) {
-        super(ndbIndexScanOperation, transaction);
+        super(storeTable, ndbIndexScanOperation, transaction);
         this.ndbIndexScanOperation = ndbIndexScanOperation;
     }
 

=== modified file 'clusterj-tie/src/main/java/com/mysql/clusterj/tie/OperationImpl.java'
--- a/clusterj-tie/src/main/java/com/mysql/clusterj/tie/OperationImpl.java	2010-09-01 03:57:51 +0000
+++ b/clusterj-tie/src/main/java/com/mysql/clusterj/tie/OperationImpl.java	2010-09-03 00:36:26 +0000
@@ -30,6 +30,7 @@ import com.mysql.clusterj.core.store.Blo
 import com.mysql.clusterj.core.store.Column;
 import com.mysql.clusterj.core.store.Operation;
 import com.mysql.clusterj.core.store.ResultData;
+import com.mysql.clusterj.core.store.Table;
 
 import com.mysql.clusterj.core.util.I18NHelper;
 import com.mysql.clusterj.core.util.Logger;
@@ -57,7 +58,7 @@ class OperationImpl implements Operation
     CharBuffer scratchCharBuffer = null;
 
     /** Current scratch buffer size */
-    int bufferSize = Utility.MAX_STRING_SIZE;
+    int scratchBufferSize = Utility.MAX_STRING_SIZE;
 
     private NdbOperation ndbOperation;
 
@@ -65,11 +66,44 @@ class OperationImpl implements Operation
 
     protected ClusterTransactionImpl clusterTransaction;
 
+    /** The size of the receive buffer for this operation (may be zero for non-read operations) */
+    protected int bufferSize;
+
+    /** The maximum column id for this operation (may be zero for non-read operations) */
+    protected int maximumColumnId;
+
+    /** The offsets into the buffer for each column (may be null for non-read operations) */
+    protected int[] offsets;
+
+    /** The lengths of fields in the buffer for each column (may be null for non-read operations) */
+    protected int[] lengths;
+
+    /** Constructor used for insert and delete operations that do not need to read data.
+     * 
+     * @param operation the operation
+     * @param transaction the transaction
+     */
     public OperationImpl(NdbOperation operation, ClusterTransactionImpl transaction) {
         this.ndbOperation = operation;
         this.clusterTransaction = transaction;
     }
 
+    /** Constructor used for read operations. The table is used to obtain data used
+     * to lay out memory for the result. 
+     * @param storeTable the table
+     * @param operation the operation
+     * @param transaction the transaction
+     */
+    public OperationImpl(Table storeTable, NdbOperation operation, ClusterTransactionImpl transaction) {
+        this.ndbOperation = operation;
+        this.clusterTransaction = transaction;
+        TableImpl tableImpl = (TableImpl)storeTable;
+        this.maximumColumnId = tableImpl.getMaximumColumnId();
+        this.bufferSize = tableImpl.getBufferSize();
+        this.offsets = tableImpl.getOffsets();
+        this.lengths = tableImpl.getLengths();
+    }
+
     public void equalBigInteger(Column storeColumn, BigInteger value) {
         ByteBuffer buffer = Utility.convertValue(storeColumn, value);
         int returnCode = ndbOperation.equal(storeColumn.getName(), buffer);
@@ -166,8 +200,8 @@ class OperationImpl implements Operation
     public ResultData resultData() {
         if (logger.isDetailEnabled()) logger.detail("storeColumns: " + Arrays.toString(storeColumns.toArray()));
         ResultDataImpl result;
-        result = new ResultDataImpl(ndbOperation, storeColumns);
-        clusterTransaction.executeNoCommit(false, false);
+        result = new ResultDataImpl(ndbOperation, storeColumns, maximumColumnId, bufferSize, offsets, lengths);
+        clusterTransaction.executeNoCommit(false, true);
         NdbErrorConst error = ndbOperation.getNdbError();
         int errorCode = error.code();
         if (errorCode != 0)
@@ -266,14 +300,14 @@ class OperationImpl implements Operation
      */
     protected ByteBuffer convertStringToByteBuffer(String value) {
         int sizeNeeded = value.length() * 2 + 2;
-        if (sizeNeeded > bufferSize) {
-            bufferSize = sizeNeeded;
+        if (sizeNeeded > scratchBufferSize) {
+            scratchBufferSize = sizeNeeded;
             scratchByteBuffer = ByteBuffer.allocateDirect(sizeNeeded);
             scratchCharBuffer = scratchByteBuffer.asCharBuffer();
-            scratchByteBuffer = null;
+//   why did this ever work         scratchByteBuffer = null;
         }
         if (scratchByteBuffer == null) {
-            scratchByteBuffer = ByteBuffer.allocateDirect(bufferSize);
+            scratchByteBuffer = ByteBuffer.allocateDirect(scratchBufferSize);
             scratchCharBuffer = scratchByteBuffer.asCharBuffer();
         } else {
             scratchByteBuffer.clear();

=== modified file 'clusterj-tie/src/main/java/com/mysql/clusterj/tie/PartitionKeyImpl.java'
--- a/clusterj-tie/src/main/java/com/mysql/clusterj/tie/PartitionKeyImpl.java	2010-04-04 00:07:21 +0000
+++ b/clusterj-tie/src/main/java/com/mysql/clusterj/tie/PartitionKeyImpl.java	2010-09-03 00:36:26 +0000
@@ -113,9 +113,6 @@ class PartitionKeyImpl implements Partit
                     + " table: " + (tableName==null?"null":tableName));
             result = db.enlist(tableName, keyParts);
         }
-      if (logger.isDebugEnabled()) logger.debug(
-              "PartitionKeyImpl.enlist transaction id: "
-               + Long.toHexString(result.getTransactionId()));
         return result;
     }
 

=== modified file 'clusterj-tie/src/main/java/com/mysql/clusterj/tie/ResultDataImpl.java'
--- a/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ResultDataImpl.java	2010-06-12 05:48:18 +0000
+++ b/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ResultDataImpl.java	2010-09-03 00:36:26 +0000
@@ -79,49 +79,29 @@ class ResultDataImpl implements ResultDa
     /** The Columns in this result */
     private final Column[] storeColumns;
 
-    /** Construct the ResultDataImpl based on an NdbOperation and a list of columns
-     * to include in the result. The ResultDataImpl is constructed before the operation
-     * is defined.
+    /** Construct the ResultDataImpl based on an NdbOperation, a list of columns
+     * to include in the result, and the pre-computed buffer layout for the result.
      * @param ndbOperation the NdbOperation
      * @param storeColumns the columns in the result
+     * @param maximumColumnId the largest column id
+     * @param bufferSize the size of the buffer needed
+     * @param offsets the array of offsets indexed by column id
+     * @param lengths the array of lengths indexed by column id
      */
-    public ResultDataImpl(NdbOperation ndbOperation, List<Column> storeColumns) {
+    public ResultDataImpl(NdbOperation ndbOperation, List<Column> storeColumns,
+            int maximumColumnId, int bufferSize, int[] offsets, int[] lengths) {
         this.ndbOperation = ndbOperation;
         // save the column list
         this.storeColumns = storeColumns.toArray(new Column[storeColumns.size()]);
-        initializeColumns(ndbOperation, storeColumns);
-    }
-
-    /** Initialize the operation using the columns that are requested.
-     * @param ndbOperation the operation
-     * @param storeColumns the columns to be retrieved
-     */
-    private void initializeColumns(NdbOperation ndbOperation,
-            List<Column> storeColumns) {
-        // collect the column ids so we can use an indexed array for offsets and lengths
-        int capacity = 0;
-        int columnId = 0;
-        int maximumColumnId = 0;
-        for (Column storeColumn: storeColumns) {
-            maximumColumnId = Math.max(maximumColumnId, storeColumn.getColumnId());
-        }
-        offsets = new int[maximumColumnId + 1];
-        lengths = new int[maximumColumnId + 1];
-        // iterate the list of store columns and create a buffer big enough for all columns
-        for (Column storeColumn: storeColumns) {
-            columnId = storeColumn.getColumnId();
-            int columnSpace = storeColumn.getColumnSpace();
-            lengths[columnId] = columnSpace;
-            offsets[columnId] = capacity;
-            capacity += columnSpace;
-        }
-        byteBuffer = ByteBuffer.allocateDirect(capacity);
+        this.offsets = offsets;
+        this.lengths = lengths;
+        byteBuffer = ByteBuffer.allocateDirect(bufferSize);
         byteBuffer.order(ByteOrder.nativeOrder());
         // iterate the list of store columns and allocate an NdbRecAttr (via getValue) for each
         ndbRecAttrs = new NdbRecAttr[maximumColumnId + 1];
         for (Column storeColumn: storeColumns) {
             NdbRecAttr ndbRecAttr = null;
-            columnId = storeColumn.getColumnId();
+            int columnId = storeColumn.getColumnId();
             byteBuffer.position(offsets[columnId]);
             if (lengths[columnId] == 0) {
                 ndbRecAttr = ndbOperation.getValue(columnId, null);

=== modified file 'clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanOperationImpl.java'
--- a/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanOperationImpl.java	2010-03-10 18:23:50 +0000
+++ b/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanOperationImpl.java	2010-09-03 00:36:26 +0000
@@ -27,6 +27,7 @@ import com.mysql.clusterj.core.query.Que
 import com.mysql.clusterj.core.store.ResultData;
 import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.store.ScanOperation;
+import com.mysql.clusterj.core.store.Table;
 
 /**
  *
@@ -35,8 +36,9 @@ class ScanOperationImpl extends Operatio
 
     private NdbScanOperation ndbScanOperation;
 
-    ScanOperationImpl(NdbScanOperation operation, ClusterTransactionImpl clusterTransaction) {
-        super(operation, clusterTransaction);
+    ScanOperationImpl(Table storeTable, NdbScanOperation operation,
+            ClusterTransactionImpl clusterTransaction) {
+        super(storeTable, operation, clusterTransaction);
         this.ndbScanOperation = operation;
     }
 
@@ -65,8 +67,9 @@ class ScanOperationImpl extends Operatio
 
     @Override
     public ResultData resultData() {
-        ResultData result = new ScanResultDataImpl(ndbScanOperation, storeColumns);
-        clusterTransaction.executeNoCommit(false, false);
+        ResultData result = new ScanResultDataImpl(ndbScanOperation, storeColumns,
+                maximumColumnId, bufferSize, offsets, lengths);
+        clusterTransaction.executeNoCommit(false, true);
         return result;
     }
 

=== modified file 'clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanResultDataImpl.java'
--- a/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanResultDataImpl.java	2010-02-20 18:45:24 +0000
+++ b/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanResultDataImpl.java	2010-09-03 00:36:26 +0000
@@ -49,8 +49,9 @@ class ScanResultDataImpl extends ResultD
     protected final int SCAN_FINISHED = 1;
     protected final int CACHE_EMPTY = 2;
 
-    public ScanResultDataImpl(NdbScanOperation ndbScanOperation, List<Column> storeColumns) {
-        super(ndbScanOperation, storeColumns);
+    public ScanResultDataImpl(NdbScanOperation ndbScanOperation, List<Column> storeColumns,
+            int maximumColumnId, int bufferSize, int[] offsets, int[] lengths) {
+        super(ndbScanOperation, storeColumns, maximumColumnId, bufferSize, offsets, lengths);
         this.ndbScanOperation = ndbScanOperation;
     }
 

=== modified file 'clusterj-tie/src/main/java/com/mysql/clusterj/tie/TableImpl.java'
--- a/clusterj-tie/src/main/java/com/mysql/clusterj/tie/TableImpl.java	2010-05-25 17:08:11 +0000
+++ b/clusterj-tie/src/main/java/com/mysql/clusterj/tie/TableImpl.java	2010-09-03 00:36:26 +0000
@@ -31,6 +31,7 @@ import com.mysql.clusterj.core.util.I18N
 import com.mysql.clusterj.core.util.Logger;
 import com.mysql.clusterj.core.util.LoggerFactoryService;
 
+import com.mysql.ndbjtie.ndbapi.NdbRecord;
 import com.mysql.ndbjtie.ndbapi.NdbDictionary.ColumnConst;
 import com.mysql.ndbjtie.ndbapi.NdbDictionary.TableConst;
 
@@ -65,6 +66,18 @@ class TableImpl implements Table {
     /** The index names for this table */
     private String[] indexNames;
 
+    /** The array of lengths of column space indexed by column id */
+    private int[] lengths;
+
+    /** The array of offsets of column space indexed by column id */
+    private int[] offsets;
+
+    /** The total size of buffer needed for all columns */
+    private int bufferSize;
+
+    /** The maximum column id */
+    private int maximumColumnId;
+
     public TableImpl(TableConst ndbTable, String[] indexNames) {
         this.tableName = ndbTable.getName();
         // process columns and partition key columns
@@ -72,6 +85,7 @@ class TableImpl implements Table {
         List<String> primaryKeyColumnNameList = new ArrayList<String>();
 
         int noOfColumns = ndbTable.getNoOfColumns();
+        ColumnImpl[] columnImpls = new ColumnImpl[noOfColumns];
         columnNames = new String[noOfColumns];
         for (int i = 0; i < noOfColumns; ++i) {
             ColumnConst column = ndbTable.getColumn(i);
@@ -84,9 +98,29 @@ class TableImpl implements Table {
             }
             ColumnConst ndbColumn = ndbTable.getColumn(i);
             String columnName = ndbColumn.getName();
-            columns.put(columnName, new ColumnImpl(tableName, ndbColumn));
+            ColumnImpl columnImpl = new ColumnImpl(tableName, ndbColumn);
+            columns.put(columnName, columnImpl);
+            columnImpls[i] = columnImpl;
             columnNames[i] = columnName;
+            // find maximum column id
+            int columnId = ndbColumn.getColumnNo();
+            if (columnId > maximumColumnId) {
+                maximumColumnId = columnId;
+            }
+        }
+        // iterate columns again and construct layout of record in memory
+        offsets = new int[maximumColumnId + 1];
+        lengths = new int[maximumColumnId + 1];
+        int offset = 0;
+        for (int i = 0; i < noOfColumns; ++i) {
+            ColumnImpl columnImpl = columnImpls[i];
+            int columnId = columnImpl.getColumnId();
+            int columnSpace = columnImpl.getColumnSpace();
+            lengths[columnId] = columnSpace;
+            offsets[columnId] = offset;
+            offset += columnSpace;            
         }
+        bufferSize = offset;
         this.primaryKeyColumnNames = 
             primaryKeyColumnNameList.toArray(new String[primaryKeyColumnNameList.size()]);
         this.partitionKeyColumnNames = 
@@ -124,4 +158,20 @@ class TableImpl implements Table {
         return columnNames;
     }
 
+    public int getMaximumColumnId() {
+        return maximumColumnId;
+    }
+
+    public int getBufferSize() {
+        return bufferSize;
+    }
+
+    public int[] getOffsets() {
+        return offsets;
+    }
+
+    public int[] getLengths() {
+        return lengths;
+    }
+
 }

=== modified file 'clusterj-tie/src/main/resources/com/mysql/clusterj/tie/Bundle.properties'
--- a/clusterj-tie/src/main/resources/com/mysql/clusterj/tie/Bundle.properties	2010-04-14 21:38:33 +0000
+++ b/clusterj-tie/src/main/resources/com/mysql/clusterj/tie/Bundle.properties	2010-09-03 00:36:26 +0000
@@ -41,3 +41,4 @@ ERR_Encode_Bad_Return_Code:Error encodin
 ERR_Mismatch_No_Of_Primary_Key_Columns:For table {0} number of primary key columns {1} doesn't match \
 number of columns in primary key index {2}.
 ERR_Failed_Loading_Library:Attempt to load native library {0} from path {1} failed with {2} ({3}).
+ERR_Unknown_Lock_Mode:The lock mode {0} is unknown.


Attachment: [text/bzr-bundle] bzr/craig.russell@oracle.com-20100903003626-rqp9pujyhydlns84.bundle
Thread
bzr push into clusterj branch (Craig.Russell:313 to 314)Craig L Russell3 Sep