예제 #1
0
파일: FTWords.java 프로젝트: jefferya/basex
  /**
   * Evaluates the full-text match.
   *
   * @param qc query context
   * @return number of tokens, used for scoring
   * @throws QueryException query exception
   */
  private int contains(final QueryContext qc) throws QueryException {
    first = true;
    final FTLexer lexer = ftt.lexer(qc.ftToken);

    // use faster evaluation for default options
    int num = 0;
    if (fast) {
      for (final byte[] t : tokens) {
        final FTTokens qtok = ftt.cache(t);
        num = Math.max(num, ftt.contains(qtok, lexer) * qtok.length());
      }
      return num;
    }

    // find and count all occurrences
    final boolean all = mode == FTMode.ALL || mode == FTMode.ALL_WORDS;
    int oc = 0;
    for (final byte[] w : unique(tokens(qc))) {
      final FTTokens qtok = ftt.cache(w);
      final int o = ftt.contains(qtok, lexer);
      if (all && o == 0) return 0;
      num = Math.max(num, o * qtok.length());
      oc += o;
    }

    // check if occurrences are in valid range. if yes, return number of tokens
    final long mn = occ != null ? toLong(occ[0], qc) : 1;
    final long mx = occ != null ? toLong(occ[1], qc) : Long.MAX_VALUE;
    if (mn == 0 && oc == 0) matches = FTNot.not(matches);
    return oc >= mn && oc <= mx ? Math.max(1, num) : 0;
  }
예제 #2
0
파일: FTWords.java 프로젝트: jefferya/basex
 @Override
 public FTExpr copy(final QueryContext qc, final VarScope scp, final IntObjMap<Var> vs) {
   final FTWords ftw =
       new FTWords(
           info,
           query.copy(qc, scp, vs),
           mode,
           occ == null ? null : Arr.copyAll(qc, scp, vs, occ));
   if (ftt != null) ftw.ftt = ftt.copy(ftw);
   ftw.tokens = tokens;
   ftw.data = data;
   ftw.first = first;
   ftw.pos = pos;
   ftw.fast = fast;
   return ftw;
 }
예제 #3
0
파일: FTWords.java 프로젝트: jefferya/basex
  /**
   * Returns a scan-based index iterator.
   *
   * @param lex lexer, including the queried value
   * @return node iterator
   * @throws QueryException query exception
   */
  private FTIndexIterator scan(final FTLexer lex) throws QueryException {
    final FTLexer input = new FTLexer(ftt.opt);
    final FTTokens fttokens = ftt.cache(lex.get());

    return new FTIndexIterator() {
      final int sz = data.meta.size;
      int pre = -1, ps;

      @Override
      public int pre() {
        return pre;
      }

      @Override
      public boolean more() {
        while (++pre < sz) {
          if (data.kind(pre) != Data.TEXT) continue;
          input.init(data.text(pre, true));
          matches.reset(ps);
          try {
            if (ftt.contains(fttokens, input) != 0) return true;
          } catch (final QueryException ignore) {
            // ignore exceptions
          }
        }
        return false;
      }

      @Override
      public FTMatches matches() {
        return matches;
      }

      @Override
      public void pos(final int p) {
        ps = p;
      }

      @Override
      public int size() {
        // worst case
        return Math.max(1, sz >>> 1);
      }
    };
  }