mirror of https://github.com/apache/poi.git
refactor LookupUtils
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1895568 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7e00f3594a
commit
7314afd6e5
|
@ -625,8 +625,10 @@ public final class LookupUtils {
|
||||||
public static int xlookupIndexOfValue(ValueEval lookupValue, ValueVector vector, MatchMode matchMode, SearchMode searchMode) throws EvaluationException {
|
public static int xlookupIndexOfValue(ValueEval lookupValue, ValueVector vector, MatchMode matchMode, SearchMode searchMode) throws EvaluationException {
|
||||||
LookupValueComparer lookupComparer = createTolerantLookupComparer(lookupValue, matchMode != MatchMode.WildcardMatch, true);
|
LookupValueComparer lookupComparer = createTolerantLookupComparer(lookupValue, matchMode != MatchMode.WildcardMatch, true);
|
||||||
int result;
|
int result;
|
||||||
if (searchMode == SearchMode.BinarySearchForward || searchMode == SearchMode.BinarySearchBackward) {
|
if (searchMode == SearchMode.BinarySearchForward) {
|
||||||
result = binarySearchIndexOfValue(lookupComparer, vector, matchMode);
|
result = binarySearchIndexOfValue(lookupComparer, vector, matchMode, false);
|
||||||
|
} else if (searchMode == SearchMode.BinarySearchBackward) {
|
||||||
|
result = binarySearchIndexOfValue(lookupComparer, vector, matchMode, true);
|
||||||
} else if (searchMode == SearchMode.IterateBackward) {
|
} else if (searchMode == SearchMode.IterateBackward) {
|
||||||
result = lookupLastIndexOfValue(lookupComparer, vector, matchMode);
|
result = lookupLastIndexOfValue(lookupComparer, vector, matchMode);
|
||||||
} else {
|
} else {
|
||||||
|
@ -711,7 +713,7 @@ public final class LookupUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int binarySearchIndexOfValue(LookupValueComparer lookupComparer, ValueVector vector,
|
private static int binarySearchIndexOfValue(LookupValueComparer lookupComparer, ValueVector vector,
|
||||||
MatchMode matchMode) {
|
MatchMode matchMode, boolean reverse) {
|
||||||
int bestMatchIdx = -1;
|
int bestMatchIdx = -1;
|
||||||
ValueEval bestMatchEval = null;
|
ValueEval bestMatchEval = null;
|
||||||
HashSet<Integer> alreadySearched = new HashSet<>();
|
HashSet<Integer> alreadySearched = new HashSet<>();
|
||||||
|
@ -758,7 +760,9 @@ public final class LookupUtils {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (result.isTypeMismatch()) {
|
if (result.isTypeMismatch()) {
|
||||||
handleMidValueTypeMismatch(lookupComparer, vector, bsi, i);
|
handleMidValueTypeMismatch(lookupComparer, vector, bsi, i, reverse);
|
||||||
|
} else if (reverse) {
|
||||||
|
bsi.narrowSearch(i, result.isGreaterThan());
|
||||||
} else {
|
} else {
|
||||||
bsi.narrowSearch(i, result.isLessThan());
|
bsi.narrowSearch(i, result.isLessThan());
|
||||||
}
|
}
|
||||||
|
@ -820,7 +824,7 @@ public final class LookupUtils {
|
||||||
}
|
}
|
||||||
CompareResult cr = lookupComparer.compareTo(vector.getItem(midIx));
|
CompareResult cr = lookupComparer.compareTo(vector.getItem(midIx));
|
||||||
if(cr.isTypeMismatch()) {
|
if(cr.isTypeMismatch()) {
|
||||||
int newMidIx = handleMidValueTypeMismatch(lookupComparer, vector, bsi, midIx);
|
int newMidIx = handleMidValueTypeMismatch(lookupComparer, vector, bsi, midIx, false);
|
||||||
if(newMidIx < 0) {
|
if(newMidIx < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -837,11 +841,12 @@ public final class LookupUtils {
|
||||||
* Excel seems to handle mismatched types initially by just stepping 'mid' ix forward to the
|
* Excel seems to handle mismatched types initially by just stepping 'mid' ix forward to the
|
||||||
* first compatible value.
|
* first compatible value.
|
||||||
* @param midIx 'mid' index (value which has the wrong type)
|
* @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
|
* @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
|
* index. Zero or greater signifies that an exact match for the lookup value was found
|
||||||
*/
|
*/
|
||||||
private static int handleMidValueTypeMismatch(LookupValueComparer lookupComparer, ValueVector vector,
|
private static int handleMidValueTypeMismatch(LookupValueComparer lookupComparer, ValueVector vector,
|
||||||
BinarySearchIndexes bsi, int midIx) {
|
BinarySearchIndexes bsi, int midIx, boolean reverse) {
|
||||||
int newMid = midIx;
|
int newMid = midIx;
|
||||||
int highIx = bsi.getHighIx();
|
int highIx = bsi.getHighIx();
|
||||||
|
|
||||||
|
@ -854,7 +859,13 @@ public final class LookupUtils {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
CompareResult cr = lookupComparer.compareTo(vector.getItem(newMid));
|
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
|
// move highIx down to the low end of the mid values
|
||||||
bsi.narrowSearch(midIx, true);
|
bsi.narrowSearch(midIx, true);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -871,7 +882,11 @@ public final class LookupUtils {
|
||||||
// Note - if moving highIx down (due to lookup<vector[newMid]),
|
// Note - if moving highIx down (due to lookup<vector[newMid]),
|
||||||
// this execution path only moves highIx it down as far as newMid, not midIx,
|
// this execution path only moves highIx it down as far as newMid, not midIx,
|
||||||
// which would be more efficient.
|
// which would be more efficient.
|
||||||
|
if (reverse) {
|
||||||
|
bsi.narrowSearch(newMid, cr.isGreaterThan());
|
||||||
|
} else {
|
||||||
bsi.narrowSearch(newMid, cr.isLessThan());
|
bsi.narrowSearch(newMid, cr.isLessThan());
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue