bug #I7KY2N 逻辑运算增加短路效果,避免多余计算
This commit is contained in:
parent
67e9616bd8
commit
d9ebc78754
|
@ -1,7 +1,6 @@
|
||||||
package com.yomahub.liteflow.flow.element.condition;
|
package com.yomahub.liteflow.flow.element.condition;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.BooleanUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||||
import com.yomahub.liteflow.exception.AndOrConditionException;
|
import com.yomahub.liteflow.exception.AndOrConditionException;
|
||||||
|
@ -11,7 +10,9 @@ import com.yomahub.liteflow.log.LFLog;
|
||||||
import com.yomahub.liteflow.log.LFLoggerManager;
|
import com.yomahub.liteflow.log.LFLoggerManager;
|
||||||
import com.yomahub.liteflow.slot.DataBus;
|
import com.yomahub.liteflow.slot.DataBus;
|
||||||
import com.yomahub.liteflow.slot.Slot;
|
import com.yomahub.liteflow.slot.Slot;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class AndOrCondition extends Condition {
|
public class AndOrCondition extends Condition {
|
||||||
|
|
||||||
|
@ -23,21 +24,10 @@ public class AndOrCondition extends Condition {
|
||||||
public void executeCondition(Integer slotIndex) throws Exception {
|
public void executeCondition(Integer slotIndex) throws Exception {
|
||||||
List<Executable> itemList = this.getItem();
|
List<Executable> itemList = this.getItem();
|
||||||
|
|
||||||
|
|
||||||
if (CollUtil.isEmpty(itemList)){
|
if (CollUtil.isEmpty(itemList)){
|
||||||
throw new AndOrConditionException("boolean item list is null");
|
throw new AndOrConditionException("boolean item list is null");
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean[] booleanArray = new boolean[itemList.size()];
|
|
||||||
|
|
||||||
for (int i = 0; i < itemList.size(); i++) {
|
|
||||||
Executable item = itemList.get(i);
|
|
||||||
item.setCurrChainId(this.getCurrChainId());
|
|
||||||
item.execute(slotIndex);
|
|
||||||
booleanArray[i] = item.getItemResultMetaValue(slotIndex);
|
|
||||||
LOG.info("the result of boolean component [{}] is [{}]", item.getId(), booleanArray[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
BooleanConditionTypeEnum booleanConditionType = this.getBooleanConditionType();
|
BooleanConditionTypeEnum booleanConditionType = this.getBooleanConditionType();
|
||||||
|
|
||||||
Slot slot = DataBus.getSlot(slotIndex);
|
Slot slot = DataBus.getSlot(slotIndex);
|
||||||
|
@ -45,16 +35,37 @@ public class AndOrCondition extends Condition {
|
||||||
String resultKey = StrUtil.format("{}_{}",this.getClass().getName(),this.hashCode());
|
String resultKey = StrUtil.format("{}_{}",this.getClass().getName(),this.hashCode());
|
||||||
switch (booleanConditionType) {
|
switch (booleanConditionType) {
|
||||||
case AND:
|
case AND:
|
||||||
slot.setAndOrResult(resultKey, BooleanUtil.and(booleanArray));
|
slot.setAndOrResult(resultKey, itemList.stream().allMatch(new AndOrConditionPredicate(slotIndex)));
|
||||||
break;
|
break;
|
||||||
case OR:
|
case OR:
|
||||||
slot.setAndOrResult(resultKey, BooleanUtil.or(booleanArray));
|
slot.setAndOrResult(resultKey, itemList.stream().anyMatch(new AndOrConditionPredicate(slotIndex)));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new AndOrConditionException("condition type must be 'AND' or 'OR'");
|
throw new AndOrConditionException("condition type must be 'AND' or 'OR'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class AndOrConditionPredicate implements Predicate<Executable> {
|
||||||
|
|
||||||
|
private final Integer slotIndex;
|
||||||
|
|
||||||
|
public AndOrConditionPredicate(Integer slotIndex) {
|
||||||
|
this.slotIndex = slotIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(Executable condition) {
|
||||||
|
try {
|
||||||
|
condition.setCurrChainId(getCurrChainId());
|
||||||
|
condition.execute(slotIndex);
|
||||||
|
return condition.getItemResultMetaValue(slotIndex);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new AndOrConditionException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class BooleanOptELSpringbootTest extends BaseTest {
|
||||||
public void testBooleanOpt2() throws Exception {
|
public void testBooleanOpt2() throws Exception {
|
||||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
|
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
|
||||||
Assertions.assertTrue(response.isSuccess());
|
Assertions.assertTrue(response.isSuccess());
|
||||||
Assertions.assertEquals("x1==>x2==>x3==>a", response.getExecuteStepStr());
|
Assertions.assertEquals("x1==>a", response.getExecuteStepStr());
|
||||||
}
|
}
|
||||||
|
|
||||||
// IF情况下AND+NOT
|
// IF情况下AND+NOT
|
||||||
|
@ -64,4 +64,13 @@ public class BooleanOptELSpringbootTest extends BaseTest {
|
||||||
Assertions.assertTrue(response.isSuccess());
|
Assertions.assertTrue(response.isSuccess());
|
||||||
Assertions.assertEquals("w1==>w2==>a==>bk==>w1==>w2==>a==>bk==>w1==>w2==>a==>bk==>w1==>w2==>a==>bk", response.getExecuteStepStr());
|
Assertions.assertEquals("w1==>w2==>a==>bk==>w1==>w2==>a==>bk==>w1==>w2==>a==>bk==>w1==>w2==>a==>bk", response.getExecuteStepStr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AND + NOT 实现短路效果
|
||||||
|
@Test
|
||||||
|
public void testBooleanOpt6() throws Exception {
|
||||||
|
LiteflowResponse response = flowExecutor.execute2Resp("chain6", "arg");
|
||||||
|
Assertions.assertTrue(response.isSuccess());
|
||||||
|
Assertions.assertEquals("x1==>b", response.getExecuteStepStr());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,4 +25,9 @@
|
||||||
<chain name="chain5">
|
<chain name="chain5">
|
||||||
WHILE(AND(w1, NOT(w2))).DO(a).BREAK(bk);
|
WHILE(AND(w1, NOT(w2))).DO(a).BREAK(bk);
|
||||||
</chain>
|
</chain>
|
||||||
|
|
||||||
|
<chain name="chain6">
|
||||||
|
IF(AND(NOT(x1), x2, x3), a, b);
|
||||||
|
</chain>
|
||||||
|
|
||||||
</flow>
|
</flow>
|
Loading…
Reference in New Issue