You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by jk...@apache.org on 2017/10/13 09:30:27 UTC

[2/2] tapestry-5 git commit: TAP5-2589: improve data source handling if the pager is not shown Counting the number of results in an expensive operation for some data sources (especially databases), so we count only as far as we need to.

TAP5-2589: improve data source handling if the pager is not shown
Counting the number of results in an expensive operation for some data sources (especially databases), so we count
only as far as we need to.


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/68303b1d
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/68303b1d
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/68303b1d

Branch: refs/heads/master
Commit: 68303b1d61d09c997bade870587d4586625f17a6
Parents: 4958b71
Author: Jochen Kemnade <jo...@eddyson.de>
Authored: Fri Oct 13 11:27:43 2017 +0200
Committer: Jochen Kemnade <jo...@eddyson.de>
Committed: Fri Oct 13 11:27:43 2017 +0200

----------------------------------------------------------------------
 .../tapestry5/corelib/components/Grid.java      | 87 +++++++++++++++++---
 .../tapestry5/corelib/components/GridRows.java  | 14 ++--
 .../tapestry5/corelib/components/Grid.tml       |  6 +-
 3 files changed, 87 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/68303b1d/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Grid.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Grid.java b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Grid.java
index 814d5e1..a884e52 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Grid.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Grid.java
@@ -285,7 +285,7 @@ public class Grid implements GridModel, ClientElement
     }
 
     /**
-     * A version of GridDataSource that caches the availableRows property. This addresses TAPESTRY-2245.
+     * A version of GridDataSource that caches the availableRows and empty properties. This addresses TAPESTRY-2245.
      */
     static class CachingDataSource implements GridDataSource
     {
@@ -295,17 +295,70 @@ public class Grid implements GridModel, ClientElement
 
         private int availableRows;
 
+        private boolean emptyCached;
+
+        private boolean empty;
+
         CachingDataSource(GridDataSource delegate)
         {
             this.delegate = delegate;
         }
 
+        @Override
+        public boolean isEmpty()
+        {
+            if (!emptyCached)
+            {
+                empty = delegate.isEmpty();
+                emptyCached = true;
+                if (empty)
+                {
+                    availableRows = 0;
+                    availableRowsCached = true;
+                }
+            }
+
+            return empty;
+        }
+
+        @Override
+        public int getAvailableRows(int limit)
+        {
+            if (!availableRowsCached)
+            {
+                int result = delegate.getAvailableRows(limit);
+                if (result == 0)
+                {
+                    empty = true;
+                    emptyCached = true;
+                } else {
+                    empty = false;
+                    emptyCached = true;
+                }
+                if (result < limit) {
+                    availableRows = result;
+                    availableRowsCached = true;
+                }
+                return result;
+            } else {
+              return Math.min(availableRows, limit);
+            }
+        }
+
         public int getAvailableRows()
         {
             if (!availableRowsCached)
             {
                 availableRows = delegate.getAvailableRows();
                 availableRowsCached = true;
+                if (availableRows == 0)
+                {
+                    empty = true;
+                    emptyCached = true;
+                } else {
+                  empty = false;
+                  emptyCached = true;
+              }
             }
 
             return availableRows;
@@ -461,7 +514,7 @@ public class Grid implements GridModel, ClientElement
 
         // If there's no rows, display the empty block placeholder.
 
-        return !renderTableIfEmpty && cachingSource.getAvailableRows() == 0 ? empty : null;
+        return !renderTableIfEmpty && cachingSource.isEmpty() ? empty : null;
     }
 
     void cleanupRender()
@@ -492,25 +545,35 @@ public class Grid implements GridModel, ClientElement
         // cached, and therefore access was very inefficient, and sorting was
         // very inconsistent during the processing of the form submission.
 
-        cachingSource = new CachingDataSource(source);
+        int effectiveCurrentPage = getCurrentPage();
 
-        int availableRows = cachingSource.getAvailableRows();
+        int numberOfRowsRequiredToShowCurrentPage = 1 + (effectiveCurrentPage - 1) * rowsPerPage;
+        int numberOfRowsRequiredToFillCurrentPage = effectiveCurrentPage * rowsPerPage;
 
-        if (availableRows == 0)
-            return;
+        cachingSource = new CachingDataSource(source);
+        if (pagerPosition != GridPagerPosition.NONE)
+        {
+            // We're going to render the pager, so we need to determine the total number of rows anyway.
+            // We do that eagerly here so we don't have to perform two count operations; the subsequent
+            // ones will return a cached result
+            cachingSource.getAvailableRows();
+        }
+        int availableRowsWithLimit = cachingSource.getAvailableRows(numberOfRowsRequiredToFillCurrentPage);
 
-        int maxPage = ((availableRows - 1) / rowsPerPage) + 1;
+        if (availableRowsWithLimit == 0)
+            return;
 
         // This captures when the number of rows has decreased, typically due to deletions.
 
-        int effectiveCurrentPage = getCurrentPage();
-
-        if (effectiveCurrentPage > maxPage)
+        if (numberOfRowsRequiredToShowCurrentPage > availableRowsWithLimit)
+        {
+            int maxPage = ((availableRowsWithLimit - 1) / rowsPerPage) + 1;
             effectiveCurrentPage = maxPage;
+        }
 
         int startIndex = (effectiveCurrentPage - 1) * rowsPerPage;
 
-        int endIndex = Math.min(startIndex + rowsPerPage - 1, availableRows - 1);
+        int endIndex = Math.min(startIndex + rowsPerPage - 1, availableRowsWithLimit - 1);
 
         cachingSource.prepare(startIndex, endIndex, sortModel.getSortConstraints());
     }
@@ -520,7 +583,7 @@ public class Grid implements GridModel, ClientElement
         // Skip rendering of component (template, body, etc.) when there's nothing to display.
         // The empty placeholder will already have rendered.
 
-        if (cachingSource.getAvailableRows() == 0)
+        if (cachingSource.isEmpty())
             return !renderTableIfEmpty ? false : null;
 
         if (inPlace && zone == null)

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/68303b1d/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/GridRows.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/GridRows.java b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/GridRows.java
index 8a4fc32..356ac32 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/GridRows.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/GridRows.java
@@ -268,16 +268,20 @@ public class GridRows
     {
         GridDataSource dataSource = gridModel.getDataSource();
 
-        int availableRows = dataSource.getAvailableRows();
+        int numberOfRowsRequiredToShowCurrentPage = 1 + (currentPage - 1) * rowsPerPage;
+        int numberOfRowsRequiredToFillCurrentPage = currentPage * rowsPerPage;
 
-        int maxPages = ((availableRows - 1) / rowsPerPage) + 1;
+        int availableRowsWithLimit = dataSource.getAvailableRows(numberOfRowsRequiredToFillCurrentPage);
 
         // This can sometimes happen when the number of items shifts between requests.
 
-        if (currentPage > maxPages) currentPage = maxPages;
-
+        if (numberOfRowsRequiredToShowCurrentPage > availableRowsWithLimit)
+        {
+            int maxPages = ((availableRowsWithLimit - 1) / rowsPerPage) + 1;
+            currentPage = maxPages;
+        }
         startRow = (currentPage - 1) * rowsPerPage;
-        endRow = Math.min(availableRows - 1, startRow + rowsPerPage - 1);
+        endRow = Math.min(availableRowsWithLimit - 1, startRow + rowsPerPage - 1);
 
         dataRowIndex = startRow;
 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/68303b1d/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Grid.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Grid.tml b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Grid.tml
index 2ba5ede..0269c68 100644
--- a/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Grid.tml
+++ b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Grid.tml
@@ -5,10 +5,10 @@
     <table t:id="table">
         <thead t:id="columns"/>
         <tbody>
-            <t:if test="dataSource.availableRows">
+            <t:unless test="dataSource.empty">
                 <tr t:id="rows"/>
-            </t:if>
-            <t:if test="!dataSource.availableRows">
+            </t:unless>
+            <t:if test="dataSource.empty">
                 <tr>
                     <td colspan="${numberOfProperties}"><t:delegate to="prop:empty"/></td>
                 </tr>