package org.basex.query.ft;
import static org.basex.query.util.Err.*;
import java.io.IOException;
import org.basex.io.serial.Serializer;
import org.basex.query.QueryContext;
import org.basex.query.QueryException;
import org.basex.query.QueryText;
import org.basex.query.expr.Expr;
import org.basex.query.item.FTNode;
import org.basex.query.iter.FTIter;
import org.basex.query.util.IndexContext;
import org.basex.query.util.Var;
import org.basex.util.InputInfo;
/**
* FTOptions expression.
*
* @author BaseX Team 2005-12, BSD License
* @author Christian Gruen
*/
public final class FTWeight extends FTExpr {
/** Weight. */
private Expr weight;
/**
* Constructor.
* @param ii input info
* @param e expression
* @param w weight
*/
public FTWeight(final InputInfo ii, final FTExpr e, final Expr w) {
super(ii, e);
weight = w;
}
@Override
public FTExpr comp(final QueryContext ctx) throws QueryException {
weight = checkUp(weight, ctx).comp(ctx);
return super.comp(ctx);
}
// called by sequential variant
@Override
public FTNode item(final QueryContext ctx, final InputInfo ii)
throws QueryException {
return weight(expr[0].item(ctx, input), ctx);
}
// called by index variant
@Override
public FTIter iter(final QueryContext ctx) {
return new FTIter() {
@Override
public FTNode next() throws QueryException {
return weight(expr[0].iter(ctx).next(), ctx);
}
};
}
/**
* Returns the item with weight calculation.
* @param item input item
* @param ctx query context
* @return item
* @throws QueryException query exception
*/
FTNode weight(final FTNode item, final QueryContext ctx)
throws QueryException {
// evaluate weight
if(item == null) return null;
final double d = checkDbl(weight, ctx);
if(Math.abs(d) > 1000) FTWEIGHT.thrw(input, d);
if(d == 0) item.all.size = 0;
item.score(item.score() * d);
return item;
}
@Override
public boolean indexAccessible(final IndexContext ic) {
// weight makes no sense as long as no index-based scoring exists
return false;
}
@Override
public boolean uses(final Use u) {
return weight.uses(u) || super.uses(u);
}
@Override
public int count(final Var v) {
return weight.count(v) + super.count(v);
}
@Override
public boolean removable(final Var v) {
return weight.removable(v) && super.removable(v);
}
@Override
public FTExpr remove(final Var v) {
weight = weight.remove(v);
return super.remove(v);
}
@Override
public void plan(final Serializer ser) throws IOException {
ser.openElement(this);
weight.plan(ser);
expr[0].plan(ser);
ser.closeElement();
}
@Override
public String toString() {
return expr[0] + " " + QueryText.WEIGHT + ' ' + weight;
}
}