package com.taobao.tddl.optimizer.costbased.after;
import java.util.Map;
import com.taobao.tddl.common.jdbc.ParameterContext;
import com.taobao.tddl.optimizer.core.plan.IDataNodeExecutor;
import com.taobao.tddl.optimizer.core.plan.IPut;
import com.taobao.tddl.optimizer.core.plan.query.IJoin;
import com.taobao.tddl.optimizer.core.plan.query.IMerge;
import com.taobao.tddl.optimizer.core.plan.query.IQuery;
/**
* 防止死锁的thread 号选择器。 每层会独立指定一个thread进行执行。这样就算是A->B->A 也不会出现死锁的问题。
* 出现死锁的主要原因是请求是blocking状态的,所以导致后面的流数据无法处理,死锁。
* 如果要修复这个问题,必须将请求发送和请求回收处理,逻辑上分开。变成发送流和接受流。才能解决,目前的方案是权宜方案 不会改变结构
*
* @author Whisper
*/
public class ChooseTreadOptimizer implements QueryPlanOptimizer {
public ChooseTreadOptimizer(){
}
@Override
public IDataNodeExecutor optimize(IDataNodeExecutor dne, Map<Integer, ParameterContext> parameterSettings,
Map<String, Object> extraCmd) {
if (extraCmd != null && extraCmd.get("initThread") != null) this.allocThread(dne,
(Integer) extraCmd.get("initThread"));
else {
this.allocThread(dne, 0);
}
return dne;
}
private void allocThread(IDataNodeExecutor dne, int i) {
dne.setThread(i);
if (dne instanceof IPut) {
if (((IPut) dne).getQueryTree() != null) {
this.allocThread(((IPut) dne).getQueryTree(), i + 1);
}
} else if (dne instanceof IQuery) {
if (((IQuery) dne).getSubQuery() != null) {
this.allocThread(((IQuery) dne).getSubQuery(), i + 1);
}
} else if (dne instanceof IMerge) {
for (IDataNodeExecutor sub : ((IMerge) dne).getSubNode()) {
this.allocThread(sub, i + 1);
}
} else if (dne instanceof IJoin) {
this.allocThread(((IJoin) dne).getLeftNode(), i + 1);
this.allocThread(((IJoin) dne).getRightNode(), i + 1);
}
}
}