You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2013/02/22 14:50:05 UTC

svn commit: r1449040 - /jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/engine/TestQueryEngineMultiThreaded.java

Author: andy
Date: Fri Feb 22 13:50:04 2013
New Revision: 1449040

URL: http://svn.apache.org/r1449040
Log:
Move TestQueryEngineMultiThreaded int test package engine and hook in TS_Engine

Added:
    jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/engine/TestQueryEngineMultiThreaded.java

Added: jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/engine/TestQueryEngineMultiThreaded.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/engine/TestQueryEngineMultiThreaded.java?rev=1449040&view=auto
==============================================================================
--- jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/engine/TestQueryEngineMultiThreaded.java (added)
+++ jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/engine/TestQueryEngineMultiThreaded.java Fri Feb 22 13:50:04 2013
@@ -0,0 +1,307 @@
+/**
+ * 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.
+ */
+
+package com.hp.hpl.jena.sparql.engine;
+
+import static org.junit.Assert.assertEquals;
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.jena.atlas.lib.StrUtils;
+import org.junit.Test;
+
+import com.hp.hpl.jena.query.Query;
+import com.hp.hpl.jena.query.QueryExecution;
+import com.hp.hpl.jena.query.QueryExecutionFactory;
+import com.hp.hpl.jena.query.QueryFactory;
+import com.hp.hpl.jena.query.ResultSetFactory;
+import com.hp.hpl.jena.query.ResultSetRewindable;
+import com.hp.hpl.jena.rdf.model.InfModel;
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+import com.hp.hpl.jena.reasoner.Reasoner;
+import com.hp.hpl.jena.reasoner.rulesys.RDFSRuleReasonerFactory;
+import com.hp.hpl.jena.shared.Lock;
+import com.hp.hpl.jena.vocabulary.ReasonerVocabulary;
+
+/**
+ * Tests for multi-threaded query execution
+ */
+public class TestQueryEngineMultiThreaded {
+    private class RunResult {
+        public int numFailures;
+        public List<Exception> exceptions = new ArrayList<Exception>();
+    }
+    
+    @Test
+    public void parallel_sparql_construct_default_model_read_lock() throws Exception {
+        Model model = this.createDefaultModel();
+        this.testParallelConstruct(model, Lock.READ, EXPECTED_NUM_TRIPLES);
+    }
+
+    @Test
+    public void parallel_sparql_construct_inference_model_read_lock() throws Exception {
+        Model model = createForwardChainingModel();
+        this.testParallelConstruct(model, Lock.READ, EXPECTED_NUM_REASONER_TRIPLES);
+    }
+    
+    @Test
+    public void parallel_sparql_construct_default_model_write_lock() throws Exception {
+        Model model = this.createDefaultModel();
+        this.testParallelConstruct(model, Lock.WRITE, EXPECTED_NUM_TRIPLES);
+    }
+
+    @Test
+    public void parallel_sparql_construct_inference_model_write_lock() throws Exception {
+        Model model = createForwardChainingModel();
+        this.testParallelConstruct(model, Lock.WRITE, EXPECTED_NUM_REASONER_TRIPLES);
+    }
+    
+    @Test
+    public void parallel_sparql_select_default_model_read_lock() throws Exception {
+        Model model = this.createDefaultModel();
+        this.testParallelSelect(model, Lock.READ, EXPECTED_NUM_RESULTS);
+    }
+
+    @Test
+    public void parallel_sparql_select_inference_model_read_lock() throws Exception {
+        Model model = createForwardChainingModel();
+        this.testParallelSelect(model, Lock.READ, EXPECTED_NUM_REASONER_RESULTS);
+    }
+    
+    @Test
+    public void parallel_sparql_select_default_model_write_lock() throws Exception {
+        Model model = this.createDefaultModel();
+        this.testParallelSelect(model, Lock.WRITE, EXPECTED_NUM_RESULTS);
+    }
+
+    @Test
+    public void parallel_sparql_select_inference_model_write_lock() throws Exception {
+        Model model = createForwardChainingModel();
+        this.testParallelSelect(model, Lock.WRITE, EXPECTED_NUM_REASONER_RESULTS);
+    }
+
+    private void testParallelConstruct(Model model, boolean lock, int expected) throws Exception {
+        RunResult runResult = new RunResult();
+        List<Thread> threads = createSparqlConstructExecutionThreads(model, lock, expected, runResult);
+        executeThreads(threads);
+        assertEquals(0, runResult.exceptions.size());
+        assertEquals(0, runResult.numFailures);
+    }
+    
+    private void testParallelSelect(Model model, boolean lock, int expected) throws Exception {
+        RunResult runResult = new RunResult();
+        List<Thread> threads = createSparqlSelectExecutionThreads(model, lock, expected, runResult);
+        executeThreads(threads);
+        assertEquals(0, runResult.exceptions.size());
+        assertEquals(0, runResult.numFailures);
+    }
+
+    private List<Thread> createSparqlConstructExecutionThreads(Model model, boolean lock, int expected, RunResult runResult) {
+        List<Thread> threads = new ArrayList<Thread>();
+
+        for (int thread = 0; thread < NUMBER_OF_THREADS; thread++) {
+            threads.add(createExecuteSparqlConstructThread(model, lock, expected, runResult));
+        }
+        return threads;
+    }
+    
+    private List<Thread> createSparqlSelectExecutionThreads(Model model, boolean lock, int expected, RunResult runResult) {
+        List<Thread> threads = new ArrayList<Thread>();
+        
+        for (int thread = 0; thread < NUMBER_OF_THREADS; thread++) {
+            threads.add(createExecuteSparqlSelectThread(model, lock, expected, runResult));
+        }
+        return threads;
+    }
+
+    private Thread createExecuteSparqlConstructThread(final Model model, final boolean lock, final int expected, final RunResult runResult) {
+        return new Thread() {
+            @Override
+            public void run() {
+                try {
+                    for (int i = 0; i < NUMBER_OF_LOOPS; i++) {
+                        Model resultModel = executeSparqlConstruct(model, CONSTRUCT_QUERY, lock);
+                        if (resultModel.size() != expected) {
+                            runResult.numFailures++;
+                        }
+                    }
+                } catch (Exception e) {
+                    runResult.exceptions.add(e);
+                }
+            }
+        };
+    }
+    
+    private Thread createExecuteSparqlSelectThread(final Model model, final boolean lock, final int expected, final RunResult runResult) {
+        return new Thread() {
+            @Override
+            public void run() {
+                try {
+                    for (int i = 0; i < NUMBER_OF_LOOPS; i++) {
+                        ResultSetRewindable rset = executeSparqlSelect(model, SELECT_QUERY, lock);
+                        if (rset.size() != expected) {
+                            runResult.numFailures++;
+                        }
+                    }
+                } catch (Exception e) {
+                    runResult.exceptions.add(e);
+                }
+            }
+        };
+    }
+
+    private void executeThreads(List<Thread> threads) throws Exception {
+        for (int thread = 0; thread < threads.size(); ++thread) {
+            threads.get(thread).start();
+        }
+        for (int thread = 0; thread < threads.size(); ++thread) {
+            threads.get(thread).join();
+        }
+    }
+
+    private Model executeSparqlConstruct(Model model, String sparql, boolean lock) {
+        Query query = QueryFactory.create(sparql);
+        QueryExecution queryExec = QueryExecutionFactory.create(query, model);
+        model.enterCriticalSection(lock);
+        try {
+            return queryExec.execConstruct();
+        } finally {
+            queryExec.close();
+            model.leaveCriticalSection();
+        }
+    }
+    
+    private ResultSetRewindable executeSparqlSelect(Model model, String sparql, boolean lock) {
+        Query query = QueryFactory.create(sparql);
+        QueryExecution queryExec = QueryExecutionFactory.create(query, model);
+        model.enterCriticalSection(lock);
+        try {
+            return ResultSetFactory.makeRewindable(queryExec.execSelect());
+        } finally {
+            queryExec.close();
+            model.leaveCriticalSection();
+        }
+    }
+    
+    private Model createDefaultModel() {
+        Model def = ModelFactory.createDefaultModel();
+        def.read(new ByteArrayInputStream(TURTLE_RDF.getBytes()), "", "TURTLE");
+        return def;
+    }
+
+    private Model createForwardChainingModel() {
+        Model baseModel = ModelFactory.createDefaultModel();
+        Model schemaModel = ModelFactory.createDefaultModel();
+        Model configurationRuleReasoner = ModelFactory.createDefaultModel();
+        com.hp.hpl.jena.rdf.model.Resource configuration = configurationRuleReasoner.createResource();
+        configuration.addProperty(ReasonerVocabulary.PROPruleMode, "forward");
+        configuration.addProperty(ReasonerVocabulary.PROPsetRDFSLevel, ReasonerVocabulary.RDFS_SIMPLE);
+        Reasoner ruleReasoner = RDFSRuleReasonerFactory.theInstance().create(configuration);
+        InfModel inf = ModelFactory.createInfModel(ruleReasoner, schemaModel, baseModel);
+        inf.read(new ByteArrayInputStream(TURTLE_RDF.getBytes()), "", "TURTLE");
+        return inf;
+    }
+
+    private static final int NUMBER_OF_THREADS = 50;
+    private static final int NUMBER_OF_LOOPS = 50;
+    private static final int EXPECTED_NUM_REASONER_TRIPLES = 42;
+    private static final int EXPECTED_NUM_TRIPLES = 42;
+    private static final int EXPECTED_NUM_REASONER_RESULTS = 6;
+    private static final int EXPECTED_NUM_RESULTS = 6;
+    private static final String CONSTRUCT_QUERY = StrUtils.strjoinNL("BASE <http://example.com/2010/04/>",
+            "construct {",
+            "?subj <gender> ?gender .",
+            "?subj <name> ?name .",
+            "?subj <age> ?age .",
+            "?subj <med> ?med .",
+            "}",
+            "where ",
+            "{",
+            "?subj a <person> .",
+            "OPTIONAL { ?subj <gender> ?gender .",
+            "?subj <name> ?name .",
+            "?subj <age> ?age .",
+            "?subj <med> ?med . }",
+            "}");
+    private static final String SELECT_QUERY = StrUtils.strjoinNL("BASE <http://example.com/2010/04/>",
+            "SELECT * WHERE { ?s a <person> }"
+            );
+    private static final String TURTLE_RDF = "@base <http://example.com/2010/04/> ." + ""
+            + "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> ."
+            + ""
+            + "<patient> rdfs:subClassOf <person> . "
+            + "<name> rdfs:subClassOf <fullName> . "
+            + "<age> rdfs:subClassOf <yearsOld> . "
+            + "<med> rdfs:subClassOf <drug> . "
+            + ""
+            + "<patient/1234> a <person> . "
+            + "<patient/1234> <name> \"Fred Smith\" ."
+            + "<patient/1234> <gender> \"Male\" ."
+            + "<patient/1234> <age> \"24\" ."
+            + "<patient/1234> <med> \"Aspirin\" ."
+            + "<patient/1234> <med> \"Atenolol\" ."
+            + "<patient/1234> <med> \"Acetominophen\" ."
+            + "<patient/1234> <med> \"Ibuprofen\" ."
+            + ""
+            + "<patient/1235> a <person> . "
+            + "<patient/1235> <name> \"F Smith\" ."
+            + "<patient/1235> <gender> \"Male\" ."
+            + "<patient/1235> <age> \"34\" ."
+            + "<patient/1235> <med> \"Aspirin\" ."
+            + "<patient/1235> <med> \"Atenolol\" ."
+            + "<patient/1235> <med> \"Acetominophen\" ."
+            + "<patient/1235> <med> \"Ibuprofen\" ."
+            + ""
+            + "<patient/1236> a <person> . "
+            + "<patient/1236> <name> \"Frederick Smith\" ."
+            + "<patient/1236> <gender> \"Male\" ."
+            + "<patient/1236> <age> \"44\" ."
+            + "<patient/1236> <med> \"Aspirin\" ."
+            + "<patient/1236> <med> \"Atenolol\" ."
+            + "<patient/1236> <med> \"Acetominophen\" ."
+            + "<patient/1236> <med> \"Ibuprofen\" ."
+            + ""
+            + "<patient/1237> a <person> . "
+            + "<patient/1237> <name> \"Freddie Smith\" ."
+            + "<patient/1237> <gender> \"Male\" ."
+            + "<patient/1237> <age> \"14\" ."
+            + "<patient/1237> <med> \"Aspirin\" ."
+            + "<patient/1237> <med> \"Atenolol\" ."
+            + "<patient/1237> <med> \"Acetominophen\" ."
+            + "<patient/1237> <med> \"Ibuprofen\" ."
+            + ""
+            + "<patient/1238> a <person> . "
+            + "<patient/1238> <name> \"Fredd Smith\" ."
+            + "<patient/1238> <gender> \"Male\" ."
+            + "<patient/1238> <age> \"54\" ."
+            + "<patient/1238> <med> \"Aspirin\" ."
+            + "<patient/1238> <med> \"Atenolol\" ."
+            + "<patient/1238> <med> \"Acetominophen\" ."
+            + "<patient/1238> <med> \"Ibuprofen\" ."
+            + ""
+            + "<patient/1239> a <person> . "
+            + "<patient/1239> <name> \"Frederic Smith\" ."
+            + "<patient/1239> <gender> \"Male\" ."
+            + "<patient/1239> <age> \"64\" ."
+            + "<patient/1239> <med> \"Aspirin\" ."
+            + "<patient/1239> <med> \"Atenolol\" ."
+            + "<patient/1239> <med> \"Acetominophen\" ."
+            + "<patient/1239> <med> \"Ibuprofen\" .";
+}
\ No newline at end of file