/** * Constructor, initializing the index structure. * * @param data data reference * @throws IOException I/O Exception */ public FTIndex(final Data data) throws IOException { super(data, true); // cache token length index inY = new DataAccess(data.meta.dbfile(DATAFTX + 'y')); inZ = new DataAccess(data.meta.dbfile(DATAFTX + 'z')); inX = new DataAccess(data.meta.dbfile(DATAFTX + 'x')); tp = new int[data.meta.maxlen + 3]; final int tl = tp.length; for (int i = 0; i < tl; ++i) tp[i] = -1; int is = inX.readNum(); while (--is >= 0) { int p = inX.readNum(); final int r; if (p < tl) { r = inX.read4(); } else { // legacy issue (7.0.2 -> 7.1) r = p << 24 | (inX.read1() & 0xFF) << 16 | (inX.read1() & 0xFF) << 8 | inX.read1() & 0xFF; p = p >> 8 | 0x40; } tp[p] = r; } tp[tl - 1] = (int) inY.length(); }
@Override public int textLen(final int pre, final boolean text) { final long o = textOff(pre); if (number(o)) return numDigits((int) o); final DataAccess da = text ? texts : values; final int l = da.readNum(o & IO.OFFCOMP - 1); // compressed: next number contains number of compressed bytes return compressed(o) ? da.readNum() : l; }
/** * Performs a wildcard search for the specified token. * * @param token token to look for * @return iterator */ private synchronized IndexIterator wc(final byte[] token) { final FTIndexIterator it = FTIndexIterator.FTEMPTY; final FTWildcard wc = new FTWildcard(token); if (!wc.parse()) return it; final IntList pr = new IntList(); final IntList ps = new IntList(); final byte[] pref = wc.prefix(); final int pl = pref.length, tl = tp.length; final int l = Math.min(tl - 1, wc.max()); for (int ti = pl; ti <= l; ti++) { int i = tp[ti]; if (i == -1) continue; int c = ti + 1; int e = -1; while (c < tl && e == -1) e = tp[c++]; i = find(pref, i, e, ti); while (i < e) { final byte[] t = inY.readBytes(i, ti); if (!startsWith(t, pref)) break; if (wc.match(t)) { inZ.cursor(pointer(i, ti)); final int s = size(i, ti); for (int d = 0; d < s; d++) { pr.add(inZ.readNum()); ps.add(inZ.readNum()); } } i += ti + ENTRY; } } return iter(new FTCache(pr, ps), token); }
/** * Returns an iterator for an index entry. * * @param off offset on entries * @param size number of id/pos entries * @param da data source * @param token index token * @return iterator */ private static FTIndexIterator iter( final long off, final int size, final DataAccess da, final byte[] token) { da.cursor(off); final IntList pr = new IntList(size); final IntList ps = new IntList(size); for (int c = 0; c < size; c++) { pr.add(da.readNum()); ps.add(da.readNum()); } return iter(new FTCache(pr, ps), token); }