All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.harbby.dsxparser.Optimizer Maven / Gradle / Ivy

The newest version!
package com.github.harbby.dsxparser;

import com.github.harbby.dsxparser.rbo.ArithmeticConstantFoldingRule;
import com.github.harbby.dsxparser.rbo.ArithmeticUnaryRule;
import com.github.harbby.dsxparser.rbo.LiteralConcatConstantFoldingRule;
import com.github.harbby.dsxparser.tree.Expression;

import java.lang.reflect.InvocationTargetException;
import java.util.*;

public class Optimizer {

    private static final Optimizer EMPTY_OPTIMIZER = new Optimizer(Collections.emptyList()) {
        @Override
        public void registerRBO(Class> ruleClass) {
            throw new UnsupportedOperationException("Empty Optimizer do not support registerRBO rele");
        }
    };

    private final Map, Set>> ruleMap = new HashMap<>();

    private static final List>> INTERNAL_RBO_RULES = Arrays.asList(
            ArithmeticUnaryRule.class,
            ArithmeticConstantFoldingRule.class,
            LiteralConcatConstantFoldingRule.class);

    private Optimizer(List>> ruleList) {
        for (Class> ruleClass : ruleList) {
            registerRBO(ruleClass);
        }
    }

    public void registerRBO(Class> ruleClass) {
        RboRule rboRule = instanceRule(ruleClass);
        ruleMap.computeIfAbsent(rboRule.bind(), k -> new HashSet<>()).add(rboRule);
    }

    public void registerRBO(RboRule rboRule) {
        ruleMap.computeIfAbsent(rboRule.bind(), k -> new HashSet<>()).add(rboRule);
    }

    public Optimizer with(RboRule rboRule) {
        Optimizer child = this;
        Optimizer wrap = new Optimizer(Collections.emptyList()) {
            @Override
            public Expression optimize(Expression e) {
                Expression expression = child.optimize(e);
                return super.optimize(expression);
            }
        };
        wrap.registerRBO(rboRule);
        return wrap;
    }

    public  Optional> match(T exp) {
        Set> rules = lookupRule(exp);
        for (RboRule rboRule : rules) {
            if (rboRule.isMatch(exp)) {
                return Optional.of(rboRule);
            }
        }
        return Optional.empty();
    }

    @SuppressWarnings("unchecked")
    private  Set> lookupRule(T exp) {
        Set> rules = ruleMap.getOrDefault(exp.getClass(), Collections.emptySet());
        return (Set>) rules;
    }

    private static RboRule instanceRule(Class> ruleClass) {
        try {
            return ruleClass.getConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException |
                 NoSuchMethodException e) {
            throw new IllegalStateException("instance rule class failed", e);
        }
    }

    public Expression optimize(Expression e) {
        Expression childFirst = e.visit(this);
        return this.match(childFirst)
                .map(r -> r.optimize(childFirst))
                .orElse(childFirst);
    }

    public static Optimizer empty() {
        return EMPTY_OPTIMIZER;
    }

    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {
        private final List>> rboRules = new ArrayList<>();
        private boolean disableBuiltinRboRule = false;

        public Builder add(Class> ruleClass) {
            this.rboRules.add(ruleClass);
            return this;
        }

        public Builder addAll(Collection>> ruleClassList) {
            this.rboRules.addAll(ruleClassList);
            return this;
        }

        public Builder disableBuiltinRboRule() {
            this.disableBuiltinRboRule = true;
            return this;
        }

        public Optimizer build() {
            if (!disableBuiltinRboRule) {
                this.addAll(INTERNAL_RBO_RULES);
            }
            return new Optimizer(rboRules);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy