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