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 2007/06/26 20:15:33 UTC

svn commit: r550891 - in /cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src: main/java/org/apache/cayenne/access/ test/java/org/apache/cayenne/access/

Author: aadamchik
Date: Tue Jun 26 11:15:32 2007
New Revision: 550891

URL: http://svn.apache.org/viewvc?view=rev&rev=550891
Log:
CAY-810 IncrementalFaultList performance improvements
changing the default algorithm for the first list pass - now will fetch only ObjectId columns for SelectQueries
my profiling tests show a significant speed up (and the bottleneck is clearly in bringing lots of unused data over the wire from db)

Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListTest.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java?view=diff&rev=550891&r1=550890&r2=550891
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java Tue Jun 26 11:15:32 2007
@@ -33,6 +33,7 @@
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.query.Query;
@@ -136,24 +137,36 @@
             helper = new PersistentListHelper();
         }
 
+        boolean resolvesFirstPage = true;
+
         if (!metadata.isFetchingDataRows() && (query instanceof SelectQuery)) {
             SelectQuery select = (SelectQuery) query;
 
             this.internalQuery.setPrefetchTree(select.getPrefetchTree());
 
-            if (select.getPrefetchTree() != null) {
-                // prefetching will blow iterated result, so strip prefetches... this is
-                // a bit of a hack
-                SelectQuery clone = select.queryWithParameters(
-                        Collections.EMPTY_MAP,
-                        true);
-                clone.clearPrefetches();
-                query = clone;
+            // optimize SelectQuery:
+            // * just select ID columns - this gives a 5-10x speedup
+            // * strip prefetches as they blow the iterated result, and are actually not
+            // needed
+
+            SelectQuery clone = select.queryWithParameters(Collections.EMPTY_MAP, true);
+            clone.clearPrefetches();
+
+            // I guess this check is redundant, as custom attributes warrant data rows
+            if (!select.isFetchingCustomAttributes()) {
+                Iterator pk = rootEntity.getDbEntity().getPrimaryKey().iterator();
+                while (pk.hasNext()) {
+                    DbAttribute attribute = (DbAttribute) pk.next();
+                    clone.addCustomDbAttribute(attribute.getName());
+                }
             }
+
+            query = clone;
+            resolvesFirstPage = false;
         }
 
         List elementsUnsynced = new ArrayList();
-        fillIn(query, elementsUnsynced);
+        fillIn(query, elementsUnsynced, resolvesFirstPage);
         this.elements = Collections.synchronizedList(elementsUnsynced);
     }
 
@@ -165,15 +178,6 @@
     }
 
     /**
-     * Returns true if it is possible to read the first page of inflated objects from the
-     * ResultSet returned from the main query. False is returned for queries with
-     * prefetches as resolving prefetches is not possible in this situation.
-     */
-    private boolean resolvesFirstPage() {
-        return internalQuery.getPrefetchTree() == null;
-    }
-
-    /**
      * Performs initialization of the internal list of objects. Only the first page is
      * fully resolved. For the rest of the list, only ObjectIds are read.
      * 
@@ -184,7 +188,7 @@
      */
     protected void fillIn(Query query) {
         synchronized (elements) {
-            fillIn(query, elements);
+            fillIn(query, elements, true);
         }
     }
 
@@ -194,7 +198,7 @@
      * 
      * @since 3.0
      */
-    protected void fillIn(Query query, List elementsList) {
+    protected void fillIn(Query query, List elementsList, boolean resolvesFirstPage) {
         QueryMetadata info = query.getMetaData(dataContext.getEntityResolver());
         boolean fetchesDataRows = internalQuery.isFetchingDataRows();
 
@@ -211,7 +215,7 @@
                 rowWidth = it.getDataRowWidth();
 
                 // resolve first page if we can
-                if (resolvesFirstPage()) {
+                if (resolvesFirstPage) {
                     // read first page completely, the rest as ObjectIds
                     for (int i = 0; i < pageSize && it.hasNextRow(); i++) {
                         elementsList.add(it.nextDataRow());
@@ -252,7 +256,7 @@
                     .unwindException(e));
         }
 
-        unfetchedObjects = (resolvesFirstPage())
+        unfetchedObjects = (resolvesFirstPage)
                 ? elementsList.size() - pageSize
                 : elementsList.size();
     }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextTest.java?view=diff&rev=550891&r1=550890&r2=550891
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextTest.java Tue Jun 26 11:15:32 2007
@@ -362,8 +362,10 @@
         assertNotNull(objects);
         assertTrue(objects instanceof IncrementalFaultList);
 
-        assertTrue(((IncrementalFaultList) objects).elements.get(0) instanceof Artist);
+        assertTrue(((IncrementalFaultList) objects).elements.get(0) instanceof Map);
         assertTrue(((IncrementalFaultList) objects).elements.get(7) instanceof Map);
+        
+        assertTrue(objects.get(0) instanceof Artist);
     }
 
     public void testPerformPaginatedQueryBigPage() throws Exception {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListTest.java?view=diff&rev=550891&r1=550890&r2=550891
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListTest.java Tue Jun 26 11:15:32 2007
@@ -119,9 +119,9 @@
 
     public void testUnfetchedObjects() throws Exception {
         prepareList(6);
-        assertEquals(DataContextTest.artistCount - 6, list.getUnfetchedObjects());
+        assertEquals(DataContextTest.artistCount, list.getUnfetchedObjects());
         list.get(7);
-        assertEquals(DataContextTest.artistCount - 12, list.getUnfetchedObjects());
+        assertEquals(DataContextTest.artistCount - 6, list.getUnfetchedObjects());
         list.resolveAll();
         assertEquals(0, list.getUnfetchedObjects());
     }
@@ -143,7 +143,7 @@
 
     public void testPagesRead1() throws Exception {
         prepareList(6);
-        assertTrue(list.elements.get(0) instanceof Artist);
+        assertTrue(list.elements.get(0) instanceof Map);
         assertTrue(list.elements.get(8) instanceof Map);
 
         list.resolveInterval(5, 10);
@@ -155,7 +155,7 @@
 
     public void testGet1() throws Exception {
         prepareList(6);
-        assertTrue(list.elements.get(0) instanceof Artist);
+        assertTrue(list.elements.get(0) instanceof Map);
         assertTrue(list.elements.get(8) instanceof Map);
 
         Object a = list.get(8);
@@ -168,9 +168,14 @@
     public void testGet2() throws Exception {
         prepareList(6);
         ((SelectQuery) query).setFetchingDataRows(true);
-        assertTrue(list.elements.get(0) instanceof Artist);
+        assertTrue(list.elements.get(0) instanceof Map);
         assertTrue(list.elements.get(8) instanceof Map);
 
+        Object a0 = list.get(0);
+
+        assertNotNull(a0);
+        assertTrue(list.elements.get(0) instanceof Artist);
+        
         Object a = list.get(8);
 
         assertNotNull(a);