NIHVIVO-3978 reduction in memory use for clearing inference scratchpad and rebuild models

This commit is contained in:
brianjlowe 2012-10-01 20:08:28 +00:00
parent 1c5e2a88b7
commit b7e2c71cc1
4 changed files with 82 additions and 43 deletions

View file

@ -2,24 +2,17 @@
package edu.cornell.mannlib.vitro.webapp.dao.jena; package edu.cornell.mannlib.vitro.webapp.dao.jena;
import java.util.HashSet;
import com.hp.hpl.jena.rdf.model.ModelChangedListener; import com.hp.hpl.jena.rdf.model.ModelChangedListener;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.SimpleReasonerSetup;
public class ABoxJenaChangeListener extends JenaChangeListener { public class ABoxJenaChangeListener extends JenaChangeListener {
private HashSet<String> ignoredGraphs = new HashSet<String>();
public ABoxJenaChangeListener(ModelChangedListener listener) { public ABoxJenaChangeListener(ModelChangedListener listener) {
super(listener); super(listener);
ignoredGraphs.add(JenaDataSourceSetupBase.JENA_INF_MODEL); ignoredGraphs.add(JenaDataSourceSetupBase.JENA_INF_MODEL);
ignoredGraphs.add(JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL); ignoredGraphs.add(JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL);
ignoredGraphs.add(JenaDataSourceSetupBase.JENA_TBOX_INF_MODEL); ignoredGraphs.add(JenaDataSourceSetupBase.JENA_TBOX_INF_MODEL);
ignoredGraphs.add(SimpleReasonerSetup.JENA_INF_MODEL_REBUILD);
ignoredGraphs.add(SimpleReasonerSetup.JENA_INF_MODEL_SCRATCHPAD);
} }
@Override @Override

View file

@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -16,6 +17,8 @@ import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.rdf.model.StmtIterator;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener; import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.SimpleReasonerSetup;
/** /**
* A ChangeListener that forwards events to a Jena ModelChangedListener * A ChangeListener that forwards events to a Jena ModelChangedListener
@ -26,23 +29,35 @@ public class JenaChangeListener implements ChangeListener {
private static final Log log = LogFactory.getLog(JenaChangeListener.class); private static final Log log = LogFactory.getLog(JenaChangeListener.class);
protected HashSet<String> ignoredGraphs = new HashSet<String>();
private ModelChangedListener listener; private ModelChangedListener listener;
private Model m = ModelFactory.createDefaultModel(); private Model m = ModelFactory.createDefaultModel();
public JenaChangeListener(ModelChangedListener listener) { public JenaChangeListener(ModelChangedListener listener) {
this.listener = listener; this.listener = listener;
ignoredGraphs.add(SimpleReasonerSetup.JENA_INF_MODEL_REBUILD);
ignoredGraphs.add(SimpleReasonerSetup.JENA_INF_MODEL_SCRATCHPAD);
} }
@Override @Override
public void addedStatement(String serializedTriple, String graphURI) { public void addedStatement(String serializedTriple, String graphURI) {
listener.addedStatement(parseTriple(serializedTriple)); if (isRelevantGraph(graphURI)) {
listener.addedStatement(parseTriple(serializedTriple));
}
} }
@Override @Override
public void removedStatement(String serializedTriple, String graphURI) { public void removedStatement(String serializedTriple, String graphURI) {
listener.removedStatement(parseTriple(serializedTriple)); if (isRelevantGraph(graphURI)) {
listener.removedStatement(parseTriple(serializedTriple));
}
} }
private boolean isRelevantGraph(String graphURI) {
return (graphURI == null || !ignoredGraphs.contains(graphURI));
}
@Override @Override
public void notifyEvent(String graphURI, Object event) { public void notifyEvent(String graphURI, Object event) {
log.debug("event: " + event.getClass()); log.debug("event: " + event.getClass());

View file

@ -4,9 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -15,11 +13,9 @@ import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.graph.Graph; import com.hp.hpl.jena.graph.Graph;
import com.hp.hpl.jena.graph.GraphEvents; import com.hp.hpl.jena.graph.GraphEvents;
import com.hp.hpl.jena.graph.GraphUtil;
import com.hp.hpl.jena.graph.Node; import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Triple; import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.graph.impl.SimpleBulkUpdateHandler; import com.hp.hpl.jena.graph.impl.SimpleBulkUpdateHandler;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.Statement;
@ -150,7 +146,7 @@ public class RDFServiceGraphBulkUpdater extends SimpleBulkUpdateHandler {
@Override @Override
public void removeAll() { public void removeAll() {
removeAll(graph); removeAll(graph, null, null, null);
notifyRemoveAll(); notifyRemoveAll();
} }
@ -183,7 +179,7 @@ public class RDFServiceGraphBulkUpdater extends SimpleBulkUpdateHandler {
StringBuffer findQuery = new StringBuffer("CONSTRUCT { ") StringBuffer findQuery = new StringBuffer("CONSTRUCT { ")
.append(findPattern) .append(findPattern)
.append("} WHERE { \n"); .append(" } WHERE { \n");
if (graphURI != null) { if (graphURI != null) {
findQuery.append(" GRAPH <" + graphURI + "> { "); findQuery.append(" GRAPH <" + graphURI + "> { ");
} }
@ -195,14 +191,30 @@ public class RDFServiceGraphBulkUpdater extends SimpleBulkUpdateHandler {
String queryString = findQuery.toString(); String queryString = findQuery.toString();
try { int chunkSize = 50000;
ChangeSet cs = graph.getRDFService().manufactureChangeSet(); boolean done = false;
cs.addRemoval(graph.getRDFService().sparqlConstructQuery(
queryString, RDFService.ModelSerializationFormat.N3), while (!done) {
String chunkQueryString = queryString + " LIMIT " + chunkSize;
try {
Model chunkToRemove = RDFServiceUtils.parseModel(
graph.getRDFService().sparqlConstructQuery(
chunkQueryString, RDFService.ModelSerializationFormat.N3),
RDFService.ModelSerializationFormat.N3);
if (chunkToRemove.size() > 0) {
ChangeSet cs = graph.getRDFService().manufactureChangeSet();
ByteArrayOutputStream out = new ByteArrayOutputStream();
chunkToRemove.write(out, "N-TRIPLE");
cs.addRemoval(new ByteArrayInputStream(out.toByteArray()),
RDFService.ModelSerializationFormat.N3, graphURI); RDFService.ModelSerializationFormat.N3, graphURI);
graph.getRDFService().changeSetUpdate(cs); graph.getRDFService().changeSetUpdate(cs);
} catch (RDFServiceException e) { } else {
throw new RuntimeException(e); done = true;
}
} catch (RDFServiceException e) {
throw new RuntimeException(e);
}
} }
} }

View file

@ -6,6 +6,7 @@ import java.io.InputStream;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Set; import java.util.Set;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -115,6 +116,8 @@ public class ABoxRecomputer {
// recompute class subsumption inferences // recompute class subsumption inferences
inferenceRebuildModel.enterCriticalSection(Lock.WRITE); inferenceRebuildModel.enterCriticalSection(Lock.WRITE);
try { try {
log.info("Clearing inference rebuild model.");
HashSet<String> unknownTypes = new HashSet<String>(); HashSet<String> unknownTypes = new HashSet<String>();
inferenceRebuildModel.removeAll(); inferenceRebuildModel.removeAll();
@ -130,12 +133,15 @@ public class ABoxRecomputer {
try { try {
addedABoxTypeAssertion(individual, inferenceRebuildModel, unknownTypes); addedABoxTypeAssertion(individual, inferenceRebuildModel, unknownTypes);
simpleReasoner.setMostSpecificTypes(individual, inferenceRebuildModel, unknownTypes); simpleReasoner.setMostSpecificTypes(individual, inferenceRebuildModel, unknownTypes);
StmtIterator sit = aboxModel.listStatements(individual, null, (RDFNode) null); List<ReasonerPlugin> pluginList = simpleReasoner.getPluginList();
while (sit.hasNext()) { if (pluginList.size() > 0) {
Statement s = sit.nextStatement(); StmtIterator sit = aboxModel.listStatements(individual, null, (RDFNode) null);
for (ReasonerPlugin plugin : simpleReasoner.getPluginList()) { while (sit.hasNext()) {
plugin.addedABoxStatement(s, aboxModel, inferenceRebuildModel, tboxModel); Statement s = sit.nextStatement();
} for (ReasonerPlugin plugin : pluginList) {
plugin.addedABoxStatement(s, aboxModel, inferenceRebuildModel, tboxModel);
}
}
} }
} catch (NullPointerException npe) { } catch (NullPointerException npe) {
log.error("a NullPointerException was received while recomputing the ABox inferences. Halting inference computation."); log.error("a NullPointerException was received while recomputing the ABox inferences. Halting inference computation.");
@ -346,7 +352,9 @@ public class ABoxRecomputer {
simpleReasoner.addedABoxTypeAssertion(stmt, inferenceModel, unknownTypes); simpleReasoner.addedABoxTypeAssertion(stmt, inferenceModel, unknownTypes);
} }
} finally { } finally {
iter.close(); if (iter != null) {
iter.close();
}
aboxModel.leaveCriticalSection(); aboxModel.leaveCriticalSection();
} }
} }
@ -384,7 +392,9 @@ public class ABoxRecomputer {
} }
} }
} finally { } finally {
iter.close(); if (iter != null) {
iter.close();
}
inferenceModel.leaveCriticalSection(); inferenceModel.leaveCriticalSection();
} }
@ -401,7 +411,9 @@ public class ABoxRecomputer {
} }
} }
} finally { } finally {
iter.close(); if (iter != null) {
iter.close();
}
} }
// Add everything from the recomputed inference model that is not already // Add everything from the recomputed inference model that is not already
@ -432,22 +444,29 @@ public class ABoxRecomputer {
} }
} }
} finally { } finally {
iter.close(); if (iter != null) {
iter.close();
}
} }
iter = scratchpadModel.listStatements(); iter = scratchpadModel.listStatements();
while (iter.hasNext()) { try {
Statement stmt = iter.next(); while (iter.hasNext()) {
Statement stmt = iter.next();
inferenceModel.enterCriticalSection(Lock.WRITE);
try { inferenceModel.enterCriticalSection(Lock.WRITE);
inferenceModel.add(stmt); try {
} finally { inferenceModel.add(stmt);
inferenceModel.leaveCriticalSection(); } finally {
} inferenceModel.leaveCriticalSection();
}
}
} finally {
if (iter != null) {
iter.close();
}
} }
} finally { } finally {
iter.close();
scratchpadModel.removeAll(); scratchpadModel.removeAll();
scratchpadModel.leaveCriticalSection(); scratchpadModel.leaveCriticalSection();
} }