package org.basex.query.util;
import org.basex.data.Data;
import org.basex.query.QueryContext;
import org.basex.query.expr.Context;
import org.basex.query.expr.Expr;
import org.basex.query.expr.ParseExpr;
import org.basex.query.path.Axis;
import org.basex.query.path.AxisPath;
import org.basex.query.path.AxisStep;
import org.basex.query.path.Path;
import org.basex.util.Array;
/**
* Container for all information needed to determine whether an index is
* accessible or not.
*
* @author BaseX Team 2005-12, BSD License
* @author Christian Gruen
* @author Sebastian Gath
*/
public final class IndexContext {
/** Query context. */
public final QueryContext ctx;
/** Data reference. */
public final Data data;
/** Index Step. */
public final AxisStep step;
/** Flag for iterative evaluation. */
public final boolean iterable;
/** Costs of index access: smaller is better, 0 means no results. */
private int costs;
/** Flag for ftnot expressions. */
public boolean not;
/** Flag for sequential processing. */
public boolean seq;
/**
* Constructor.
* @param c query context
* @param d data reference
* @param s index step
* @param i iterable flag
*/
public IndexContext(final QueryContext c, final Data d, final AxisStep s,
final boolean i) {
ctx = c;
data = d;
step = s;
iterable = i;
}
/**
* Rewrites the specified expression for index access.
* @param ex expression to be rewritten
* @param root new root expression
* @param text text flag
* @return index access
*/
public Expr invert(final Expr ex, final ParseExpr root, final boolean text) {
// handle context node
if(ex instanceof Context) {
if(text) return root;
// add attribute step
if(step.test.name == null) return root;
return Path.get(root.input, root,
AxisStep.get(step.input, Axis.SELF, step.test));
}
final AxisPath orig = (AxisPath) ex;
final AxisPath path = orig.invertPath(root, step);
if(!text) {
// add attribute step
final AxisStep s = orig.step(orig.steps.length - 1);
if(s.test.name != null) {
Expr[] steps = { AxisStep.get(s.input, Axis.SELF, s.test) };
for(final Expr e : path.steps) steps = Array.add(steps, e);
path.steps = steps;
}
}
return path;
}
/**
* Adds the estimated costs.
* @param c cost to be added
*/
public void addCosts(final int c) {
costs = Math.max(1, costs + c);
}
/**
* Sets the estimated costs.
* @param c cost to be added
*/
public void costs(final int c) {
costs = c;
}
/**
* Returns the estimated costs.
* @return costs
*/
public int costs() {
return costs;
}
}