You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2020/12/28 13:24:02 UTC

[groovy] branch master updated: Tweak calculating index

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new a2f1310  Tweak calculating index
a2f1310 is described below

commit a2f131044c1f7d38b2737e06421baae566744483
Author: Daniel Sun <su...@apache.org>
AuthorDate: Mon Dec 28 21:23:44 2020 +0800

    Tweak calculating index
---
 .../collection/runtime/QueryableCollection.java    |  6 +++-
 .../provider/collection/runtime/WindowImpl.java    | 38 ++++++++++++----------
 2 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/QueryableCollection.java b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/QueryableCollection.java
index 749fa22..889422b 100644
--- a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/QueryableCollection.java
+++ b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/QueryableCollection.java
@@ -236,7 +236,11 @@ class QueryableCollection<T> implements Queryable<T>, Serializable {
         return from(this.stream().sorted(comparator));
     }
 
-    protected <U extends Comparable<? super U>> Comparator<T> makeComparator(Order<? super T, ? extends U>... orders) {
+    protected static <T, U extends Comparable<? super U>> Comparator<T> makeComparator(List<? extends Order<? super T, ? extends U>> orders) {
+        return makeComparator(orders.toArray(Order.EMPTY_ARRAY));
+    }
+
+    protected static <T, U extends Comparable<? super U>> Comparator<T> makeComparator(Order<? super T, ? extends U>... orders) {
         if (null == orders || 0 == orders.length) {
             return null;
         }
diff --git a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/WindowImpl.java b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/WindowImpl.java
index 10b0670..f89054c 100644
--- a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/WindowImpl.java
+++ b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/WindowImpl.java
@@ -24,6 +24,9 @@ import java.util.List;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
+import static java.util.Collections.binarySearch;
+import static java.util.Comparator.comparing;
+
 /**
  * Represents window which stores elements used by window functions
  *
@@ -34,7 +37,7 @@ import java.util.stream.Collectors;
 class WindowImpl<T, U extends Comparable<? super U>> extends QueryableCollection<T> implements Window<T> {
     private static final long serialVersionUID = -3458969297047398621L;
     private final Tuple2<T, Long> currentRecord;
-    private final long index;
+    private final int index;
     private final WindowDefinition<T, U> windowDefinition;
     private final U value;
     private final Function<? super T, ? extends U> keyExtractor;
@@ -54,23 +57,12 @@ class WindowImpl<T, U extends Comparable<? super U>> extends QueryableCollection
             this.value = null;
         }
 
-        int tmpIndex = -1;
-        for (int i = 0, n = sortedList.size(); i < n; i++) {
-            final Tuple2<T, Long> record = sortedList.get(i);
-            if (currentRecord.getV1() == record.getV1() && currentRecord.getV2().equals(record.getV2())) {
-                tmpIndex = i;
-                break;
-            }
-        }
+        List<Queryable.Order<? super T, ? extends U>> orderList = windowDefinition.orderBy();
+        int tmpIndex = null == orderList || orderList.isEmpty()
+                        ? binarySearch(sortedList, currentRecord, comparing(Tuple2::getV2))
+                        : binarySearch(sortedList, currentRecord, makeComparator(composeOrders(orderList)).thenComparing(Tuple2::getV2));
 
-        this.index = tmpIndex;
-    }
-
-    private static <T, U extends Comparable<? super U>> List<Order<? super Tuple2<T, Long>, ? extends U>> composeOrders(WindowDefinition<T, U> windowDefinition) {
-        List<Order<? super Tuple2<T, Long>, ? extends U>> result = windowDefinition.orderBy().stream()
-                .map(order -> new Order<Tuple2<T, Long>, U>(t -> order.getKeyExtractor().apply(t.getV1()), order.isAsc()))
-                .collect(Collectors.toList());
-        return result;
+        this.index = tmpIndex >= 0 ? tmpIndex : -tmpIndex - 1;
     }
 
     @Override
@@ -84,7 +76,7 @@ class WindowImpl<T, U extends Comparable<? super U>> extends QueryableCollection
         if (0 == lead) {
             field = extractor.apply(currentRecord.getV1());
         } else if (0 <= index + lead && index + lead < this.size()) {
-            field = extractor.apply(this.toList().get((int) index + (int) lead));
+            field = extractor.apply(this.toList().get(index + (int) lead));
         } else {
             field = def;
         }
@@ -181,4 +173,14 @@ class WindowImpl<T, U extends Comparable<? super U>> extends QueryableCollection
         }
         return lastRowIndex;
     }
+
+    private static <T, U extends Comparable<? super U>> List<Order<Tuple2<T, Long>, U>> composeOrders(List<Queryable.Order<? super T, ? extends U>> orderList) {
+        return orderList.stream()
+                .map(order -> new Order<Tuple2<T, Long>, U>(t -> order.getKeyExtractor().apply(t.getV1()), order.isAsc()))
+                .collect(Collectors.toList());
+    }
+
+    private static <T, U extends Comparable<? super U>> List<Order<Tuple2<T, Long>, U>> composeOrders(WindowDefinition<T, U> windowDefinition) {
+        return composeOrders(windowDefinition.orderBy());
+    }
 }