You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by cl...@apache.org on 2015/05/10 15:03:31 UTC
[02/50] [abbrv] jena git commit: JENA-904: Fix for LPBRuleEngine
leaking activeInterpreters
JENA-904: Fix for LPBRuleEngine leaking activeInterpreters
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/4edc6d38
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/4edc6d38
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/4edc6d38
Branch: refs/heads/add-contract-tests
Commit: 4edc6d38613970894165565000f9d1f1a50a6e4c
Parents: 84d0615
Author: Andy Seaborne <an...@apache.org>
Authored: Fri May 1 12:56:24 2015 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Fri May 1 12:56:24 2015 +0100
----------------------------------------------------------------------
.../rulesys/impl/ConsumerChoicePointFrame.java | 11 ++
.../jena/reasoner/rulesys/impl/FrameObject.java | 5 +-
.../reasoner/rulesys/impl/LPInterpreter.java | 3 +-
.../rulesys/impl/LPTopGoalIterator.java | 1 +
.../rulesys/impl/TopLevelTripleMatchFrame.java | 2 +
.../reasoner/rulesys/impl/TripleMatchFrame.java | 1 +
.../rulesys/impl/TestLPBRuleEngineLeak.java | 171 +++++++++++++++++++
.../jena/reasoner/rulesys/test/TestPackage.java | 4 +
8 files changed, 196 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/4edc6d38/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/ConsumerChoicePointFrame.java
----------------------------------------------------------------------
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/ConsumerChoicePointFrame.java b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/ConsumerChoicePointFrame.java
index e0d0b85..a1c2c26 100644
--- a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/ConsumerChoicePointFrame.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/ConsumerChoicePointFrame.java
@@ -161,6 +161,17 @@ public class ConsumerChoicePointFrame extends GenericTripleMatchFrame
context.setReady(this);
}
+ @Override
+ public void close() {
+ super.close();
+ if (generator != null && generator.interpreter != null) {
+ generator.interpreter.close();
+ // .. but NOT
+ //generator.setComplete();
+ // as it seems to cause other tests to fail
+ }
+ }
+
/**
* Notify that this consumer choice point has finished consuming all
* the results of a closed generator.
http://git-wip-us.apache.org/repos/asf/jena/blob/4edc6d38/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/FrameObject.java
----------------------------------------------------------------------
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/FrameObject.java b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/FrameObject.java
index 39ccc52..4128d36 100644
--- a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/FrameObject.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/FrameObject.java
@@ -54,7 +54,10 @@ public class FrameObject {
* Close the frame actively. This frees any internal resources, frees this frame and
* frees the frame to which this is linked.
*/
- public void close() {
+ public void close() {
+ if (link != null) {
+ link.close();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/jena/blob/4edc6d38/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPInterpreter.java
----------------------------------------------------------------------
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPInterpreter.java b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPInterpreter.java
index 3edbb6d..fee6c97 100644
--- a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPInterpreter.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPInterpreter.java
@@ -164,8 +164,9 @@ public class LPInterpreter {
*/
public void close() {
isComplete = true;
- engine.detach(this);
if (cpFrame != null) cpFrame.close();
+ engine.detach(this);
+
}
/**
http://git-wip-us.apache.org/repos/asf/jena/blob/4edc6d38/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPTopGoalIterator.java
----------------------------------------------------------------------
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPTopGoalIterator.java b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPTopGoalIterator.java
index cb14070..d4d471b 100644
--- a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPTopGoalIterator.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPTopGoalIterator.java
@@ -197,6 +197,7 @@ public class LPTopGoalIterator implements ClosableIterator<Triple>, LPInterprete
// Check for any dangling generators which are complete
interpreter.getEngine().checkForCompletions();
+ interpreter.close();
// Close this top goal
lookAhead = null;
//LogFactory.getLog( getClass() ).debug( "Nulling and closing LPTopGoalIterator " + interpreter );
http://git-wip-us.apache.org/repos/asf/jena/blob/4edc6d38/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/TopLevelTripleMatchFrame.java
----------------------------------------------------------------------
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/TopLevelTripleMatchFrame.java b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/TopLevelTripleMatchFrame.java
index 80a718d..0caf8b2 100644
--- a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/TopLevelTripleMatchFrame.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/TopLevelTripleMatchFrame.java
@@ -66,6 +66,8 @@ public class TopLevelTripleMatchFrame extends GenericChoiceFrame {
@Override
public void close() {
if (matchIterator != null) matchIterator.close();
+ super.close();
+
}
}
http://git-wip-us.apache.org/repos/asf/jena/blob/4edc6d38/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/TripleMatchFrame.java
----------------------------------------------------------------------
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/TripleMatchFrame.java b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/TripleMatchFrame.java
index 8d4891d..74b1a1b 100644
--- a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/TripleMatchFrame.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/TripleMatchFrame.java
@@ -73,6 +73,7 @@ public class TripleMatchFrame extends GenericTripleMatchFrame {
*/
@Override public void close() {
if (matchIterator != null) matchIterator.close();
+ super.close();
}
}
http://git-wip-us.apache.org/repos/asf/jena/blob/4edc6d38/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/impl/TestLPBRuleEngineLeak.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/impl/TestLPBRuleEngineLeak.java b/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/impl/TestLPBRuleEngineLeak.java
new file mode 100644
index 0000000..58e0afb
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/impl/TestLPBRuleEngineLeak.java
@@ -0,0 +1,171 @@
+/*
+ * 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 org.apache.jena.reasoner.rulesys.impl;
+
+import java.lang.reflect.Field;
+import java.util.List;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.junit.Test;
+
+import org.apache.jena.graph.Factory;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.reasoner.rulesys.FBRuleInfGraph;
+import org.apache.jena.reasoner.rulesys.FBRuleReasoner;
+import org.apache.jena.reasoner.rulesys.Rule;
+import org.apache.jena.util.iterator.ExtendedIterator;
+import org.apache.jena.vocabulary.RDF;
+import org.apache.jena.vocabulary.RDFS;
+
+public class TestLPBRuleEngineLeak extends TestCase {
+ public static TestSuite suite() {
+ return new TestSuite(TestLPBRuleEngineLeak.class, "TestLPBRuleEngineLeak");
+ }
+
+ protected Node a = NodeFactory.createURI("a");
+ protected Node b = NodeFactory.createURI("b");
+ protected Node nohit = NodeFactory.createURI("nohit");
+ protected Node p = NodeFactory.createURI("p");
+ protected Node C1 = NodeFactory.createURI("C1");
+ protected Node C2 = NodeFactory.createURI("C2");
+ protected Node ty = RDF.Nodes.type;
+
+ public FBRuleReasoner createReasoner(List<Rule> rules) {
+ FBRuleReasoner reasoner = new FBRuleReasoner(rules);
+ reasoner.tablePredicate(RDFS.Nodes.subClassOf);
+ reasoner.tablePredicate(RDF.Nodes.type);
+ reasoner.tablePredicate(p);
+ return reasoner;
+ }
+
+ @Test
+ public void testNotLeakingActiveInterpreters() throws Exception {
+ Graph data = Factory.createGraphMem();
+ data.add(new Triple(a, ty, C1));
+ data.add(new Triple(b, ty, C1));
+ List<Rule> rules = Rule
+ .parseRules("[r1: (?x p ?t) <- (?x rdf:type C1), makeInstance(?x, p, C2, ?t)]"
+ + "[r2: (?t rdf:type C2) <- (?x rdf:type C1), makeInstance(?x, p, C2, ?t)]");
+
+ FBRuleInfGraph infgraph = (FBRuleInfGraph) createReasoner(rules).bind(
+ data);
+
+ LPBRuleEngine engine = getEngineForGraph(infgraph);
+ assertEquals(0, engine.activeInterpreters.size());
+ assertEquals(0, engine.tabledGoals.size());
+
+ // we ask for a non-hit -- it works, but only because we call it.hasNext()
+ ExtendedIterator<Triple> it = infgraph.find(nohit, ty, C1);
+ assertFalse(it.hasNext());
+ it.close();
+ assertEquals(0, engine.activeInterpreters.size());
+
+ // and again.
+ // Ensure this is not cached by asking for a different triple pattern
+ ExtendedIterator<Triple> it2 = infgraph.find(nohit, ty, C2);
+ // uuups, forgot to call it.hasNext(). But .close() should tidy
+ it2.close();
+ assertEquals(0, engine.activeInterpreters.size());
+
+
+ // OK, let's ask for something that is in the graph
+
+ ExtendedIterator<Triple> it3 = infgraph.find(a, ty, C1);
+ assertTrue(it3.hasNext());
+ assertEquals(a, it3.next().getMatchSubject());
+
+ // .. and what if we forget to call next() to consume b?
+ // (e.g. return from a method with the first hit)
+
+ // this should be enough
+ it3.close();
+ // without leaks of activeInterpreters
+ assertEquals(0, engine.activeInterpreters.size());
+ }
+
+ @Test
+ public void testTabledGoalsCacheHits() throws Exception {
+ Graph data = Factory.createGraphMem();
+ data.add(new Triple(a, ty, C1));
+ List<Rule> rules = Rule
+ .parseRules("[r1: (?x p ?t) <- (?x rdf:type C1), makeInstance(?x, p, C2, ?t)]"
+ + "[r2: (?t rdf:type C2) <- (?x rdf:type C1), makeInstance(?x, p, C2, ?t)]");
+
+ FBRuleInfGraph infgraph = (FBRuleInfGraph) createReasoner(rules).bind(
+ data);
+
+ LPBRuleEngine engine = getEngineForGraph(infgraph);
+ assertEquals(0, engine.activeInterpreters.size());
+ assertEquals(0, engine.tabledGoals.size());
+
+ ExtendedIterator<Triple> it = infgraph.find(a, ty, C1);
+ while (it.hasNext()) {
+ it.next();
+ // FIXME: Why do I need to consume all from the iterator
+ // to avoid leaking activeInterpreters? Calling .close()
+ // below should have been enough.
+ }
+ it.close();
+ // how many were cached
+ assertEquals(1, engine.tabledGoals.size());
+ // and no leaks of activeInterpreters
+ assertEquals(0, engine.activeInterpreters.size());
+
+ // Now ask again:
+ it = infgraph.find(a, ty, C1);
+ while (it.hasNext()) {
+ it.next();
+ }
+ it.close();
+ // if it was a cache hit, no change here:
+ assertEquals(1, engine.tabledGoals.size());
+ assertEquals(0, engine.activeInterpreters.size());
+ }
+
+ /**
+ * Use introspection to get to the LPBRuleEngine.
+ * <p>
+ * We are crossing package boundaries and therefore this test would always
+ * be in the wrong package for either FBRuleInfGraph or LPBRuleEngine.
+ * <p>
+ * <strong>This method should only be used for test purposes.</strong>
+ *
+ * @param infgraph
+ * @return
+ * @throws SecurityException
+ * @throws NoSuchFieldException
+ * @throws IllegalArgumentException
+ * @throws IllegalAccessException
+ */
+ private LPBRuleEngine getEngineForGraph(FBRuleInfGraph infgraph)
+ throws NoSuchFieldException, SecurityException,
+ IllegalArgumentException, IllegalAccessException {
+ Field bEngine = FBRuleInfGraph.class.getDeclaredField("bEngine");
+ bEngine.setAccessible(true);
+ LPBRuleEngine engine = (LPBRuleEngine) bEngine.get(infgraph);
+ return engine;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/4edc6d38/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/TestPackage.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/TestPackage.java b/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/TestPackage.java
index af51f6d..1a25ae7 100755
--- a/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/TestPackage.java
+++ b/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/TestPackage.java
@@ -20,9 +20,12 @@ package org.apache.jena.reasoner.rulesys.test;
import junit.framework.TestSuite ;
+
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
+import org.apache.jena.reasoner.rulesys.impl.TestLPBRuleEngineLeak;
+
/**
* Aggregate tester that runs all the test associated with the rulesys package.
*/
@@ -49,6 +52,7 @@ public class TestPackage extends TestSuite {
addTest( "TestGenericRules", TestGenericRules.suite() );
addTest( "TestRETE", TestRETE.suite() );
addTest( TestSetRules.suite() );
+ addTest( TestLPBRuleEngineLeak.suite() );
addTest( "OWLRuleUnitTests", OWLUnitTest.suite() );
addTest( "TestBugs", TestBugs.suite() );
addTest( "TestOWLMisc", TestOWLMisc.suite() );