Skip to content

Commit f1cc78d

Browse files
author
zhengyang.zhu
committed
#2139 avoid lookupLinearSearch malloc slice
1 parent bb1105b commit f1cc78d

File tree

1 file changed

+80
-14
lines changed

1 file changed

+80
-14
lines changed

calc.go

Lines changed: 80 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14996,6 +14996,66 @@ func (fn *formulaFuncs) HYPERLINK(argsList *list.List) formulaArg {
1499614996
return newStringFormulaArg(argsList.Back().Value.(formulaArg).Value())
1499714997
}
1499814998

14999+
// calcMatch returns the position of the value by given match type, criteria
15000+
// and lookup array for the formula function MATCH.
15001+
func calcMatchMatrix(vertical bool, matchType int, criteria *formulaCriteria, lookupArray [][]formulaArg) formulaArg {
15002+
idx := -1
15003+
var result *formulaArg
15004+
15005+
var calc = func(i int, arg formulaArg) bool {
15006+
switch matchType {
15007+
case 0:
15008+
if ok, _ := formulaCriteriaEval(arg, criteria); ok {
15009+
out := newNumberFormulaArg(float64(i + 1))
15010+
result = &out
15011+
return true
15012+
}
15013+
case -1:
15014+
if ok, _ := formulaCriteriaEval(arg, &formulaCriteria{
15015+
Type: criteriaGe, Condition: criteria.Condition,
15016+
}); ok {
15017+
idx = i
15018+
return false
15019+
}
15020+
if criteria.Condition.Type == ArgNumber {
15021+
return true
15022+
}
15023+
case 1:
15024+
if ok, _ := formulaCriteriaEval(arg, &formulaCriteria{
15025+
Type: criteriaLe, Condition: criteria.Condition,
15026+
}); ok {
15027+
idx = i
15028+
return false
15029+
}
15030+
if criteria.Condition.Type == ArgNumber {
15031+
return true
15032+
}
15033+
}
15034+
return false
15035+
}
15036+
15037+
if vertical {
15038+
for i, row := range lookupArray {
15039+
if ok := calc(i, row[0]); ok {
15040+
break
15041+
}
15042+
}
15043+
} else {
15044+
for i, cell := range lookupArray[0] {
15045+
if ok := calc(i, cell); ok {
15046+
break
15047+
}
15048+
}
15049+
}
15050+
if result != nil {
15051+
return *result
15052+
}
15053+
if idx == -1 {
15054+
return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
15055+
}
15056+
return newNumberFormulaArg(float64(idx + 1))
15057+
}
15058+
1499915059
// calcMatch returns the position of the value by given match type, criteria
1500015060
// and lookup array for the formula function MATCH.
1500115061
func calcMatch(matchType int, criteria *formulaCriteria, lookupArray []formulaArg) formulaArg {
@@ -15110,18 +15170,8 @@ func (fn *formulaFuncs) TRANSPOSE(argsList *list.List) formulaArg {
1511015170
// lookupLinearSearch sequentially checks each look value of the lookup array until
1511115171
// a match is found or the whole list has been searched.
1511215172
func lookupLinearSearch(vertical bool, lookupValue, lookupArray, matchMode, searchMode formulaArg) (int, bool) {
15113-
var tableArray []formulaArg
15114-
if vertical {
15115-
for _, row := range lookupArray.Matrix {
15116-
tableArray = append(tableArray, row[0])
15117-
}
15118-
} else {
15119-
tableArray = lookupArray.Matrix[0]
15120-
}
1512115173
matchIdx, wasExact := -1, false
15122-
start:
15123-
for i, cell := range tableArray {
15124-
lhs := cell
15174+
var linearSearch = func(i int, cell, lhs formulaArg) bool {
1512515175
if lookupValue.Type == ArgNumber {
1512615176
if lhs = cell.ToNumber(); lhs.Type == ArgError {
1512715177
lhs = cell
@@ -15135,12 +15185,28 @@ start:
1513515185
matchIdx = i
1513615186
wasExact = true
1513715187
if searchMode.Number == searchModeLinear {
15138-
break start
15188+
return true
1513915189
}
1514015190
}
1514115191
if matchMode.Number == matchModeMinGreater || matchMode.Number == matchModeMaxLess {
15142-
matchIdx = int(calcMatch(int(matchMode.Number), formulaCriteriaParser(lookupValue), tableArray).Number)
15143-
continue
15192+
matchIdx = int(calcMatchMatrix(vertical, int(matchMode.Number), formulaCriteriaParser(lookupValue), lookupArray.Matrix).Number)
15193+
return false
15194+
}
15195+
return false
15196+
}
15197+
15198+
if vertical {
15199+
for i, row := range lookupArray.Matrix {
15200+
lhs := row[0]
15201+
if linearSearch(i, lhs, lhs) {
15202+
break
15203+
}
15204+
}
15205+
} else {
15206+
for i, lhs := range lookupArray.Matrix[0] {
15207+
if linearSearch(i, lhs, lhs) {
15208+
break
15209+
}
1514415210
}
1514515211
}
1514615212
return matchIdx, wasExact

0 commit comments

Comments
 (0)