package org.basex.query.ft; import static org.basex.query.QueryText.*; import org.basex.query.QueryContext; import org.basex.query.QueryException; import org.basex.query.expr.Expr; import org.basex.query.item.Bln; import org.basex.query.item.DBNode; import org.basex.query.item.FTNode; import org.basex.query.iter.FTIter; import org.basex.query.iter.Iter; import org.basex.query.util.IndexContext; import org.basex.util.InputInfo; import org.basex.util.ft.FTLexer; /** * Sequential FTContains expression with index access. * * @author BaseX Team 2005-12, BSD License * @author Sebastian Gath */ final class FTContainsIndex extends FTContains { /** Index context. */ private final IndexContext ictx; /** Current node item. */ private FTNode ftn; /** Node iterator. */ private FTIter fti; /** * Constructor. * @param ii input info * @param e contains, select and optional ignore expression * @param f full-text expression * @param ic index context */ FTContainsIndex(final InputInfo ii, final Expr e, final FTExpr f, final IndexContext ic) { super(e, f, ii); ictx = ic; } @Override public Bln item(final QueryContext ctx, final InputInfo ii) throws QueryException { final Iter ir = expr.iter(ctx); final FTLexer tmp = ctx.fttoken; ctx.fttoken = lex; // create index iterator if(fti == null) { fti = ftexpr.iter(ctx); ftn = fti.next(); } // find next relevant index entry boolean found = false; DBNode n = null; while(!found && (n = (DBNode) ir.next()) != null) { // find entry with pre value equal to or larger than current node while(ftn != null && n.pre > ftn.pre) ftn = fti.next(); found = (ftn != null && n.pre == ftn.pre) ^ ictx.not; } // reset index iterator after all nodes have been processed if(n == null) fti = null; // add entry to visualization if(found && ctx.ftpos != null && !ictx.not) { ctx.ftpos.add(ftn.data, ftn.pre, ftn.all); } ctx.fttoken = tmp; return Bln.get(found ? 1 : 0); } @Override public String toString() { return expr + " " + CONTAINS + ' ' + TEXT + ' ' + ftexpr; } }