Skip to content

Commit

Permalink
[MOD] Refactorings. #1115
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianGruen committed Feb 24, 2025
1 parent 72afdcf commit d791bda
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 89 deletions.
2 changes: 1 addition & 1 deletion basex-core/src/main/java/org/basex/query/QueryText.java
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ public interface QueryText {
/** Serialization. */ byte[] CHARACTER_MAP = token("character-map");
/** Serialization. */ byte[] MAP_STRING = token("map-string");

/** Debugging info. */ String DEBUG_LOCAL = "Local Variables";
/** Debugging info. */ byte[] DEBUG_ASSIGNMENTS = token("Assignments:");

/** Java prefix. */ String JAVA_PREFIX_COLON = "java:";
/** Java keyword: new. */ String NEW = "new";
Expand Down
4 changes: 2 additions & 2 deletions basex-core/src/main/java/org/basex/query/func/Function.java
Original file line number Diff line number Diff line change
Expand Up @@ -1689,8 +1689,8 @@ EMPTY_SEQUENCE_Z, flag(NDT), PROC_URI, Perm.ADMIN),
_PROF_TYPE(ProfType::new, "type(value)",
params(ITEM_ZM), ITEM_ZM, flag(NDT), PROF_URI),
/** XQuery function. */
_PROF_VARIABLES(ProfVariables::new, "variables()",
params(), EMPTY_SEQUENCE_Z, flag(NDT), PROF_URI),
_PROF_VARIABLES(ProfVariables::new, "variables([map,label])",
params(MAP_ZO, STRING_ZO), EMPTY_SEQUENCE_Z, flag(NDT), PROF_URI),

// Random Module

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
package org.basex.query.func.prof;

import static org.basex.util.Token.*;
import static org.basex.query.func.Function.*;

import java.util.List;

import org.basex.query.*;
import org.basex.query.expr.*;
import org.basex.query.expr.constr.*;
import org.basex.query.func.*;
import org.basex.query.func.fn.*;
import org.basex.query.util.*;
import org.basex.query.util.hash.*;
import org.basex.query.value.*;
import org.basex.query.util.list.*;
import org.basex.query.value.item.*;
import org.basex.query.value.seq.*;
import org.basex.query.value.type.*;
import org.basex.query.var.*;
import org.basex.util.*;
import org.basex.util.hash.*;

/**
* Function implementation.
Expand All @@ -26,67 +24,39 @@
*/
public final class ProfVariables extends StandardFunc {
@Override
public Item item(final QueryContext qc, final InputInfo ii) {
throw Util.notExpected();
public Item item(final QueryContext qc, final InputInfo ii) throws QueryException {
final Item map = arg(0).item(qc, info);
final byte[] label = toZeroToken(arg(1), qc);

if(!map.isEmpty()) {
final TokenBuilder tb = new TokenBuilder();
toMap(map).forEach((key, value) -> {
if(value != Empty.UNDEFINED) {
tb.add(Prop.NL).add(" ").add(key.toJava()).add(" := ").add(value);
}
});
FnTrace.trace(tb.finish(), label.length != 0 ? label : QueryText.DEBUG_ASSIGNMENTS, qc);
}
return Empty.VALUE;
}

@Override
protected Expr opt(final CompileContext cc) throws QueryException {
final List<Var> vars = cc.vs().vars;
final QNmSet names = new QNmSet();
final Expr[] varRefs = new Expr[vars.size()];
for(int i = 0; i < vars.size(); ++i) {
final Var var = vars.get(i);
names.add(var.name);
varRefs[i] = new VarRef(info, var);
}
return new VarHandler(info, names, varRefs);
}

/**
* Function implementation for logging defined variables.
*/
private static class VarHandler extends Arr {
/** Names of variables. */
final QNmSet names;
if(!arg(0).seqType().zero()) return this;

/**
* Constructor.
* @param info input info
* @param names variable names
* @param varRefs variable references
*/
protected VarHandler(final InputInfo info, final QNmSet names, final Expr... varRefs) {
super(info, SeqType.EMPTY_SEQUENCE_Z, varRefs);
this.names = names;
// create map constructor with context value and variable names/references
final ExprList list = new ExprList();
if(cc.qc.focus.value != null) {
list.add(new ContextValue(info)).add(Str.get("."));
}

@Override
public Value value(final QueryContext qc) throws QueryException {
final TokenBuilder tb = new TokenBuilder().add(QueryText.DEBUG_LOCAL).add(':');
int i = 0;
for(final QNm name : names) {
final Value value = exprs[i++].value(qc);
if(value != null) tb.add(Prop.NL).add(" $").add(name).add(" := ").add(value);
final List<Var> vars = cc.vs().vars;
final QNmSet names = new QNmSet();
for(int v = vars.size() - 1; v >= 0; --v) {
final Var var = vars.get(v);
if(names.add(var.name)) {
list.add(new VarRef(info, var)).add(Str.get(Strings.concat('$', var.name.prefixId())));
}
FnTrace.trace(token(tb.toString()), EMPTY, qc);
return Empty.VALUE;
}

@Override
public boolean has(final Flag... flags) {
for(final Flag flag : flags) if(flag == Flag.NDT) return true;
return super.has(flags);
}

@Override
public Expr copy(final CompileContext cc, final IntObjMap<Var> vm) {
return copyType(new VarHandler(info, names, copyAll(cc, vm, args())));
}

@Override
public void toString(final QueryString qs) {
qs.token("prof:variables").params(exprs);
}
return cc.function(_PROF_VARIABLES, info, new CMap(info, list.reverse().finish()));
}
}
58 changes: 31 additions & 27 deletions basex-core/src/main/java/org/basex/query/var/QueryStack.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package org.basex.query.var;

import org.basex.query.*;
import org.basex.query.func.prof.*;
import org.basex.query.value.*;
import org.basex.query.value.seq.*;
import org.basex.util.*;

/**
Expand All @@ -13,13 +15,13 @@
public final class QueryStack {
/** Initial stack size. */
private static final int INIT = 1 << 5;
/** The currently assigned values. */
private Value[] stack = new Value[INIT];
/** The currently assigned variables. */
/** Assigned values. */
private Value[] values = new Value[INIT];
/** Declared variables. */
private Var[] vars = new Var[INIT];
/** The frame pointer, marking the start of the current stack frame. */
/** Frame pointer, marking the start of the current stack frame. */
private int start;
/** The stack limit, marking the end of the current stack frame. */
/** Stack limit, marking the end of the current stack frame. */
private int end;

/**
Expand All @@ -43,8 +45,8 @@ public int enterFrame(final int size) {
public void reuseFrame(final int size) {
final int s = start;
ensureCapacity(s + size);
final Value[] stck = stack;
for(int e = end; --e >= s;) stck[e] = null;
final Value[] vls = values;
for(int e = end; --e >= s;) vls[e] = null;
end = s + size;
}

Expand All @@ -54,15 +56,15 @@ public void reuseFrame(final int size) {
*/
public void exitFrame(final int fp) {
final int s = start;
final Value[] stck = stack;
for(int en = end; --en >= s;) stck[en] = null;
final Value[] vls = values;
for(int en = end; --en >= s;) vls[en] = null;
end = s;
start = fp;

final int sl = stck.length;
int len = sl;
while(len > INIT && sl <= len >> 2) len >>= 1;
if(len != sl) resize(len);
final int vl = vls.length;
int ns = vl;
while(ns > INIT && vl <= ns >> 2) ns >>= 1;
if(ns != vl) resize(ns);
}

/**
Expand All @@ -79,10 +81,10 @@ public boolean tco(final int size) {
* @param size required stack size
*/
private void ensureCapacity(final int size) {
final int sl = stack.length;
int len = sl;
while(size > len) len <<= 1;
if(len != sl) resize(len);
final int vl = values.length;
int ns = vl;
while(size > ns) ns <<= 1;
if(ns != vl) resize(ns);
}

/**
Expand All @@ -91,21 +93,23 @@ private void ensureCapacity(final int size) {
*/
private void resize(final int size) {
final int os = end;
final Value[] nst = new Value[size];
Array.copy(stack, os, nst);
stack = nst;
final Var[] nvr = new Var[size];
Array.copy(vars, os, nvr);
vars = nvr;
final Value[] vls = new Value[size];
Array.copy(values, os, vls);
values = vls;
final Var[] vrs = new Var[size];
Array.copy(vars, os, vrs);
vars = vrs;
}

/**
* Gets the value bound to the given variable in the current stack frame.
* @param var variable
* @return bound value
* @return bound value, or {@link Empty#UNDEFINED} reference (required for {@link ProfVariables})
*/
public Value get(final Var var) {
return var.slot == -1 ? null : stack[start + var.slot];
final int vs = var.slot;
final Value value = vs == -1 ? null : values[start + vs];
return value != null ? value : Empty.UNDEFINED;
}

/**
Expand All @@ -117,12 +121,12 @@ public Value get(final Var var) {
*/
public void set(final Var var, final Value value, final QueryContext qc) throws QueryException {
final int pos = start + var.slot;
stack[pos] = var.checkType(value, qc, null);
vars[pos] = var;
values[pos] = var.checkType(value, qc, null);
}

@Override
public String toString() {
return new TokenBuilder().add(getClass()).add('[').addAll(stack, ", ").add(']').toString();
return new TokenBuilder().add(getClass()).add('[').addAll(values, ", ").add(']').toString();
}
}
14 changes: 14 additions & 0 deletions basex-core/src/test/java/org/basex/query/func/ProfModuleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.basex.query.func.Function.*;

import org.basex.*;
import org.basex.query.*;
import org.junit.jupiter.api.*;

/**
Expand Down Expand Up @@ -72,7 +73,20 @@ public final class ProfModuleTest extends SandboxTest {
/** Test method. */
@Test public void variables() {
final Function func = _PROF_VARIABLES;
final String name = func.args().replace("()", "");

// ensure that profiling leads to no unexpected errors (the debug output is not tested)
query("for $x in 1 to 2 return " + func.args(), "");
query(func.args() + ", let $x := " + _RANDOM_DOUBLE.args() + " return floor($x * $x)", 0);
query(func.args() + ", let $x := " + wrap(1) + " return $x, " + func.args(), 1);
query("fn { " + func.args() + "}(1)", "");

query("function-lookup(xs:QName('" + name + "'), 0)()", "");
query("function-lookup(xs:QName(" + wrap(name) + "), 0)()", "");

query(func.args(" {}"), "");
query("function-lookup(xs:QName('" + name + "'), 1)({})", "");
query("function-lookup(xs:QName(" + wrap(name) + "), 1)({})", "");
error(func.args(1), QueryError.INVCONVERT_X_X_X);
}
}

0 comments on commit d791bda

Please sign in to comment.