]> source.dussan.org Git - vaadin-framework.git/commitdiff
Reduce Grid's sort complexity. (#11566)
authorAnna Koskinen <Ansku@users.noreply.github.com>
Wed, 15 May 2019 05:45:13 +0000 (08:45 +0300)
committerSun Zhe <31067185+ZheSun88@users.noreply.github.com>
Thu, 16 May 2019 10:32:54 +0000 (13:32 +0300)
- limit DataCommunicator workaround from #11320 to ComboBox only
- don't reset DataCommunicator before modifying all sorting data

Fixes #11532

server/src/main/java/com/vaadin/data/provider/DataCommunicator.java
server/src/main/java/com/vaadin/data/provider/HierarchicalDataCommunicator.java
server/src/main/java/com/vaadin/ui/Grid.java
server/src/test/java/com/vaadin/data/provider/DataCommunicatorTest.java
uitest/src/main/java/com/vaadin/tests/components/grid/GridSortComplexity.java [new file with mode: 0644]
uitest/src/test/java/com/vaadin/tests/components/grid/GridSortComplexityTest.java [new file with mode: 0644]

index 35dad20c494ddaf6fec516257d819b8ca7f830ae..4b1291917639e76738499fe1a4bf63b6f1bf5c39 100644 (file)
@@ -40,6 +40,7 @@ import com.vaadin.shared.data.DataCommunicatorClientRpc;
 import com.vaadin.shared.data.DataCommunicatorConstants;
 import com.vaadin.shared.data.DataRequestRpc;
 import com.vaadin.shared.extension.datacommunicator.DataCommunicatorState;
+import com.vaadin.ui.ComboBox;
 
 import elemental.json.Json;
 import elemental.json.JsonArray;
@@ -530,7 +531,9 @@ public class DataCommunicator<T> extends AbstractExtension {
     public void reset() {
         // Only needed if a full reset is not pending.
         if (!reset) {
-            beforeClientResponse(true);
+            if (getParent() instanceof ComboBox) {
+                beforeClientResponse(true);
+            }
             // Soft reset through client-side re-request.
             getClientRpc().reset(getDataProviderSize());
         }
@@ -569,6 +572,25 @@ public class DataCommunicator<T> extends AbstractExtension {
         return updatedData;
     }
 
+    /**
+     * Sets the {@link Comparator} to use with in-memory sorting.
+     *
+     * @param comparator
+     *            comparator used to sort data
+     * @param immediateReset
+     *            {@code true} if an internal reset should be performed
+     *            immediately after updating the comparator (unless full reset
+     *            is already pending), {@code false} if you are going to trigger
+     *            reset separately later
+     */
+    public void setInMemorySorting(Comparator<T> comparator,
+            boolean immediateReset) {
+        inMemorySorting = comparator;
+        if (immediateReset) {
+            reset();
+        }
+    }
+
     /**
      * Sets the {@link Comparator} to use with in-memory sorting.
      *
@@ -576,8 +598,7 @@ public class DataCommunicator<T> extends AbstractExtension {
      *            comparator used to sort data
      */
     public void setInMemorySorting(Comparator<T> comparator) {
-        inMemorySorting = comparator;
-        reset();
+        setInMemorySorting(comparator, true);
     }
 
     /**
@@ -595,11 +616,29 @@ public class DataCommunicator<T> extends AbstractExtension {
      *
      * @param sortOrder
      *            list of sort order information to pass to a query
-     */
-    public void setBackEndSorting(List<QuerySortOrder> sortOrder) {
+     * @param immediateReset
+     *            {@code true} if an internal reset should be performed
+     *            immediately after updating the comparator (unless full reset
+     *            is already pending), {@code false} if you are going to trigger
+     *            reset separately later
+     */
+    public void setBackEndSorting(List<QuerySortOrder> sortOrder,
+            boolean immediateReset) {
         backEndSorting.clear();
         backEndSorting.addAll(sortOrder);
-        reset();
+        if (immediateReset) {
+            reset();
+        }
+    }
+
+    /**
+     * Sets the {@link QuerySortOrder}s to use with backend sorting.
+     *
+     * @param sortOrder
+     *            list of sort order information to pass to a query
+     */
+    public void setBackEndSorting(List<QuerySortOrder> sortOrder) {
+        setBackEndSorting(sortOrder, true);
     }
 
     /**
index 73bd9e02211f046969db23438e57851999a2df3e..706f0a939157e1a9491193923fa39615e0c687c8 100644 (file)
@@ -406,19 +406,31 @@ public class HierarchicalDataCommunicator<T> extends DataCommunicator<T> {
     }
 
     @Override
-    public void setBackEndSorting(List<QuerySortOrder> sortOrder) {
+    public void setBackEndSorting(List<QuerySortOrder> sortOrder,
+            boolean immediateReset) {
         if (mapper != null) {
             mapper.setBackEndSorting(sortOrder);
         }
-        super.setBackEndSorting(sortOrder);
+        super.setBackEndSorting(sortOrder, immediateReset);
     }
 
     @Override
-    public void setInMemorySorting(Comparator<T> comparator) {
+    public void setBackEndSorting(List<QuerySortOrder> sortOrder) {
+        setBackEndSorting(sortOrder, true);
+    }
+
+    @Override
+    public void setInMemorySorting(Comparator<T> comparator,
+            boolean immediateReset) {
         if (mapper != null) {
             mapper.setInMemorySorting(comparator);
         }
-        super.setInMemorySorting(comparator);
+        super.setInMemorySorting(comparator, immediateReset);
+    }
+
+    @Override
+    public void setInMemorySorting(Comparator<T> comparator) {
+        setInMemorySorting(comparator, true);
     }
 
     @Override
index 74cd9a4626d1a04f70d306e89dd94f54eb5bbe7d..3c9116fab33e5c837c9e4abfc6257864c7e040ef 100644 (file)
@@ -4909,14 +4909,15 @@ public class Grid<T> extends AbstractListing<T> implements HasComponents,
     private void sort(boolean userOriginated) {
         // Set sort orders
         // In-memory comparator
-        getDataCommunicator().setInMemorySorting(createSortingComparator());
+        getDataCommunicator().setInMemorySorting(createSortingComparator(),
+                false);
 
         // Back-end sort properties
         List<QuerySortOrder> sortProperties = new ArrayList<>();
         sortOrder.stream().map(
                 order -> order.getSorted().getSortOrder(order.getDirection()))
                 .forEach(s -> s.forEach(sortProperties::add));
-        getDataCommunicator().setBackEndSorting(sortProperties);
+        getDataCommunicator().setBackEndSorting(sortProperties, true);
 
         // Close grid editor if it's open.
         if (getEditor().isOpen()) {
index 98ae758b6d896f2d7f3d13c8105ce936163a16df..c187c91471068e55ebd5a0ee41a74996cbf9f259 100644 (file)
@@ -1,5 +1,9 @@
 package com.vaadin.data.provider;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.concurrent.Future;
@@ -21,9 +25,6 @@ import com.vaadin.ui.UI;
 import elemental.json.Json;
 import elemental.json.JsonArray;
 import elemental.json.JsonObject;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 
 /**
  * @author Vaadin Ltd
@@ -302,7 +303,7 @@ public class DataCommunicatorTest {
         // Mark communicator clean
         ui.getConnectorTracker().markClean(communicator);
 
-        assertFalse("Communicator should not be marked for hard reset",
+        assertTrue("Communicator should be marked for hard reset",
                 communicator.reset);
         assertFalse("DataCommunicator should not be marked as dirty",
                 ui.getConnectorTracker().isDirty(communicator));
diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridSortComplexity.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridSortComplexity.java
new file mode 100644 (file)
index 0000000..4a60765
--- /dev/null
@@ -0,0 +1,64 @@
+package com.vaadin.tests.components.grid;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.vaadin.data.provider.DataProvider;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.SelectionMode;
+
+public class GridSortComplexity extends AbstractTestUIWithLog {
+
+    @Override
+    protected int getLogSize() {
+        return 10;
+    }
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        List<Integer> data = new ArrayList<>();
+        data.add(0);
+        data.add(1);
+        data.add(2);
+
+        Grid<Integer> grid = new Grid<>();
+        grid.addSortListener(event -> {
+            log("ON SORT: "
+                    + event.getSortOrder().get(0).getDirection().name());
+        });
+
+        grid.addColumn(Integer::valueOf).setCaption("ID").setId("id")
+                .setSortable(true).setSortProperty("id");
+
+        grid.setDataProvider(DataProvider.fromCallbacks(query -> {
+            log("FETCH");
+            if (query.getSortOrders().isEmpty() || "ASCENDING".equals(
+                    query.getSortOrders().get(0).getDirection().name())) {
+                return data.stream();
+            } else {
+                return data.stream().sorted(Collections.reverseOrder());
+            }
+        }, query -> {
+            log("SIZE");
+            return data.size();
+        }));
+
+        grid.setSelectionMode(SelectionMode.NONE);
+        grid.setWidth("250px");
+        grid.setHeightByRows(3);
+        addComponent(grid);
+    }
+
+    @Override
+    protected String getTestDescription() {
+        return "Sorting Grid should not fetch data and recalculate size multiple times.";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 11532;
+    }
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/GridSortComplexityTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/GridSortComplexityTest.java
new file mode 100644 (file)
index 0000000..e7f4721
--- /dev/null
@@ -0,0 +1,24 @@
+package com.vaadin.tests.components.grid;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.vaadin.testbench.elements.GridElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class GridSortComplexityTest extends MultiBrowserTest {
+
+    @Test
+    public void testOperationCountUponSorting() {
+        openTestURL();
+        GridElement grid = $(GridElement.class).first();
+        assertEquals("2. FETCH", getLogRow(0));
+        assertEquals("1. SIZE", getLogRow(1));
+
+        grid.getHeaderCell(0, 0).click();
+        assertEquals("5. FETCH", getLogRow(0));
+        assertEquals("4. ON SORT: ASCENDING", getLogRow(1));
+        assertEquals("3. SIZE", getLogRow(2));
+    }
+}