閱讀901 返回首頁    go 微軟 go windows


Pig源碼分析: 邏輯執行計劃優化

Whole View

本文分析的是邏輯執行計劃優化的代碼結構,具體每種Rule的實現不做分析。

看本文之前最好參考之前那篇邏輯執行計劃模型的文章。



Architecture

幾個關鍵類/接口的關係:


每個關鍵類/接口的實現和繼承結構在下麵各節展開。


Optimizer

PlanOptimizer是抽象類,主要和Rule、PlanTransformListener、OperatorPlan打交道。

public abstract class PlanOptimizer {
 
    protected List<Set<Rule>> ruleSets;
    protected OperatorPlan plan;
    protected List<PlanTransformListener> listeners;
    protected int maxIter;

它接受一個OperatorPlan,即Operators的DAG模型,在optimize()方法裏,遍曆ruleSet,得到幾批Rules,即Set<Rule>。對於每批Rules,調用每個rule.match(plan)來處理傳入的OperatorPlan,返回一個匹配成功的List<OperatorPlan> matches,對這些match的plans進行進一步處理。首先獲得rule的transformer,然後進行transformer的check()和transform()操作。如果需要Listener操作的,還會遍曆listeners,讓每個PlanTransformListener監聽到transformer進行的transform操作,transformer的reportChanges()方法可以返回他transform操作修改的部分。

代碼如下:

    public void optimize() throws FrontendException {

        for (Set<Rule> rs : ruleSets) {
            boolean sawMatch = false;
            int numIterations = 0;
            do {
                sawMatch = false;
                for (Rule rule : rs) {
                    List<OperatorPlan> matches = rule.match(plan);
                    if (matches != null) {
                        Transformer transformer = rule.getNewTransformer();
                        for (OperatorPlan m : matches) {
                            try {
                                if (transformer.check(m)) {
                                    sawMatch = true;
                                    transformer.transform(m);
                                    if (!rule.isSkipListener()) {
                                        for(PlanTransformListener l: listeners) {
                                            l.transformed(plan, transformer.reportChanges());
                                        }
                                    }
                                }
                            } catch (Exception e) {
                                StringBuffer message = new StringBuffer("Error processing rule " + rule.name);
                                if (!rule.isMandatory()) {
                                    message.append(". Try -t " + rule.name);
                                }
                                throw new FrontendException(message.toString(), 2000, e);
                            }
                        }
                    }
                }
            } while(sawMatch && ++numIterations < maxIter);
        }
    }

實現類:



LogicalPlanOptimizer

LogicalPlanOptimizer類是PlanOptimizer的子類

 

默認加載兩個Listener:


Listener的這兩個實現在PlanTransformerListener一節具體展開講述。

 

初始化的時候會buildRuleSets(),把需要添加的Rule都生成出來,然後校對該Rule是否被強製加入,或被turn off,從而選擇性地放入優化規則。以下列舉了所有候選的優化規則,Rule是順序執行的:



Transformer

Transformer是抽象類,有三個方法需要子類實現:

check()方法,利用pattern來匹配plan裏符合的operator集合,返回match的operator集

transform()方法,具體實施對tree的轉換操作

reportChanges()方法,報告tree的哪部分被transform操作過了(隻包括被修改了的或增加了的,不包括刪除的node),目的是為了讓Listener得知,從而可以修改schema或annotation等等。

 

繼承結構如下:



PlanTransformerListener

PlanTransformListener監聽一個plan被修改後會觸發。

舉例:

當一個Rule把一次join裏的Filter步驟提前到join操作之間做,那麼過濾部分的input schema很可能需要改變,此時一個schema listener就會被觸發並執行。

 

PlanTransformListener是一個接口,需要實現一個方法:

public void transformed(OperatorPlan fp, OperatorPlan tp) throws FrontendException;

下麵具體介紹兩個實現類


ProjectionPatcher

作用是在映射操作中修補引用信息

有兩個內部靜態類



SchemaPatcher

使用於邏輯執行計劃優化過程,plantransform了之後修補schema信息


Rule

public abstract class Rule {
    protected String name = null;
    protected OperatorPlan pattern;
    transient protected OperatorPlan currentPlan;
private transient Set<Operator> matchedNodes = 
new HashSet<Operator>();
    private boolean mandatory;
    private boolean skipListener = false;

Rule已經把 match(OperatorPlan plan)方法的邏輯實現好了。

子類需要實現的是buildPattern()方法,來製定各自的”模式”,即pattern變量。

子類還需要實現getNewTransformer()方法來實例化一個transformer,transformer的check()和transform()方法會進一步處理rule匹配的operators。

 

Rulematch()的用途是確保plan的所有子plan都滿足該rule的pattern。

實現邏輯比較繁雜。


Rule繼承結構



具體每個Rule不分析了。



全文完 :)






最後更新:2017-04-03 12:56:09

  上一篇:go HDU4716-A Computer Graphics Problem
  下一篇:go cocos2dx 一步步入門 CCMoveTo/CCMoveBy/CCRotateTo/CCRotateBy