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 2016/06/29 15:39:30 UTC

[1/6] jena git commit: JENA-901 LPBRuleEngine.tabledGoals now a Guava Cache

Repository: jena
Updated Branches:
  refs/heads/master fc4056538 -> 4754dd5dd


JENA-901 LPBRuleEngine.tabledGoals now a Guava Cache

with a boundary of 512k entries (override with system
property jena.rulesys.lp.max_cached_tabled_goals)
and weak references, so it should not run out of memory.


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/a9b8dc1c
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/a9b8dc1c
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/a9b8dc1c

Branch: refs/heads/master
Commit: a9b8dc1c55e5f350cf17494455a159f32128b3b4
Parents: c5bf5c5
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Mon Mar 23 23:05:08 2015 +0000
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Fri Jun 24 13:20:28 2016 +0100

----------------------------------------------------------------------
 jena-core/pom.xml                               |  22 +-
 .../reasoner/rulesys/impl/LPBRuleEngine.java    | 220 +++++++++++--------
 .../rulesys/impl/TestLPBRuleEngine.java         | 163 ++++++++++++++
 .../jena/reasoner/rulesys/test/TestPackage.java |  12 +-
 4 files changed, 318 insertions(+), 99 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/a9b8dc1c/jena-core/pom.xml
----------------------------------------------------------------------
diff --git a/jena-core/pom.xml b/jena-core/pom.xml
index c0179e0..2261db9 100644
--- a/jena-core/pom.xml
+++ b/jena-core/pom.xml
@@ -58,27 +58,33 @@
     </dependency>
 
     <dependency>
+    	<groupId>org.apache.jena</groupId>
+    	<artifactId>jena-shadowed-guava</artifactId>
+    	<version>3.1.1-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
       <groupId>xerces</groupId>
       <artifactId>xercesImpl</artifactId>
     </dependency>
-    
-     <dependency> 
-       <artifactId>commons-cli</artifactId> 
-       <groupId>commons-cli</groupId> 
-     </dependency> 
+
+     <dependency>
+       <artifactId>commons-cli</artifactId>
+       <groupId>commons-cli</groupId>
+     </dependency>
 
     <dependency>
       <groupId>org.xenei</groupId>
       <artifactId>junit-contracts</artifactId>
       <scope>test</scope>
     </dependency>
-    
+
     <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-all</artifactId>
       <scope>test</scope>
     </dependency>
-    
+
     <dependency>
       <groupId>com.jayway.awaitility</groupId>
       <artifactId>awaitility</artifactId>
@@ -90,7 +96,7 @@
       <artifactId>jena-base</artifactId>
       <version>3.1.1-SNAPSHOT</version>
     </dependency>
-    
+
     <dependency>
       <groupId>org.apache.jena</groupId>
       <artifactId>jena-base</artifactId>

http://git-wip-us.apache.org/repos/asf/jena/blob/a9b8dc1c/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
----------------------------------------------------------------------
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
index 94d24c3..edfc575 100644
--- a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
@@ -18,14 +18,28 @@
 
 package org.apache.jena.reasoner.rulesys.impl;
 
-import org.apache.jena.graph.* ;
-import org.apache.jena.reasoner.* ;
-import org.apache.jena.reasoner.rulesys.* ;
-import org.apache.jena.util.iterator.* ;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+
+import org.apache.jena.ext.com.google.common.cache.Cache;
+import org.apache.jena.ext.com.google.common.cache.CacheBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.*;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.reasoner.ReasonerException;
+import org.apache.jena.reasoner.TriplePattern;
+import org.apache.jena.reasoner.rulesys.BackwardRuleInfGraphI;
+import org.apache.jena.reasoner.rulesys.Rule;
+import org.apache.jena.util.iterator.ExtendedIterator;
+import org.apache.jena.util.iterator.WrappedIterator;
 
 /**
  * LP version of the core backward chaining engine. For each parent inference
@@ -35,46 +49,49 @@ import java.util.*;
  * of the LPInterpreter - one per query.
  */
 public class LPBRuleEngine {
-    
+
 //  =======================================================================
 //   variables
 
     /** Store which holds the raw and compiled rules */
     protected LPRuleStore ruleStore;
-    
+
     /** The parent inference graph to which this engine is attached */
     protected BackwardRuleInfGraphI infGraph;
-    
+
     /** True if debug information should be written out */
     protected boolean traceOn = false;
-    
+
     /** Set to true to flag that derivations should be logged */
     protected boolean recordDerivations;
-        
+
     /** List of engine instances which are still processing queries */
-    protected List<LPInterpreter> activeInterpreters = new ArrayList<>();
-    
+    protected List<LPInterpreter> activeInterpreters = new LinkedList<>();
+
+    protected final int MAX_CACHED_TABLED_GOALS =
+			Integer.getInteger("jena.rulesys.lp.max_cached_tabled_goals", 512*1024);
+
     /** Table mapping tabled goals to generators for those goals.
-     *  This is here so that partial goal state can be shared across multiple queries. */
-    protected HashMap<TriplePattern, Generator> tabledGoals = new HashMap<>();
-    
+     *  This is here so that partial goal state can be shared across multiple queries.
+     */
+    protected Cache<TriplePattern, Generator> tabledGoals = CacheBuilder.newBuilder()
+    	       .maximumSize(MAX_CACHED_TABLED_GOALS).weakValues().build();
+
     /** Set of generators waiting to be run */
     protected LinkedList<LPAgendaEntry> agenda = new LinkedList<>();
-//    protected List agenda = new ArrayList();
-//    protected Collection agenda = new HashSet();
-    
+
     /** Optional profile of number of time each rule is entered, set to non-null to profile */
     protected HashMap<String, Count> profile;
-    
+
     /** The number of generator cycles to wait before running a completion check.
      *  If set to 0 then checks will be done in the generator each time. */
     public static final int CYCLES_BETWEEN_COMPLETION_CHECK = 3;
-    
+
     static Logger logger = LoggerFactory.getLogger(LPBRuleEngine.class);
-    
+
 //  =======================================================================
 //  Constructors
-    
+
     /**
      * Constructor.
      * @param infGraph the parent inference graph which is using this engine
@@ -84,7 +101,7 @@ public class LPBRuleEngine {
         this.infGraph = infGraph;
         ruleStore = rules;
     }
-    
+
     /**
      * Constructor. Creates an empty engine to which rules must be added.
      * @param infGraph the parent inference graph which is using this engine
@@ -93,10 +110,10 @@ public class LPBRuleEngine {
         this.infGraph = infGraph;
         ruleStore = new LPRuleStore();
     }
-    
+
 //  =======================================================================
 //  Control methods
-    
+
     /**
      * Start a new interpreter running to answer a query.
      * @param goal the query to be processed
@@ -107,20 +124,20 @@ public class LPBRuleEngine {
         activeInterpreters.add(interpreter);
         return WrappedIterator.create( new LPTopGoalIterator(interpreter));
     }
-    
+
     /**
      * Clear all tabled results.
      */
     public synchronized void reset() {
         checkSafeToUpdate();
-        tabledGoals = new HashMap<>();
+        tabledGoals.invalidateAll();
         agenda.clear();
     }
-    
+
     /**
      * Add a single rule to the store.
      * N.B. This will invalidate current partial results and the engine
-     * should be reset() before future queries. 
+     * should be reset() before future queries.
      */
     public synchronized void addRule(Rule rule) {
         checkSafeToUpdate();
@@ -129,17 +146,17 @@ public class LPBRuleEngine {
         }
         ruleStore.addRule(rule);
     }
-    
+
     /**
      * Remove a single rule from the store.
      * N.B. This will invalidate current partial results and the engine
-     * should be reset() before future queries. 
+     * should be reset() before future queries.
      */
     public synchronized void deleteRule(Rule rule) {
         checkSafeToUpdate();
         ruleStore.deleteRule(rule);
     }
-    
+
     /**
      * Return an ordered list of all registered rules.
      */
@@ -147,15 +164,15 @@ public class LPBRuleEngine {
         checkSafeToUpdate();
         return ruleStore.getAllRules();
     }
-    
+
     /**
      * Delete all the rules.
      */
     public synchronized void deleteAllRules() {
         checkSafeToUpdate();
-        ruleStore.deleteAllRules();     
+        ruleStore.deleteAllRules();
     }
-    
+
     /**
      * Stop the current work. Forcibly stop all current query instances over this engine.
      */
@@ -167,7 +184,7 @@ public class LPBRuleEngine {
             aCopy.close();
         }
     }
-       
+
     /**
      * Set the state of the trace flag. If set to true then rule firings
      * are logged out to the Log at "INFO" level.
@@ -175,21 +192,21 @@ public class LPBRuleEngine {
     public void setTraceOn(boolean state) {
         traceOn = state;
     }
-    
+
     /**
      * Return true if traces of rule firings should be logged.
      */
     public boolean isTraceOn() {
         return traceOn;
     }
-       
+
     /**
      * Set to true to enable derivation caching
      */
     public void setDerivationLogging(boolean recordDerivations) {
         this.recordDerivations = recordDerivations;
     }
-    
+
     /**
      * Return true in derivations should be logged.
      */
@@ -201,23 +218,23 @@ public class LPBRuleEngine {
     public LPRuleStore getRuleStore() {
         return ruleStore;
     }
-    
+
     /** Return the parent infernce graph associated with this engine */
     public BackwardRuleInfGraphI getInfGraph() {
         return infGraph;
     }
-    
+
     /** Detatch the given engine from the list of active engines for this inf graph */
     public synchronized void detach(LPInterpreter engine) {
         activeInterpreters.remove(engine);
     }
-    
+
     /**
      * Check that there are no currently processing queries.
      * Could throw an exception here but often this can be caused by simply leaving
      * an unclosed iterator. So instead we try to close the iterators and assume the
      * rest of the context will be reset by the add call.
-     * 
+     *
      * <p>Should be called from within a synchronized block.
      */
     public void checkSafeToUpdate() {
@@ -236,8 +253,8 @@ public class LPBRuleEngine {
             }
         }
     }
-    
-    
+
+
 //  =======================================================================
 //  Interface for tabled operations
 
@@ -248,42 +265,73 @@ public class LPBRuleEngine {
     public synchronized void tablePredicate(Node predicate) {
         ruleStore.tablePredicate(predicate);
     }
-    
+
     /**
      * Return a generator for the given goal (assumes that the caller knows that
      * the goal should be tabled).
+     *
+     * Note: If an earlier Generator for the same <code>goal</code> exists in the
+     * cache, it will be returned without considering the provided <code>clauses</code>.
+     *
      * @param goal the goal whose results are to be generated
      * @param clauses the precomputed set of code blocks used to implement the goal
      */
-    public synchronized Generator generatorFor(TriplePattern goal, List<RuleClauseCode> clauses) {
-        Generator generator = tabledGoals.get(goal);
-        if (generator == null) {
-            LPInterpreter interpreter = new LPInterpreter(this, goal, clauses, false);
-            activeInterpreters.add(interpreter);
-            generator = new Generator(interpreter, goal);
-            schedule(generator);
-            tabledGoals.put(goal, generator);
-        }
-        return generator;
+    public synchronized Generator generatorFor(final TriplePattern goal, final List<RuleClauseCode> clauses) {
+        try {
+			return tabledGoals.get(goal, new Callable<Generator>() {
+			 	@Override
+			    public Generator call() {
+			 		/** FIXME: Unify with #generatorFor(TriplePattern) - but investigate what about
+			 		 * the edge case that this method might have been called with the of goal == null
+			 		 * or goal.size()==0 -- which gives different behaviour in
+			 		 * LPInterpreter constructor than through the route of
+			 		 * generatorFor(TriplePattern) which calls a different LPInterpreter constructor
+			 		 * which would fill in from RuleStore.
+			 		 */
+			        LPInterpreter interpreter = new LPInterpreter(LPBRuleEngine.this, goal, clauses, false);
+			        activeInterpreters.add(interpreter);
+			        Generator generator = new Generator(interpreter, goal);
+			        schedule(generator);
+			        return generator;
+			 	}
+			});
+		} catch (ExecutionException e) {
+			if (e.getCause() instanceof RuntimeException) {
+				throw (RuntimeException)e.getCause();
+			}
+			throw new RuntimeException(e);
+		}
     }
-        
+
     /**
      * Return a generator for the given goal (assumes that the caller knows that
      * the goal should be tabled).
      * @param goal the goal whose results are to be generated
      */
-    public synchronized Generator generatorFor(TriplePattern goal) {
-        Generator generator = tabledGoals.get(goal);
-        if (generator == null) {
-            LPInterpreter interpreter = new LPInterpreter(this, goal, false);
-            activeInterpreters.add(interpreter);
-            generator = new Generator(interpreter, goal);
-            schedule(generator);
-            tabledGoals.put(goal, generator);
-        }
-        return generator;
+    public synchronized Generator generatorFor(final TriplePattern goal) {
+        try {
+			return tabledGoals.get(goal, new Callable<Generator>() {
+			 	@Override
+			    public Generator call() {
+		            LPInterpreter interpreter = new LPInterpreter(LPBRuleEngine.this, goal, false);
+		            activeInterpreters.add(interpreter);
+		            Generator generator = new Generator(interpreter, goal);
+		            schedule(generator);
+		            return generator;
+			 	}
+			});
+		} catch (ExecutionException e) {
+			if (e.getCause() instanceof RuntimeException) {
+				throw (RuntimeException)e.getCause();
+			}
+			throw new RuntimeException(e);
+		}
+    }
+
+    long cachedTabledGoals() {
+    	return tabledGoals.size();
     }
-    
+
     /**
      * Register that a generator or specific generator state (Consumer choice point)
      * is now ready to run.
@@ -291,7 +339,7 @@ public class LPBRuleEngine {
     public void schedule(LPAgendaEntry state) {
         agenda.add(state);
     }
-    
+
     /**
      * Run the scheduled generators until the given generator is ready to run.
      */
@@ -300,14 +348,14 @@ public class LPBRuleEngine {
         if (CYCLES_BETWEEN_COMPLETION_CHECK > 0) {
             batch = new ArrayList<>(CYCLES_BETWEEN_COMPLETION_CHECK);
         }
-        int count = 0; 
+        int count = 0;
         while(!gen.isReady()) {
             if (agenda.isEmpty()) {
 //                System.out.println("Cycled " + this + ", " + count);
                 return;
             }
-            
-            LPAgendaEntry next = getNextAgendaEntry(); 
+
+            LPAgendaEntry next = getNextAgendaEntry();
             next.pump();
             count ++;
             if (CYCLES_BETWEEN_COMPLETION_CHECK > 0) {
@@ -321,10 +369,10 @@ public class LPBRuleEngine {
         if (CYCLES_BETWEEN_COMPLETION_CHECK > 0 && !batch.isEmpty()) {
             Generator.checkForCompletions(batch);
         }
-        
+
 //        System.out.println("Cycled " + this + ", " + count);
     }
-    
+
     /**
      * Pick and agenda entry to progress and remove it from the queue
      */
@@ -336,7 +384,7 @@ public class LPBRuleEngine {
             return next;
         }
     }
-    
+
     /**
      * Check all known interpeter contexts to see if any are complete.
      */
@@ -356,10 +404,10 @@ public class LPBRuleEngine {
         }
         Generator.checkForCompletions( contexts );
     }
-    
+
 //  =======================================================================
 //  Profiling support
-   
+
     /**
      * Record a rule invocation in the profile count.
      */
@@ -374,7 +422,7 @@ public class LPBRuleEngine {
             }
         }
     }
-    
+
     /**
      * Reset the profile.
      * @param enable it true then profiling will continue with a new empty profile table,
@@ -383,7 +431,7 @@ public class LPBRuleEngine {
     public void resetProfile(boolean enable) {
         profile = enable ? new HashMap<String, Count>() : null;
     }
-    
+
     /**
      * Print a profile of rules used since the last reset.
      */
@@ -401,7 +449,7 @@ public class LPBRuleEngine {
             }
         }
     }
-    
+
     /**
      * Record count of number of rule invocations, used in profile structure only.
      */
@@ -413,29 +461,29 @@ public class LPBRuleEngine {
         public Count(RuleClauseCode clause) {
             this.clause = clause;
         }
-        
+
         /** return the count value */
         public int getCount() {
-            return count;        
+            return count;
         }
-        
+
         /** increment the count value, return the count object */
         public Count inc() {
             count++;
             return this;
         }
-        
+
         /** Ordering */
         @Override
         public int compareTo(Count other) {
             return (count < other.count) ? -1 : ( (count == other.count) ? 0 : +1);
         }
-        
+
         /** Printable form */
         @Override
         public String toString() {
             return " " + count + "\t - " + clause;
         }
-        
+
     }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/a9b8dc1c/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/impl/TestLPBRuleEngine.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/impl/TestLPBRuleEngine.java b/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/impl/TestLPBRuleEngine.java
new file mode 100644
index 0000000..12436f0
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/impl/TestLPBRuleEngine.java
@@ -0,0 +1,163 @@
+/*
+ * 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 TestLPBRuleEngine extends TestCase {
+	public static TestSuite suite() {
+		return new TestSuite(TestLPBRuleEngine.class, "TestLPBRuleEngine");
+	}
+
+	protected Node a = NodeFactory.createURI("a");
+	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 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());
+	}
+
+	@Test
+	public void testSaturateTabledGoals() throws Exception {
+		final int MAX = 1024;
+		// Set the cache size very small just for this test
+		System.setProperty("jena.rulesys.lp.max_cached_tabled_goals", "" + MAX);
+		try {
+			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());
+
+			// JENA-901
+			// Let's ask about lots of unknown subjects
+			for (int i = 0; i < MAX * 128; i++) {
+				Node test = NodeFactory.createURI("test" + i);
+				ExtendedIterator<Triple> it = infgraph.find(test, ty, C2);
+				assertFalse(it.hasNext());
+				it.close();
+			}
+
+			// Let's see how many were cached
+			assertEquals(MAX, engine.tabledGoals.size());
+			// and no leaks of activeInterpreters (this will happen if we forget
+			// to call hasNext above)
+			assertEquals(0, engine.activeInterpreters.size());
+		} finally {
+			System.clearProperty("jena.rulesys.lp.max_cached_tabled_goals");
+
+		}
+	}
+
+	/**
+	 * 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/a9b8dc1c/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 1a25ae7..fe3518c 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
@@ -25,6 +25,7 @@ import org.slf4j.Logger ;
 import org.slf4j.LoggerFactory ;
 
 import org.apache.jena.reasoner.rulesys.impl.TestLPBRuleEngineLeak;
+import org.apache.jena.reasoner.rulesys.impl.TestLPBRuleEngine;
 
 /**
  * Aggregate tester that runs all the test associated with the rulesys package.
@@ -33,21 +34,22 @@ import org.apache.jena.reasoner.rulesys.impl.TestLPBRuleEngineLeak;
 public class TestPackage extends TestSuite {
 
     protected static Logger logger = LoggerFactory.getLogger(TestPackage.class);
-    
+
     static public TestSuite suite() {
         return new TestPackage();
     }
-    
+
     /** Creates new TestPackage */
     private TestPackage() {
         super("RuleSys");
-        
+
         addTestSuite( TestConfigVocabulary.class );
         addTestSuite( TestGenericRuleReasonerConfig.class );
         addTest( "TestBasics", TestBasics.suite() );
         addTest( "TestBackchainer", TestBackchainer.suite() );
         addTest( "TestLPBasics", TestBasicLP.suite() );
         addTest( "TestLPDerivation", TestLPDerivation.suite() );
+        addTest( TestLPBRuleEngine.suite() );
         addTest( "TestFBRules", TestFBRules.suite() );
         addTest( "TestGenericRules", TestGenericRules.suite() );
         addTest( "TestRETE", TestRETE.suite() );
@@ -60,7 +62,7 @@ public class TestPackage extends TestSuite {
         addTest( "TestComparatorBuiltins", TestComparatorBuiltins.suite() );
         addTest( "FRuleEngineIFactoryTest", FRuleEngineIFactoryTest.suite() );
         //addTest ("TestRuleLoader", TestRuleLoader.suite() );
-        
+
         try {
             /* uncomment the following block when we switch to java 1.6 and update ConcurrentTest to do deadlock detection */
 //            // Check the JVM supports the management interfaces needed for
@@ -73,7 +75,7 @@ public class TestPackage extends TestSuite {
         }
         addTestSuite( TestInferenceReification.class );
         addTestSuite( TestRestrictionsDontNeedTyping.class );
-        
+
         // No longer needed because the tests are now subsumed in OWLUnitTest
         // addTest( "TestOWLConsistency", TestOWLRules.suite() );
     }


[5/6] jena git commit: Merge commit 'refs/pull/47/head' of github.com:apache/jena

Posted by an...@apache.org.
Merge commit 'refs/pull/47/head' of github.com:apache/jena

This closes #47.


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/50d60085
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/50d60085
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/50d60085

Branch: refs/heads/master
Commit: 50d60085a33c393cf928bff502c78f74518b1aba
Parents: fc40565 05885d7
Author: Andy Seaborne <an...@apache.org>
Authored: Wed Jun 29 16:36:30 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Wed Jun 29 16:36:30 2016 +0100

----------------------------------------------------------------------
 jena-core/pom.xml                               |  22 +-
 .../reasoner/rulesys/impl/LPBRuleEngine.java    | 218 +++++++++++--------
 .../rulesys/impl/TestLPBRuleEngine.java         | 163 ++++++++++++++
 .../jena/reasoner/rulesys/test/TestPackage.java |  12 +-
 4 files changed, 317 insertions(+), 98 deletions(-)
----------------------------------------------------------------------



[4/6] jena git commit: JENA-901 Java 8 style Callable

Posted by an...@apache.org.
JENA-901 Java 8 style Callable


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/05885d70
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/05885d70
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/05885d70

Branch: refs/heads/master
Commit: 05885d70c3ce62c2c0a017b0b3f9481d57ac5d3b
Parents: f1a2752
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Fri Jun 24 13:35:49 2016 +0100
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Fri Jun 24 13:35:49 2016 +0100

----------------------------------------------------------------------
 .../reasoner/rulesys/impl/LPBRuleEngine.java    | 48 +++++++++-----------
 1 file changed, 21 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/05885d70/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
----------------------------------------------------------------------
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
index 0ea82dd..08e8f82 100644
--- a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
@@ -281,24 +281,21 @@ public class LPBRuleEngine {
      * @param clauses the precomputed set of code blocks used to implement the goal
      */
     public synchronized Generator generatorFor(final TriplePattern goal, final List<RuleClauseCode> clauses) {
-          return getCachedTabledGoal(goal, new Callable<Generator>() {
-      		 	@Override
-      		    public Generator call() {
-      		 		/** FIXME: Unify with #generatorFor(TriplePattern) - but investigate what about
-      		 		 * the edge case that this method might have been called with the of goal == null
-      		 		 * or goal.size()==0 -- which gives different behaviour in
-      		 		 * LPInterpreter constructor than through the route of
-      		 		 * generatorFor(TriplePattern) which calls a different LPInterpreter constructor
-      		 		 * which would fill in from RuleStore.
-      		 		 */
-      		        LPInterpreter interpreter = new LPInterpreter(LPBRuleEngine.this, goal, clauses, false);
-      		        activeInterpreters.add(interpreter);
-      		        Generator generator = new Generator(interpreter, goal);
-      		        schedule(generator);
-      		        return generator;
-      		 	}
-      		});
-    }
+        return getCachedTabledGoal(goal, () -> {
+	 		/** FIXME: Unify with #generatorFor(TriplePattern) - but investigate what about
+	 		 * the edge case that this method might have been called with the of goal == null
+	 		 * or goal.size()==0 -- which gives different behaviour in
+	 		 * LPInterpreter constructor than through the route of
+	 		 * generatorFor(TriplePattern) which calls a different LPInterpreter constructor
+	 		 * which would fill in from RuleStore.
+	 		 */
+			LPInterpreter interpreter = new LPInterpreter(LPBRuleEngine.this, goal, clauses, false);
+			activeInterpreters.add(interpreter);
+			Generator generator = new Generator(interpreter, goal);
+			schedule(generator);
+			return generator;
+		});
+	}
 
     /**
      * Return a generator for the given goal (assumes that the caller knows that
@@ -306,15 +303,12 @@ public class LPBRuleEngine {
      * @param goal the goal whose results are to be generated
      */
     public synchronized Generator generatorFor(final TriplePattern goal) {
-		return getCachedTabledGoal(goal, new Callable<Generator>() {
-		 	@Override
-		    public Generator call() {
-	            LPInterpreter interpreter = new LPInterpreter(LPBRuleEngine.this, goal, false);
-	            activeInterpreters.add(interpreter);
-	            Generator generator = new Generator(interpreter, goal);
-	            schedule(generator);
-	            return generator;
-		 	}
+    	return getCachedTabledGoal(goal, () -> {
+            LPInterpreter interpreter = new LPInterpreter(LPBRuleEngine.this, goal, false);
+            activeInterpreters.add(interpreter);
+            Generator generator = new Generator(interpreter, goal);
+            schedule(generator);
+            return generator;
 		});
     }
 


[2/6] jena git commit: JENA-901 Avoid exposing the Guava cache as protected

Posted by an...@apache.org.
JENA-901 Avoid exposing the Guava cache as protected

.. but just in case (and to match the rest of the class)
add protected methods for manipulating the cache


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/529fc965
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/529fc965
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/529fc965

Branch: refs/heads/master
Commit: 529fc9656a9742e47a0ce4a2a6e21a6257c6cc05
Parents: a9b8dc1
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Tue Mar 31 00:58:23 2015 +0100
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Fri Jun 24 13:26:52 2016 +0100

----------------------------------------------------------------------
 jena-core/pom.xml                               |  2 +-
 .../reasoner/rulesys/impl/LPBRuleEngine.java    | 83 +++++++++++---------
 2 files changed, 45 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/529fc965/jena-core/pom.xml
----------------------------------------------------------------------
diff --git a/jena-core/pom.xml b/jena-core/pom.xml
index 2261db9..a142371 100644
--- a/jena-core/pom.xml
+++ b/jena-core/pom.xml
@@ -59,7 +59,7 @@
 
     <dependency>
     	<groupId>org.apache.jena</groupId>
-    	<artifactId>jena-shadowed-guava</artifactId>
+    	<artifactId>jena-shaded-guava</artifactId>
     	<version>3.1.1-SNAPSHOT</version>
     </dependency>
 

http://git-wip-us.apache.org/repos/asf/jena/blob/529fc965/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
----------------------------------------------------------------------
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
index edfc575..4ce515d 100644
--- a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
@@ -73,8 +73,11 @@ public class LPBRuleEngine {
 
     /** Table mapping tabled goals to generators for those goals.
      *  This is here so that partial goal state can be shared across multiple queries.
+     *
+     *  Note: Do no expose as protected/public, as this depends on
+     *  the shadowed org.apache.jena.ext.com.google.common.*
      */
-    protected Cache<TriplePattern, Generator> tabledGoals = CacheBuilder.newBuilder()
+    Cache<TriplePattern, Generator> tabledGoals = CacheBuilder.newBuilder()
     	       .maximumSize(MAX_CACHED_TABLED_GOALS).weakValues().build();
 
     /** Set of generators waiting to be run */
@@ -130,7 +133,7 @@ public class LPBRuleEngine {
      */
     public synchronized void reset() {
         checkSafeToUpdate();
-        tabledGoals.invalidateAll();
+        clearCachedTabledGoals();
         agenda.clear();
     }
 
@@ -277,30 +280,23 @@ public class LPBRuleEngine {
      * @param clauses the precomputed set of code blocks used to implement the goal
      */
     public synchronized Generator generatorFor(final TriplePattern goal, final List<RuleClauseCode> clauses) {
-        try {
-			return tabledGoals.get(goal, new Callable<Generator>() {
-			 	@Override
-			    public Generator call() {
-			 		/** FIXME: Unify with #generatorFor(TriplePattern) - but investigate what about
-			 		 * the edge case that this method might have been called with the of goal == null
-			 		 * or goal.size()==0 -- which gives different behaviour in
-			 		 * LPInterpreter constructor than through the route of
-			 		 * generatorFor(TriplePattern) which calls a different LPInterpreter constructor
-			 		 * which would fill in from RuleStore.
-			 		 */
-			        LPInterpreter interpreter = new LPInterpreter(LPBRuleEngine.this, goal, clauses, false);
-			        activeInterpreters.add(interpreter);
-			        Generator generator = new Generator(interpreter, goal);
-			        schedule(generator);
-			        return generator;
-			 	}
-			});
-		} catch (ExecutionException e) {
-			if (e.getCause() instanceof RuntimeException) {
-				throw (RuntimeException)e.getCause();
-			}
-			throw new RuntimeException(e);
-		}
+          return getCachedTabledGoal(goal, new Callable<Generator>() {
+      		 	@Override
+      		    public Generator call() {
+      		 		/** FIXME: Unify with #generatorFor(TriplePattern) - but investigate what about
+      		 		 * the edge case that this method might have been called with the of goal == null
+      		 		 * or goal.size()==0 -- which gives different behaviour in
+      		 		 * LPInterpreter constructor than through the route of
+      		 		 * generatorFor(TriplePattern) which calls a different LPInterpreter constructor
+      		 		 * which would fill in from RuleStore.
+      		 		 */
+      		        LPInterpreter interpreter = new LPInterpreter(LPBRuleEngine.this, goal, clauses, false);
+      		        activeInterpreters.add(interpreter);
+      		        Generator generator = new Generator(interpreter, goal);
+      		        schedule(generator);
+      		        return generator;
+      		 	}
+      		});
     }
 
     /**
@@ -309,29 +305,38 @@ public class LPBRuleEngine {
      * @param goal the goal whose results are to be generated
      */
     public synchronized Generator generatorFor(final TriplePattern goal) {
-        try {
-			return tabledGoals.get(goal, new Callable<Generator>() {
-			 	@Override
-			    public Generator call() {
-		            LPInterpreter interpreter = new LPInterpreter(LPBRuleEngine.this, goal, false);
-		            activeInterpreters.add(interpreter);
-		            Generator generator = new Generator(interpreter, goal);
-		            schedule(generator);
-		            return generator;
-			 	}
-			});
+		return getCachedTabledGoal(goal, new Callable<Generator>() {
+		 	@Override
+		    public Generator call() {
+	            LPInterpreter interpreter = new LPInterpreter(LPBRuleEngine.this, goal, false);
+	            activeInterpreters.add(interpreter);
+	            Generator generator = new Generator(interpreter, goal);
+	            schedule(generator);
+	            return generator;
+		 	}
+		});
+    }
+
+    protected Generator getCachedTabledGoal(TriplePattern goal,
+			Callable<Generator> callable) {
+    	try {
+			return tabledGoals.get(goal, callable);
 		} catch (ExecutionException e) {
 			if (e.getCause() instanceof RuntimeException) {
 				throw (RuntimeException)e.getCause();
 			}
 			throw new RuntimeException(e);
 		}
-    }
+	}
 
-    long cachedTabledGoals() {
+	protected long cachedTabledGoals() {
     	return tabledGoals.size();
     }
 
+	protected void clearCachedTabledGoals() {
+		tabledGoals.invalidateAll();
+	}
+
     /**
      * Register that a generator or specific generator state (Consumer choice point)
      * is now ready to run.


[6/6] jena git commit: Remove direct dependency on shared-guava

Posted by an...@apache.org.
Remove direct dependency on shared-guava


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/4754dd5d
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/4754dd5d
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/4754dd5d

Branch: refs/heads/master
Commit: 4754dd5dd0eba92ffaa7da523a0d9c57b56c5f15
Parents: 50d6008
Author: Andy Seaborne <an...@apache.org>
Authored: Wed Jun 29 16:39:10 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Wed Jun 29 16:39:10 2016 +0100

----------------------------------------------------------------------
 jena-core/pom.xml | 6 ------
 1 file changed, 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/4754dd5d/jena-core/pom.xml
----------------------------------------------------------------------
diff --git a/jena-core/pom.xml b/jena-core/pom.xml
index a142371..dce95ee 100644
--- a/jena-core/pom.xml
+++ b/jena-core/pom.xml
@@ -58,12 +58,6 @@
     </dependency>
 
     <dependency>
-    	<groupId>org.apache.jena</groupId>
-    	<artifactId>jena-shaded-guava</artifactId>
-    	<version>3.1.1-SNAPSHOT</version>
-    </dependency>
-
-    <dependency>
       <groupId>xerces</groupId>
       <artifactId>xercesImpl</artifactId>
     </dependency>


[3/6] jena git commit: Use JenaRuntime.getSystemProperty

Posted by an...@apache.org.
Use JenaRuntime.getSystemProperty

See https://github.com/apache/jena/pull/47#discussion_r29499092


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/f1a2752b
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/f1a2752b
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/f1a2752b

Branch: refs/heads/master
Commit: f1a2752bc881f61777a94fbc3ec8c3fbffb731ea
Parents: 529fc96
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Fri Jun 24 13:32:51 2016 +0100
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Fri Jun 24 13:32:51 2016 +0100

----------------------------------------------------------------------
 .../org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java    | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/f1a2752b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
----------------------------------------------------------------------
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
index 4ce515d..0ea82dd 100644
--- a/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/rulesys/impl/LPBRuleEngine.java
@@ -27,6 +27,7 @@ import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 
+import org.apache.jena.JenaRuntime;
 import org.apache.jena.ext.com.google.common.cache.Cache;
 import org.apache.jena.ext.com.google.common.cache.CacheBuilder;
 import org.slf4j.Logger;
@@ -68,8 +69,8 @@ public class LPBRuleEngine {
     /** List of engine instances which are still processing queries */
     protected List<LPInterpreter> activeInterpreters = new LinkedList<>();
 
-    protected final int MAX_CACHED_TABLED_GOALS =
-			Integer.getInteger("jena.rulesys.lp.max_cached_tabled_goals", 512*1024);
+    protected final int MAX_CACHED_TABLED_GOALS = Integer.parseInt(
+    		JenaRuntime.getSystemProperty("jena.rulesys.lp.max_cached_tabled_goals", "524288"));
 
     /** Table mapping tabled goals to generators for those goals.
      *  This is here so that partial goal state can be shared across multiple queries.