package org.basex.data; import org.basex.core.Prop; import org.basex.index.IdPreMap; import org.basex.index.Index; import org.basex.index.IndexToken.IndexType; import org.basex.index.path.PathSummary; import org.basex.index.value.MemValues; import org.basex.index.value.UpdatableMemValues; import org.basex.index.Names; import org.basex.io.random.TableMemAccess; import org.basex.util.Token; /** * This class stores and organizes the database table and the index structures * for textual content in a compressed memory structure. * The table mapping is documented in {@link Data}. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ public final class MemData extends Data { /** * Constructor. * @param tag tag index * @param att attribute name index * @param ps path summary * @param ns namespaces * @param pr database properties */ public MemData(final Names tag, final Names att, final PathSummary ps, final Namespaces ns, final Prop pr) { meta = new MetaData(pr); table = new TableMemAccess(meta); if(meta.updindex) { idmap = new IdPreMap(meta.lastid); txtindex = new UpdatableMemValues(this); atvindex = new UpdatableMemValues(this); } else { txtindex = new MemValues(this); atvindex = new MemValues(this); } tagindex = tag == null ? new Names(meta) : tag; atnindex = att == null ? new Names(meta) : att; paths = ps == null ? new PathSummary(this) : ps; nspaces = ns == null ? new Namespaces() : ns; } /** * Light-weight constructor, adopting data structures from the * specified database. * @param data data reference */ public MemData(final Data data) { this(data.tagindex, data.atnindex, data.paths, null, data.meta.prop); } /** * Constructor, creating a new, empty database. * @param pr property reference */ public MemData(final Prop pr) { this(null, null, null, null, pr); } @Override public void flush() { } @Override public void close() { } @Override public void closeIndex(final IndexType type) { } @Override public void setIndex(final IndexType type, final Index index) { } @Override public boolean updating(final boolean updating) { return true; } @Override public byte[] text(final int pre, final boolean text) { return ((MemValues) (text ? txtindex : atvindex)).key((int) textOff(pre)); } @Override public long textItr(final int pre, final boolean text) { return Token.toLong(text(pre, text)); } @Override public double textDbl(final int pre, final boolean text) { return Token.toDouble(text(pre, text)); } @Override public int textLen(final int pre, final boolean text) { return text(pre, text).length; } // UPDATE OPERATIONS ======================================================== @Override protected void delete(final int pre, final boolean text) { } @Override public void updateText(final int pre, final byte[] val, final int kind) { final int id = id(pre); if(meta.updindex) { final boolean txt = kind != ATTR; ((MemValues) (txt ? txtindex : atvindex)).delete(text(pre, txt), id); } textOff(pre, index(pre, id, val, kind)); } @Override protected long index(final int pre, final int id, final byte[] txt, final int kind) { return ((MemValues) (kind == ATTR ? atvindex : txtindex)). index(txt, meta.updindex ? id : pre); } @Override protected void indexDelete(final int pre, final int size) { final int l = pre + size; for(int p = pre; p < l; ++p) { final int k = kind(p); final boolean isAttr = k == ATTR; // skip nodes which are not attribute, text, comment, or proc. instruction if(isAttr || k == TEXT || k == COMM || k == PI) { final byte[] key = text(p, !isAttr); ((MemValues) (isAttr ? atvindex : txtindex)).delete(key, id(p)); } } } }