MCPcopy Create free account
hub / github.com/BaseXdb/basex / opt

Method opt

basex-core/src/main/java/org/basex/query/expr/Switch.java:90–149  ·  view source on GitHub ↗

Optimizes the expression. @param cc compilation context @return optimized or original expression @throws QueryException query exception

(final CompileContext cc)

Source from the content-addressed store, hash-verified

88 * @throws QueryException query exception
89 */
90 private Expr opt(final CompileContext cc) throws QueryException {
91 final ExprList cases = new ExprList();
92 Item cnd = cond instanceof Value ? cond.atomItem(cc.qc, info) : null;
93 final ArrayList<SwitchGroup> tmpGroups = new ArrayList<>();
94 for(final SwitchGroup group : groups) {
95 final int el = group.exprs.length;
96 final ExprList list = new ExprList(el).add(group.rtrn());
97 for(int e = 1; e < el; e++) {
98 final Expr expr = group.exprs[e];
99 // check if same case expression exists more than once
100 boolean remove = cases.contains(expr);
101 if(!remove && cnd != null) {
102 // pre-evaluate values; skip remaining checks if match is found
103 if(expr instanceof Value) {
104 if(group.match(cnd, e, cc.qc)) return group.rtrn();
105 remove = true;
106 } else {
107 // value unknown at compile: perform no further compile-time checks
108 cnd = null;
109 }
110 }
111 if(remove) {
112 cc.info(OPTREMOVE_X_X, expr, (Supplier<?>) this::description);
113 } else {
114 cases.add(expr);
115 list.add(expr);
116 }
117 }
118 // build list of branches (add those with case left, or the default branch)
119 if(list.size() > 1 || el == 1) {
120 group.exprs = list.finish();
121 tmpGroups.add(group);
122 }
123 }
124
125 // merge branches with identical return path
126 for(int g = 0; g < tmpGroups.size(); g++) {
127 final SwitchGroup group1 = g > 0 ? tmpGroups.get(g - 1) : null, group2 = tmpGroups.get(g);
128 if(g > 0 && group1.rtrn().equals(group2.rtrn())) {
129 if(g + 1 == tmpGroups.size() && !group1.has(Flag.NDT)) {
130 tmpGroups.set(g - 1, group2);
131 } else {
132 final ExprList list = new ExprList(group1.exprs.length + group2.exprs.length - 1);
133 list.add(group1.exprs).add(Arrays.copyOfRange(group2.exprs, 1, group2.exprs.length));
134 tmpGroups.set(g - 1, new SwitchGroup(group1.info, list.finish()).optimize(cc));
135 }
136 tmpGroups.remove(g--);
137 }
138 }
139
140 // update branches
141 if(tmpGroups.size() != groups.length) {
142 groups = tmpGroups.toArray(SwitchGroup[]::new);
143 cc.info(OPTSIMPLE_X_X, (Supplier<?>) this::description, this);
144 }
145
146 Expr expr = simplify();
147 if(expr == this) expr = toIf(cc);

Callers 1

optimizeMethod · 0.95

Calls 15

rtrnMethod · 0.95
simplifyMethod · 0.95
toIfMethod · 0.95
addMethod · 0.65
containsMethod · 0.65
infoMethod · 0.65
sizeMethod · 0.65
getMethod · 0.65
setMethod · 0.65
removeMethod · 0.65
atomItemMethod · 0.45
matchMethod · 0.45

Tested by

no test coverage detected