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/04 08:53:29 UTC

svn commit: r1895568 - /poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/LookupUtils.java

Author: fanningpj
Date: Sat Dec  4 08:53:29 2021
New Revision: 1895568

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

Modified:
    poi/trunk/poi/src/main/java/org/apache/poi/ss/formula/functions/LookupUtils.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=1895568&r1=1895567&r2=1895568&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 Sat Dec  4 08:53:29 2021
@@ -625,8 +625,10 @@ public final class LookupUtils {
     public static int xlookupIndexOfValue(ValueEval lookupValue, ValueVector vector, MatchMode matchMode, SearchMode searchMode) throws EvaluationException {
         LookupValueComparer lookupComparer = createTolerantLookupComparer(lookupValue, matchMode != MatchMode.WildcardMatch, true);
         int result;
-        if (searchMode == SearchMode.BinarySearchForward || searchMode == SearchMode.BinarySearchBackward) {
-            result = binarySearchIndexOfValue(lookupComparer, vector, matchMode);
+        if (searchMode == SearchMode.BinarySearchForward) {
+            result = binarySearchIndexOfValue(lookupComparer, vector, matchMode, false);
+        } else if (searchMode == SearchMode.BinarySearchBackward) {
+            result = binarySearchIndexOfValue(lookupComparer, vector, matchMode, true);
         } else if (searchMode == SearchMode.IterateBackward) {
             result = lookupLastIndexOfValue(lookupComparer, vector, matchMode);
         } else {
@@ -711,7 +713,7 @@ public final class LookupUtils {
     }
 
     private static int binarySearchIndexOfValue(LookupValueComparer lookupComparer, ValueVector vector,
-                                                MatchMode matchMode) {
+                                                MatchMode matchMode, boolean reverse) {
         int bestMatchIdx = -1;
         ValueEval bestMatchEval = null;
         HashSet<Integer> alreadySearched = new HashSet<>();
@@ -758,7 +760,9 @@ public final class LookupUtils {
                     break;
             }
             if (result.isTypeMismatch()) {
-                handleMidValueTypeMismatch(lookupComparer, vector, bsi, i);
+                handleMidValueTypeMismatch(lookupComparer, vector, bsi, i, reverse);
+            } else if (reverse) {
+                bsi.narrowSearch(i, result.isGreaterThan());
             } else {
                 bsi.narrowSearch(i, result.isLessThan());
             }
@@ -820,7 +824,7 @@ public final class LookupUtils {
             }
             CompareResult cr = lookupComparer.compareTo(vector.getItem(midIx));
             if(cr.isTypeMismatch()) {
-                int newMidIx = handleMidValueTypeMismatch(lookupComparer, vector, bsi, midIx);
+                int newMidIx = handleMidValueTypeMismatch(lookupComparer, vector, bsi, midIx, false);
                 if(newMidIx < 0) {
                     continue;
                 }
@@ -837,11 +841,12 @@ public final class LookupUtils {
      * Excel seems to handle mismatched types initially by just stepping 'mid' ix forward to the
      * first compatible value.
      * @param midIx 'mid' index (value which has the wrong type)
+     * @param reverse the data is sorted in reverse order
      * @return usually -1, signifying that the BinarySearchIndex has been narrowed to the new mid
      * index.  Zero or greater signifies that an exact match for the lookup value was found
      */
     private static int handleMidValueTypeMismatch(LookupValueComparer lookupComparer, ValueVector vector,
-            BinarySearchIndexes bsi, int midIx) {
+            BinarySearchIndexes bsi, int midIx, boolean reverse) {
         int newMid = midIx;
         int highIx = bsi.getHighIx();
 
@@ -854,7 +859,13 @@ public final class LookupUtils {
                 return -1;
             }
             CompareResult cr = lookupComparer.compareTo(vector.getItem(newMid));
-            if(cr.isLessThan() && newMid == highIx-1) {
+            if(cr.isLessThan() && !reverse && newMid == highIx-1) {
+                // move highIx down to the low end of the mid values
+                bsi.narrowSearch(midIx, true);
+                return -1;
+                // but only when "newMid == highIx-1"? slightly weird.
+                // It would seem more efficient to always do this.
+            } else if(cr.isGreaterThan() && reverse && newMid == highIx-1) {
                 // move highIx down to the low end of the mid values
                 bsi.narrowSearch(midIx, true);
                 return -1;
@@ -871,7 +882,11 @@ public final class LookupUtils {
             // Note - if moving highIx down (due to lookup<vector[newMid]),
             // this execution path only moves highIx it down as far as newMid, not midIx,
             // which would be more efficient.
-            bsi.narrowSearch(newMid, cr.isLessThan());
+            if (reverse) {
+                bsi.narrowSearch(newMid, cr.isGreaterThan());
+            } else {
+                bsi.narrowSearch(newMid, cr.isLessThan());
+            }
             return -1;
         }
     }



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