com.bigdata.rdf.rio.TestStatementBuffer Maven / Gradle / Ivy
Show all versions of bigdata-rdf-test Show documentation
/**
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
*/
/*
* Created on Jan 29, 2007
*/
package com.bigdata.rdf.rio;
import java.util.Properties;
import org.openrdf.model.Literal;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.impl.LiteralImpl;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.model.vocabulary.RDFS;
import com.bigdata.rdf.axioms.NoAxioms;
import com.bigdata.rdf.internal.XSD;
import com.bigdata.rdf.internal.impl.bnode.SidIV;
import com.bigdata.rdf.load.IStatementBufferFactory;
import com.bigdata.rdf.model.BigdataBNode;
import com.bigdata.rdf.model.BigdataLiteral;
import com.bigdata.rdf.model.BigdataStatement;
import com.bigdata.rdf.model.BigdataURI;
import com.bigdata.rdf.model.BigdataValueFactory;
import com.bigdata.rdf.model.StatementEnum;
import com.bigdata.rdf.sparql.ast.QueryHints;
import com.bigdata.rdf.store.AbstractTripleStore;
import com.bigdata.rdf.store.AbstractTripleStoreTestCase;
/**
* Test suite for {@link StatementBuffer}.
*
* @author Bryan Thompson
*
* TODO Parameterize with {@link IStatementBufferFactory} and use to
* test other implementations as well? If not, then port tests so that
* they are also run against other implementations (especially the
* tests for reification done right).
*/
public class TestStatementBuffer extends AbstractTripleStoreTestCase {
/**
*
*/
public TestStatementBuffer() {
}
/**
* @param name
*/
public TestStatementBuffer(String name) {
super(name);
}
public void test_ctor01() {
final int capacity = 27;
final int queueCapacity = 0;
final AbstractTripleStore store = getStore();
try {
final StatementBuffer buffer = new StatementBuffer(
store, capacity, queueCapacity);
assertEquals(store, buffer.getDatabase());
// assertTrue(buffer.distinct);
assertEquals(capacity, buffer.getCapacity());
assertEquals(capacity * store.getSPOKeyArity() + 5, buffer.values.length);
assertEquals(capacity, buffer.stmts.length);
assertEquals(5, buffer.numURIs);
assertEquals(0, buffer.numLiterals);
assertEquals(0, buffer.numBNodes);
assertEquals(0, buffer.numStmts);
} finally {
store.__tearDownUnitTest();
}
}
public void test_ctor02() {
final int capacity = 27;
final int queueCapacity = 10;
final AbstractTripleStore store = getStore();
try {
final StatementBuffer buffer = new StatementBuffer(
store, capacity, queueCapacity);
assertEquals(store, buffer.getDatabase());
// assertTrue(buffer.distinct);
assertEquals(capacity, buffer.getCapacity());
assertEquals(capacity * store.getSPOKeyArity() + 5, buffer.values.length);
assertEquals(capacity, buffer.stmts.length);
assertEquals(5, buffer.numURIs);
assertEquals(0, buffer.numLiterals);
assertEquals(0, buffer.numBNodes);
assertEquals(0, buffer.numStmts);
} finally {
store.__tearDownUnitTest();
}
}
/**
* Test verifies detection of duplicate terms and their automatic
* replacement with a canonicalizing term.
*/
public void test_handleStatement_distinctTerm() {
final int capacity = 5;
final AbstractTripleStore store = getStore();
try {
final StatementBuffer buffer = new StatementBuffer(
store, capacity);
// assertTrue(buffer.distinct);
/*
* add a statement.
*/
final URI s1 = new URIImpl("http://www.foo.org");
final URI p1 = RDF.TYPE;
final URI o1 = RDFS.RESOURCE;
final URI c1 = null; // no context.
buffer.handleStatement(s1, p1, o1, c1, StatementEnum.Explicit);
assertEquals(8, buffer.numURIs);
assertEquals(0, buffer.numLiterals);
assertEquals(0, buffer.numBNodes);
assertEquals(1, buffer.numStmts);
/*
* add another statement.
*/
final URI s2 = new URIImpl("http://www.foo.org"); // duplicate term!
final URI p2 = RDFS.LABEL;
final Literal o2 = new LiteralImpl("test lit.");
final URI c2 = null;
buffer.handleStatement(s2, p2, o2, c2, StatementEnum.Explicit);
assertEquals(9, buffer.numURIs); // only 4 since one is duplicate.
assertEquals(1, buffer.numLiterals);
assertEquals(0, buffer.numBNodes);
assertEquals(2, buffer.numStmts);
/*
* add a duplicate statement.
*/
final URI s3 = new URIImpl("http://www.foo.org"); // duplicate term
final URI p3 = RDFS.LABEL; // duplicate term
final Literal o3 = new LiteralImpl("test lit."); // duplicate term
final URI c3 = null;
buffer.handleStatement(s3, p3, o3, c3, StatementEnum.Explicit);
assertEquals(9, buffer.numURIs);
assertEquals(1, buffer.numLiterals);
assertEquals(0, buffer.numBNodes);
assertEquals(3, buffer.numStmts);
/*
* add a duplicate statement using the _same_ term objects.
*/
buffer.handleStatement(s3, p3, o3, c3, StatementEnum.Explicit);
assertEquals(9, buffer.numURIs);
assertEquals(1, buffer.numLiterals);
assertEquals(0, buffer.numBNodes);
assertEquals(4, buffer.numStmts);
buffer.flush();
} finally {
store.__tearDownUnitTest();
}
}
/**
* Test verifies interpretation of triples by the {@link StatementBuffer} by
* validating how the triples written onto the statement buffer are loaded
* into the {@link AbstractTripleStore}.
*/
public void test_statementBuffer() {
final int capacity = 5;
final Properties properties = new Properties(getProperties());
// turn off entailments.
properties.setProperty(AbstractTripleStore.Options.AXIOMS_CLASS,
NoAxioms.class.getName());
final AbstractTripleStore store = getStore(properties);
try {
// store is empty.
assertEquals(0,store.getStatementCount());
final BigdataValueFactory vf = store.getValueFactory();
final StatementBuffer buffer = new StatementBuffer(
store, capacity);
/*
* add a statement.
*/
final URI s1 = new URIImpl("http://www.foo.org");
final URI p1 = RDF.TYPE;
final URI o1 = RDFS.RESOURCE;
final URI c1 = null; // no context.
buffer.add(vf.createStatement(s1, p1, o1, c1, StatementEnum.Explicit));
/*
* add another statement.
*/
final URI s2 = new URIImpl("http://www.foo.org"); // duplicate term!
final URI p2 = RDFS.LABEL;
final Literal o2 = new LiteralImpl("test lit.");
final URI c2 = null;
buffer.add(vf.createStatement(s2, p2, o2, c2, StatementEnum.Explicit));
/*
* add a duplicate statement.
*/
final URI s3 = new URIImpl("http://www.foo.org"); // duplicate term
final URI p3 = RDFS.LABEL; // duplicate term
final Literal o3 = new LiteralImpl("test lit."); // duplicate term
final URI c3 = null;
buffer.handleStatement(s3, p3, o3, c3, StatementEnum.Explicit);
// store is still empty (statements are buffered).
assertEquals(0,store.getStatementCount());
// flush the buffer.
buffer.flush();
// the statements are now in the store.
assertEquals(2, store.getStatementCount());
assertTrue(store.hasStatement(s1, p1, o1));
assertTrue(store.hasStatement(s2, p2, o2));
assertFalse(store.hasStatement(s1, p2, o1));
} finally {
store.__tearDownUnitTest();
}
}
/**
* A unit test in which the translation of reified statements into inline
* statements disabled. This test uses the same data as the test below.
*/
public void test_reificationDoneRight_disabled() {
if (QueryHints.DEFAULT_REIFICATION_DONE_RIGHT)
return;
final int capacity = 20;
final Properties properties = new Properties(getProperties());
// turn off entailments.
properties.setProperty(AbstractTripleStore.Options.AXIOMS_CLASS,
NoAxioms.class.getName());
final AbstractTripleStore store = getStore(properties);
try {
// * @prefix : .
// * @prefix news: .
// * @prefix rdf: .
// * @prefix rdfs: .
// * @prefix dc: .
// * @prefix xsd: .
// *
// * :SAP :bought :sybase .
// * _:s1 rdf:subject :SAP .
// * _:s1 rdf:predicate :bought .
// * _:s1 rdf:object :sybase .
// * _:s1 rdf:type rdf:Statement .
// * _:s1 dc:source news:us-sybase .
// * _:s1 dc:created "2011-04-05T12:00:00Z"^^xsd:dateTime .
final BigdataValueFactory vf = store.getValueFactory();
final BigdataURI SAP = vf.createURI("http://example.com/SAP");
final BigdataURI bought = vf.createURI("http://example.com/bought");
final BigdataURI sybase = vf.createURI("http://example.com/sybase");
final BigdataURI dcSource = vf.createURI("http://purl.org/dc/terms/source");
final BigdataURI dcCreated = vf.createURI("http://purl.org/dc/terms/created");
final BigdataURI newsSybase = vf.createURI("http://example.com/news/us-sybase");
final BigdataLiteral createdDate = vf.createLiteral("2011-04-05T12:00:00Z",XSD.DATETIME);
final BigdataBNode s1 = vf.createBNode("s1");
// store is empty.
assertEquals(0, store.getStatementCount());
final StatementBuffer buffer = new StatementBuffer(
store, capacity);
// ground statement.
buffer.add(vf.createStatement(SAP, bought, sybase,
null/* context */, StatementEnum.Explicit));
// model of that statement (RDF reification).
buffer.add(vf.createStatement(s1, RDF.SUBJECT, SAP,
null/* context */, StatementEnum.Explicit));
buffer.add(vf.createStatement(s1, RDF.PREDICATE, bought,
null/* context */, StatementEnum.Explicit));
buffer.add(vf.createStatement(s1, RDF.OBJECT, sybase,
null/* context */, StatementEnum.Explicit));
buffer.add(vf.createStatement(s1, RDF.TYPE, RDF.STATEMENT,
null/* context */, StatementEnum.Explicit));
// metadata statements.
buffer.add(vf.createStatement(s1, dcSource, newsSybase,
null/* context */, StatementEnum.Explicit));
buffer.add(vf.createStatement(s1, dcCreated, createdDate,
null/* context */, StatementEnum.Explicit));
// flush the buffer.
buffer.flush();
// the statements are now in the store.
assertEquals(7, store.getStatementCount());
assertTrue(store.hasStatement(SAP, bought, sybase));
assertTrue(store.hasStatement(s1, RDF.SUBJECT, SAP));
assertTrue(store.hasStatement(s1, RDF.PREDICATE, bought));
assertTrue(store.hasStatement(s1, RDF.OBJECT, sybase));
assertTrue(store.hasStatement(s1, RDF.TYPE, RDF.STATEMENT));
assertTrue(store.hasStatement(s1, dcSource, newsSybase));
assertTrue(store.hasStatement(s1, dcCreated, createdDate));
} finally {
store.__tearDownUnitTest();
}
}
/**
* Unit test verifies that triples which look like part of a reified model
* of a statement are collected and then reported using SIDs.
*
* For example, given the following source data:
*
*
* @prefix : .
* @prefix news: .
* @prefix rdf: .
* @prefix rdfs: .
* @prefix dc: .
* @prefix xsd: .
*
* :SAP :bought :sybase .
* _:s1 rdf:subject :SAP .
* _:s1 rdf:predicate :bought .
* _:s1 rdf:object :sybase .
* _:s1 rdf:type rdf:Statement .
* _:s1 dc:source news:us-sybase .
* _:s1 dc:created "2011-04-05T12:00:00Z"^^xsd:dateTime .
*
*
* Only the following three triples would actually be reported:
*
*
* :SAP :bought :sybase .
* <<:SAP :bought :sybase>> dc:source news:us-sybase .
* <<:SAP :bought :sybase>> dc:created "2011-04-05T12:00:00Z"^^xsd:dateTime .
*
*
* TODO Implement this test. This parser mode should be conditioned on
* {@link QueryHints#DEFAULT_REIFICATION_DONE_RIGHT} for now. It should be
* configurable so the parser can be reused without having this SIDS style
* interpretation (at least for benchmarking).
*
* We need to be careful that reified (versus inlined) statements about
* statements do not make it accidentally into the DB. Intercepting things
* at the {@link StatementBuffer} goes a long way toward that goal. We will
* also have to review the scale-out data loader and the sail truth
* maintenance assertion and retraction buffers in this regard. Retraction
* could be a bit messy if people only pull out, e.g., rdf:subject, while
* leaving in the rest of the triples. However, maybe it is not so bad since
* you have to give all of the triples in the statement model in order to
* cause anything about that statement to be removed (and also give the
* ground triple itself).
*
* Note that the following has exactly the same interpretation - it will
* generate the same three triples, including the ground triple and the two
* statements about that ground triple.
*
*
* <<:SAP :bought :sybase>> dc:source news:us-sybase ;
* dc:created "2011-04-05T12:00:00Z"^^xsd:dateTime .
*
*/
public void test_reificationDoneRight_enabled() {
final int capacity = 20;
final Properties properties = new Properties(getProperties());
// turn off entailments.
properties.setProperty(AbstractTripleStore.Options.AXIOMS_CLASS,
NoAxioms.class.getName());
final AbstractTripleStore store = getStore(properties);
try {
if(!QueryHints.DEFAULT_REIFICATION_DONE_RIGHT) {
/*
* Disabled.
*/
return;
}
if (!store.isStatementIdentifiers()) {
/**
* Disabled. FIXME This should be ON for TRIPLES or QUADS. It
* only works in the SIDS mode right now. The root cause is
*
*
* Caused by: java.lang.IllegalArgumentException: context bound, but not quads or sids: < TermId(7B), TermId(5U), com.bigdata.rdf.internal.impl.literal.LiteralExtensionIV@25889b2f, TermId(8B) : Explicit >
* at com.bigdata.rdf.spo.SPOIndexWriter.call(SPOIndexWriter.java:275)
*
*/
return;
}
// * @prefix : .
// * @prefix news: .
// * @prefix rdf: .
// * @prefix rdfs: .
// * @prefix dc: .
// * @prefix xsd: .
// *
// * :SAP :bought :sybase .
// * _:s1 rdf:subject :SAP .
// * _:s1 rdf:predicate :bought .
// * _:s1 rdf:object :sybase .
// * _:s1 rdf:type rdf:Statement .
// * _:s1 dc:source news:us-sybase .
// * _:s1 dc:created "2011-04-05T12:00:00Z"^^xsd:dateTime .
final BigdataValueFactory vf = store.getValueFactory();
final BigdataURI SAP = vf.createURI("http://example.com/SAP");
final BigdataURI bought = vf.createURI("http://example.com/bought");
final BigdataURI sybase = vf.createURI("http://example.com/sybase");
final BigdataURI dcSource = vf.createURI("http://purl.org/dc/terms/source");
final BigdataURI dcCreated = vf.createURI("http://purl.org/dc/terms/created");
final BigdataURI newsSybase = vf.createURI("http://example.com/news/us-sybase");
final BigdataLiteral createdDate = vf.createLiteral("2011-04-05T12:00:00Z",XSD.DATETIME);
final BigdataBNode s1 = vf.createBNode("s1");
// store is empty.
assertEquals(0, store.getStatementCount());
final StatementBuffer buffer = new StatementBuffer(
store, capacity);
// ground statement.
buffer.add(vf.createStatement(SAP, bought, sybase,
null/* context */, StatementEnum.Explicit));
// model of that statement (RDF reification).
buffer.add(vf.createStatement(s1, RDF.SUBJECT, SAP,
null/* context */, StatementEnum.Explicit));
buffer.add(vf.createStatement(s1, RDF.PREDICATE, bought,
null/* context */, StatementEnum.Explicit));
buffer.add(vf.createStatement(s1, RDF.OBJECT, sybase,
null/* context */, StatementEnum.Explicit));
buffer.add(vf.createStatement(s1, RDF.TYPE, RDF.STATEMENT,
null/* context */, StatementEnum.Explicit));
// metadata statements.
final BigdataStatement mds1 = vf.createStatement(s1, dcSource,
newsSybase, null, StatementEnum.Explicit);
final BigdataStatement mds2 = vf.createStatement(s1, dcCreated,
createdDate, null, StatementEnum.Explicit);
buffer.add(mds1);
buffer.add(mds2);
// flush the buffer.
buffer.flush();
/*
* FIXME This is failing because the StatementBuffer has not been
* modified to recognize reified statements for which a ground
* statement exists and then write them onto the database using
* SidIVs instead of statement models.
*/
// the statements are now in the store.
assertEquals(3, store.getStatementCount());
assertTrue(store.hasStatement(SAP, bought, sybase));
assertFalse(store.hasStatement(s1, RDF.SUBJECT, SAP));
assertFalse(store.hasStatement(s1, RDF.PREDICATE, bought));
assertFalse(store.hasStatement(s1, RDF.OBJECT, sybase));
assertFalse(store.hasStatement(s1, RDF.TYPE, RDF.STATEMENT));
assertTrue(store.hasStatement(s1, dcSource, newsSybase));
assertTrue(store.hasStatement(s1, dcCreated, createdDate));
/*
* FIXME BigdataStatementImpl currently relies on c() to be the
* SidIV. This needs to be changed. The SidIV should now be formed
* dynamically from the concatenation of the subject, predicate, and
* object roles IVs. The context role [c] needs to remain available
* for use with named graphs. The SidIV can be formed dynamically
* since it depends solely on the (s,p,o) components.
*/
// mds1.setStatementIdentifier(true);
// mds2.setStatementIdentifier(true);
assertTrue(mds1.hasStatementIdentifier());
assertTrue(mds2.hasStatementIdentifier());
final SidIV> sidIV1 = (SidIV>) mds1.getStatementIdentifier();
final SidIV> sidIV2 = (SidIV>) mds2.getStatementIdentifier();
assertEquals(sidIV1.getInlineValue().s(), mds1.s());
assertEquals(sidIV1.getInlineValue().p(), mds1.p());
assertEquals(sidIV1.getInlineValue().o(), mds1.o());
assertEquals(sidIV2.getInlineValue().s(), mds2.s());
assertEquals(sidIV2.getInlineValue().p(), mds2.p());
assertEquals(sidIV2.getInlineValue().o(), mds2.o());
/*
* FIXME Implement quads mode RDR
*/
// assertNull(sidIV1.getInlineValue().c());
// assertNull(sidIV2.getInlineValue().c());
} finally {
store.__tearDownUnitTest();
}
}
/**
* Triples mode test suite.
*/
public static class TestTriplesModeAPs extends TestStatementBuffer {
@Override
public Properties getProperties() {
final Properties properties = new Properties(super.getProperties());
// turn off quads.
properties.setProperty(AbstractTripleStore.Options.QUADS, "false");
// turn on triples
properties.setProperty(AbstractTripleStore.Options.TRIPLES_MODE,
"true");
return properties;
}
}
public void test_context_stripping() {
int capacity = 1;
final AbstractTripleStore store = getStore(getProperties());
try {
final BigdataValueFactory vf = store.getValueFactory();
final BigdataURI s = vf.createURI("http://example.com/s");
final BigdataURI p = vf.createURI("http://example.com/p");
final BigdataURI o = vf.createURI("http://example.com/o");
final BigdataURI c = vf.createURI("http://example.com/c");
final StatementBuffer buffer = new StatementBuffer(
store, capacity);
buffer.add(vf.createStatement(s, p, o, c, StatementEnum.Explicit));
// flush the buffer.
buffer.flush();
assertTrue(store.hasStatement(s, p, o));
assertFalse(store.hasStatement(s, p, o, c));
} finally {
store.__tearDownUnitTest();
}
}
}