http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/80faf06d/sail/src/test/java/mvm/rya/ArbitraryLengthQueryTest.java ---------------------------------------------------------------------- diff --git a/sail/src/test/java/mvm/rya/ArbitraryLengthQueryTest.java b/sail/src/test/java/mvm/rya/ArbitraryLengthQueryTest.java new file mode 100644 index 0000000..4a5d871 --- /dev/null +++ b/sail/src/test/java/mvm/rya/ArbitraryLengthQueryTest.java @@ -0,0 +1,500 @@ +package mvm.rya; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.accumulo.core.client.Connector; +import org.apache.accumulo.core.client.Instance; +import org.apache.accumulo.core.client.mock.MockInstance; +import org.openrdf.model.Resource; +import org.openrdf.query.MalformedQueryException; +import org.openrdf.query.QueryEvaluationException; +import org.openrdf.query.QueryLanguage; +import org.openrdf.query.TupleQuery; +import org.openrdf.query.TupleQueryResultHandlerException; +import org.openrdf.query.resultio.text.tsv.SPARQLResultsTSVWriter; +import org.openrdf.repository.Repository; +import org.openrdf.repository.RepositoryConnection; +import org.openrdf.repository.RepositoryException; +import org.openrdf.rio.RDFFormat; +import org.openrdf.rio.RDFParseException; + +import mvm.rya.accumulo.AccumuloRdfConfiguration; +import mvm.rya.accumulo.AccumuloRyaDAO; +import mvm.rya.rdftriplestore.RdfCloudTripleStore; +import mvm.rya.rdftriplestore.RyaSailRepository; +import mvm.rya.rdftriplestore.inference.InferenceEngine; +import mvm.rya.rdftriplestore.namespace.NamespaceManager; +import junit.framework.TestCase; + +/** + * The purpose of this is to provide a test case that illustrates a failure that is being encountered. A working test is + * provided as well to demonstrate that a successful query can be made. + */ +public class ArbitraryLengthQueryTest extends TestCase { + + /** + * The repository used for the tests. + */ + private Repository repository; + + @Override + public void setUp() throws Exception { + super.setUp(); + + final RdfCloudTripleStore store = new MockRdfCloudStore(); + + final NamespaceManager nm = new NamespaceManager(store.getRyaDAO(), store.getConf()); + store.setNamespaceManager(nm); + + repository = new RyaSailRepository(store); + repository.initialize(); + + load(); + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + repository.shutDown(); + } + + /** + * This test works. The expected result is 6 rows ranging from "Model1Class 1" through "Model1Class 6". + * + * @throws RepositoryException + * @throws QueryEvaluationException + * @throws TupleQueryResultHandlerException + * + * @throws MalformedQueryException + */ + public void testWithoutSubquery() throws RepositoryException, QueryEvaluationException, TupleQueryResultHandlerException, MalformedQueryException { + final String query = "SELECT ?i ?i_label ?i_class ?i_v1" + + "WHERE {" + + "?i <http://www.w3.org/2000/01/rdf-schema#label> ?i_label ." + + "?i a ?i_class ." + + "?i_class <http://www.w3.org/2000/01/rdf-schema#subClassOf>* <http://dragon-research.com/cham/model/model1#Model1Class> ." + + "OPTIONAL { ?i <http://dragon-research.com/cham/model/model1#name> ?i_v1 } ." + + "}" + + "ORDER BY ?i_label"; + + final RepositoryConnection conn = repository.getConnection(); + final TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query); + RdfCloudTripleStoreConnectionTest.CountTupleHandler countTupleHandler = new RdfCloudTripleStoreConnectionTest.CountTupleHandler(); + tupleQuery.evaluate(countTupleHandler); + assertEquals(6, countTupleHandler.getCount()); + conn.close(); + } + + /** + * This test fails. The expected result is 6 rows ranging from "Model1Class 1 Event" to "Model1Class 6 Event". The + * current result is a RejectedExecutionException. + * + * @throws RepositoryException + * @throws QueryEvaluationException + * @throws TupleQueryResultHandlerException + * + * @throws MalformedQueryException + */ + public void testWithSubquery() throws RepositoryException, QueryEvaluationException, TupleQueryResultHandlerException, MalformedQueryException { + final String query = "SELECT ?i ?i_label ?i_class ?i_v1 ?i_v2 ?i_v2_label ?i_v2_class ?i_v2_v1" + + "WHERE {" + + "?i <http://www.w3.org/2000/01/rdf-schema#label> ?i_label ." + + "?i a ?i_class ." + + "?i_class <http://www.w3.org/2000/01/rdf-schema#subClassOf>* <http://dragon-research.com/cham/model/model1#Event> ." + + "OPTIONAL { ?i <http://dragon-research.com/cham/model/model1#name> ?i_v1 } ." + + "?i <http://dragon-research.com/cham/model/model1#hasTemporalEntity> ?i_v2 ." + + "{" + + "SELECT ?i_v2 ?i_v2_label ?i_v2_class ?i_v2_v1" + + "WHERE {" + + "?i_v2 <http://www.w3.org/2000/01/rdf-schema#label> ?i_v2_label ." + + "?i_v2 a ?i_v2_class ." + + "?i_v2_class <http://www.w3.org/2000/01/rdf-schema#subClassOf>* <http://dragon-research.com/cham/model/model1#TemporalInstant> ." + + "OPTIONAL { ?i_v2 <http://dragon-research.com/cham/model/model1#dateTime> ?i_v2_v1 } ." + + "}" + + "ORDER BY ?i_v2_label" + + "}" + + "}" + + "ORDER BY ?i_label"; + + final RepositoryConnection conn = repository.getConnection(); + final TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, query); + RdfCloudTripleStoreConnectionTest.CountTupleHandler countTupleHandler = new RdfCloudTripleStoreConnectionTest.CountTupleHandler(); + tupleQuery.evaluate(countTupleHandler); + assertEquals(6, countTupleHandler.getCount()); + conn.close(); + } + + /** + * Load the t-box and a-box turtle from strings defined within this class. + * + * @throws RepositoryException + * @throws RDFParseException + * @throws IOException + */ + private void load() throws RepositoryException, RDFParseException, IOException { + final RepositoryConnection conn = repository.getConnection(); + + // T-Box + String ttlString = MODEL_TTL; + InputStream stringInput = new ByteArrayInputStream(ttlString.getBytes()); + conn.add(stringInput, "http://dragon-research.com/cham/model/model1", RDFFormat.TURTLE, new Resource[]{}); + + // A-Box + ttlString = BUCKET_TTL; + stringInput = new ByteArrayInputStream(ttlString.getBytes()); + conn.add(stringInput, "http://dragon-research.com/cham/bucket/bucket1", RDFFormat.TURTLE, new Resource[]{}); + + conn.commit(); + conn.close(); + } + + /** + * Mock RDF cloud store for one shot testing. + */ + public class MockRdfCloudStore extends RdfCloudTripleStore { + public MockRdfCloudStore() { + super(); + final Instance instance = new MockInstance(); + try { + final AccumuloRdfConfiguration conf = new AccumuloRdfConfiguration(); + setConf(conf); + + final Connector connector = instance.getConnector("", ""); + final AccumuloRyaDAO cdao = new AccumuloRyaDAO(); + cdao.setConf(conf); + cdao.setConnector(connector); + setRyaDAO(cdao); + inferenceEngine = new InferenceEngine(); + inferenceEngine.setRyaDAO(cdao); + inferenceEngine.setRefreshGraphSchedule(5000); //every 5 sec + inferenceEngine.setConf(conf); + setInferenceEngine(inferenceEngine); + } catch (final Exception e) { + e.printStackTrace(); + } + } + } + + /** + * The ontology t-box in turtle. + */ + private static String MODEL_TTL = "@prefix : <http://dragon-research.com/cham/model/model1#> ." + + "@prefix cham: <http://dragon-research.com/cham/schema#> ." + + "@prefix dc: <http://purl.org/dc/elements/1.1/> ." + + "@prefix owl: <http://www.w3.org/2002/07/owl#> ." + + "@prefix qudt: <http://data.nasa.gov/qudt/owl/qudt#> ." + + "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ." + + "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> ." + + "@prefix unit: <http://data.nasa.gov/qudt/owl/unit#> ." + + "@prefix xml: <http://www.w3.org/XML/1998/namespace> ." + + "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> ." + + "" + + "<http://dragon-research.com/cham/model/model1>" + + " rdf:type owl:Ontology ;" + + " rdfs:label \"Model1 Ontology\"^^xsd:string ;" + + " :versionInfo \"0.1\"^^xsd:string ;" + + " dc:title \"Model1 Ontology\"^^xsd:string ." + + "" + + ":ModelClassD" + + " rdf:type owl:Class ;" + + " rdfs:label \"ModelClassD\"^^xsd:string ;" + + " rdfs:subClassOf" + + " [ rdf:type owl:Restriction ;" + + " owl:maxQualifiedCardinality" + + " \"1\"^^xsd:nonNegativeInteger ;" + + " owl:onDataRange xsd:string ;" + + " owl:onProperty :name" + + " ] ;" + + " rdfs:subClassOf" + + " [ rdf:type owl:Restriction ;" + + " owl:allValuesFrom :Model1ClassAssoc ;" + + " owl:onProperty :hasModel1ClassAssoc" + + " ] ." + + "" + + ":ModelClassC" + + " rdf:type owl:Class ;" + + " rdfs:label \"ModelClassC\"^^xsd:string ;" + + " rdfs:subClassOf :ModelClassD ." + + "" + + ":Modle1ClassB" + + " rdf:type owl:Class ;" + + " rdfs:label \"Modle1ClassB\"^^xsd:string ;" + + " rdfs:subClassOf :ModelClassC ." + + "" + + ":Model1ClassA" + + " rdf:type owl:Class ;" + + " rdfs:label \"Model1ClassA\"^^xsd:string ;" + + " rdfs:subClassOf :Modle1ClassB ." + + "" + + ":Model1Class" + + " rdf:type owl:Class ;" + + " rdfs:label \"Model1Class\"^^xsd:string ;" + + " rdfs:subClassOf :Model1ClassA ;" + + " rdfs:subClassOf" + + " [ rdf:type owl:Restriction ;" + + " owl:maxQualifiedCardinality" + + " \"1\"^^xsd:nonNegativeInteger ;" + + " owl:onDataRange xsd:string ;" + + " owl:onProperty :model1ClassId" + + " ] ." + + "" + + ":Model1Event" + + " rdf:type owl:Class ;" + + " rdfs:label \"Model1Event\"^^xsd:string ;" + + " rdfs:subClassOf :Event ;" + + " rdfs:subClassOf" + + " [ rdf:type owl:Restriction ;" + + " owl:allValuesFrom :Model1ClassA ;" + + " owl:onProperty :hasModel1ClassA" + + " ] ." + + "" + + ":Model1ClassAssoc" + + " rdf:type owl:Class ;" + + " rdfs:label \"Model1ClassAssoc\"^^xsd:string ;" + + " rdfs:subClassOf owl:Thing ;" + + " rdfs:subClassOf" + + " [ rdf:type owl:Restriction ;" + + " owl:maxQualifiedCardinality" + + " \"1\"^^xsd:nonNegativeInteger ;" + + " owl:onDataRange xsd:string ;" + + " owl:onProperty :name" + + " ] ;" + + " rdfs:subClassOf" + + " [ rdf:type owl:Restriction ;" + + " owl:maxQualifiedCardinality" + + " \"1\"^^xsd:nonNegativeInteger ;" + + " owl:onClass :ModelClassD ;" + + " owl:onProperty :hasEntity" + + " ] ;" + + " rdfs:subClassOf" + + " [ rdf:type owl:Restriction ;" + + " owl:allValuesFrom :ModelClassD ;" + + " owl:onProperty :hasEntity" + + " ] ." + + "" + + ":TemporalEntity" + + " rdf:type owl:Class ;" + + " rdfs:label \"TemporalEntity\"^^xsd:string ;" + + " rdfs:subClassOf owl:Thing ." + + "" + + ":TemporalInstant" + + " rdf:type owl:Class ;" + + " rdfs:label \"TemporalInstant\"^^xsd:string ;" + + " rdfs:subClassOf :TemporalEntity ;" + + " rdfs:subClassOf" + + " [ rdf:type owl:Restriction ;" + + " owl:maxQualifiedCardinality" + + " \"1\"^^xsd:nonNegativeInteger ;" + + " owl:onDataRange xsd:dateTime ;" + + " owl:onProperty :dateTime" + + " ] ." + + "" + + ":model1ClassId" + + " rdf:type owl:DatatypeProperty ;" + + " rdfs:domain :Model1Class ;" + + " rdfs:label \"model1ClassId\"^^xsd:string ;" + + " rdfs:range xsd:string ." + + "" + + ":hasModel1ClassAssoc" + + " rdf:type owl:ObjectProperty ;" + + " rdfs:domain :ModelClassD ;" + + " rdfs:label \"hasModel1ClassAssoc\"^^xsd:string ;" + + " rdfs:range :Model1ClassAssoc ." + + "" + + ":name" + + " rdf:type owl:DatatypeProperty ;" + + " rdfs:domain :Model1ClassAssoc , :ModelClassD ;" + + " rdfs:label \"name\"^^xsd:string ;" + + " rdfs:range xsd:string ." + + "" + + ":hasTemporalEntity" + + " rdf:type owl:ObjectProperty ;" + + " rdfs:domain :ThreatAnalysis , :Event , :TrackingData , :Threat , :Vulnerability ;" + + " rdfs:label \"hasTemporalEntity\"^^xsd:string ;" + + " rdfs:range :TemporalEntity ." + + "" + + ":hasEntity" + + " rdf:type owl:ObjectProperty ;" + + " rdfs:domain :Model1ClassAssoc ;" + + " rdfs:label \"hasEntity\"^^xsd:string ;" + + " rdfs:range :ModelClassD ." + + "" + + ":dateTime" + + " rdf:type owl:DatatypeProperty ;" + + " rdfs:domain :TemporalInstant ;" + + " rdfs:label \"dateTime\"^^xsd:string ;" + + " rdfs:range xsd:dateTime ." + + "" + + ":Event" + + " rdf:type owl:Class ;" + + " rdfs:label \"Event\"^^xsd:string ;" + + " rdfs:subClassOf :ModelClassD ;" + + " rdfs:subClassOf" + + " [ rdf:type owl:Restriction ;" + + " owl:allValuesFrom :TemporalEntity ;" + + " owl:onProperty :hasTemporalEntity" + + " ] ;" + + " rdfs:subClassOf" + + " [ rdf:type owl:Restriction ;" + + " owl:maxQualifiedCardinality" + + " \"1\"^^xsd:nonNegativeInteger ;" + + " owl:onClass :TemporalEntity ;" + + " owl:onProperty :hasTemporalEntity" + + " ] ." + + "" + + ":hasModel1ClassA" + + " rdf:type owl:ObjectProperty ;" + + " rdfs:domain :Model1Event ;" + + " rdfs:label \"hasModel1ClassA\"^^xsd:string ;" + + " rdfs:range :Model1ClassA ." + + "" + + "rdfs:label" + + " rdf:type owl:AnnotationProperty ." + + "" + + "xsd:date" + + " rdf:type rdfs:Datatype ." + + "" + + "xsd:time" + + " rdf:type rdfs:Datatype ."; + + /** + * The ontology a-box in turtle. + */ + private static String BUCKET_TTL = "@prefix : <http://dragon-research.com/cham/bucket/bucket1#> ." + + "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> ." + + "@prefix owl: <http://www.w3.org/2002/07/owl#> ." + + "@prefix xsd: <http://www.w3.org/2001/XMLSchema#> ." + + "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ." + + "@prefix model1: <http://dragon-research.com/cham/model/model1#> ." + + "" + + ":i1 a model1:Model1Class ;" + + " rdfs:label \"Model1Class 1\"^^xsd:string ;" + + " model1:name \"Model1Class 1\"^^xsd:string ;" + + " model1:hasModel1ClassAssoc :i1-assoc ;" + + " model1:model1ClassId \"ID01\"^^xsd:string ." + + " " + + ":i1-assoc a model1:Model1ClassAssoc ;" + + " rdfs:label \"Model1Class 1 Assoc\"^^xsd:string ;" + + " model1:hasEntity :i1-event ." + + " " + + ":i1-event a model1:Model1Event ;" + + " rdfs:label \"Model1Class 1 Event\"^^xsd:string ;" + + " model1:hasTemporalEntity :i1-time ." + + "" + + ":i1-time a model1:TemporalInstant ;" + + " rdfs:label \"Model1Class 1 Time\"^^xsd:string ;" + + " model1:dateTime \"1994-02-07T21:47:01.000Z\"^^xsd:dateTime ." + + " " + + ":i2 a model1:Model1Class ;" + + " rdfs:label \"Model1Class 2\"^^xsd:string ;" + + " model1:name \"Model1Class 2\"^^xsd:string ;" + + " model1:hasModel1ClassAssoc :i2-assoc ;" + + " model1:model1ClassId \"ID02\"^^xsd:string ." + + "" + + ":i2-assoc a model1:Model1ClassAssoc ;" + + " rdfs:label \"Model1Class 2 Assoc\"^^xsd:string ;" + + " model1:hasEntity :i2-event ." + + " " + + ":i2-event a model1:Model1Event ;" + + " rdfs:label \"Model1Class 2 Event\"^^xsd:string ;" + + " model1:hasTemporalEntity :i2-time ." + + "" + + ":i2-time a model1:TemporalInstant ;" + + " rdfs:label \"Model1Class 2 Time\"^^xsd:string ;" + + " model1:dateTime \"1995-11-06T05:15:01.000Z\"^^xsd:dateTime ." + + " " + + ":i3 a model1:Model1Class ;" + + " rdfs:label \"Model1Class 3\"^^xsd:string ;" + + " model1:name \"Model1Class 3\"^^xsd:string ;" + + " model1:hasModel1ClassAssoc :i3-assoc ;" + + " model1:model1ClassId \"ID03\"^^xsd:string ." + + "" + + ":i3-assoc a model1:Model1ClassAssoc ;" + + " rdfs:label \"Model1Class 3 Assoc\"^^xsd:string ;" + + " model1:hasEntity :i3-event ." + + " " + + ":i3-event a model1:Model1Event ;" + + " rdfs:label \"Model1Class 3 Event\"^^xsd:string ;" + + " model1:hasTemporalEntity :i3-time ." + + "" + + ":i3-time a model1:TemporalInstant ;" + + " rdfs:label \"Model1Class 3 Time\"^^xsd:string ;" + + " model1:dateTime \"1999-04-30T16:30:00.000Z\"^^xsd:dateTime ." + + " " + + ":i4 a model1:Model1Class ;" + + " rdfs:label \"Model1Class 4\"^^xsd:string ;" + + " model1:name \"Model1Class 4\"^^xsd:string ;" + + " model1:hasModel1ClassAssoc :i4-assoc ;" + + " model1:model1ClassId \"ID04\"^^xsd:string ." + + "" + + ":i4-assoc a model1:Model1ClassAssoc ;" + + " rdfs:label \"Model1Class 4 Assoc\"^^xsd:string ;" + + " model1:hasEntity :i4-event ." + + " " + + ":i4-event a model1:Model1Event ;" + + " rdfs:label \"Model1Class 4 Event\"^^xsd:string ;" + + " model1:hasTemporalEntity :i4-time ." + + "" + + ":i4-time a model1:TemporalInstant ;" + + " rdfs:label \"Model1Class 4 Time\"^^xsd:string ;" + + " model1:dateTime \"2001-02-27T21:20:00.000Z\"^^xsd:dateTime ." + + " " + + ":i5 a model1:Model1Class ;" + + " rdfs:label \"Model1Class 5\"^^xsd:string ;" + + " model1:name \"Model1Class 5\"^^xsd:string ;" + + " model1:hasModel1ClassAssoc :i5-assoc ;" + + " model1:model1ClassId \"ID05\"^^xsd:string ." + + "" + + ":i5-assoc a model1:Model1ClassAssoc ;" + + " rdfs:label \"Model1Class 5 Assoc\"^^xsd:string ;" + + " model1:hasEntity :i5-event ." + + " " + + ":i5-event a model1:Model1Event ;" + + " rdfs:label \"Model1Class 5 Event\"^^xsd:string ;" + + " model1:hasTemporalEntity :i5-time ." + + "" + + ":i5-time a model1:TemporalInstant ;" + + " rdfs:label \"Model1Class 5 Time\"^^xsd:string ;" + + " model1:dateTime \"2002-01-16T00:30:00.000Z\"^^xsd:dateTime ." + + " " + + ":i6 a model1:Model1Class ;" + + " rdfs:label \"Model1Class 6\"^^xsd:string ;" + + " model1:name \"Model1Class 6\"^^xsd:string ;" + + " model1:hasModel1ClassAssoc :i6-assoc ;" + + " model1:model1ClassId \"ID06\"^^xsd:string ." + + "" + + ":i6-assoc a model1:Model1ClassAssoc ;" + + " rdfs:label \"Model1Class 6 Assoc\"^^xsd:string ;" + + " model1:hasEntity :i6-event ." + + " " + + ":i6-event a model1:Model1Event ;" + + " rdfs:label \"Model1Class 6 Event\"^^xsd:string ;" + + " model1:hasTemporalEntity :i6-time ." + + "" + + ":i6-time a model1:TemporalInstant ;" + + " rdfs:label \"Model1Class 6 Time\"^^xsd:string ;" + + " model1:dateTime \"2003-04-08T13:43:00.000Z\"^^xsd:dateTime ."; +}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/80faf06d/sail/src/test/java/mvm/rya/HashJoinTest.java ---------------------------------------------------------------------- diff --git a/sail/src/test/java/mvm/rya/HashJoinTest.java b/sail/src/test/java/mvm/rya/HashJoinTest.java new file mode 100644 index 0000000..bbcdbcd --- /dev/null +++ b/sail/src/test/java/mvm/rya/HashJoinTest.java @@ -0,0 +1,374 @@ +package mvm.rya; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import info.aduna.iteration.CloseableIteration; +import junit.framework.TestCase; +import mvm.rya.accumulo.AccumuloRdfConfiguration; +import mvm.rya.accumulo.AccumuloRyaDAO; +import mvm.rya.api.RdfCloudTripleStoreUtils; +import mvm.rya.api.domain.RyaStatement; +import mvm.rya.api.domain.RyaType; +import mvm.rya.api.domain.RyaURI; +import mvm.rya.api.persist.RyaDAOException; +import mvm.rya.api.persist.query.join.HashJoin; +import org.apache.accumulo.core.client.Connector; +import org.apache.accumulo.core.client.mock.MockInstance; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; + +/** + * Date: 7/24/12 + * Time: 5:51 PM + */ +public class HashJoinTest { + private AccumuloRyaDAO dao; + static String litdupsNS = "urn:test:litdups#"; + private Connector connector; + private AccumuloRdfConfiguration conf = new AccumuloRdfConfiguration(); + + @Before + public void init() throws Exception { + dao = new AccumuloRyaDAO(); + connector = new MockInstance().getConnector("", ""); + dao.setConnector(connector); + dao.setConf(conf); + dao.init(); + } + + @After + public void destroy() throws Exception { + dao.destroy(); + } + + @Test + public void testSimpleJoin() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, two)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, two)); + dao.add(new RyaStatement(subj3, pred, one)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + + + //1 join + HashJoin hjoin = new HashJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = hjoin.join(null, + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, one), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, two)); + + Set<RyaURI> uris = new HashSet<RyaURI>(); + while (join.hasNext()) { + uris.add(join.next()); + } + assertTrue(uris.contains(subj1)); + assertTrue(uris.contains(subj2)); + assertTrue(uris.contains(subj3)); + assertTrue(uris.contains(subj4)); + join.close(); + } + + @Test + public void testSimpleJoinMultiWay() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaType four = new RyaType("4"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, two)); + dao.add(new RyaStatement(subj1, pred, three)); + dao.add(new RyaStatement(subj1, pred, four)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, two)); + dao.add(new RyaStatement(subj2, pred, three)); + dao.add(new RyaStatement(subj2, pred, four)); + dao.add(new RyaStatement(subj3, pred, one)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj3, pred, three)); + dao.add(new RyaStatement(subj3, pred, four)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + dao.add(new RyaStatement(subj4, pred, three)); + dao.add(new RyaStatement(subj4, pred, four)); + + + //1 join + HashJoin hjoin = new HashJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = hjoin.join(null, + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, one), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, two), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, three), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, four) + ); + + Set<RyaURI> uris = new HashSet<RyaURI>(); + while (join.hasNext()) { + uris.add(join.next()); + } + assertTrue(uris.contains(subj1)); + assertTrue(uris.contains(subj2)); + assertTrue(uris.contains(subj3)); + assertTrue(uris.contains(subj4)); + join.close(); + } + + @Test + public void testMergeJoinMultiWay() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType zero = new RyaType("0"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaType four = new RyaType("4"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, two)); + dao.add(new RyaStatement(subj1, pred, three)); + dao.add(new RyaStatement(subj1, pred, four)); + dao.add(new RyaStatement(subj2, pred, zero)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, two)); + dao.add(new RyaStatement(subj2, pred, three)); + dao.add(new RyaStatement(subj2, pred, four)); + dao.add(new RyaStatement(subj3, pred, one)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj3, pred, four)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + dao.add(new RyaStatement(subj4, pred, three)); + dao.add(new RyaStatement(subj4, pred, four)); + + + //1 join + HashJoin hjoin = new HashJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = hjoin.join(null, + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, one), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, two), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, three), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, four) + ); + + Set<RyaURI> uris = new HashSet<RyaURI>(); + while (join.hasNext()) { + uris.add(join.next()); + } + assertTrue(uris.contains(subj1)); + assertTrue(uris.contains(subj2)); + assertTrue(uris.contains(subj4)); + join.close(); + } + + @Test + public void testMergeJoinMultiWayNone() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType zero = new RyaType("0"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaType four = new RyaType("4"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, three)); + dao.add(new RyaStatement(subj1, pred, four)); + dao.add(new RyaStatement(subj2, pred, zero)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, four)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj3, pred, four)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + dao.add(new RyaStatement(subj4, pred, three)); + + + //1 join + HashJoin hjoin = new HashJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = hjoin.join(null, + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, one), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, two), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, three), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, four) + ); + + assertFalse(join.hasNext()); + join.close(); + } + + @Test + public void testMergeJoinMultiWayNone2() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType zero = new RyaType("0"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaType four = new RyaType("4"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, four)); + dao.add(new RyaStatement(subj2, pred, zero)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, four)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj3, pred, four)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + + + //1 join + HashJoin hjoin = new HashJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = hjoin.join(null, + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, one), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, two), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, three), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, four) + ); + + assertFalse(join.hasNext()); + join.close(); + } + + @Test + public void testSimpleHashJoinPredicateOnly() throws Exception { + //add data + RyaURI pred1 = new RyaURI(litdupsNS, "pred1"); + RyaURI pred2 = new RyaURI(litdupsNS, "pred2"); + RyaType one = new RyaType("1"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred1, one)); + dao.add(new RyaStatement(subj1, pred2, one)); + dao.add(new RyaStatement(subj2, pred1, one)); + dao.add(new RyaStatement(subj2, pred2, one)); + dao.add(new RyaStatement(subj3, pred1, one)); + dao.add(new RyaStatement(subj3, pred2, one)); + dao.add(new RyaStatement(subj4, pred1, one)); + dao.add(new RyaStatement(subj4, pred2, one)); + + + //1 join + HashJoin ijoin = new HashJoin(dao.getQueryEngine()); + CloseableIteration<RyaStatement, RyaDAOException> join = ijoin.join(null, pred1, pred2); + + int count = 0; + while (join.hasNext()) { + RyaStatement next = join.next(); + count++; + } + assertEquals(4, count); + join.close(); + } + + @Test + public void testSimpleMergeJoinPredicateOnly2() throws Exception { + //add data + RyaURI pred1 = new RyaURI(litdupsNS, "pred1"); + RyaURI pred2 = new RyaURI(litdupsNS, "pred2"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred1, one)); + dao.add(new RyaStatement(subj1, pred1, two)); + dao.add(new RyaStatement(subj1, pred1, three)); + dao.add(new RyaStatement(subj1, pred2, one)); + dao.add(new RyaStatement(subj1, pred2, two)); + dao.add(new RyaStatement(subj1, pred2, three)); + dao.add(new RyaStatement(subj2, pred1, one)); + dao.add(new RyaStatement(subj2, pred1, two)); + dao.add(new RyaStatement(subj2, pred1, three)); + dao.add(new RyaStatement(subj2, pred2, one)); + dao.add(new RyaStatement(subj2, pred2, two)); + dao.add(new RyaStatement(subj2, pred2, three)); + dao.add(new RyaStatement(subj3, pred1, one)); + dao.add(new RyaStatement(subj3, pred1, two)); + dao.add(new RyaStatement(subj3, pred1, three)); + dao.add(new RyaStatement(subj3, pred2, one)); + dao.add(new RyaStatement(subj3, pred2, two)); + dao.add(new RyaStatement(subj3, pred2, three)); + dao.add(new RyaStatement(subj4, pred1, one)); + dao.add(new RyaStatement(subj4, pred1, two)); + dao.add(new RyaStatement(subj4, pred1, three)); + dao.add(new RyaStatement(subj4, pred2, one)); + dao.add(new RyaStatement(subj4, pred2, two)); + dao.add(new RyaStatement(subj4, pred2, three)); + + + //1 join + HashJoin ijoin = new HashJoin(dao.getQueryEngine()); + CloseableIteration<RyaStatement, RyaDAOException> join = ijoin.join(null, pred1, pred2); + + int count = 0; + while (join.hasNext()) { + RyaStatement next = join.next(); + count++; + } + assertEquals(12, count); + join.close(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/80faf06d/sail/src/test/java/mvm/rya/IterativeJoinTest.java ---------------------------------------------------------------------- diff --git a/sail/src/test/java/mvm/rya/IterativeJoinTest.java b/sail/src/test/java/mvm/rya/IterativeJoinTest.java new file mode 100644 index 0000000..610b8eb --- /dev/null +++ b/sail/src/test/java/mvm/rya/IterativeJoinTest.java @@ -0,0 +1,365 @@ +package mvm.rya; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import info.aduna.iteration.CloseableIteration; +import junit.framework.TestCase; +import mvm.rya.accumulo.AccumuloRdfConfiguration; +import mvm.rya.accumulo.AccumuloRyaDAO; +import mvm.rya.api.RdfCloudTripleStoreUtils; +import mvm.rya.api.domain.RyaStatement; +import mvm.rya.api.domain.RyaType; +import mvm.rya.api.domain.RyaURI; +import mvm.rya.api.persist.RyaDAOException; +import mvm.rya.api.persist.query.join.IterativeJoin; +import org.apache.accumulo.core.client.Connector; +import org.apache.accumulo.core.client.mock.MockInstance; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static junit.framework.Assert.*; + +/** + * Date: 7/24/12 + * Time: 5:51 PM + */ +public class IterativeJoinTest { + private AccumuloRyaDAO dao; + static String litdupsNS = "urn:test:litdups#"; + private Connector connector; + private AccumuloRdfConfiguration conf = new AccumuloRdfConfiguration(); + + @Before + public void init() throws Exception { + dao = new AccumuloRyaDAO(); + connector = new MockInstance().getConnector("", ""); + dao.setConnector(connector); + dao.setConf(conf); + dao.init(); + } + + @After + public void destroy() throws Exception { + dao.destroy(); + } + + @Test + public void testSimpleIterativeJoin() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, two)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, two)); + dao.add(new RyaStatement(subj3, pred, one)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + + //1 join + IterativeJoin iterJoin = new IterativeJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = iterJoin.join(null, new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, one), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, two)); + + Set<RyaURI> uris = new HashSet<RyaURI>(); + while (join.hasNext()) { + uris.add(join.next()); + } + assertTrue(uris.contains(subj1)); + assertTrue(uris.contains(subj2)); + assertTrue(uris.contains(subj3)); + assertTrue(uris.contains(subj4)); + join.close(); + } + + @Test + public void testSimpleIterativeJoinMultiWay() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaType four = new RyaType("4"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, two)); + dao.add(new RyaStatement(subj1, pred, three)); + dao.add(new RyaStatement(subj1, pred, four)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, two)); + dao.add(new RyaStatement(subj2, pred, three)); + dao.add(new RyaStatement(subj2, pred, four)); + dao.add(new RyaStatement(subj3, pred, one)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj3, pred, three)); + dao.add(new RyaStatement(subj3, pred, four)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + dao.add(new RyaStatement(subj4, pred, three)); + dao.add(new RyaStatement(subj4, pred, four)); + + //1 join + IterativeJoin iterativeJoin = new IterativeJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = iterativeJoin.join(null, + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, one), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, two), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, three), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, four) + ); + + Set<RyaURI> uris = new HashSet<RyaURI>(); + while (join.hasNext()) { + uris.add(join.next()); + } + assertTrue(uris.contains(subj1)); + assertTrue(uris.contains(subj2)); + assertTrue(uris.contains(subj3)); + assertTrue(uris.contains(subj4)); + join.close(); + } + + @Test + public void testIterativeJoinMultiWay() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType zero = new RyaType("0"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaType four = new RyaType("4"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, two)); + dao.add(new RyaStatement(subj1, pred, three)); + dao.add(new RyaStatement(subj1, pred, four)); + dao.add(new RyaStatement(subj2, pred, zero)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, two)); + dao.add(new RyaStatement(subj2, pred, three)); + dao.add(new RyaStatement(subj2, pred, four)); + dao.add(new RyaStatement(subj3, pred, one)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj3, pred, four)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + dao.add(new RyaStatement(subj4, pred, three)); + dao.add(new RyaStatement(subj4, pred, four)); + + //1 join + IterativeJoin iterativeJoin = new IterativeJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = iterativeJoin.join(null, + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, one), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, two), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, three), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, four) + ); + + Set<RyaURI> uris = new HashSet<RyaURI>(); + while (join.hasNext()) { + uris.add(join.next()); + } + assertTrue(uris.contains(subj1)); + assertTrue(uris.contains(subj2)); + assertTrue(uris.contains(subj4)); + join.close(); + } + + @Test + public void testIterativeJoinMultiWayNone() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType zero = new RyaType("0"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaType four = new RyaType("4"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, three)); + dao.add(new RyaStatement(subj1, pred, four)); + dao.add(new RyaStatement(subj2, pred, zero)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, four)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj3, pred, four)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + dao.add(new RyaStatement(subj4, pred, three)); + + //1 join + IterativeJoin iterativeJoin = new IterativeJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = iterativeJoin.join(null, + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, one), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, two), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, three), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, four) + ); + + assertFalse(join.hasNext()); + join.close(); + } + + @Test + public void testIterativeJoinMultiWayNone2() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType zero = new RyaType("0"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaType four = new RyaType("4"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, four)); + dao.add(new RyaStatement(subj2, pred, zero)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, four)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj3, pred, four)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + + //1 join + IterativeJoin iterativeJoin = new IterativeJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = iterativeJoin.join(null, new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, one), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, two), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, three), + new RdfCloudTripleStoreUtils.CustomEntry<RyaURI, RyaType>(pred, four) + ); + + assertFalse(join.hasNext()); + join.close(); + } + + @Test + public void testSimpleIterativeJoinPredicateOnly() throws Exception { + //add data + RyaURI pred1 = new RyaURI(litdupsNS, "pred1"); + RyaURI pred2 = new RyaURI(litdupsNS, "pred2"); + RyaType one = new RyaType("1"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred1, one)); + dao.add(new RyaStatement(subj1, pred2, one)); + dao.add(new RyaStatement(subj2, pred1, one)); + dao.add(new RyaStatement(subj2, pred2, one)); + dao.add(new RyaStatement(subj3, pred1, one)); + dao.add(new RyaStatement(subj3, pred2, one)); + dao.add(new RyaStatement(subj4, pred1, one)); + dao.add(new RyaStatement(subj4, pred2, one)); + + + //1 join + IterativeJoin ijoin = new IterativeJoin(dao.getQueryEngine()); + CloseableIteration<RyaStatement, RyaDAOException> join = ijoin.join(null, pred1, pred2); + + int count = 0; + while (join.hasNext()) { + RyaStatement next = join.next(); + count++; + } + assertEquals(4, count); + join.close(); + } + + @Test + public void testSimpleIterativeJoinPredicateOnly2() throws Exception { + //add data + RyaURI pred1 = new RyaURI(litdupsNS, "pred1"); + RyaURI pred2 = new RyaURI(litdupsNS, "pred2"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred1, one)); + dao.add(new RyaStatement(subj1, pred1, two)); + dao.add(new RyaStatement(subj1, pred1, three)); + dao.add(new RyaStatement(subj1, pred2, one)); + dao.add(new RyaStatement(subj1, pred2, two)); + dao.add(new RyaStatement(subj1, pred2, three)); + dao.add(new RyaStatement(subj2, pred1, one)); + dao.add(new RyaStatement(subj2, pred1, two)); + dao.add(new RyaStatement(subj2, pred1, three)); + dao.add(new RyaStatement(subj2, pred2, one)); + dao.add(new RyaStatement(subj2, pred2, two)); + dao.add(new RyaStatement(subj2, pred2, three)); + dao.add(new RyaStatement(subj3, pred1, one)); + dao.add(new RyaStatement(subj3, pred1, two)); + dao.add(new RyaStatement(subj3, pred1, three)); + dao.add(new RyaStatement(subj3, pred2, one)); + dao.add(new RyaStatement(subj3, pred2, two)); + dao.add(new RyaStatement(subj3, pred2, three)); + dao.add(new RyaStatement(subj4, pred1, one)); + dao.add(new RyaStatement(subj4, pred1, two)); + dao.add(new RyaStatement(subj4, pred1, three)); + dao.add(new RyaStatement(subj4, pred2, one)); + dao.add(new RyaStatement(subj4, pred2, two)); + dao.add(new RyaStatement(subj4, pred2, three)); + + + //1 join + IterativeJoin ijoin = new IterativeJoin(dao.getQueryEngine()); + CloseableIteration<RyaStatement, RyaDAOException> join = ijoin.join(null, pred1, pred2); + + int count = 0; + while (join.hasNext()) { + RyaStatement next = join.next(); + count++; + } + assertEquals(12, count); + join.close(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/80faf06d/sail/src/test/java/mvm/rya/MergeJoinTest.java ---------------------------------------------------------------------- diff --git a/sail/src/test/java/mvm/rya/MergeJoinTest.java b/sail/src/test/java/mvm/rya/MergeJoinTest.java new file mode 100644 index 0000000..e4f07c4 --- /dev/null +++ b/sail/src/test/java/mvm/rya/MergeJoinTest.java @@ -0,0 +1,370 @@ +package mvm.rya; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + +import info.aduna.iteration.CloseableIteration; +import mvm.rya.accumulo.AccumuloRdfConfiguration; +import mvm.rya.accumulo.AccumuloRyaDAO; +import mvm.rya.api.domain.RyaStatement; +import mvm.rya.api.domain.RyaType; +import mvm.rya.api.domain.RyaURI; +import mvm.rya.api.persist.RyaDAOException; +import mvm.rya.api.persist.query.join.MergeJoin; +import org.apache.accumulo.core.client.Connector; +import org.apache.accumulo.core.client.mock.MockInstance; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static junit.framework.Assert.*; +import static mvm.rya.api.RdfCloudTripleStoreUtils.CustomEntry; + +/** + * TODO: Move to rya.api when we have proper mock ryaDao + * + * Date: 7/24/12 + * Time: 9:49 AM + */ +public class MergeJoinTest { + + private AccumuloRyaDAO dao; + static String litdupsNS = "urn:test:litdups#"; + private Connector connector; + private AccumuloRdfConfiguration conf = new AccumuloRdfConfiguration(); + + @Before + public void init() throws Exception { + dao = new AccumuloRyaDAO(); + connector = new MockInstance().getConnector("", ""); + dao.setConnector(connector); + dao.setConf(conf); + dao.init(); + } + + @After + public void destroy() throws Exception { + dao.destroy(); + } + + @Test + public void testSimpleMergeJoin() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, two)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, two)); + dao.add(new RyaStatement(subj3, pred, one)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + + + //1 join + MergeJoin mergeJoin = new MergeJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = mergeJoin.join(null, new CustomEntry<RyaURI, RyaType>(pred, one), + new CustomEntry<RyaURI, RyaType>(pred, two)); + + Set<RyaURI> uris = new HashSet<RyaURI>(); + while (join.hasNext()) { + uris.add(join.next()); + } + assertTrue(uris.contains(subj1)); + assertTrue(uris.contains(subj2)); + assertTrue(uris.contains(subj3)); + assertTrue(uris.contains(subj4)); + join.close(); + } + + @Test + public void testSimpleMergeJoinPredicateOnly() throws Exception { + //add data + RyaURI pred1 = new RyaURI(litdupsNS, "pred1"); + RyaURI pred2 = new RyaURI(litdupsNS, "pred2"); + RyaType one = new RyaType("1"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred1, one)); + dao.add(new RyaStatement(subj1, pred2, one)); + dao.add(new RyaStatement(subj2, pred1, one)); + dao.add(new RyaStatement(subj2, pred2, one)); + dao.add(new RyaStatement(subj3, pred1, one)); + dao.add(new RyaStatement(subj3, pred2, one)); + dao.add(new RyaStatement(subj4, pred1, one)); + dao.add(new RyaStatement(subj4, pred2, one)); + + + //1 join + MergeJoin mergeJoin = new MergeJoin(dao.getQueryEngine()); + CloseableIteration<RyaStatement, RyaDAOException> join = mergeJoin.join(null, pred1, pred2); + + int count = 0; + while (join.hasNext()) { + RyaStatement next = join.next(); + count++; + } + assertEquals(4, count); + join.close(); + } + + @Test + public void testSimpleMergeJoinPredicateOnly2() throws Exception { + //add data + RyaURI pred1 = new RyaURI(litdupsNS, "pred1"); + RyaURI pred2 = new RyaURI(litdupsNS, "pred2"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred1, one)); + dao.add(new RyaStatement(subj1, pred1, two)); + dao.add(new RyaStatement(subj1, pred1, three)); + dao.add(new RyaStatement(subj1, pred2, one)); + dao.add(new RyaStatement(subj1, pred2, two)); + dao.add(new RyaStatement(subj1, pred2, three)); + dao.add(new RyaStatement(subj2, pred1, one)); + dao.add(new RyaStatement(subj2, pred1, two)); + dao.add(new RyaStatement(subj2, pred1, three)); + dao.add(new RyaStatement(subj2, pred2, one)); + dao.add(new RyaStatement(subj2, pred2, two)); + dao.add(new RyaStatement(subj2, pred2, three)); + dao.add(new RyaStatement(subj3, pred1, one)); + dao.add(new RyaStatement(subj3, pred1, two)); + dao.add(new RyaStatement(subj3, pred1, three)); + dao.add(new RyaStatement(subj3, pred2, one)); + dao.add(new RyaStatement(subj3, pred2, two)); + dao.add(new RyaStatement(subj3, pred2, three)); + dao.add(new RyaStatement(subj4, pred1, one)); + dao.add(new RyaStatement(subj4, pred1, two)); + dao.add(new RyaStatement(subj4, pred1, three)); + dao.add(new RyaStatement(subj4, pred2, one)); + dao.add(new RyaStatement(subj4, pred2, two)); + dao.add(new RyaStatement(subj4, pred2, three)); + + + //1 join + MergeJoin mergeJoin = new MergeJoin(dao.getQueryEngine()); + CloseableIteration<RyaStatement, RyaDAOException> join = mergeJoin.join(null, pred1, pred2); + + int count = 0; + while (join.hasNext()) { + RyaStatement next = join.next(); + count++; + } + assertEquals(12, count); + join.close(); + } + + @Test + public void testSimpleMergeJoinMultiWay() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaType four = new RyaType("4"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, two)); + dao.add(new RyaStatement(subj1, pred, three)); + dao.add(new RyaStatement(subj1, pred, four)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, two)); + dao.add(new RyaStatement(subj2, pred, three)); + dao.add(new RyaStatement(subj2, pred, four)); + dao.add(new RyaStatement(subj3, pred, one)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj3, pred, three)); + dao.add(new RyaStatement(subj3, pred, four)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + dao.add(new RyaStatement(subj4, pred, three)); + dao.add(new RyaStatement(subj4, pred, four)); + + + //1 join + MergeJoin mergeJoin = new MergeJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = mergeJoin.join(null, new CustomEntry<RyaURI, RyaType>(pred, one), + new CustomEntry<RyaURI, RyaType>(pred, two), + new CustomEntry<RyaURI, RyaType>(pred, three), + new CustomEntry<RyaURI, RyaType>(pred, four) + ); + + Set<RyaURI> uris = new HashSet<RyaURI>(); + while (join.hasNext()) { + uris.add(join.next()); + } + assertTrue(uris.contains(subj1)); + assertTrue(uris.contains(subj2)); + assertTrue(uris.contains(subj3)); + assertTrue(uris.contains(subj4)); + join.close(); + } + + @Test + public void testMergeJoinMultiWay() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType zero = new RyaType("0"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaType four = new RyaType("4"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, two)); + dao.add(new RyaStatement(subj1, pred, three)); + dao.add(new RyaStatement(subj1, pred, four)); + dao.add(new RyaStatement(subj2, pred, zero)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, two)); + dao.add(new RyaStatement(subj2, pred, three)); + dao.add(new RyaStatement(subj2, pred, four)); + dao.add(new RyaStatement(subj3, pred, one)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj3, pred, four)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + dao.add(new RyaStatement(subj4, pred, three)); + dao.add(new RyaStatement(subj4, pred, four)); + + + //1 join + MergeJoin mergeJoin = new MergeJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = mergeJoin.join(null, new CustomEntry<RyaURI, RyaType>(pred, one), + new CustomEntry<RyaURI, RyaType>(pred, two), + new CustomEntry<RyaURI, RyaType>(pred, three), + new CustomEntry<RyaURI, RyaType>(pred, four) + ); + + Set<RyaURI> uris = new HashSet<RyaURI>(); + while (join.hasNext()) { + uris.add(join.next()); + } + assertTrue(uris.contains(subj1)); + assertTrue(uris.contains(subj2)); + assertTrue(uris.contains(subj4)); + join.close(); + } + + @Test + public void testMergeJoinMultiWayNone() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType zero = new RyaType("0"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaType four = new RyaType("4"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, three)); + dao.add(new RyaStatement(subj1, pred, four)); + dao.add(new RyaStatement(subj2, pred, zero)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, four)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj3, pred, four)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + dao.add(new RyaStatement(subj4, pred, three)); + + + //1 join + MergeJoin mergeJoin = new MergeJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = mergeJoin.join(null, new CustomEntry<RyaURI, RyaType>(pred, one), + new CustomEntry<RyaURI, RyaType>(pred, two), + new CustomEntry<RyaURI, RyaType>(pred, three), + new CustomEntry<RyaURI, RyaType>(pred, four) + ); + + assertFalse(join.hasNext()); + join.close(); + } + + @Test + public void testMergeJoinMultiWayNone2() throws Exception { + //add data + RyaURI pred = new RyaURI(litdupsNS, "pred1"); + RyaType zero = new RyaType("0"); + RyaType one = new RyaType("1"); + RyaType two = new RyaType("2"); + RyaType three = new RyaType("3"); + RyaType four = new RyaType("4"); + RyaURI subj1 = new RyaURI(litdupsNS, "subj1"); + RyaURI subj2 = new RyaURI(litdupsNS, "subj2"); + RyaURI subj3 = new RyaURI(litdupsNS, "subj3"); + RyaURI subj4 = new RyaURI(litdupsNS, "subj4"); + + dao.add(new RyaStatement(subj1, pred, one)); + dao.add(new RyaStatement(subj1, pred, four)); + dao.add(new RyaStatement(subj2, pred, zero)); + dao.add(new RyaStatement(subj2, pred, one)); + dao.add(new RyaStatement(subj2, pred, four)); + dao.add(new RyaStatement(subj3, pred, two)); + dao.add(new RyaStatement(subj3, pred, four)); + dao.add(new RyaStatement(subj4, pred, one)); + dao.add(new RyaStatement(subj4, pred, two)); + + + //1 join + MergeJoin mergeJoin = new MergeJoin(dao.getQueryEngine()); + CloseableIteration<RyaURI, RyaDAOException> join = mergeJoin.join(null, new CustomEntry<RyaURI, RyaType>(pred, one), + new CustomEntry<RyaURI, RyaType>(pred, two), + new CustomEntry<RyaURI, RyaType>(pred, three), + new CustomEntry<RyaURI, RyaType>(pred, four) + ); + + assertFalse(join.hasNext()); + join.close(); + } +}