package org.basex.index.ft;
import java.io.IOException;
import org.basex.data.Data;
import org.basex.data.FTMatches;
import org.basex.index.Index;
import org.basex.index.IndexCache;
import org.basex.io.random.DataAccess;
import org.basex.util.list.IntList;
/**
* This abstract class defines methods for the available full-text indexes.
*
* @author BaseX Team 2005-12, BSD License
* @author Christian Gruen
*/
public abstract class FTIndex implements Index {
/** Cache for number of hits and data reference per token. */
final IndexCache cache = new IndexCache();
/** Data reference. */
final Data data;
/** Scoring mode. 1 = document based, 2 = text-node based .*/
final int scm;
/** Minimum scoring value. */
final double max;
/** Minimum scoring value. */
final double min;
/**
* Returns a new full-text index instance.
* @param d data reference
* @param wild wildcard index
* @return index instance
* @throws IOException IOException
*/
public static FTIndex get(final Data d, final boolean wild)
throws IOException {
return wild ? new FTTrie(d) : new FTFuzzy(d);
}
/**
* Constructor.
* @param d data reference
*/
FTIndex(final Data d) {
data = d;
scm = d.meta.scoring;
max = Math.log(data.meta.maxscore + 1);
min = Math.log(data.meta.minscore - 1);
}
/**
* Returns an iterator for an index entry.
* @param off offset on entries
* @param size number of pre/pos entries
* @param da data source
* @param fast fast evaluation
* @return iterator
*/
final synchronized FTIndexIterator iter(final long off, final int size,
final DataAccess da, final boolean fast) {
// cache results
da.cursor(off);
final IntList vals = new IntList();
for(int c = 0, lp = 0; c < size;) {
if(lp == 0) {
if(scm > 0) vals.add(da.readNum());
lp = da.readNum();
vals.add(lp);
}
final int pr = lp;
vals.add(da.readNum());
while(++c < size) {
lp = da.readNum();
vals.add(lp);
if(lp != pr) break;
vals.add(da.readNum());
}
}
return new FTIndexIterator() {
final FTMatches all = new FTMatches(toknum);
int c, pre, lpre;
double sc = -1;
@Override
public synchronized boolean more() {
if(c == vals.size()) return false;
if(lpre == 0) {
if(scm > 0) sc = (Math.log(vals.get(c++)) - min) / (max - min);
lpre = vals.get(c++);
}
pre = lpre;
all.reset(toknum);
all.or(vals.get(c++));
while(c < vals.size() && (lpre = vals.get(c++)) == pre) {
final int n = vals.get(c++);
if(!fast) all.or(n);
}
return true;
}
@Override
public synchronized FTMatches matches() {
return all;
}
@Override
public synchronized int next() {
return pre;
}
@Override
public synchronized int size() {
return size;
}
@Override
public synchronized double score() {
return sc;
}
@Override
public String toString() {
return Integer.toString(size);
}
};
}
}