You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ss...@apache.org on 2013/07/22 12:56:11 UTC
[6/7] git commit: improved concurrency in value factory and triple
store persistence by using Guava's specialised implementations;
hopefully fixes the issue with spurious duplicate node creation
improved concurrency in value factory and triple store persistence by using Guava's specialised implementations; hopefully fixes the issue with spurious duplicate node creation
Project: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/commit/7dc78513
Tree: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/tree/7dc78513
Diff: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/diff/7dc78513
Branch: refs/heads/develop
Commit: 7dc785137fbb799b3843322de5cc35f500fa8b90
Parents: c5e4411
Author: Sebastian Schaffert <ss...@apache.org>
Authored: Mon Jul 22 12:55:36 2013 +0200
Committer: Sebastian Schaffert <ss...@apache.org>
Committed: Mon Jul 22 12:55:36 2013 +0200
----------------------------------------------------------------------
.../kiwi/persistence/KiWiConnection.java | 13 +-
.../kiwi/persistence/KiWiPersistence.java | 24 +-
.../marmotta/kiwi/sail/KiWiValueFactory.java | 452 +++++++++----------
3 files changed, 228 insertions(+), 261 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/7dc78513/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java
index 2b62024..506c567 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java
+++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiConnection.java
@@ -29,8 +29,6 @@ import org.apache.marmotta.kiwi.caching.KiWiCacheManager;
import org.apache.marmotta.kiwi.config.KiWiConfiguration;
import org.apache.marmotta.kiwi.model.caching.TripleTable;
import org.apache.marmotta.kiwi.model.rdf.*;
-import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect;
-import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect;
import org.apache.marmotta.kiwi.persistence.util.ResultSetIteration;
import org.apache.marmotta.kiwi.persistence.util.ResultTransformerFunction;
import org.openrdf.model.Literal;
@@ -1673,9 +1671,8 @@ public class KiWiConnection {
* @throws SQLException
*/
public long getNextSequence(String sequenceName) throws SQLException {
- AtomicLong sequence = persistence.getMemorySequence(sequenceName);
- if(batchCommit && persistence.getConfiguration().isMemorySequences() && sequence != null) {
- return sequence.incrementAndGet();
+ if(batchCommit && persistence.getConfiguration().isMemorySequences()) {
+ return persistence.incrementAndGetMemorySequence(sequenceName);
} else {
requireJDBCConnection();
@@ -1893,10 +1890,10 @@ public class KiWiConnection {
requireJDBCConnection();
try {
- for(Map.Entry<String,AtomicLong> entry : persistence.getMemorySequences().entrySet()) {
- if( entry.getValue().get() > 0) {
+ for(Map.Entry<String,Long> entry : persistence.getMemorySequences().asMap().entrySet()) {
+ if( entry.getValue() > 0) {
PreparedStatement updateSequence = getPreparedStatement(entry.getKey()+".set");
- updateSequence.setLong(1, entry.getValue().get());
+ updateSequence.setLong(1, entry.getValue());
if(updateSequence.execute()) {
updateSequence.getResultSet().close();
} else {
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/7dc78513/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiPersistence.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiPersistence.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiPersistence.java
index c297eff..12ff73f 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiPersistence.java
+++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/persistence/KiWiPersistence.java
@@ -17,6 +17,7 @@
*/
package org.apache.marmotta.kiwi.persistence;
+import com.google.common.util.concurrent.AtomicLongMap;
import org.apache.marmotta.kiwi.caching.KiWiCacheManager;
import org.apache.marmotta.kiwi.config.KiWiConfiguration;
import org.apache.marmotta.kiwi.model.rdf.KiWiNode;
@@ -76,7 +77,7 @@ public class KiWiPersistence {
* A map holding in-memory sequences to be used for sequence caching in case the appropriate configuration option
* is configued and batched commits are enabled.
*/
- private Map<String,AtomicLong> memorySequences;
+ private AtomicLongMap<String> memorySequences;
private ReentrantLock sequencesLock;
@@ -196,7 +197,7 @@ public class KiWiPersistence {
sequencesLock.lock();
try {
if(memorySequences == null) {
- memorySequences = new ConcurrentHashMap<String,AtomicLong>();
+ memorySequences = AtomicLongMap.create();
}
try {
@@ -216,7 +217,7 @@ public class KiWiPersistence {
ResultSet resultNodeId = queryNodeId.executeQuery();
try {
if(resultNodeId.next()) {
- memorySequences.put(sequenceName,new AtomicLong(resultNodeId.getLong(1)-1));
+ memorySequences.put(sequenceName,resultNodeId.getLong(1)-1);
} else {
throw new SQLException("the sequence did not return a new value");
}
@@ -563,27 +564,18 @@ public class KiWiPersistence {
return configuration;
}
- public Map<String, AtomicLong> getMemorySequences() {
+ public AtomicLongMap<String> getMemorySequences() {
return memorySequences;
}
- public AtomicLong getMemorySequence(String name) {
+ public long incrementAndGetMemorySequence(String name) {
if(memorySequences != null) {
- sequencesLock.lock();
- try {
- return memorySequences.get(name);
- } finally {
- sequencesLock.unlock();
- }
+ return memorySequences.incrementAndGet(name);
} else {
- return null;
+ return 0;
}
}
- public void setMemorySequences(Map<String, AtomicLong> memorySequences) {
- this.memorySequences = memorySequences;
- }
-
public void garbageCollect() throws SQLException {
this.garbageCollector.garbageCollect();
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/7dc78513/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiValueFactory.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiValueFactory.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiValueFactory.java
index b2b5a28..3331704 100644
--- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiValueFactory.java
+++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/sail/KiWiValueFactory.java
@@ -17,45 +17,27 @@
*/
package org.apache.marmotta.kiwi.sail;
-import info.aduna.iteration.Iterations;
-
-import java.sql.SQLException;
-import java.util.*;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.locks.ReentrantLock;
-
-import javax.xml.datatype.XMLGregorianCalendar;
-
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.util.concurrent.Monitor;
import org.apache.commons.lang3.LocaleUtils;
import org.apache.marmotta.commons.sesame.model.LiteralCommons;
import org.apache.marmotta.commons.sesame.model.Namespaces;
import org.apache.marmotta.commons.util.DateUtils;
import org.apache.marmotta.kiwi.model.caching.IntArray;
-import org.apache.marmotta.kiwi.model.rdf.KiWiAnonResource;
-import org.apache.marmotta.kiwi.model.rdf.KiWiBooleanLiteral;
-import org.apache.marmotta.kiwi.model.rdf.KiWiDateLiteral;
-import org.apache.marmotta.kiwi.model.rdf.KiWiDoubleLiteral;
-import org.apache.marmotta.kiwi.model.rdf.KiWiIntLiteral;
-import org.apache.marmotta.kiwi.model.rdf.KiWiLiteral;
-import org.apache.marmotta.kiwi.model.rdf.KiWiNode;
-import org.apache.marmotta.kiwi.model.rdf.KiWiResource;
-import org.apache.marmotta.kiwi.model.rdf.KiWiStringLiteral;
-import org.apache.marmotta.kiwi.model.rdf.KiWiTriple;
-import org.apache.marmotta.kiwi.model.rdf.KiWiUriResource;
+import org.apache.marmotta.kiwi.model.rdf.*;
import org.apache.marmotta.kiwi.persistence.KiWiConnection;
-import org.openrdf.model.BNode;
-import org.openrdf.model.Literal;
-import org.openrdf.model.Resource;
-import org.openrdf.model.Statement;
-import org.openrdf.model.URI;
-import org.openrdf.model.Value;
-import org.openrdf.model.ValueFactory;
+import org.openrdf.model.*;
import org.openrdf.model.impl.ContextStatementImpl;
-import org.openrdf.repository.RepositoryException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.collect.MapMaker;
+import javax.xml.datatype.XMLGregorianCalendar;
+import java.sql.SQLException;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
/**
* Add file description here!
@@ -86,11 +68,9 @@ public class KiWiValueFactory implements ValueFactory {
private KiWiStore store;
- private ReentrantLock nodeLock;
- //private ReentrantLock tripleLock;
- private ConcurrentMap<String,ReentrantLock> resourceLocks;
- private ConcurrentMap<Object,ReentrantLock> literalLocks;
+ private LoadingCache<String,Monitor> resourceLocks;
+ private LoadingCache<String,Monitor> literalLocks;
private String defaultContext;
@@ -110,13 +90,11 @@ public class KiWiValueFactory implements ValueFactory {
// used for generating sequence numbers for RDF nodes
private KiWiConnection batchConnection;
- private ReentrantLock commitLock;
+ private Monitor commitLock;
public KiWiValueFactory(KiWiStore store, String defaultContext) {
- nodeLock = store.nodeLock;
- //tripleLock = store.tripleLock;
- resourceLocks = new MapMaker().weakKeys().weakValues().makeMap();
- literalLocks = new MapMaker().weakKeys().weakValues().makeMap();
+ resourceLocks = CacheBuilder.newBuilder().weakValues().build(new LockCacheLoader());
+ literalLocks = CacheBuilder.newBuilder().weakValues().build(new LockCacheLoader());
anonIdGenerator = new Random();
tripleRegistry = store.tripleRegistry;
@@ -126,14 +104,14 @@ public class KiWiValueFactory implements ValueFactory {
// batch commits
this.nodeBatch = new ArrayList<KiWiNode>(batchSize);
- this.commitLock = new ReentrantLock();
+ this.commitLock = new Monitor();
this.batchCommit = store.getPersistence().getConfiguration().isBatchCommit();
this.batchSize = store.getPersistence().getConfiguration().getBatchSize();
- this.batchUriLookup = new HashMap<String,KiWiUriResource>();
- this.batchBNodeLookup = new HashMap<String, KiWiAnonResource>();
- this.batchLiteralLookup = new HashMap<String,KiWiLiteral>();
+ this.batchUriLookup = new ConcurrentHashMap<String,KiWiUriResource>();
+ this.batchBNodeLookup = new ConcurrentHashMap<String, KiWiAnonResource>();
+ this.batchLiteralLookup = new ConcurrentHashMap<String,KiWiLiteral>();
}
protected KiWiConnection aqcuireConnection() {
@@ -165,33 +143,6 @@ public class KiWiValueFactory implements ValueFactory {
}
}
- protected ReentrantLock acquireResourceLock(String uri) {
- ReentrantLock lock;
- synchronized (resourceLocks) {
- lock = resourceLocks.get(uri);
- if(lock == null) {
- lock = new ReentrantLock();
- resourceLocks.put(uri,lock);
- }
- }
- lock.lock();
-
- return lock;
- }
-
- protected ReentrantLock acquireLiteralLock(Object value) {
- ReentrantLock lock;
- synchronized (literalLocks) {
- lock = literalLocks.get(value);
- if(lock == null) {
- lock = new ReentrantLock();
- literalLocks.put(value,lock);
- }
- }
- lock.lock();
-
- return lock;
- }
/**
* Creates a new bNode.
*
@@ -211,51 +162,56 @@ public class KiWiValueFactory implements ValueFactory {
@Override
public URI createURI(String uri) {
- KiWiUriResource result = batchUriLookup.get(uri);
-
- if(result != null) {
- return result;
- } else {
+ Monitor lock = resourceLocks.getUnchecked(uri);
+ lock.enter();
- ReentrantLock lock = acquireResourceLock(uri);
- KiWiConnection connection = aqcuireConnection();
- try {
- // first look in the registry for newly created resources if the resource has already been created and
- // is still volatile
- result = connection.loadUriResource(uri);
+ try {
+ KiWiUriResource result = batchUriLookup.get(uri);
- if(result == null) {
- result = new KiWiUriResource(uri);
+ if(result != null) {
+ return result;
+ } else {
- if(result.getId() == null) {
- if(batchCommit) {
- result.setId(connection.getNodeId());
- synchronized (nodeBatch) {
- nodeBatch.add(result);
- batchUriLookup.put(uri,result);
+ KiWiConnection connection = aqcuireConnection();
+ try {
+ // first look in the registry for newly created resources if the resource has already been created and
+ // is still volatile
+ result = connection.loadUriResource(uri);
- if(nodeBatch.size() >= batchSize) {
- flushBatch(connection);
+ if(result == null) {
+ result = new KiWiUriResource(uri);
+
+ if(result.getId() == null) {
+ if(batchCommit) {
+ result.setId(connection.getNodeId());
+ synchronized (nodeBatch) {
+ nodeBatch.add(result);
+ batchUriLookup.put(uri,result);
+
+ if(nodeBatch.size() >= batchSize) {
+ flushBatch(connection);
+ }
}
+ } else {
+ connection.storeNode(result, false);
}
- } else {
- connection.storeNode(result, false);
}
- }
- if(result.getId() == null) {
- log.error("node ID is null!");
+ if(result.getId() == null) {
+ log.error("node ID is null!");
+ }
}
- }
- return result;
- } catch (SQLException e) {
- log.error("database error, could not load URI resource",e);
- throw new IllegalStateException("database error, could not load URI resource",e);
- } finally {
- releaseConnection(connection);
- lock.unlock();
+ return result;
+ } catch (SQLException e) {
+ log.error("database error, could not load URI resource",e);
+ throw new IllegalStateException("database error, could not load URI resource",e);
+ } finally {
+ releaseConnection(connection);
+ }
}
+ } finally {
+ lock.leave();
}
}
@@ -286,45 +242,50 @@ public class KiWiValueFactory implements ValueFactory {
*/
@Override
public BNode createBNode(String nodeID) {
- KiWiAnonResource result = batchBNodeLookup.get(nodeID);
+ Monitor lock = resourceLocks.getUnchecked(nodeID);
+ lock.enter();
- if(result != null) {
- return result;
- } else {
- nodeLock.lock();
- KiWiConnection connection = aqcuireConnection();
- try {
- // first look in the registry for newly created resources if the resource has already been created and
- // is still volatile
- result = connection.loadAnonResource(nodeID);
+ try {
+ KiWiAnonResource result = batchBNodeLookup.get(nodeID);
- if(result == null) {
- result = new KiWiAnonResource(nodeID);
+ if(result != null) {
+ return result;
+ } else {
+ KiWiConnection connection = aqcuireConnection();
+ try {
+ // first look in the registry for newly created resources if the resource has already been created and
+ // is still volatile
+ result = connection.loadAnonResource(nodeID);
- if(result.getId() == null) {
- if(batchCommit) {
- result.setId(connection.getNodeId());
- synchronized (nodeBatch) {
- nodeBatch.add(result);
- batchBNodeLookup.put(nodeID,result);
- }
- if(nodeBatch.size() >= batchSize) {
- flushBatch(connection);
+ if(result == null) {
+ result = new KiWiAnonResource(nodeID);
+
+ if(result.getId() == null) {
+ if(batchCommit) {
+ result.setId(connection.getNodeId());
+ synchronized (nodeBatch) {
+ nodeBatch.add(result);
+ batchBNodeLookup.put(nodeID,result);
+ }
+ if(nodeBatch.size() >= batchSize) {
+ flushBatch(connection);
+ }
+ } else {
+ connection.storeNode(result, false);
}
- } else {
- connection.storeNode(result, false);
}
}
- }
- return result;
- } catch (SQLException e) {
- log.error("database error, could not load anonymous resource",e);
- throw new IllegalStateException("database error, could not load anonymous resource",e);
- } finally {
- releaseConnection(connection);
- nodeLock.unlock();
+ return result;
+ } catch (SQLException e) {
+ log.error("database error, could not load anonymous resource",e);
+ throw new IllegalStateException("database error, could not load anonymous resource",e);
+ } finally {
+ releaseConnection(connection);
+ }
}
+ } finally {
+ lock.leave();
}
}
@@ -418,119 +379,125 @@ public class KiWiValueFactory implements ValueFactory {
} else if(type == null) {
type = LiteralCommons.getXSDType(value.getClass());
}
+ String key = LiteralCommons.createCacheKey(value.toString(),locale,type);
- KiWiLiteral result = batchLiteralLookup.get(LiteralCommons.createCacheKey(value.toString(),locale,type));
+ Monitor lock = literalLocks.getUnchecked(key);
+ lock.enter();
+ try {
+ KiWiLiteral result = batchLiteralLookup.get(key);
- if(result != null) {
- return result;
- } else {
- final KiWiUriResource rtype = (KiWiUriResource)createURI(type);
- ReentrantLock lock = acquireLiteralLock(value);
- KiWiConnection connection = aqcuireConnection();
- try {
+ if(result != null) {
+ return result;
+ } else {
+ final KiWiUriResource rtype = (KiWiUriResource)createURI(type);
+ KiWiConnection connection = aqcuireConnection();
+ try {
- // differentiate between the different types of the value
- if(value instanceof Date || type.equals(Namespaces.NS_XSD+"dateTime")) {
- // parse if necessary
- final Date dvalue;
- if(value instanceof Date) {
- dvalue = (Date)value;
- } else {
- dvalue = DateUtils.parseDate(value.toString());
- }
- result = connection.loadLiteral(dvalue);
+ // differentiate between the different types of the value
+ if(value instanceof Date || type.equals(Namespaces.NS_XSD+"dateTime")) {
+ // parse if necessary
+ final Date dvalue;
+ if(value instanceof Date) {
+ dvalue = (Date)value;
+ } else {
+ dvalue = DateUtils.parseDate(value.toString());
+ }
- if(result == null) {
- result= new KiWiDateLiteral(dvalue, rtype);
- }
- } else if(Integer.class.equals(value.getClass()) || int.class.equals(value.getClass()) ||
- Long.class.equals(value.getClass()) || long.class.equals(value.getClass()) ||
- type.equals(Namespaces.NS_XSD+"integer") || type.equals(Namespaces.NS_XSD+"long")) {
- long ivalue = 0;
- if(Integer.class.equals(value.getClass()) || int.class.equals(value.getClass())) {
- ivalue = (Integer)value;
- } else if(Long.class.equals(value.getClass()) || long.class.equals(value.getClass())) {
- ivalue = (Long)value;
- } else {
- ivalue = Long.parseLong(value.toString());
- }
+ result = connection.loadLiteral(dvalue);
+ if(result == null) {
+ result= new KiWiDateLiteral(dvalue, rtype);
+ }
+ } else if(Integer.class.equals(value.getClass()) || int.class.equals(value.getClass()) ||
+ Long.class.equals(value.getClass()) || long.class.equals(value.getClass()) ||
+ type.equals(Namespaces.NS_XSD+"integer") || type.equals(Namespaces.NS_XSD+"long")) {
+ long ivalue = 0;
+ if(Integer.class.equals(value.getClass()) || int.class.equals(value.getClass())) {
+ ivalue = (Integer)value;
+ } else if(Long.class.equals(value.getClass()) || long.class.equals(value.getClass())) {
+ ivalue = (Long)value;
+ } else {
+ ivalue = Long.parseLong(value.toString());
+ }
- result = connection.loadLiteral(ivalue);
- if(result == null) {
- result= new KiWiIntLiteral(ivalue, rtype);
- }
- } else if(Double.class.equals(value.getClass()) || double.class.equals(value.getClass()) ||
- Float.class.equals(value.getClass()) || float.class.equals(value.getClass()) ||
- type.equals(Namespaces.NS_XSD+"double") || type.equals(Namespaces.NS_XSD+"float")) {
- double dvalue = 0.0;
- if(Float.class.equals(value.getClass()) || float.class.equals(value.getClass())) {
- dvalue = (Float)value;
- } else if(Double.class.equals(value.getClass()) || double.class.equals(value.getClass())) {
- dvalue = (Double)value;
- } else {
- dvalue = Double.parseDouble(value.toString());
- }
+ result = connection.loadLiteral(ivalue);
+ if(result == null) {
+ result= new KiWiIntLiteral(ivalue, rtype);
+ }
+ } else if(Double.class.equals(value.getClass()) || double.class.equals(value.getClass()) ||
+ Float.class.equals(value.getClass()) || float.class.equals(value.getClass()) ||
+ type.equals(Namespaces.NS_XSD+"double") || type.equals(Namespaces.NS_XSD+"float")) {
+ double dvalue = 0.0;
+ if(Float.class.equals(value.getClass()) || float.class.equals(value.getClass())) {
+ dvalue = (Float)value;
+ } else if(Double.class.equals(value.getClass()) || double.class.equals(value.getClass())) {
+ dvalue = (Double)value;
+ } else {
+ dvalue = Double.parseDouble(value.toString());
+ }
- result = connection.loadLiteral(dvalue);
- if(result == null) {
- result= new KiWiDoubleLiteral(dvalue, rtype);
- }
- } else if(Boolean.class.equals(value.getClass()) || boolean.class.equals(value.getClass()) ||
- type.equals(Namespaces.NS_XSD+"boolean")) {
- boolean bvalue = false;
- if(Boolean.class.equals(value.getClass()) || boolean.class.equals(value.getClass())) {
- bvalue = (Boolean)value;
- } else {
- bvalue = Boolean.parseBoolean(value.toString());
- }
+ result = connection.loadLiteral(dvalue);
+ if(result == null) {
+ result= new KiWiDoubleLiteral(dvalue, rtype);
+ }
+ } else if(Boolean.class.equals(value.getClass()) || boolean.class.equals(value.getClass()) ||
+ type.equals(Namespaces.NS_XSD+"boolean")) {
+ boolean bvalue = false;
+ if(Boolean.class.equals(value.getClass()) || boolean.class.equals(value.getClass())) {
+ bvalue = (Boolean)value;
+ } else {
+ bvalue = Boolean.parseBoolean(value.toString());
+ }
- result = connection.loadLiteral(bvalue);
- if(result == null) {
- result= new KiWiBooleanLiteral(bvalue, rtype);
- }
- } else {
- result = connection.loadLiteral(value.toString(), lang, rtype);
+ result = connection.loadLiteral(bvalue);
- if(result == null) {
- result = new KiWiStringLiteral(value.toString(), locale, rtype);
+ if(result == null) {
+ result= new KiWiBooleanLiteral(bvalue, rtype);
+ }
+ } else {
+ result = connection.loadLiteral(value.toString(), lang, rtype);
+
+ if(result == null) {
+ result = new KiWiStringLiteral(value.toString(), locale, rtype);
+ }
}
- }
- if(result.getId() == null) {
- if(batchCommit) {
- result.setId(connection.getNodeId());
- synchronized (nodeBatch) {
- nodeBatch.add(result);
- batchLiteralLookup.put(LiteralCommons.createCacheKey(value.toString(),locale,type), result);
-
- if(nodeBatch.size() >= batchSize) {
- flushBatch(connection);
+ if(result.getId() == null) {
+ if(batchCommit) {
+ result.setId(connection.getNodeId());
+ synchronized (nodeBatch) {
+ nodeBatch.add(result);
+ batchLiteralLookup.put(LiteralCommons.createCacheKey(value.toString(),locale,type), result);
+
+ if(nodeBatch.size() >= batchSize) {
+ flushBatch(connection);
+ }
}
+ } else {
+ connection.storeNode(result, false);
}
- } else {
- connection.storeNode(result, false);
}
- }
- return result;
+ return result;
- } catch (SQLException e) {
- log.error("database error, could not load literal",e);
- throw new IllegalStateException("database error, could not load literal",e);
- } finally {
- releaseConnection(connection);
- lock.unlock();
+ } catch (SQLException e) {
+ log.error("database error, could not load literal",e);
+ throw new IllegalStateException("database error, could not load literal",e);
+ } finally {
+ releaseConnection(connection);
+ }
}
+ } finally {
+ lock.leave();
}
}
@@ -790,27 +757,28 @@ public class KiWiValueFactory implements ValueFactory {
* the node batch.
*/
public void flushBatch(KiWiConnection con) throws SQLException {
- commitLock.lock();
- try {
- if(batchCommit && nodeBatch.size() > 0) {
- con.startNodeBatch();
+ if(commitLock.tryEnter()) {
+ try {
+ if(batchCommit && nodeBatch.size() > 0) {
+ con.startNodeBatch();
- synchronized (nodeBatch) {
- for(KiWiNode n : nodeBatch) {
- con.storeNode(n,true);
- }
- nodeBatch.clear();
+ synchronized (nodeBatch) {
+ for(KiWiNode n : nodeBatch) {
+ con.storeNode(n,true);
+ }
+ nodeBatch.clear();
- batchLiteralLookup.clear();
- batchUriLookup.clear();
- batchBNodeLookup.clear();
- }
+ batchLiteralLookup.clear();
+ batchUriLookup.clear();
+ batchBNodeLookup.clear();
+ }
- con.commitNodeBatch();
+ con.commitNodeBatch();
+ }
+ } finally {
+ commitLock.leave();
}
- } finally {
- commitLock.unlock();
}
}
@@ -825,4 +793,14 @@ public class KiWiValueFactory implements ValueFactory {
log.warn("could not close value factory connection: {}",e.getMessage());
}
}
+
+ /**
+ * A simple Guava cache loader implementation for generating object-based locks
+ */
+ private static class LockCacheLoader extends CacheLoader<Object,Monitor> {
+ @Override
+ public Monitor load(Object key) throws Exception {
+ return new Monitor();
+ }
+ }
}