package com.bigdata.rdf.graph.impl.bd;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.openrdf.model.BNode;
import org.openrdf.model.Literal;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import com.bigdata.rdf.graph.IGASEngine;
import com.bigdata.rdf.graph.IGASProgram;
import com.bigdata.rdf.graph.IGASSchedulerImpl;
import com.bigdata.rdf.graph.IStaticFrontier;
import com.bigdata.rdf.graph.impl.GASState;
import com.bigdata.rdf.graph.impl.bd.BigdataGASEngine.BigdataGraphAccessor;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.internal.IVUtility;
import com.bigdata.rdf.internal.impl.TermId;
import com.bigdata.rdf.internal.impl.bnode.SidIV;
import com.bigdata.rdf.model.BigdataValue;
import com.bigdata.rdf.spo.ISPO;
import com.bigdata.rdf.store.AbstractTripleStore;
public class BigdataGASState<VS, ES, ST> extends GASState<VS, ES, ST> {
static private final Logger log = Logger.getLogger(BigdataGASState.class);
@Override
protected BigdataGraphAccessor getGraphAccessor() {
return (BigdataGraphAccessor) super.getGraphAccessor();
}
public BigdataGASState(final IGASEngine gasEngine, //
final BigdataGraphAccessor graphAccessor,//
final IStaticFrontier frontier,
final IGASSchedulerImpl gasScheduler,
final IGASProgram<VS, ES, ST> gasProgram) {
super(gasEngine, graphAccessor, frontier, gasScheduler, gasProgram);
}
/**
* {@inheritDoc}
*
* TODO EDGE STATE: edge state should be traced out also.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void traceState() {
super.traceState();
if (!log.isTraceEnabled())
return;
final AbstractTripleStore kb = getGraphAccessor().getKB();
// Get all terms in the frontier.
final Set<IV<?, ?>> tmp = new HashSet<IV<?, ?>>();
for (Value v : frontier()) {
tmp.add((IV) v);
}
// Add all IVs for the vertexState.
tmp.addAll((Collection) vertexState.keySet());
// Batch resolve all IVs.
final Map<IV<?, ?>, BigdataValue> m = kb.getLexiconRelation().getTerms(
tmp);
log.trace("frontier: size=" + frontier().size());
for (Value v : frontier()) {
log.trace("frontier: iv=" + v + " (" + m.get(v) + ")");
}
log.trace("vertexState: size=" + vertexState.size());
for (Map.Entry<Value, VS> e : vertexState.entrySet()) {
final Value v = e.getKey();
final BigdataValue val = m.get(v);
log.trace("vertexState: vertex=" + v + " (" + val + "), state="
+ e.getValue());
}
}
@Override
public String toString(final Statement e) {
return getGraphAccessor().getKB().toString((ISPO) e);
}
/**
* {@inheritDoc}
* <p>
* Note: The {@link IV} classes sometimes implement more than one kind of
* {@link Value}. E.g., {@link TermId} can be a {@link BNode}, {@link URI},
* or {@link Literal} and implements ALL of those interfaces. So we have to
* make an {@link IV}-specific check here.
*
* TODO This is visiting all edges, including link attributes (aka
* hyperedges or statements about statements). Should we further restrict
* traversal to only simple edges (by checking that the source and target
* vertices are not {@link SidIV}s).
*/
@Override
public boolean isEdge(final Statement e) {
final ISPO spo = (ISPO) e;
/**
* For the early development of the GAS API, this test was written using
* o.isURI() rather than o.isResource(). That caused edges that ended in
* a bnode to be ignored, which means that a lot of the FOAF data set we
* were using was ignored. This was changed in r7365 to use
* isResource(). That change invalidates the historical baseline for the
* BFS and SSSP performance. This is also documented at the ticket
* below.
*
* @see <a
* href="https://sourceforge.net/apps/trac/bigdata/ticket/629#comment:33">
* Graph Mining API </a>
*/
return spo.o().isResource();
// return spo.o().isURI();
}
@Override
public boolean isAttrib(final Statement e) {
return !isEdge(e);
}
@Override
public boolean isLinkAttrib(final Statement e,
final URI linkAttribType) {
final ISPO edge = (ISPO) e;
if (!edge.p().equals(linkAttribType)) {
// Edge does not use the specified link attribute type.
return false;
}
if (!(edge.s() instanceof SidIV)) {
// The subject of the edge is not a Statement.
return false;
}
return true;
}
@SuppressWarnings("rawtypes")
@Override
public Statement decodeStatement(final Value v) {
if (!(v instanceof IV))
return null;
final IV tmp = (IV) v;
if (!tmp.isStatement())
return null;
final ISPO decodedEdge = (ISPO) tmp.getInlineValue();
return decodedEdge;
}
@SuppressWarnings("rawtypes")
@Override
public int compareTo(final Value u, final Value v) {
return IVUtility.compare((IV) u, (IV) v);
}
@Override
@SuppressWarnings("rawtypes")
public Value getOtherVertex(final Value u, final Statement e) {
if (e.getSubject() instanceof SidIV) {
final ISPO spo = ((SidIV) e.getSubject()).getInlineValue();
if (spo.s().equals(u))
return spo.o();
return spo.s();
} else {
if (e.getSubject().equals(u))
return e.getObject();
return e.getSubject();
}
}
/**
* This will only work for the BigdataGASState.
*/
@Override
public Literal getLinkAttr(final Value u, final Statement e) {
if (e.getObject() instanceof IV) {
final IV iv = (IV) e.getObject();
if (iv.isLiteral()) {
if (iv.isInline()) {
return (Literal) iv;
} else {
return (Literal) iv.getValue();
}
}
} else if (e.getObject() instanceof Literal) {
return (Literal) e.getObject();
}
return null;
}
}