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

Method optimize

basex-core/src/main/java/org/basex/query/func/Closure.java:165–224  ·  view source on GitHub ↗
(final CompileContext cc)

Source from the content-addressed store, hash-verified

163 }
164
165 @Override
166 public Expr optimize(final CompileContext cc) {
167 cc.pushScope(vs);
168 try {
169 // inline all values in the closure
170 final Iterator<Entry<Var, Expr>> iter = global.entrySet().iterator();
171 Map<Var, Expr> add = null;
172 final int limit = cc.qc.context.options.get(MainOptions.INLINELIMIT);
173 while(iter.hasNext()) {
174 final Entry<Var, Expr> entry = iter.next();
175 final Var var = entry.getKey();
176 final Expr ex = entry.getValue();
177
178 Expr inline = null;
179 if(ex instanceof final Value value) {
180 // values are always inlined into the closure
181 inline = var.checkType(value, cc.qc, cc);
182 } else if(ex instanceof final Closure cl) {
183 // nested closures are inlined if their size and number of closed-over variables is small
184 if(!cl.has(Flag.NDT) && cl.global.size() < 5
185 && expr.count(var) != VarUsage.MORE_THAN_ONCE && cl.exprSize() < limit) {
186 cc.info(OPTINLINE_X, entry);
187 for(final Entry<Var, Expr> expr2 : cl.global.entrySet()) {
188 final Var var2 = cc.copy(expr2.getKey(), null);
189 if(add == null) add = new HashMap<>();
190 add.put(var2, expr2.getValue());
191 expr2.setValue(new VarRef(cl.info, var2).optimize(cc));
192 }
193 inline = cl;
194 }
195 }
196 if(inline != null) {
197 expr = new InlineContext(var, inline, cc).inline(expr);
198 iter.remove();
199 }
200 }
201 // add all newly added bindings
202 if(add != null) global.putAll(add);
203 } catch(final QueryException ex) {
204 expr = FnError.get(ex, expr);
205 } finally {
206 cc.removeScope(this);
207 }
208
209 final SeqType st = expr.seqType();
210 final SeqType dt = declType == null || st.instanceOf(declType) ? st : declType;
211 exprType.assign(FuncType.get(anns, dt, params));
212
213 // only evaluate if:
214 // - the closure is empty, so we don't lose variables
215 // - the result size is not too large
216 if(global.isEmpty() && !cc.largeResult(expr)) {
217 try {
218 return cc.preEval(this);
219 } catch(final QueryException ex) {
220 expr = FnError.get(ex, expr);
221 }
222 }

Callers 3

compileMethod · 0.95
refineMethod · 0.95
inlineMethod · 0.95

Calls 15

checkTypeMethod · 0.95
getMethod · 0.95
instanceOfMethod · 0.95
getMethod · 0.95
pushScopeMethod · 0.80
getKeyMethod · 0.80
removeScopeMethod · 0.80
largeResultMethod · 0.80
getMethod · 0.65
nextMethod · 0.65
sizeMethod · 0.65
countMethod · 0.65

Tested by

no test coverage detected