You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2021/12/03 09:58:41 UTC

svn commit: r1895542 - in /poi/trunk/poi/src: main/java/org/apache/poi/ss/formula/functions/LookupUtils.java test/java/org/apache/poi/ss/formula/atp/TestXLookupFunction.java

Author: fanningpj
Date: Fri Dec  3 09:58:40 2021
New Revision: 1895542

URL: http://svn.apache.org/viewvc?rev=1895542&view=rev
Log:
refactor LookupUtils

Modified:
    poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/LookupUtils.java
    poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/atp/TestXLookupFunction.java

Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/LookupUtils.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/LookupUtils.java?rev=1895542&r1=1895541&r2=1895542&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/LookupUtils.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/LookupUtils.java Fri Dec  3 09:58:40 2021
@@ -18,6 +18,7 @@
 package org.apache.poi.ss.formula.functions;
 
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.regex.Matcher;
@@ -624,7 +625,9 @@ public final class LookupUtils {
     public static int xlookupIndexOfValue(ValueEval lookupValue, ValueVector vector, MatchMode matchMode, SearchMode searchMode) throws EvaluationException {
         LookupValueComparer lookupComparer = createTolerantLookupComparer(lookupValue, true, true);
         int result;
-        if (searchMode == SearchMode.IterateBackward || searchMode == SearchMode.BinarySearchBackward) {
+        if (searchMode == SearchMode.BinarySearchForward || searchMode == SearchMode.BinarySearchBackward) {
+            result = binarySearchIndexOfValue(lookupComparer, vector, matchMode);
+        } else if (searchMode == SearchMode.IterateBackward) {
             result = lookupLastIndexOfValue(lookupComparer, vector, matchMode);
         } else {
             result = lookupFirstIndexOfValue(lookupComparer, vector, matchMode);
@@ -707,6 +710,57 @@ public final class LookupUtils {
         return bestMatchIdx;
     }
 
+    private static int binarySearchIndexOfValue(LookupValueComparer lookupComparer, ValueVector vector,
+                                                MatchMode matchMode) {
+        int bestMatchIdx = -1;
+        ValueEval bestMatchEval = null;
+        HashSet<Integer> alreadySearched = new HashSet<>();
+        BinarySearchIndexes bsi = new BinarySearchIndexes(vector.getSize());
+        while (true) {
+            int i = bsi.getMidIx();
+            if(i < 0 || alreadySearched.contains(i)) {
+                return bestMatchIdx;
+            }
+            alreadySearched.add(i);
+            ValueEval valueEval = vector.getItem(i);
+            CompareResult result = lookupComparer.compareTo(valueEval);
+            if (result.isEqual()) {
+                return i;
+            }
+            switch (matchMode) {
+                case ExactMatchFallbackToLargerValue:
+                    if (result.isLessThan()) {
+                        if (bestMatchEval == null) {
+                            bestMatchIdx = i;
+                            bestMatchEval = valueEval;
+                        } else {
+                            LookupValueComparer matchComparer = createTolerantLookupComparer(valueEval, true, true);
+                            if (matchComparer.compareTo(bestMatchEval).isLessThan()) {
+                                bestMatchIdx = i;
+                                bestMatchEval = valueEval;
+                            }
+                        }
+                    }
+                    break;
+                case ExactMatchFallbackToSmallerValue:
+                    if (result.isGreaterThan()) {
+                        if (bestMatchEval == null) {
+                            bestMatchIdx = i;
+                            bestMatchEval = valueEval;
+                        } else {
+                            LookupValueComparer matchComparer = createTolerantLookupComparer(valueEval, true, true);
+                            if (matchComparer.compareTo(bestMatchEval).isGreaterThan()) {
+                                bestMatchIdx = i;
+                                bestMatchEval = valueEval;
+                            }
+                        }
+                    }
+                    break;
+            }
+            bsi.narrowSearch(i, result.isLessThan());
+        }
+    }
+
     /**
      * Encapsulates some standard binary search functionality so the unusual Excel behaviour can
      * be clearly distinguished.

Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/atp/TestXLookupFunction.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/atp/TestXLookupFunction.java?rev=1895542&r1=1895541&r2=1895542&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/atp/TestXLookupFunction.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/atp/TestXLookupFunction.java Fri Dec  3 09:58:40 2021
@@ -94,7 +94,6 @@ public class TestXLookupFunction {
         }
     }
 
-
     private HSSFWorkbook initWorkbook1() {
         HSSFWorkbook wb = new HSSFWorkbook();
         HSSFSheet sheet = wb.createSheet();



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org