Skip to content

Commit 3912e3a

Browse files
author
linzhijun
committed
fix
1 parent 3c24bda commit 3912e3a

4 files changed

Lines changed: 46 additions & 54 deletions

File tree

‎JavaScript/dist/toolgood.algorithm.js‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎JavaScript/src/FunctionCache.js‎

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -50,28 +50,29 @@ export class FunctionCache extends IFunctionCache {
5050
let result = this.calculateCache.get(funExp);
5151
if (result != null) return result;
5252
const tree = AlgorithmEngineHelper.ParseCalculate(funExp);
53-
return this.CreateCalculate(tree, funExp);
53+
const fun = this.CreateCalculate(tree, funExp);
54+
this.calculateCache.set(funExp, fun);
55+
return fun;
5456
}
5557

5658
CreateCalculate(tree, exp) {
57-
if (tree.Type === CalculateTreeType.Error) {
58-
throw new Error(tree.ErrorMessage);
59-
}
60-
const key = exp.substring(tree.start, tree.end + 1);
61-
if (this.calculateCache.has(key)) {
62-
return this.calculateCache.get(key);
63-
}
6459
if (tree.Type === CalculateTreeType.String) {
60+
// 仅叶子节点需要字符串内容;中间节点不再以子串作为缓存 key,避免 substring 产生 O(n²) 子串驻留
61+
const key = exp.substring(tree.start, tree.end + 1);
62+
if (this.calculateCache.has(key)) {
63+
return this.calculateCache.get(key);
64+
}
6565
const fun = AlgorithmEngineHelper.ParseFormula(key);
6666
this.calculateCache.set(key, fun);
6767
return fun;
6868
}
69+
if (tree.Type === CalculateTreeType.Error) {
70+
throw new Error(tree.ErrorMessage);
71+
}
6972

7073
const leftFunc = this.CreateCalculate(tree.nodes[0], exp);
7174
const rightFunc = this.CreateCalculate(tree.nodes[1], exp);
72-
const fun = this.CombineCalculate(leftFunc, tree.Type, rightFunc);
73-
this.calculateCache.set(key, fun);
74-
return fun;
75+
return this.CombineCalculate(leftFunc, tree.Type, rightFunc);
7576
}
7677

7778
CombineCalculate(left, type, right) {
@@ -104,32 +105,26 @@ export class FunctionCache extends IFunctionCache {
104105
let result = this.conditionCache.get(funExp);
105106
if (result != null) return result;
106107
const tree = AlgorithmEngineHelper.ParseCondition(funExp);
107-
return this.CreateCondition(tree, funExp);
108+
const fun = this.CreateCondition(tree, funExp);
109+
this.conditionCache.set(funExp, fun);
110+
return fun;
108111
}
109112

110113
CreateCondition(tree, exp) {
111-
if (tree.Type === ConditionTreeType.Error) {
112-
throw new Error(tree.ErrorMessage);
113-
}
114-
const key = exp.substring(tree.start, tree.end + 1);
115-
if (this.conditionCache.has(key)) {
116-
return this.conditionCache.get(key);
117-
}
118114
if (tree.Type === ConditionTreeType.String) {
119115
// 直接走计算树路径,避免对同一 key 重入
120-
return this.ParseWithCache(key);
116+
return this.ParseWithCache(exp.substring(tree.start, tree.end + 1));
117+
}
118+
if (tree.Type === ConditionTreeType.Error) {
119+
throw new Error(tree.ErrorMessage);
121120
}
122121

123122
const leftFunc = this.CreateCondition(tree.nodes[0], exp);
124123
const rightFunc = this.CreateCondition(tree.nodes[1], exp);
125124
if (tree.Type === ConditionTreeType.And) {
126-
const fun = AlgorithmEngineHelper.Condition_And(leftFunc, rightFunc);
127-
this.conditionCache.set(key, fun);
128-
return fun;
125+
return AlgorithmEngineHelper.Condition_And(leftFunc, rightFunc);
129126
} else if (tree.Type === ConditionTreeType.Or) {
130-
const fun = AlgorithmEngineHelper.Condition_Or(leftFunc, rightFunc);
131-
this.conditionCache.set(key, fun);
132-
return fun;
127+
return AlgorithmEngineHelper.Condition_Or(leftFunc, rightFunc);
133128
}
134129
throw new Error(tree.ErrorMessage);
135130
}

‎java/toolgood.algorithm/src/main/java/toolgood/algorithm/FunctionCache.java‎

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,18 @@ public FunctionBase ParseWithCache(String funExp) {
3434
FunctionBase result = calculateCache.get(funExp);
3535
if (result != null) return result;
3636
CalculateTree tree = AlgorithmEngineHelper.ParseCalculate(funExp);
37-
return CreateCalculate(tree, funExp);
37+
FunctionBase fun = CreateCalculate(tree, funExp);
38+
calculateCache.put(funExp, fun);
39+
return fun;
3840
}
3941

4042
private FunctionBase CreateCalculate(CalculateTree tree, String exp) {
41-
if (tree.Type == CalculateTreeType.Error) {
42-
throw new RuntimeException(tree.ErrorMessage);
43-
}
44-
String key = exp.substring(tree.Start, tree.End + 1);
45-
if (calculateCache.containsKey(key)) {
46-
return calculateCache.get(key);
47-
}
4843
if (tree.Type == CalculateTreeType.String) {
44+
// 仅叶子节点需要字符串内容;中间节点不再以子串作为缓存 key,避免 substring 产生 O(n²) 子串驻留
45+
String key = exp.substring(tree.Start, tree.End + 1);
46+
if (calculateCache.containsKey(key)) {
47+
return calculateCache.get(key);
48+
}
4949
try {
5050
FunctionBase fun = AlgorithmEngineHelper.ParseFormula(key);
5151
calculateCache.put(key, fun);
@@ -54,44 +54,39 @@ private FunctionBase CreateCalculate(CalculateTree tree, String exp) {
5454
throw new RuntimeException(e);
5555
}
5656
}
57+
if (tree.Type == CalculateTreeType.Error) {
58+
throw new RuntimeException(tree.ErrorMessage);
59+
}
5760

5861
FunctionBase leftFunc = CreateCalculate(tree.Nodes.get(0), exp);
5962
FunctionBase rightFunc = CreateCalculate(tree.Nodes.get(1), exp);
6063
CombineCalculateType combineType = CombineCalculateType.intToEnum(tree.Type.getValue());
61-
FunctionBase fun = AlgorithmEngineHelper.CombineCalculate(leftFunc, combineType, rightFunc);
62-
calculateCache.put(key, fun);
63-
return fun;
64+
return AlgorithmEngineHelper.CombineCalculate(leftFunc, combineType, rightFunc);
6465
}
6566

6667
public FunctionBase ParseConditionWithCache(String funExp) {
6768
FunctionBase result = conditionCache.get(funExp);
6869
if (result != null) return result;
6970
ConditionTree tree = AlgorithmEngineHelper.ParseCondition(funExp);
70-
return CreateCondition(tree, funExp);
71+
FunctionBase fun = CreateCondition(tree, funExp);
72+
conditionCache.put(funExp, fun);
73+
return fun;
7174
}
7275

7376
private FunctionBase CreateCondition(ConditionTree tree, String exp) {
77+
if (tree.Type == ConditionTreeType.String) {
78+
return ParseWithCache(exp.substring(tree.Start, tree.End + 1));
79+
}
7480
if (tree.Type == ConditionTreeType.Error) {
7581
throw new RuntimeException(tree.ErrorMessage);
7682
}
77-
String key = exp.substring(tree.Start, tree.End + 1);
78-
if (conditionCache.containsKey(key)) {
79-
return conditionCache.get(key);
80-
}
81-
if (tree.Type == ConditionTreeType.String) {
82-
return ParseWithCache(key);
83-
}
8483

8584
FunctionBase leftFunc = CreateCondition(tree.Nodes.get(0), exp);
8685
FunctionBase rightFunc = CreateCondition(tree.Nodes.get(1), exp);
8786
if (tree.Type == ConditionTreeType.And) {
88-
FunctionBase fun = AlgorithmEngineHelper.Condition_And(leftFunc, rightFunc);
89-
conditionCache.put(key, fun);
90-
return fun;
87+
return AlgorithmEngineHelper.Condition_And(leftFunc, rightFunc);
9188
} else if (tree.Type == ConditionTreeType.Or) {
92-
FunctionBase fun = AlgorithmEngineHelper.Condition_Or(leftFunc, rightFunc);
93-
conditionCache.put(key, fun);
94-
return fun;
89+
return AlgorithmEngineHelper.Condition_Or(leftFunc, rightFunc);
9590
}
9691
throw new RuntimeException(tree.ErrorMessage);
9792
}

‎java/toolgood.algorithm/src/main/java/toolgood/algorithm/calculationlogic/CalculationLogicEngine.java‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
*/
2121
public class CalculationLogicEngine {
2222
private final IFunctionCache _functionCache;
23-
private final List<CalculationLogicInfo> _initValueInfos = new ArrayList<>();
24-
private final List<CalculationLogicInfo> _calculationLogicInfos = new ArrayList<>();
23+
private final List<CalculationLogicInfo> _initValueInfos;
24+
private final List<CalculationLogicInfo> _calculationLogicInfos;
2525
private final boolean _useCalculationLogicInfo;
2626
private final AlgorithmEngineEx _engine;
2727

@@ -32,6 +32,8 @@ public CalculationLogicEngine(IFunctionCache functionCache, boolean useCalculati
3232
_functionCache = functionCache;
3333
_useCalculationLogicInfo = useCalculationLogicInfo;
3434
_engine = new AlgorithmEngineEx();
35+
_initValueInfos = useCalculationLogicInfo ? new ArrayList<>() : null;
36+
_calculationLogicInfos = useCalculationLogicInfo ? new ArrayList<>() : null;
3537
}
3638

3739
// #region SetScene

0 commit comments

Comments
 (0)