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 Russell | 3 Sep |