package org.basex.data;
import static org.basex.core.Text.*;
import java.io.*;
import org.basex.core.*;
import org.basex.index.*;
import org.basex.index.name.*;
import org.basex.index.path.*;
import org.basex.index.value.*;
import org.basex.io.random.*;
import org.basex.util.*;
import org.basex.util.hash.*;
/**
* 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-17, BSD License
* @author Christian Gruen
*/
public final class MemData extends Data {
/** Texts. */
private final TokenSet texts;
/** Attribute Values. */
private final TokenSet values;
/**
* Constructor.
* @param paths path index
* @param nspaces namespaces
* @param opts database options
*/
public MemData(final PathIndex paths, final Namespaces nspaces, final MainOptions opts) {
this(null, null, paths, nspaces, null, null, opts);
}
/**
* Constructor for creating a new, empty database.
* @param opts database options
*/
public MemData(final MainOptions opts) {
this(null, null, opts);
}
/**
* Constructor for building a new database.
* @param elemNames element name index
* @param attrNames attribute name index
* @param paths path index
* @param nspaces namespaces
* @param texts texts
* @param values values
* @param options database options
*/
private MemData(final Names elemNames, final Names attrNames, final PathIndex paths,
final Namespaces nspaces, final TokenSet texts, final TokenSet values,
final MainOptions options) {
super(new MetaData(options));
table = new TableMemAccess(meta);
if(meta.updindex) idmap = new IdPreMap(meta.lastid);
this.texts = texts == null ? new TokenSet() : texts;
this.values = values == null ? new TokenSet() : values;
this.elemNames = elemNames == null ? new Names(meta) : elemNames;
this.attrNames = attrNames == null ? new Names(meta) : attrNames;
this.paths = paths == null ? new PathIndex(this) : paths;
this.nspaces = nspaces == null ? new Namespaces() : nspaces;
}
@Override
public void createIndex(final IndexType type, final Command cmd) throws IOException {
final IndexBuilder ib;
switch(type) {
case TEXT: case ATTRIBUTE: case TOKEN:
ib = new MemValuesBuilder(this, type); break;
case FULLTEXT:
throw new BaseXException(NO_MAINMEM);
default:
throw Util.notExpected();
}
try {
if(cmd != null) cmd.pushJob(ib);
set(type, ib.build());
} finally {
if(cmd != null) cmd.popJob();
}
}
@Override
public void dropIndex(final IndexType type) throws BaseXException {
switch(type) {
case TEXT: break;
case ATTRIBUTE: break;
case TOKEN: break;
case FULLTEXT: throw new BaseXException(NO_MAINMEM);
default: throw Util.notExpected();
}
set(type, null);
}
/**
* Assigns the specified index.
* @param type index to be opened
* @param index index instance
*/
private void set(final IndexType type, final ValueIndex index) {
meta.dirty = true;
switch(type) {
case TEXT: textIndex = index; break;
case ATTRIBUTE: attrIndex = index; break;
case TOKEN: tokenIndex = index; break;
case FULLTEXT: ftIndex = index; break;
default: break;
}
}
@Override
public void startUpdate(final MainOptions opts) { }
@Override
public void finishUpdate(final MainOptions opts) { }
@Override
public void flush(final boolean all) { }
@Override
public byte[] text(final int pre, final boolean text) {
return (text ? texts : values).key((int) textRef(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;
}
@Override
public boolean inMemory() {
return true;
}
/**
* Returns the string values of the database.
* @param text text/attribute flag
* @return set
*/
public TokenSet values(final boolean text) {
return text ? texts : values;
}
// UPDATE OPERATIONS ========================================================
@Override
protected void delete(final int pre, final boolean text) { }
@Override
protected void updateText(final int pre, final byte[] value, final int kind) {
indexDelete(pre, -1, 1);
textRef(pre, textRef(value, kind != ATTR));
indexAdd(pre, -1, 1, null);
}
@Override
protected long textRef(final byte[] value, final boolean text) {
return (text ? texts : values).put(value);
}
}