From 2357a40ab609fbcc93b6932647af57400c2a46ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Fri, 28 Jul 2023 15:15:05 +0200 Subject: [PATCH] GH-4134 add benchmarks and tests for the LmdbStore to the ShaclSail --- .../optimizer/ParentReferenceChecker.java | 20 +++---- core/sail/shacl/pom.xml | 6 ++ .../sail/shacl/MultithreadedLmdbStoreIT.java | 57 ++++++++++++++++++ .../shacl/MultithreadedLmdbStoreRDFSIT.java | 58 +++++++++++++++++++ .../benchmark/ComplexLargeBenchmark.java | 43 ++++++++++++++ 5 files changed, 174 insertions(+), 10 deletions(-) create mode 100644 core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/MultithreadedLmdbStoreIT.java create mode 100644 core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/MultithreadedLmdbStoreRDFSIT.java diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/optimizer/ParentReferenceChecker.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/optimizer/ParentReferenceChecker.java index a42a2aed746..05a7d0b97d8 100644 --- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/optimizer/ParentReferenceChecker.java +++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/optimizer/ParentReferenceChecker.java @@ -56,7 +56,7 @@ public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet bindings) } verifySerializable(tupleExpr); - tupleExpr.visit(new ParentCheckingVisitor()); + tupleExpr.visit(new ParentCheckingVisitor(ParentReferenceChecker.this.previousOptimizerInPipeline)); } private void verifySerializable(QueryModelNode tupleExpr) { @@ -89,24 +89,24 @@ private Object bytesToObject(byte[] str) { } } - private class ParentCheckingVisitor extends AbstractQueryModelVisitor { + private final static class ParentCheckingVisitor extends AbstractQueryModelVisitor { private final ArrayDeque ancestors = new ArrayDeque<>(); + private final String previousOptimizer; + + public ParentCheckingVisitor(QueryOptimizer previousOptimizerInPipeline) { + if (previousOptimizerInPipeline != null) { + this.previousOptimizer = previousOptimizerInPipeline.getClass().getSimpleName(); + } else + this.previousOptimizer = "query parsing"; + } @Override protected void meetNode(QueryModelNode node) throws RuntimeException { QueryModelNode expectedParent = ancestors.peekLast(); if (node.getParentNode() != expectedParent) { - String previousOptimizer; - if (ParentReferenceChecker.this.previousOptimizerInPipeline != null) { - previousOptimizer = ParentReferenceChecker.this.previousOptimizerInPipeline.getClass() - .getSimpleName(); - } else { - previousOptimizer = "query parsing"; - } String message = "After " + previousOptimizer + " there was an unexpected parent for node " + node + ": " + node.getParentNode() + " (expected " + expectedParent + ")"; - assert node.getParentNode() == expectedParent : message; } diff --git a/core/sail/shacl/pom.xml b/core/sail/shacl/pom.xml index b234ccfb88b..d26ee58e5bf 100644 --- a/core/sail/shacl/pom.xml +++ b/core/sail/shacl/pom.xml @@ -85,6 +85,12 @@ junit-jupiter-params test + + ${project.groupId} + rdf4j-sail-lmdb + ${project.version} + test + diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/MultithreadedLmdbStoreIT.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/MultithreadedLmdbStoreIT.java new file mode 100644 index 00000000000..4584b9e10c0 --- /dev/null +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/MultithreadedLmdbStoreIT.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2023 Eclipse RDF4J contributors. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Distribution License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + *******************************************************************************/ +package org.eclipse.rdf4j.sail.shacl; + +import java.io.File; +import java.io.IOException; + +import org.apache.commons.io.FileUtils; +import org.assertj.core.util.Files; +import org.eclipse.rdf4j.common.transaction.IsolationLevels; +import org.eclipse.rdf4j.sail.NotifyingSail; +import org.eclipse.rdf4j.sail.NotifyingSailConnection; +import org.eclipse.rdf4j.sail.lmdb.LmdbStore; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; + +@Tag("slow") +public class MultithreadedLmdbStoreIT extends MultithreadedTest { + + File file; + + @AfterEach + public void after() { + try { + FileUtils.deleteDirectory(file); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @BeforeEach + public void before() { + file = Files.newTemporaryFolder(); + System.out.println("Max memory: " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + " MB"); + } + + @Override + NotifyingSail getBaseSail() { + NotifyingSail notifyingSail = new LmdbStore(file); + try (NotifyingSailConnection connection = notifyingSail.getConnection()) { + connection.begin(IsolationLevels.NONE); + connection.clear(); + connection.commit(); + } + return notifyingSail; + } + +} diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/MultithreadedLmdbStoreRDFSIT.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/MultithreadedLmdbStoreRDFSIT.java new file mode 100644 index 00000000000..2a01f18a268 --- /dev/null +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/MultithreadedLmdbStoreRDFSIT.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2023 Eclipse RDF4J contributors. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Distribution License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + *******************************************************************************/ +package org.eclipse.rdf4j.sail.shacl; + +import java.io.File; +import java.io.IOException; + +import org.apache.commons.io.FileUtils; +import org.assertj.core.util.Files; +import org.eclipse.rdf4j.common.transaction.IsolationLevels; +import org.eclipse.rdf4j.sail.NotifyingSail; +import org.eclipse.rdf4j.sail.NotifyingSailConnection; +import org.eclipse.rdf4j.sail.inferencer.fc.SchemaCachingRDFSInferencer; +import org.eclipse.rdf4j.sail.lmdb.LmdbStore; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; + +@Tag("slow") +public class MultithreadedLmdbStoreRDFSIT extends MultithreadedTest { + + File file; + + @AfterEach + public void after() { + try { + FileUtils.deleteDirectory(file); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @BeforeEach + public void before() { + file = Files.newTemporaryFolder(); + } + + @Override + NotifyingSail getBaseSail() { + NotifyingSail notifyingSail = new LmdbStore(file); + notifyingSail = new SchemaCachingRDFSInferencer(notifyingSail); + try (NotifyingSailConnection connection = notifyingSail.getConnection()) { + connection.begin(IsolationLevels.NONE); + connection.clear(); + connection.commit(); + } + return notifyingSail; + } + +} diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/ComplexLargeBenchmark.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/ComplexLargeBenchmark.java index 4eaab833a2f..48f9236611d 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/ComplexLargeBenchmark.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/benchmark/ComplexLargeBenchmark.java @@ -15,6 +15,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.URL; import java.util.concurrent.TimeUnit; import org.apache.commons.io.FileUtils; @@ -31,6 +32,8 @@ import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection; import org.eclipse.rdf4j.rio.RDFFormat; import org.eclipse.rdf4j.rio.Rio; +import org.eclipse.rdf4j.sail.NotifyingSail; +import org.eclipse.rdf4j.sail.lmdb.LmdbStore; import org.eclipse.rdf4j.sail.nativerdf.NativeStore; import org.eclipse.rdf4j.sail.shacl.ShaclSail; import org.eclipse.rdf4j.sail.shacl.ShaclSailConnection; @@ -322,6 +325,46 @@ public void noPreloadingNonEmptyParallel() { } + @Benchmark + public void noPreloadingNonEmptyParallelLmdb() { + + try { + File file = Files.newTemporaryFolder(); + SailRepository repository = new SailRepository(new ShaclSail(new LmdbStore(file))); + try (SailRepositoryConnection connection = repository.getConnection()) { + connection.begin(ShaclSail.TransactionSettings.ValidationApproach.Disabled); + URL shacl = ComplexLargeBenchmark.class.getClassLoader().getResource("complexBenchmark/shacl.trig"); + connection.add(shacl, RDFFormat.TRIG); + connection.commit(); + } + + ((ShaclSail) repository.getSail()).setTransactionalValidationLimit(1000000); + + try (SailRepositoryConnection connection = repository.getConnection()) { + connection.begin(IsolationLevels.NONE, ShaclSail.TransactionSettings.ValidationApproach.Disabled); + SimpleValueFactory vf = SimpleValueFactory.getInstance(); + connection.add(vf.createBNode(), DUMMY_PREDICATE, vf.createBNode()); + connection.commit(); + } + + ((ShaclSail) repository.getSail()).setParallelValidation(true); + ((ShaclSail) repository.getSail()).setCacheSelectNodes(true); + ((ShaclSail) repository.getSail()).setPerformanceLogging(false); + + try (SailRepositoryConnection connection = repository.getConnection()) { + connection.begin(IsolationLevels.NONE); + connection.add(realData); + connection.commit(); + } + + repository.shutDown(); + + } catch (IOException e) { + throw new RuntimeException(e); + } + + } + @Benchmark public void noPreloadingNonEmptyParallelReadCommitted() {