/** * Writes full-text data for a single token to disk.<br> * Format: {@code score? pre1 pos1 pre2 pos2 ... (0 score)? pre...} * * @param out DataOutput for disk access * @param vpre compressed pre values * @param vpos compressed pos values * @throws IOException IOException */ final void writeFTData(final DataOutput out, final byte[] vpre, final byte[] vpos) throws IOException { int np = 4, pp = 4, lp = -1, lu = -1; final int ns = Num.size(vpre); while (np < ns) { if (scm > 0) { final int p = Num.get(vpre, np); if (lp != p) { // new pre value: find document root int u = unit.sortedIndexOf(p); if (u < 0) u = -u - 1; if (lu != u) { // new unit: store scoring final int s = Scoring.tfIDF(freq.get(fc++), maxfreq[u], unit.size(), ntoken[token]); if (max < s) max = s; if (min > s) min = s; if (np != 4) out.write(0); out.writeNum(s); lu = u; } lp = p; } } // full-text data is stored here, with -scoreU, pre1, pos1, ..., // -scoreU, preU, posU for (final int l = np + Num.length(vpre, np); np < l; ++np) out.write(vpre[np]); for (final int l = pp + Num.length(vpos, pp); pp < l; ++pp) out.write(vpos[pp]); } ++token; }
/** * Checks if the predicates are successful for the specified item. * * @param it item to be checked * @param qc query context * @return result of check * @throws QueryException query exception */ protected final boolean preds(final Item it, final QueryContext qc) throws QueryException { if (preds.length == 0) return true; // set context value and position final Value cv = qc.value; try { if (qc.scoring) { double s = 0; for (final Expr p : preds) { qc.value = it; final Item i = p.test(qc, info); if (i == null) return false; s += i.score(); } it.score(Scoring.avg(s, preds.length)); } else { for (final Expr p : preds) { qc.value = it; if (p.test(qc, info) == null) return false; } } return true; } finally { qc.value = cv; } }
/** * Merges two matches. * * @param i1 first item * @param i2 second item */ private static void and(final FTNode i1, final FTNode i2) { final FTMatches all = new FTMatches((byte) Math.max(i1.matches().pos, i2.matches().pos)); for (final FTMatch s1 : i1.matches()) { for (final FTMatch s2 : i2.matches()) { all.add(new FTMatch(s1.size() + s2.size()).add(s1).add(s2)); } } i1.score(Scoring.avg(i1.score() + i2.score(), 2)); i1.matches(all); }
@Override public FTNode item(final QueryContext qc, final InputInfo ii) throws QueryException { if (pos == 0) pos = ++qc.ftPos; matches.reset(pos); final int c = contains(qc); if (c == 0) matches.size(0); // scoring: include number of tokens for calculations return new FTNode(matches, c == 0 ? 0 : Scoring.word(c, qc.ftToken.count())); }
@Override public Item item(final QueryContext qc, final InputInfo ii) throws QueryException { // compute scoring if (qc.scoring) { double s = 0; boolean f = false; for (final Expr expr : exprs) { final Item it = expr.ebv(qc, info); f |= it.bool(ii); s += it.score(); } return Bln.get(f, Scoring.avg(s, exprs.length)); } // standard evaluation for (final Expr expr : exprs) { if (expr.ebv(qc, info).bool(ii)) return Bln.TRUE; } return Bln.FALSE; }