You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2014/03/27 15:30:51 UTC

svn commit: r1582323 - in /cayenne/main/trunk: cayenne-crypto/src/main/java/org/apache/cayenne/crypto/batch/ cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/ cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/ cayenne-s...

Author: aadamchik
Date: Thu Mar 27 14:30:50 2014
New Revision: 1582323

URL: http://svn.apache.org/r1582323
Log:
CAY-1923 Optimize BatchTranslator - use fixed size array of BatchParameterBinding

precompiling bindings ... updating them for each row

Modified:
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/batch/CryptoBatchTranslatorFactoryDecorator.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/BatchAction.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchParameterBinding.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchTranslator.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DefaultBatchTranslator.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DeleteBatchTranslator.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/InsertBatchTranslator.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/SoftDeleteBatchTranslator.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/UpdateBatchTranslator.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8LOBBatchAction.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8LOBBatchTranslator.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/CommonsJdbcEventLogger.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/JdbcEventLogger.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/NoopJdbcEventLogger.java
    cayenne/main/trunk/cayenne-server/src/test/java/org/apache/cayenne/access/translator/batch/DefaultBatchTranslatorTest.java
    cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt

Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/batch/CryptoBatchTranslatorFactoryDecorator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/batch/CryptoBatchTranslatorFactoryDecorator.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/batch/CryptoBatchTranslatorFactoryDecorator.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/batch/CryptoBatchTranslatorFactoryDecorator.java Thu Mar 27 14:30:50 2014
@@ -18,8 +18,6 @@
  ****************************************************************/
 package org.apache.cayenne.crypto.batch;
 
-import java.util.List;
-
 import org.apache.cayenne.access.translator.batch.BatchParameterBinding;
 import org.apache.cayenne.access.translator.batch.BatchTranslator;
 import org.apache.cayenne.access.translator.batch.BatchTranslatorFactory;
@@ -57,10 +55,16 @@ public class CryptoBatchTranslatorFactor
             public String getSql() {
                 return delegateTranslator.getSql();
             }
-
+            
+            @Override
+            public BatchParameterBinding[] getBindings() {
+                return delegateTranslator.getBindings();
+            }
+            
             @Override
-            public List<BatchParameterBinding> createBindings(BatchQueryRow row) {
-                List<BatchParameterBinding> bindings = delegateTranslator.createBindings(row);
+            public BatchParameterBinding[] updateBindings(BatchQueryRow row) {
+              
+                BatchParameterBinding[] bindings = delegateTranslator.updateBindings(row);
 
                 for (BatchParameterBinding b : bindings) {
                     if (columnMapper.isEncrypted(b.getAttribute())) {

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/BatchAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/BatchAction.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/BatchAction.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/BatchAction.java Thu Mar 27 14:30:50 2014
@@ -26,7 +26,6 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
 
 import org.apache.cayenne.CayenneException;
 import org.apache.cayenne.ResultIterator;
@@ -54,13 +53,14 @@ public class BatchAction extends BaseSQL
     protected BatchQuery query;
     protected RowDescriptor keyRowDescriptor;
 
-    private static void bind(DbAdapter adapter, PreparedStatement statement, List<BatchParameterBinding> bindings)
+    private static void bind(DbAdapter adapter, PreparedStatement statement, BatchParameterBinding[] bindings)
             throws SQLException, Exception {
-        int len = bindings.size();
-        for (int i = 0; i < len; i++) {
-            BatchParameterBinding b = bindings.get(i);
-            adapter.bindParameter(statement, b.getValue(), i + 1, b.getAttribute().getType(), b.getAttribute()
-                    .getScale());
+
+        for (BatchParameterBinding b : bindings) {
+            if (!b.isExcluded()) {
+                adapter.bindParameter(statement, b.getValue(), b.getStatementPosition(), b.getAttribute().getType(), b
+                        .getAttribute().getScale());
+            }
         }
     }
 
@@ -100,21 +100,21 @@ public class BatchAction extends BaseSQL
     protected void runAsBatch(Connection con, BatchTranslator translator, OperationObserver delegate)
             throws SQLException, Exception {
 
-        String queryStr = translator.getSql();
+        String sql = translator.getSql();
         JdbcEventLogger logger = dataNode.getJdbcEventLogger();
         boolean isLoggable = logger.isLoggable();
 
         // log batch SQL execution
-        logger.logQuery(queryStr, Collections.EMPTY_LIST);
+        logger.logQuery(sql, Collections.EMPTY_LIST);
 
         // run batch
 
         DbAdapter adapter = dataNode.getAdapter();
-        PreparedStatement statement = con.prepareStatement(queryStr);
+        PreparedStatement statement = con.prepareStatement(sql);
         try {
             for (BatchQueryRow row : query.getRows()) {
 
-                List<BatchParameterBinding> bindings = translator.createBindings(row);
+                BatchParameterBinding[] bindings = translator.updateBindings(row);
                 logger.logQueryParameters("batch bind", bindings);
                 bind(adapter, statement, bindings);
 
@@ -171,7 +171,7 @@ public class BatchAction extends BaseSQL
         try {
             for (BatchQueryRow row : query.getRows()) {
 
-                List<BatchParameterBinding> bindings = translator.createBindings(row);
+                BatchParameterBinding[] bindings = translator.updateBindings(row);
                 logger.logQueryParameters("bind", bindings);
 
                 bind(adapter, statement, bindings);

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchParameterBinding.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchParameterBinding.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchParameterBinding.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchParameterBinding.java Thu Mar 27 14:30:50 2014
@@ -25,12 +25,15 @@ import org.apache.cayenne.map.DbAttribut
  */
 public class BatchParameterBinding {
 
+    static final int EXCLUDED_POSITION = -1;
+
     private DbAttribute attribute;
     private Object value;
+    private int statementPosition;
 
-    public BatchParameterBinding(DbAttribute attribute, Object value) {
+    public BatchParameterBinding(DbAttribute attribute) {
         this.attribute = attribute;
-        this.value = value;
+        this.statementPosition = EXCLUDED_POSITION;
     }
 
     public DbAttribute getAttribute() {
@@ -44,4 +47,33 @@ public class BatchParameterBinding {
     public void setValue(Object value) {
         this.value = value;
     }
+
+    public int getStatementPosition() {
+        return statementPosition;
+    }
+
+    public void setStatementPosition(int statementPosition) {
+        this.statementPosition = statementPosition;
+    }
+
+    public boolean isExcluded() {
+        return statementPosition == EXCLUDED_POSITION;
+    }
+
+    /**
+     * Marks the binding object as excluded for the current iteration.
+     */
+    public void exclude() {
+        this.statementPosition = EXCLUDED_POSITION;
+        this.value = null;
+    }
+
+    /**
+     * Sets the value of the binding and initializes statement position var,
+     * thus "including" this binding in the current iteration.
+     */
+    public void include(int statementPosition, Object value) {
+        this.statementPosition = statementPosition;
+        this.value = value;
+    }
 }

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchTranslator.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchTranslator.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchTranslator.java Thu Mar 27 14:30:50 2014
@@ -19,8 +19,6 @@
 
 package org.apache.cayenne.access.translator.batch;
 
-import java.util.List;
-
 import org.apache.cayenne.query.BatchQueryRow;
 
 /**
@@ -36,7 +34,16 @@ public interface BatchTranslator {
     String getSql();
 
     /**
-     * Returns PreparedStatement bindings for a given row.
+     * Returns the widest possible array of bindings for this query. Each
+     * binding's position corresponds to a value position in
+     * {@link BatchQueryRow}.
+     */
+    BatchParameterBinding[] getBindings();
+
+    /**
+     * Updates internal bindings to be used with a given row, returning updated
+     * bindings array. Note that usually the returned array is the same copy on
+     * every iteration, only with changed object state.
      */
-    List<BatchParameterBinding> createBindings(BatchQueryRow row);
+    BatchParameterBinding[] updateBindings(BatchQueryRow row);
 }

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DefaultBatchTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DefaultBatchTranslator.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DefaultBatchTranslator.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DefaultBatchTranslator.java Thu Mar 27 14:30:50 2014
@@ -19,7 +19,6 @@
 package org.apache.cayenne.access.translator.batch;
 
 import java.sql.Types;
-import java.util.List;
 
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.QuotingStrategy;
@@ -40,6 +39,7 @@ public abstract class DefaultBatchTransl
 
     protected boolean translated;
     protected String sql;
+    protected BatchParameterBinding[] bindings;
 
     public DefaultBatchTranslator(BatchQuery query, DbAdapter adapter, String trimFunction) {
         this.query = query;
@@ -50,12 +50,11 @@ public abstract class DefaultBatchTransl
     protected void ensureTranslated() {
         if (!translated) {
             this.sql = createSql();
+            this.bindings = createBindings();
             translated = true;
         }
     }
 
-    protected abstract String createSql();
-
     /**
      * Translates BatchQuery into an SQL string formatted to use in a
      * PreparedStatement.
@@ -66,11 +65,23 @@ public abstract class DefaultBatchTransl
         return sql;
     }
 
-    /**
-     * Returns PreparedStatement bindings for a given row.
-     */
     @Override
-    public abstract List<BatchParameterBinding> createBindings(BatchQueryRow row);
+    public BatchParameterBinding[] getBindings() {
+        ensureTranslated();
+        return bindings;
+    }
+    
+    @Override
+    public BatchParameterBinding[] updateBindings(BatchQueryRow row) {
+        ensureTranslated();
+        return doUpdateBindings(row);
+    }
+
+    protected abstract String createSql();
+
+    protected abstract BatchParameterBinding[] createBindings();
+    
+    protected abstract BatchParameterBinding[] doUpdateBindings(BatchQueryRow row);
 
     /**
      * Appends the name of the column to the query buffer. Subclasses use this

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DeleteBatchTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DeleteBatchTranslator.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DeleteBatchTranslator.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DeleteBatchTranslator.java Thu Mar 27 14:30:50 2014
@@ -19,7 +19,6 @@
 
 package org.apache.cayenne.access.translator.batch;
 
-import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
@@ -71,29 +70,39 @@ public class DeleteBatchTranslator exten
         }
     }
 
-    /**
-     * @since 3.2
-     */
     @Override
-    public List<BatchParameterBinding> createBindings(BatchQueryRow row) {
-
+    protected BatchParameterBinding[] createBindings() {
         DeleteBatchQuery deleteBatch = (DeleteBatchQuery) query;
         List<DbAttribute> attributes = deleteBatch.getDbAttributes();
         int len = attributes.size();
 
-        List<BatchParameterBinding> bindings = new ArrayList<BatchParameterBinding>(len);
+        BatchParameterBinding[] bindings = new BatchParameterBinding[len];
 
         for (int i = 0; i < len; i++) {
-
             DbAttribute a = attributes.get(i);
+            bindings[i] = new BatchParameterBinding(a);
+        }
+
+        return bindings;
+    }
+
+    @Override
+    protected BatchParameterBinding[] doUpdateBindings(BatchQueryRow row) {
+
+        int len = bindings.length;
+
+        DeleteBatchQuery deleteBatch = (DeleteBatchQuery) query;
+
+        for (int i = 0, j = 1; i < len; i++) {
+
+            BatchParameterBinding b = bindings[i];
 
             // skip null attributes... they are translated as "IS NULL"
-            if (deleteBatch.isNull(a)) {
-                continue;
+            if (deleteBatch.isNull(b.getAttribute())) {
+                b.exclude();
+            } else {
+                b.include(j++, row.getValue(i));
             }
-
-            Object value = row.getValue(i);
-            bindings.add(new BatchParameterBinding(a, value));
         }
 
         return bindings;

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/InsertBatchTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/InsertBatchTranslator.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/InsertBatchTranslator.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/InsertBatchTranslator.java Thu Mar 27 14:30:50 2014
@@ -19,7 +19,6 @@
 
 package org.apache.cayenne.access.translator.batch;
 
-import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.cayenne.dba.DbAdapter;
@@ -39,28 +38,6 @@ public class InsertBatchTranslator exten
         super(query, adapter, null);
     }
 
-    /**
-     * @since 3.2
-     */
-    @Override
-    public List<BatchParameterBinding> createBindings(BatchQueryRow row) {
-
-        List<DbAttribute> attributes = query.getDbAttributes();
-        int len = attributes.size();
-
-        List<BatchParameterBinding> bindings = new ArrayList<BatchParameterBinding>(len);
-
-        for (int i = 0; i < len; i++) {
-            DbAttribute a = attributes.get(i);
-            if (includeInBatch(a)) {
-                Object value = row.getValue(i);
-                bindings.add(new BatchParameterBinding(a, value));
-            }
-        }
-
-        return bindings;
-    }
-
     @Override
     protected String createSql() {
 
@@ -103,6 +80,48 @@ public class InsertBatchTranslator exten
         return buffer.toString();
     }
 
+    @Override
+    protected BatchParameterBinding[] createBindings() {
+        List<DbAttribute> attributes = query.getDbAttributes();
+        int len = attributes.size();
+
+        BatchParameterBinding[] bindings = new BatchParameterBinding[len];
+
+        for (int i = 0; i < len; i++) {
+            DbAttribute a = attributes.get(i);
+            bindings[i] = new BatchParameterBinding(a);
+
+            // include/exclude state depends on DbAttribute only and can be
+            // precompiled here
+            if (includeInBatch(a)) {
+                // setting fake position here... all we care about is that it is
+                // > -1
+                bindings[i].include(1, null);
+            } else {
+                bindings[i].exclude();
+            }
+        }
+
+        return bindings;
+    }
+
+    @Override
+    protected BatchParameterBinding[] doUpdateBindings(BatchQueryRow row) {
+        int len = bindings.length;
+
+        for (int i = 0, j = 1; i < len; i++) {
+
+            BatchParameterBinding b = bindings[i];
+
+            // exclusions are permanent
+            if (!b.isExcluded()) {
+                b.include(j++, row.getValue(i));
+            }
+        }
+
+        return bindings;
+    }
+
     /**
      * Returns true if an attribute should be included in the batch.
      * 

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/SoftDeleteBatchTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/SoftDeleteBatchTranslator.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/SoftDeleteBatchTranslator.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/SoftDeleteBatchTranslator.java Thu Mar 27 14:30:50 2014
@@ -18,8 +18,6 @@
  ****************************************************************/
 package org.apache.cayenne.access.translator.batch;
 
-import java.util.List;
-
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.QuotingStrategy;
 import org.apache.cayenne.map.DbAttribute;
@@ -55,14 +53,42 @@ public class SoftDeleteBatchTranslator e
     }
 
     @Override
-    public List<BatchParameterBinding> createBindings(BatchQueryRow row) {
+    protected BatchParameterBinding[] createBindings() {
+
+        BatchParameterBinding[] superBindings = super.createBindings();
+
+        int slen = superBindings.length;
 
-        List<BatchParameterBinding> bindings = super.createBindings(row);
+        BatchParameterBinding[] bindings = new BatchParameterBinding[slen + 1];
 
         DbAttribute deleteAttribute = query.getDbEntity().getAttribute(deletedFieldName);
-        bindings.add(0, new BatchParameterBinding(deleteAttribute, true));
+        bindings[0] = new BatchParameterBinding(deleteAttribute);
+        bindings[0].include(1, true);
+        
+        System.arraycopy(superBindings, 0, bindings, 1, slen);
 
         return bindings;
     }
 
+    @Override
+    protected BatchParameterBinding[] doUpdateBindings(BatchQueryRow row) {
+        int len = bindings.length;
+
+        DeleteBatchQuery deleteBatch = (DeleteBatchQuery) query;
+
+        // skip position 0... Otherwise follow super algorithm
+        for (int i = 1, j = 2; i < len; i++) {
+
+            BatchParameterBinding b = bindings[i];
+
+            // skip null attributes... they are translated as "IS NULL"
+            if (deleteBatch.isNull(b.getAttribute())) {
+                b.exclude();
+            } else {
+                b.include(j++, row.getValue(i - 1));
+            }
+        }
+
+        return bindings;
+    }
 }

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/UpdateBatchTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/UpdateBatchTranslator.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/UpdateBatchTranslator.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/UpdateBatchTranslator.java Thu Mar 27 14:30:50 2014
@@ -19,7 +19,6 @@
 
 package org.apache.cayenne.access.translator.batch;
 
-import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
@@ -79,7 +78,32 @@ public class UpdateBatchTranslator exten
     }
 
     @Override
-    public List<BatchParameterBinding> createBindings(BatchQueryRow row) {
+    protected BatchParameterBinding[] createBindings() {
+        UpdateBatchQuery updateBatch = (UpdateBatchQuery) query;
+
+        List<DbAttribute> updatedDbAttributes = updateBatch.getUpdatedAttributes();
+        List<DbAttribute> qualifierAttributes = updateBatch.getQualifierAttributes();
+
+        int ul = updatedDbAttributes.size();
+        int ql = qualifierAttributes.size();
+
+        BatchParameterBinding[] bindings = new BatchParameterBinding[ul + ql];
+
+        for (int i = 0; i < ul; i++) {
+            DbAttribute a = updatedDbAttributes.get(i);
+            bindings[i] = new BatchParameterBinding(a);
+        }
+
+        for (int i = 0; i < ql; i++) {
+            DbAttribute a = qualifierAttributes.get(i);
+            bindings[ul + i] = new BatchParameterBinding(a);
+        }
+
+        return bindings;
+    }
+
+    @Override
+    protected BatchParameterBinding[] doUpdateBindings(BatchQueryRow row) {
 
         UpdateBatchQuery updateBatch = (UpdateBatchQuery) query;
 
@@ -89,13 +113,11 @@ public class UpdateBatchTranslator exten
         int ul = updatedDbAttributes.size();
         int ql = qualifierAttributes.size();
 
-        List<BatchParameterBinding> bindings = new ArrayList<BatchParameterBinding>(ul + ql);
+        int j = 1;
 
         for (int i = 0; i < ul; i++) {
             Object value = row.getValue(i);
-
-            DbAttribute a = updatedDbAttributes.get(i);
-            bindings.add(new BatchParameterBinding(a, value));
+            bindings[i].include(j++, value);
         }
 
         for (int i = 0; i < ql; i++) {
@@ -108,7 +130,7 @@ public class UpdateBatchTranslator exten
             }
 
             Object value = row.getValue(ul + i);
-            bindings.add(new BatchParameterBinding(a, value));
+            bindings[ul + i].include(j++, value);
         }
 
         return bindings;

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8LOBBatchAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8LOBBatchAction.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8LOBBatchAction.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8LOBBatchAction.java Thu Mar 27 14:30:50 2014
@@ -55,13 +55,12 @@ class Oracle8LOBBatchAction implements S
     private DbAdapter adapter;
     private JdbcEventLogger logger;
 
-    private static void bind(DbAdapter adapter, PreparedStatement statement, List<BatchParameterBinding> bindings)
+    private static void bind(DbAdapter adapter, PreparedStatement statement, BatchParameterBinding[] bindings)
             throws SQLException, Exception {
-        int len = bindings.size();
-        for (int i = 0; i < len; i++) {
-            BatchParameterBinding b = bindings.get(i);
-            adapter.bindParameter(statement, b.getValue(), i + 1, b.getAttribute().getType(), b.getAttribute()
-                    .getScale());
+
+        for (BatchParameterBinding b : bindings) {
+            adapter.bindParameter(statement, b.getValue(), b.getStatementPosition(), b.getAttribute().getType(), b
+                    .getAttribute().getScale());
         }
     }
 
@@ -105,7 +104,7 @@ class Oracle8LOBBatchAction implements S
             PreparedStatement statement = connection.prepareStatement(updateStr);
             try {
 
-                List<BatchParameterBinding> bindings = translator.createBindings(row);
+                BatchParameterBinding[] bindings = translator.updateBindings(row);
                 logger.logQueryParameters("bind", bindings);
 
                 bind(adapter, statement, bindings);

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8LOBBatchTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8LOBBatchTranslator.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8LOBBatchTranslator.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8LOBBatchTranslator.java Thu Mar 27 14:30:50 2014
@@ -20,7 +20,6 @@
 package org.apache.cayenne.dba.oracle;
 
 import java.sql.Types;
-import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
@@ -109,23 +108,41 @@ abstract class Oracle8LOBBatchTranslator
             }
         }
     }
-
+    
     @Override
-    public List<BatchParameterBinding> createBindings(BatchQueryRow row) {
+    protected BatchParameterBinding[] createBindings() {
         List<DbAttribute> dbAttributes = query.getDbAttributes();
         int len = dbAttributes.size();
 
-        List<BatchParameterBinding> bindings = new ArrayList<BatchParameterBinding>(len);
+        BatchParameterBinding[] bindings = new BatchParameterBinding[len];
 
         for (int i = 0; i < len; i++) {
-            Object value = row.getValue(i);
             DbAttribute attribute = dbAttributes.get(i);
+            bindings[i] = new BatchParameterBinding(attribute);
+        }
+
+        return bindings;
+    }
+    
+    @Override
+    protected BatchParameterBinding[] doUpdateBindings(BatchQueryRow row) {
+
+        int len = bindings.length;
+
+        for (int i = 0, j = 1; i < len; i++) {
+
+            BatchParameterBinding b = bindings[i];
+
+            Object value = row.getValue(i);
+            DbAttribute attribute = b.getAttribute();
             int type = attribute.getType();
 
             // TODO: (Andrus) This works as long as there is no LOBs in
             // qualifier
             if (isUpdateableColumn(value, type)) {
-                bindings.add(new BatchParameterBinding(attribute, value));
+                b.include(j++, value);
+            } else {
+                b.exclude();
             }
         }
 

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/CommonsJdbcEventLogger.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/CommonsJdbcEventLogger.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/CommonsJdbcEventLogger.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/CommonsJdbcEventLogger.java Thu Mar 27 14:30:50 2014
@@ -269,30 +269,7 @@ public class CommonsJdbcEventLogger impl
         }
     }
 
-    private void buildLog(StringBuilder buffer, List<BatchParameterBinding> bindings) {
-
-        int len = bindings.size();
-
-        for (int i = 0; i < len; i++) {
-
-            if (i > 0) {
-                buffer.append(", ");
-            }
-
-            BatchParameterBinding b = bindings.get(i);
-            DbAttribute attribute = b.getAttribute();
-
-            buffer.append(i + 1);
-
-            if (attribute != null) {
-                buffer.append("->");
-                buffer.append(attribute.getName());
-            }
-
-            buffer.append(":");
-            sqlLiteralForObject(buffer, b.getValue());
-        }
-    }
+   
 
     private boolean isInserting(String query) {
         if (query == null || query.length() == 0)
@@ -333,16 +310,47 @@ public class CommonsJdbcEventLogger impl
     }
 
     @Override
-    public void logQueryParameters(String label, List<BatchParameterBinding> bindings) {
+    public void logQueryParameters(String label, BatchParameterBinding[] bindings) {
 
-        if (isLoggable() && bindings.size() > 0) {
-            StringBuilder buffer = new StringBuilder();
+        if (isLoggable() && bindings.length > 0) {
 
-            buffer.append("[").append(label).append(": ");
-            buildLog(buffer, bindings);
-            buffer.append("]");
+            boolean hasIncluded = false;
+            StringBuilder buffer = null;
 
-            logger.info(buffer.toString());
+            int len = bindings.length;
+            for (int i = 0, j = 1; i < len; i++) {
+                BatchParameterBinding b = bindings[i];
+
+                if (b.isExcluded()) {
+                    continue;
+                }
+
+                if (hasIncluded) {
+                    buffer.append(", ");
+                } else {
+                    hasIncluded = true;
+                    buffer = new StringBuilder();
+                    buffer.append("[").append(label).append(": ");
+                }
+
+                DbAttribute attribute = b.getAttribute();
+
+                buffer.append(j++);
+
+                if (attribute != null) {
+                    buffer.append("->");
+                    buffer.append(attribute.getName());
+                }
+
+                buffer.append(":");
+                sqlLiteralForObject(buffer, b.getValue());
+            }
+
+            if (hasIncluded) {
+                buffer.append("]");
+
+                logger.info(buffer.toString());
+            }
         }
     }
 

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/JdbcEventLogger.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/JdbcEventLogger.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/JdbcEventLogger.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/JdbcEventLogger.java Thu Mar 27 14:30:50 2014
@@ -61,7 +61,7 @@ public interface JdbcEventLogger {
     /**
      * @since 3.2
      */
-    void logQueryParameters(String label, List<BatchParameterBinding> bindings);
+    void logQueryParameters(String label, BatchParameterBinding[] bindings);
 
     /**
      * @deprecated since 3.2 in favor of

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/NoopJdbcEventLogger.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/NoopJdbcEventLogger.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/NoopJdbcEventLogger.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/log/NoopJdbcEventLogger.java Thu Mar 27 14:30:50 2014
@@ -76,7 +76,7 @@ public class NoopJdbcEventLogger impleme
     }
     
     @Override
-    public void logQueryParameters(String label, List<BatchParameterBinding> bindings) {
+    public void logQueryParameters(String label, BatchParameterBinding[] bindings) {
     }
 
     public void logSelectCount(int count, long time) {

Modified: cayenne/main/trunk/cayenne-server/src/test/java/org/apache/cayenne/access/translator/batch/DefaultBatchTranslatorTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/test/java/org/apache/cayenne/access/translator/batch/DefaultBatchTranslatorTest.java?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/test/java/org/apache/cayenne/access/translator/batch/DefaultBatchTranslatorTest.java (original)
+++ cayenne/main/trunk/cayenne-server/src/test/java/org/apache/cayenne/access/translator/batch/DefaultBatchTranslatorTest.java Thu Mar 27 14:30:50 2014
@@ -22,8 +22,6 @@ package org.apache.cayenne.access.transl
 import static org.mockito.Mockito.mock;
 
 import java.sql.Types;
-import java.util.Collections;
-import java.util.List;
 
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.JdbcAdapter;
@@ -51,8 +49,13 @@ public class DefaultBatchTranslatorTest 
             }
 
             @Override
-            public List<BatchParameterBinding> createBindings(BatchQueryRow row) {
-                return Collections.emptyList();
+            protected BatchParameterBinding[] createBindings() {
+                return new BatchParameterBinding[0];
+            }
+
+            @Override
+            protected BatchParameterBinding[] doUpdateBindings(BatchQueryRow row) {
+                return new BatchParameterBinding[0];
             }
         };
 
@@ -71,8 +74,13 @@ public class DefaultBatchTranslatorTest 
             }
 
             @Override
-            public List<BatchParameterBinding> createBindings(BatchQueryRow row) {
-                return Collections.emptyList();
+            protected BatchParameterBinding[] createBindings() {
+                return new BatchParameterBinding[0];
+            }
+
+            @Override
+            protected BatchParameterBinding[] doUpdateBindings(BatchQueryRow row) {
+                return new BatchParameterBinding[0];
             }
         };
 
@@ -100,8 +108,13 @@ public class DefaultBatchTranslatorTest 
             }
 
             @Override
-            public List<BatchParameterBinding> createBindings(BatchQueryRow row) {
-                return Collections.emptyList();
+            protected BatchParameterBinding[] createBindings() {
+                return new BatchParameterBinding[0];
+            }
+
+            @Override
+            protected BatchParameterBinding[] doUpdateBindings(BatchQueryRow row) {
+                return new BatchParameterBinding[0];
             }
         };
 

Modified: cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt?rev=1582323&r1=1582322&r2=1582323&view=diff
==============================================================================
--- cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt (original)
+++ cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt Thu Mar 27 14:30:50 2014
@@ -44,6 +44,7 @@ CAY-1915 BatchTranslator instead of perf
 CAY-1918 Replace Oracle LOB hacks with JDBC 4.0 API
 CAY-1919 Split DataNode creation into a separate DataNodeFactory
 CAY-1920 DI: add support for decorators
+CAY-1923 Optimize BatchTranslator - use fixed size array of BatchParameterBinding
 
 Bug Fixes: