Skip to content

Commit 7216935

Browse files
zhuzhengyangzhengyang.zhu
andauthored
This closes qax-os#2139, avoid lookupLinearSearch malloc slice (qax-os#2140)
- Reduce memory and time cost about 50% Co-authored-by: zhengyang.zhu <[email protected]>
1 parent f1ac51e commit 7216935

File tree

1 file changed

+70
-14
lines changed

1 file changed

+70
-14
lines changed

calc.go

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15285,6 +15285,56 @@ func (fn *formulaFuncs) HYPERLINK(argsList *list.List) formulaArg {
1528515285
return newStringFormulaArg(argsList.Back().Value.(formulaArg).Value())
1528615286
}
1528715287

15288+
// calcMatch returns the position of the value by given match type, criteria
15289+
// and lookup array for the formula function MATCH.
15290+
// matchType only contains -1, and 1.
15291+
func calcMatchMatrix(vertical bool, matchType int, criteria *formulaCriteria, lookupArray [][]formulaArg) formulaArg {
15292+
idx := -1
15293+
var calc = func(i int, arg formulaArg) bool {
15294+
switch matchType {
15295+
case -1:
15296+
if ok, _ := formulaCriteriaEval(arg, &formulaCriteria{
15297+
Type: criteriaGe, Condition: criteria.Condition,
15298+
}); ok {
15299+
idx = i
15300+
return false
15301+
}
15302+
if criteria.Condition.Type == ArgNumber {
15303+
return true
15304+
}
15305+
case 1:
15306+
if ok, _ := formulaCriteriaEval(arg, &formulaCriteria{
15307+
Type: criteriaLe, Condition: criteria.Condition,
15308+
}); ok {
15309+
idx = i
15310+
return false
15311+
}
15312+
if criteria.Condition.Type == ArgNumber {
15313+
return true
15314+
}
15315+
}
15316+
return false
15317+
}
15318+
15319+
if vertical {
15320+
for i, row := range lookupArray {
15321+
if ok := calc(i, row[0]); ok {
15322+
break
15323+
}
15324+
}
15325+
} else {
15326+
for i, cell := range lookupArray[0] {
15327+
if ok := calc(i, cell); ok {
15328+
break
15329+
}
15330+
}
15331+
}
15332+
if idx == -1 {
15333+
return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
15334+
}
15335+
return newNumberFormulaArg(float64(idx + 1))
15336+
}
15337+
1528815338
// calcMatch returns the position of the value by given match type, criteria
1528915339
// and lookup array for the formula function MATCH.
1529015340
func calcMatch(matchType int, criteria *formulaCriteria, lookupArray []formulaArg) formulaArg {
@@ -15399,18 +15449,8 @@ func (fn *formulaFuncs) TRANSPOSE(argsList *list.List) formulaArg {
1539915449
// lookupLinearSearch sequentially checks each look value of the lookup array until
1540015450
// a match is found or the whole list has been searched.
1540115451
func lookupLinearSearch(vertical bool, lookupValue, lookupArray, matchMode, searchMode formulaArg) (int, bool) {
15402-
var tableArray []formulaArg
15403-
if vertical {
15404-
for _, row := range lookupArray.Matrix {
15405-
tableArray = append(tableArray, row[0])
15406-
}
15407-
} else {
15408-
tableArray = lookupArray.Matrix[0]
15409-
}
1541015452
matchIdx, wasExact := -1, false
15411-
start:
15412-
for i, cell := range tableArray {
15413-
lhs := cell
15453+
var linearSearch = func(i int, cell, lhs formulaArg) bool {
1541415454
if lookupValue.Type == ArgNumber {
1541515455
if lhs = cell.ToNumber(); lhs.Type == ArgError {
1541615456
lhs = cell
@@ -15424,12 +15464,28 @@ start:
1542415464
matchIdx = i
1542515465
wasExact = true
1542615466
if searchMode.Number == searchModeLinear {
15427-
break start
15467+
return true
1542815468
}
1542915469
}
1543015470
if matchMode.Number == matchModeMinGreater || matchMode.Number == matchModeMaxLess {
15431-
matchIdx = int(calcMatch(int(matchMode.Number), formulaCriteriaParser(lookupValue), tableArray).Number)
15432-
continue
15471+
matchIdx = int(calcMatchMatrix(vertical, int(matchMode.Number), formulaCriteriaParser(lookupValue), lookupArray.Matrix).Number)
15472+
return false
15473+
}
15474+
return false
15475+
}
15476+
15477+
if vertical {
15478+
for i, row := range lookupArray.Matrix {
15479+
lhs := row[0]
15480+
if linearSearch(i, lhs, lhs) {
15481+
break
15482+
}
15483+
}
15484+
} else {
15485+
for i, lhs := range lookupArray.Matrix[0] {
15486+
if linearSearch(i, lhs, lhs) {
15487+
break
15488+
}
1543315489
}
1543415490
}
1543515491
return matchIdx, wasExact

0 commit comments

Comments
 (0)