This class provides access to a fuzzy full-text index structure stored on disk. Each token has an entry in sizes, saving its length and a pointer on ftdata, where to find the token and its ftdata. The three database index files start with the prefix DataText#DATAFTX and have the following
| 51 | * @author Christian Gruen |
| 52 | */ |
| 53 | public final class FTIndex extends ValueIndex { |
| 54 | /** Minimum fixed size for each token entry. */ |
| 55 | private static final int ENTRY = 9; |
| 56 | |
| 57 | /** Cached texts. Increases used memory, but speeds up repeated queries. */ |
| 58 | private final IntObjectMap<byte[]> ctext = new IntObjectMap<>(); |
| 59 | /** Levenshtein reference. */ |
| 60 | private final Levenshtein ls = new Levenshtein(); |
| 61 | |
| 62 | /** Index storing each unique token length and pointer |
| 63 | * on the first token with this length. */ |
| 64 | private final DataAccess dataX; |
| 65 | /** Index storing each token, its data size and pointer on the data. */ |
| 66 | private final DataAccess dataY; |
| 67 | /** Storing PRE and POS values for each token. */ |
| 68 | private final DataAccess dataZ; |
| 69 | |
| 70 | /** Cache for number of hits and data reference per token. */ |
| 71 | private final IndexCache cache = new IndexCache(); |
| 72 | /** Token positions. */ |
| 73 | private final int[] positions; |
| 74 | |
| 75 | /** |
| 76 | * Constructor, initializing the index structure. |
| 77 | * @param data data reference |
| 78 | * @throws IOException I/O Exception |
| 79 | */ |
| 80 | public FTIndex(final Data data) throws IOException { |
| 81 | super(data, IndexType.FULLTEXT); |
| 82 | // cache token length index |
| 83 | dataX = new DataAccess(data.meta.dbFile(DATAFTX + 'x')); |
| 84 | dataY = new DataAccess(data.meta.dbFile(DATAFTX + 'y')); |
| 85 | dataZ = new DataAccess(data.meta.dbFile(DATAFTX + 'z')); |
| 86 | positions = new int[data.meta.maxlen + 3]; |
| 87 | final int pl = positions.length; |
| 88 | for(int p = 0; p < pl; p++) positions[p] = -1; |
| 89 | for(int is = dataX.readNum(); --is >= 0;) { |
| 90 | final int p = dataX.readNum(); |
| 91 | positions[p] = dataX.read4(); |
| 92 | } |
| 93 | positions[pl - 1] = (int) dataY.length(); |
| 94 | } |
| 95 | |
| 96 | @Override |
| 97 | public synchronized IndexCosts costs(final IndexSearch search) { |
| 98 | final byte[] token = search.token(); |
| 99 | if(token.length > data.meta.maxlen) return null; |
| 100 | |
| 101 | // estimate costs for queries which stretch over multiple index entries |
| 102 | final FTOpt opt = ((FTLexer) search).ftOpt(); |
| 103 | return IndexCosts.get(opt.is(FZ) || opt.is(WC) ? Math.max(1, data.meta.size >> 4) : |
| 104 | entry(token).size); |
| 105 | } |
| 106 | |
| 107 | @Override |
| 108 | public synchronized IndexIterator iter(final IndexSearch search) { |
| 109 | // current search token |
| 110 | final FTLexer lexer = (FTLexer) search; |
nothing calls this directly
no outgoing calls
no test coverage detected