@Override protected long index(final int pre, final int id, final byte[] value, final int kind) { final DataAccess store; final TokenObjMap<IntList> map; if (kind == ATTR) { store = values; map = meta.attrindex ? atvBuffer : null; } else { store = texts; // don't index document names map = meta.textindex && kind != DOC ? txtBuffer : null; } // add text to map to index later if (meta.updindex && map != null && value.length <= meta.maxlen) { IntList ids = map.get(value); if (ids == null) { ids = new IntList(1); map.put(value, ids); } ids.add(id); } // add text to text file // inline integer value... final long v = toSimpleInt(value); if (v != Integer.MIN_VALUE) return v | IO.OFFNUM; // store text final long off = store.length(); final byte[] val = COMP.get().pack(value); store.writeToken(off, val); return val == value ? off : off | IO.OFFCOMP; }
/** * Calculates the text offset and writes the text value. * * @param value value to be inlined * @param text text/attribute flag * @return inline value or text position * @throws IOException I/O exception */ private long textOff(final byte[] value, final boolean text) throws IOException { // inline integer values... final long v = Token.toSimpleInt(value); if (v != Integer.MIN_VALUE) return v | IO.OFFNUM; // store text final DataOutput store = text ? xout : vout; final long off = store.size(); final byte[] val = COMP.get().pack(value); store.writeToken(val); return val == value ? off : off | IO.OFFCOMP; }
@Override protected void updateText(final int pre, final byte[] value, final int kind) { final boolean text = kind != ATTR; if (meta.updindex) { // update indexes final int id = id(pre); final byte[] oldval = text(pre, text); final DiskValues index = (DiskValues) (text ? textIndex : attrIndex); // don't index document names if (index != null && kind != DOC) index.replace(oldval, value, id); } // reference to text store final DataAccess store = text ? texts : values; // file length final long len = store.length(); // new entry (offset or value) final long v = toSimpleInt(value); if (v != Integer.MIN_VALUE) { // inline integer value textOff(pre, v | IO.OFFNUM); } else { // text to be stored (possibly packed) final byte[] val = COMP.get().pack(value); // old entry (offset or value) final long old = textOff(pre); // find text store offset final long off; if (number(old)) { // numeric entry: append new entry at the end off = len; } else { // text size (0 if value will be inlined) final int vl = val.length; off = store.free(old & IO.OFFCOMP - 1, vl + Num.length(vl)); } store.writeToken(off, val); textOff(pre, val == value ? off : off | IO.OFFCOMP); } }
/** * Returns a text (text, comment, pi) or attribute value. * * @param off text offset * @param text text or attribute flag * @return text */ private byte[] txt(final long off, final boolean text) { final byte[] txt = (text ? texts : values).readToken(off & IO.OFFCOMP - 1); return compressed(off) ? COMP.get().unpack(txt) : txt; }