com.bigdata.rdf.internal.impl.TermId Maven / Gradle / Ivy
/**
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
[email protected]
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.bigdata.rdf.internal.impl;
import org.openrdf.model.BNode;
import org.openrdf.model.Literal;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import com.bigdata.btree.keys.IKeyBuilder;
import com.bigdata.btree.keys.KeyBuilder;
import com.bigdata.io.LongPacker;
import com.bigdata.rdf.internal.DTE;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.internal.IVUtility;
import com.bigdata.rdf.internal.NotMaterializedException;
import com.bigdata.rdf.internal.VTE;
import com.bigdata.rdf.internal.impl.literal.NumericIV;
import com.bigdata.rdf.model.BigdataLiteral;
import com.bigdata.rdf.model.BigdataValue;
import com.bigdata.util.Bytes;
/**
* Implementation for any kind of RDF {@link Value} when the values is not being
* inlined. Instances of this class can represent {@link URI}s, {@link BNode}s
* (if they are not being inlined), or {@link Literal}s (including datatype
* literals if they are not being inlined). Larger RDF {@link Value}s should be
* represented with {@link BlobIV} instead of this class.
*/
public class TermId
extends AbstractNonInlineIV {
/**
*
*/
private static final long serialVersionUID = 4309045651680610931L;
/**
* Value used for a "NULL" term identifier.
*/
public static final transient long NULL = 0L;
/** The term identifier. */
private final long termId;
final public boolean isNullIV() {
return termId == NULL;
}
/**
* Singleton for a "null" {@link IV}.
*/
final public static transient TermId> NullIV = TermId.mockIV(VTE.URI);
/**
* Create a mock {@link IV} having the indicated {@link VTE} which will
* report true
for {@link #isNullIV()}. This is used by some
* code patterns where we need to associate a {@link BigdataValue} not in
* the database with an {@link IV} on a temporary basis.
*
* @param vte
* The {@link VTE}.
*
* @return The mock {@link IV}.
*/
@SuppressWarnings("rawtypes")
static public TermId> mockIV(final VTE vte) {
/*
* Note: This MUST be consistent with TermsIndexHelper#makeKey() !!!
*/
return new TermId(vte, NULL);
}
@Override
public IV clone(final boolean clearCache) {
final TermId tmp = new TermId(flags, termId);
if (!clearCache) {
tmp.setValue(getValueCache());
}
return tmp;
}
/**
* Constructor for a term identifier when you are decoding and already have
* the flags.
*
* @param flags
* The flags
* @param termId
*/
public TermId(final byte flags, final long termId) {
super(flags);
this.termId = termId;
}
/**
* Constructor for a term identifier.
* @param vte
* @param termId
*/
public TermId(final VTE vte, final long termId) {
/*
* Note: XSDBoolean happens to be assigned the code value of 0, which is
* the value we want when the data type enumeration will be ignored.
*/
super(vte, false/* extension */, DTE.XSDBoolean);
this.termId = termId;
}
/**
* Human readable representation includes the term identifier, whether this
* is a URI, Literal, Blank node, or Statement identifier and the datatype
* URI if one is assigned. This representation is based solely on the flag
* bits and the term identifier.
*
* The cached {@link BigdataValue}, if any, is also rendered. This is done
* using {@link BigdataValue#stringValue()} in order to avoid possible
* infinite recursion through {@link BigdataValue#toString()} if the latter
* were to display the {@link IV}.
*/
@Override
public String toString() {
return "TermId(" + termId + String.valueOf(getVTE().getCharCode())
+ ")"
+ (hasValue() ? "[" + getValue().stringValue() + "]" : "");
}
/**
* Decodes the output of {@link #toString()}, returning a new {@link TermId}
* .
*
* @param s
* The string representation.
*
* @return The {@link TermIV}.
*/
static public TermId> fromString(final String s) {
final int pos = s.indexOf("[");
final int end = (pos > 0 ? pos : s.length()) - 2;
final long tid = Long.valueOf(s.substring(7, end));
final char type = s.charAt(end);
@SuppressWarnings("rawtypes")
final TermId> tmp = new TermId(VTE.valueOf(type), tid);
return tmp;
}
/**
* Return the termId.
*/
final public long getTermId() {
return termId;
}
/**
* {@inheritDoc
*
* Note: only the termId matters for equality, unless either is #NULL, in
* which case this will compare the cached {@link BigdataValue}s if they
* exist. Null IVs without cached values are never equal.
*/
@Override
public boolean equals(final Object o) {
if (this == o)
return true;
if (o instanceof TermId>) {
final TermId> t = (TermId>) o;
if (this.termId == NULL || t.termId == NULL) {
if (this.hasValue() && t.hasValue()) {
return this.getValue().equals(t.getValue());
} else {
return false;
}
} else {
return termId == t.termId;
}
// return termId == ((TermId>) o).termId;
}
return false;
}
/**
* Return the hash code of the long term identifier.
*
* @see Long#hashCode()
*/
@Override
public int hashCode() {
return (int) (termId ^ (termId >>> 32));
}
@Override
public int byteLength() {
if (IVUtility.PACK_TIDS) {
return 1 + LongPacker.getByteLength(termId);
} else {
return 1 + Bytes.SIZEOF_LONG;
}
}
@Override
public int _compareTo(final IV o) {
final long termId2 = ((TermId>) o).termId;
return termId < termId2 ? -1 : termId > termId2 ? 1 : 0;
}
@Override
public IKeyBuilder encode(final IKeyBuilder keyBuilder) {
// First emit the flags byte.
keyBuilder.appendSigned(flags());
if (IVUtility.PACK_TIDS) {
// variable length encoding
((KeyBuilder) keyBuilder).pack(termId);
} else {
// fixed length encoding.
keyBuilder.append(termId);
}
return keyBuilder;
}
/**
* Overrides {@link BNode#getID()}.
*
* Creates a unique blank node ID based on the {@link TermId}'s internal
* data.
*/
@Override
public String getID() {
return Long.toString(termId);
}
@Override
public boolean isNumeric() {
V value = getValue();
if (value==null)
throw new NotMaterializedException();
if (!(value instanceof BigdataLiteral))
return false;
return NumericIV.numericalDatatypes.contains(((BigdataLiteral)value).getDatatype());
}
// /**
// * Override default serialization to send the cached {@link BigdataValue}.
// *
// * @see https://sourceforge.net/apps/trac/bigdata/ticket/337
// */
// private void writeObject(java.io.ObjectOutputStream out) throws IOException {
//
// out.defaultWriteObject();
//
// out.writeObject(getValueCache());
//
// }
//
// /**
// * Override default serialization to recover the cached {@link BigdataValue}
// * .
// */
// @SuppressWarnings("unchecked")
// private void readObject(java.io.ObjectInputStream in) throws IOException,
// ClassNotFoundException {
//
// in.defaultReadObject();
//
// final V v = (V) in.readObject();
//
// if (v != null) {
// // set the value cache.
// setValue(v);
// }
//
// }
}